1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 /* PDF 1.4 blending functions */
17 
18 #ifndef gxblend_INCLUDED
19 #  define gxblend_INCLUDED
20 
21 #include "gxcindex.h"
22 #include "gxcvalue.h"
23 #include "gxfrac.h"
24 #include "gxdevcli.h"
25 
26 #define RAW_DUMP 0
27 #define RAW_DUMP_AS_PAM 0
28 /* Useful bash fragment to batch convert pams to pngs:
29  * for f in *.pam; do g=${f%.*}; echo $g; convert $g.pam $g.png ; done
30  * NB: "convert" is imagemagick convert, so may need to be installed.
31  */
32 
33 /* #define DUMP_TO_PNG */
34 
35 #define	PDF14_MAX_PLANES GX_DEVICE_COLOR_MAX_COMPONENTS+3  /* Needed for alpha channel, shape, group alpha */
36 
37 typedef bits16 ArtPixMaxDepth;
38 
39 #define ART_MAX_CHAN GX_DEVICE_COLOR_MAX_COMPONENTS
40 
41 typedef struct pdf14_device_s pdf14_device;
42 
43 typedef struct pdf14_buf_s pdf14_buf;
44 
45 typedef struct gs_separations_s gs_separations;
46 
47 /*
48  * This structure contains procedures for processing which differ
49  * between the different blending color spaces.
50  *
51  * The Luminosity, Color, Saturation, and Hue blend modes depend
52  * upon the blending color space.  Currently the blending color space
53  * matches the process color model of the compositing device.  We need
54  * two routines to implement the four 'non separable' blend modes.
55  */
56 typedef struct {
57     /*
58      * Perform luminosity and color blending.  (Also used for hue blending.)
59      */
60     void (* blend_luminosity)(int n_chan, byte *gs_restrict dst,
61                     const byte *gs_restrict backdrop, const byte *gs_restrict src);
62     /*
63      * Perform saturation blending.  (Also used for hue blending.)
64      */
65     void (* blend_saturation)(int n_chan, byte *gs_restrict dst,
66                     const byte *gs_restrict backdrop, const byte *gs_restrict src);
67     /* And 16 bit variants */
68     void (* blend_luminosity16)(int n_chan, uint16_t *gs_restrict dst,
69                     const uint16_t *gs_restrict backdrop, const uint16_t *gs_restrict src);
70     void (* blend_saturation16)(int n_chan, uint16_t *gs_restrict dst,
71                     const uint16_t *gs_restrict backdrop, const uint16_t *gs_restrict src);
72 } pdf14_nonseparable_blending_procs_s;
73 
74 typedef pdf14_nonseparable_blending_procs_s
75                 pdf14_nonseparable_blending_procs_t;
76 
77 /* This is used to so that we can change procedures based
78  * upon the Smask color space. previously we always
79  *  went to the device space */
80 
81 typedef struct {
82 
83     pdf14_nonseparable_blending_procs_t device_procs;
84     gx_device_procs color_mapping_procs;
85 
86 } pdf14_parent_cs_params_s;
87 
88 typedef pdf14_parent_cs_params_s pdf14_parent_cs_params_t;
89 
90 /* This function is used for mapping Smask CMYK or RGB data to a monochrome alpha buffer */
91 void smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride,
92                               int plane_stride, const byte *gs_restrict src, byte *gs_restrict des, bool isadditive,
93                               gs_transparency_mask_subtype_t SMask_SubType, bool deep
94 #if RAW_DUMP
95                               , const gs_memory_t *mem
96 #endif
97                               );
98 void smask_blend(byte *gs_restrict src, int width, int height, int rowstride,
99                  int planestride, bool deep);
100 
101 void smask_copy(int num_rows, int num_cols, int row_stride,
102                          byte *gs_restrict src, const byte *gs_restrict des);
103 void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan,
104                int row_stride, int plane_stride, byte *gs_restrict src, const byte *gs_restrict des,
105                gsicc_link_t *icclink, bool deep);
106 /* For spot colors, blend modes must be white preserving and separable */
107 bool blend_valid_for_spot(gs_blend_mode_t blend_mode);
108 
109 /**
110  * art_blend_pixel_8: Compute PDF 1.4 blending function on 8-bit pixels.
111  * @dst: Where to store resulting pixel.
112  * @backdrop: Backdrop pixel color.
113  * @src: Source pixel color.
114  * @n_chan: Number of channels.
115  * @blend_mode: Blend mode.
116  * @pblend_procs: Procs for handling non separable blending modes.
117  * @p14dev: pdf14 device.  Needed for handling CompatibleOverprint mode
118  *
119  * Computes the blend of two pixels according the PDF 1.4 transparency
120  * spec (section 3.2, Blend Mode). A few things to keep in mind about
121  * this implementation:
122  *
123  * 1. This is a reference implementation, not a high-performance one.
124  * Blending using this function will incur a function call and switch
125  * statement per pixel, and will also incur the extra cost of 16 bit
126  * math.
127  *
128  * 2. Zero is black, one is white. In a subtractive color space such
129  * as CMYK, all pixels should be represented as "complemented", as
130  * described in section 3.1 (Blending Color Space) of the PDF 1.4
131  * transparency spec.
132  *
133  * 3. I haven't really figured out how to handle the Compatible blend
134  * mode. I wouldn't be surprised if it required an API change.
135  **/
136 void
137 art_blend_pixel_8(byte *gs_restrict dst, const byte *gs_restrict backdrop,
138                 const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode,
139                 const pdf14_nonseparable_blending_procs_t * pblend_procs,
140                 pdf14_device *p14dev);
141 
142 void
143 art_blend_pixel_16(uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
144                    const uint16_t *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode,
145                    const pdf14_nonseparable_blending_procs_t * pblend_procs,
146                    pdf14_device *p14dev);
147 
148 #ifdef UNUSED
149 /**
150  * art_pdf_union_8: Union together two alpha values.
151  * @alpha1: One alpha value.
152  * @alpha2: Another alpha value.
153  *
154  * Return value: Union (@alpha1, @alpha2).
155  **/
156 byte art_pdf_union_8(byte alpha1, byte alpha2);
157 #endif
158 
159 /**
160  * art_pdf_union_mul_8: Union together two alpha values, with mask.
161  * @alpha1: One alpha value.
162  * @alpha2: Another alpha value.
163  * @alpha_mask: A mask alpha value;
164  *
165  * Return value: Union (@alpha1, @alpha2 * @alpha_mask).
166  **/
167 /* byte art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask); */
168 
169 static inline byte
art_pdf_union_mul_8(byte alpha1,byte alpha2,byte alpha_mask)170 art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask)
171 {
172     int tmp;
173     if (alpha_mask != 0xff)
174     {
175         tmp = alpha2 * alpha_mask + 0x80;
176         alpha2 = (tmp + (tmp >> 8))>>8;
177     }
178     tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80;
179     return 0xff - ((tmp + (tmp >> 8)) >> 8);
180 }
181 
182 static inline uint16_t
art_pdf_union_mul_16(uint16_t alpha1,uint16_t alpha2_,uint16_t alpha_mask)183 art_pdf_union_mul_16(uint16_t alpha1, uint16_t alpha2_, uint16_t alpha_mask)
184 {
185     int alpha2 = alpha2_;
186     if (alpha_mask != 0xffff)
187     {
188         int am = alpha_mask + (alpha_mask>>15);
189         alpha2 = (alpha2 * am + 0x8000)>>16;
190     }
191     alpha2 += alpha2>>15;
192     alpha2 = ((0xffff - alpha1) * (0x10000 - alpha2) + 0x8000)>>16;
193     return 0xffff - (alpha2 >> 16);
194 }
195 
196 /**
197  * art_pdf_composite_pixel_alpha_8: Composite two alpha pixels.
198  * @dst: Where to store resulting pixel, also initially backdrop color.
199  * @src: Source pixel color.
200  * @n_chan: Number of channels.
201  * @blend_mode: Blend mode.
202  * @pblend_procs: Procs for handling non separable blending modes.
203  * @p14dev: pdf14 device.
204  *
205  * Composites two pixels using the basic compositing operation. A few
206  * things to keep in mind:
207  *
208  * 1. This is a reference implementation, not a high-performance one.
209  *
210  * 2. All pixels are assumed to have a single alpha channel.
211  *
212  * 3. Zero is black, one is white.
213  *
214  * The first "first_spot" channels are blended with blend_mode. The
215  * remaining channels are blended with BLEND_MODE_Normal.
216  *
217  * Also note that src and dst are expected to be allocated aligned to
218  * 32 bit boundaries, ie bytes from [0] to [(n_chan + 3) & -4] may
219  * be accessed.
220  **/
221 void
222 art_pdf_composite_pixel_alpha_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan,
223         gs_blend_mode_t blend_mode, int first_spot,
224         const pdf14_nonseparable_blending_procs_t * pblend_procs,
225         pdf14_device *p14dev);
226 
227 void
228 art_pdf_composite_pixel_alpha_16(uint16_t *gs_restrict dst, const uint16_t *gs_restrict src, int n_chan,
229         gs_blend_mode_t blend_mode, int first_spot,
230         const pdf14_nonseparable_blending_procs_t * pblend_procs,
231         pdf14_device *p14dev);
232 
233 /**
234  * art_pdf_composite_knockout_8: knockout compositing.
235  * @dst: Destination pixel array -- has been initialized with background
236  * @src: Source pixel.
237  * n_chan: Number of channels.
238  * p14dev: pdf14 device
239  *
240  * This function handles the knockout case: an isolated knockout group,
241  * and an elementary shape. The alpha channel of @src is interpreted as shape.
242  **/
243 void
244 art_pdf_composite_knockout_8(byte *gs_restrict dst,
245                                     const byte *gs_restrict src,
246                                     int n_chan,
247                                     gs_blend_mode_t blend_mode,
248                                     const pdf14_nonseparable_blending_procs_t * pblend_procs,
249                                     pdf14_device *p14dev);
250 
251 void
252 art_pdf_composite_knockout_16(uint16_t *gs_restrict dst,
253                                     const uint16_t *gs_restrict src,
254                                     int n_chan,
255                                     gs_blend_mode_t blend_mode,
256                                     const pdf14_nonseparable_blending_procs_t * pblend_procs,
257                                     pdf14_device *p14dev);
258 
259 /**
260  * art_pdf_knockoutisolated_group_8: Knockout for isolated group.
261  * @dst: Destination pixel.
262  * @src: Source pixel.
263  * @n_chan: Number of channels.
264  *
265  * This function handles the simple case with an isolated knockout group.
266  **/
267 void
268 art_pdf_knockoutisolated_group_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan);
269 
270 void
271 art_pdf_knockoutisolated_group_16(uint16_t *gs_restrict dst, const uint16_t *gs_restrict src, int n_chan);
272 
273 /**
274 * art_pdf_knockoutisolated_group_8: Knockout for isolated group.
275 * @dst: Destination pixel.
276 * @src: Source pixel.
277 * @src_alpha: current alpha from the graphic state
278 * @aa_alpha:  alpha coming from the anti-aliasing buffer
279 * @n_chan: Number of channels.
280 * @p14dev: pdf14 device
281 *
282 * This function handles the simple case with an isolated knockout group but where
283 * we have an alpha from AA and from the current graphic state.
284 **/
285 void
286 art_pdf_knockoutisolated_group_aa_8(byte *gs_restrict dst, const byte *gs_restrict src, byte src_alpha,
287     byte aa_alpha, int n_chan, pdf14_device *p14dev);
288 
289 /*
290  * Routines for handling the non separable blending modes.
291  */
292 /* RGB blending color space */
293 void art_blend_luminosity_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
294                            const byte *gs_restrict src);
295 void art_blend_saturation_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
296                            const byte *gs_restrict src);
297 void art_blend_luminosity_rgb_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
298                            const uint16_t *gs_restrict src);
299 void art_blend_saturation_rgb_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
300                            const uint16_t *gs_restrict src);
301 /* CMYK and CMYK + spot blending color space */
302 void art_blend_saturation_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
303                            const byte *gs_restrict src);
304 void art_blend_luminosity_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
305                            const byte *gs_restrict src);
306 void art_blend_saturation_cmyk_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
307                            const uint16_t *gs_restrict src);
308 void art_blend_luminosity_cmyk_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
309                            const uint16_t *gs_restrict src);
310 /* 'Custom' i.e. unknown blending color space. */
311 void art_blend_luminosity_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
312                            const byte *gs_restrict src);
313 void art_blend_saturation_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop,
314                            const byte *gs_restrict src);
315 void art_blend_luminosity_custom_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
316                            const uint16_t *gs_restrict src);
317 void art_blend_saturation_custom_16(int n_chan, uint16_t *gs_restrict dst, const uint16_t *gs_restrict backdrop,
318                            const uint16_t *gs_restrict src);
319 
320 void pdf14_unpack_rgb_mix(int num_comp, gx_color_index color,
321                           pdf14_device * p14dev, byte * out);
322 void pdf14_unpack_gray_mix(int num_comp, gx_color_index color,
323                            pdf14_device * p14dev, byte * out);
324 void pdf14_unpack_additive(int num_comp, gx_color_index color,
325                            pdf14_device * p14dev, byte * out);
326 void pdf14_unpack_subtractive(int num_comp, gx_color_index color,
327                               pdf14_device * p14dev, byte * out);
328 void pdf14_unpack_custom(int num_comp, gx_color_index color,
329                          pdf14_device * p14dev, byte * out);
330 
331 void pdf14_unpack16_rgb_mix(int num_comp, gx_color_index color,
332                             pdf14_device * p14dev, uint16_t * out);
333 void pdf14_unpack16_gray_mix(int num_comp, gx_color_index color,
334                              pdf14_device * p14dev, uint16_t * out);
335 void pdf14_unpack16_additive(int num_comp, gx_color_index color,
336                              pdf14_device * p14dev, uint16_t * out);
337 void pdf14_unpack16_subtractive(int num_comp, gx_color_index color,
338                                 pdf14_device * p14dev, uint16_t * out);
339 void pdf14_unpack16_custom(int num_comp, gx_color_index color,
340                            pdf14_device * p14dev, uint16_t * out);
341 
342 void pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool knockout_buff
343 #if RAW_DUMP
344                              , gs_memory_t *mem
345 #endif
346                              );
347 
348 int pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile,
349                                pdf14_buf *tos, cmm_profile_t *tos_profile,
350                                gs_memory_t *memory, gs_gstate *pgs,
351                                gx_device *dev, bool knockout_buff);
352 
353 void pdf14_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
354               int x0, int x1, int y0, int y1, int n_chan, bool additive,
355               const pdf14_nonseparable_blending_procs_t * pblend_procs,
356               bool has_matte, bool overprint, gx_color_index drawn_comps,
357               gs_memory_t *memory, gx_device *dev);
358 
359 void pdf14_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos,
360                                    int x0, int x1, int y0, int y1,
361                                    gs_memory_t *memory, gx_device *dev);
362 
363 gx_color_index pdf14_encode_color(gx_device *dev, const gx_color_value colors[]);
364 gx_color_index pdf14_encode_color_tag(gx_device *dev, const gx_color_value colors[]);
365 gx_color_index pdf14_encode_color16(gx_device *dev, const gx_color_value colors[]);
366 gx_color_index pdf14_encode_color16_tag(gx_device *dev, const gx_color_value colors[]);
367 
368 int pdf14_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out);
369 int pdf14_decode_color16(gx_device * dev, gx_color_index color, gx_color_value * out);
370 void pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]);
371 void pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs,
372                            frac r, frac g, frac b, frac out[]);
373 void pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]);
374 
375 void pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]);
376 void pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs,
377     frac r, frac g, frac b, frac out[]);
378 void pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]);
379 
380 void pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]);
381 void pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs,
382     frac r, frac g, frac b, frac out[]);
383 void pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]);
384 
385 void gx_build_blended_image_row(const byte *gs_restrict buf_ptr, int planestride,
386                                 int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
387 void gx_build_blended_image_row16(const byte *gs_restrict buf_ptr, int planestride,
388                                   int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
389 void gx_blend_image_buffer(byte *buf_ptr, int width, int height,
390                       int rowstride, int planestride, int num_comp, byte bg);
391 void gx_blend_image_buffer16(byte *buf_ptr, int width, int height,
392     int rowstride, int planestride, int num_comp, uint16_t bg);
393 void gx_blend_image_buffer8to16(const byte *buf_ptr, unsigned short *buf_ptr_out,
394     int width, int height, int rowstride, int planestride, int num_comp, byte bg);
395 int gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr,
396                       int planestride, int rowstride,
397                       int x0, int y0, int width, int height, int num_comp, uint16_t bg,
398                       bool has_tags, gs_int_rect rect, gs_separations *pseparations, bool deep);
399 int gx_put_blended_image_custom(gx_device *target, byte *buf_ptr,
400                       int planestride, int rowstride,
401                       int x0, int y0, int width, int height, int num_comp, uint16_t bg, bool deep);
402 
403 /* Function moved between compilation units to allow inlining. */
404 int pdf14_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
405                                      gx_color_index color, const gx_device_color *pdc,
406                                      bool devn);
407 
408 
409 
410 #if RAW_DUMP
411 
412 void dump_raw_buffer(const gs_memory_t *mem,
413                      int num_rows, int width, int n_chan,
414                      int plane_stride, int rowstride,
415                      char filename[],const byte *Buffer, bool deep);
416 void dump_raw_buffer_be(const gs_memory_t *mem,
417                         int num_rows, int width, int n_chan,
418                         int plane_stride, int rowstride,
419                         char filename[],const byte *Buffer, bool deep);
420 #endif
421 
422 #endif /* gxblend_INCLUDED */
423