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 
17 /* Extended halftone operators for Ghostscript library */
18 #include "memory_.h"
19 #include "string_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gsstruct.h"
23 #include "gsutil.h"		/* for gs_next_ids */
24 #include "gzstate.h"
25 #include "gxdevice.h"		/* for gzht.h */
26 #include "gzht.h"
27 
28 
29 /* Imports from gscolor.c */
30 void load_transfer_map(gs_gstate *, gx_transfer_map *, double);
31 
32 /* Forward declarations */
33 static int process_spot(gx_ht_order *, gs_gstate *,
34                          gs_spot_halftone *, gs_memory_t *);
35 static int process_threshold(gx_ht_order *, gs_gstate *,
36                               gs_threshold_halftone *, gs_memory_t *);
37 static int process_threshold2(gx_ht_order *, gs_gstate *,
38                                gs_threshold2_halftone *, gs_memory_t *);
39 static int process_client_order(gx_ht_order *, gs_gstate *,
40                                  gs_client_order_halftone *, gs_memory_t *);
41 
42 /* Structure types */
43 public_st_halftone_component();
44 public_st_ht_component_element();
45 
46 /* GC procedures */
47 
48 static
49 ENUM_PTRS_WITH(halftone_component_enum_ptrs, gs_halftone_component *hptr) return 0;
50 case 0:
51 switch (hptr->type)
52 {
53     case ht_type_spot:
54 ENUM_RETURN((hptr->params.spot.transfer == 0 ?
55              hptr->params.spot.transfer_closure.data :
56              0));
57     case ht_type_threshold:
58 ENUM_RETURN_CONST_STRING_PTR(gs_halftone_component,
59                              params.threshold.thresholds);
60     case ht_type_threshold2:
61 return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds);
62     case ht_type_client_order:
63 ENUM_RETURN(hptr->params.client_order.client_data);
64     default:			/* not possible */
65 return 0;
66 }
67 case 1:
68 switch (hptr->type) {
69     case ht_type_threshold:
70         ENUM_RETURN((hptr->params.threshold.transfer == 0 ?
71                      hptr->params.threshold.transfer_closure.data :
72                      0));
73     case ht_type_threshold2:
74         ENUM_RETURN(hptr->params.threshold2.transfer_closure.data);
75     case ht_type_client_order:
76         ENUM_RETURN(hptr->params.client_order.transfer_closure.data);
77     default:
78         return 0;
79 }
80 ENUM_PTRS_END
RELOC_PTRS_WITH(halftone_component_reloc_ptrs,gs_halftone_component * hptr)81 static RELOC_PTRS_WITH(halftone_component_reloc_ptrs, gs_halftone_component *hptr)
82 {
83     switch (hptr->type) {
84         case ht_type_spot:
85             if (hptr->params.spot.transfer == 0)
86                 RELOC_VAR(hptr->params.spot.transfer_closure.data);
87             break;
88         case ht_type_threshold:
89             RELOC_CONST_STRING_VAR(hptr->params.threshold.thresholds);
90             if (hptr->params.threshold.transfer == 0)
91                 RELOC_VAR(hptr->params.threshold.transfer_closure.data);
92             break;
93         case ht_type_threshold2:
94             RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds);
95             RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data);
96             break;
97         case ht_type_client_order:
98             RELOC_VAR(hptr->params.client_order.client_data);
99             RELOC_VAR(hptr->params.client_order.transfer_closure.data);
100             break;
101         default:
102             break;
103     }
104 }
105 RELOC_PTRS_END
106 
107 /* setcolorscreen */
108 int
gs_setcolorscreen(gs_gstate * pgs,gs_colorscreen_halftone * pht)109 gs_setcolorscreen(gs_gstate * pgs, gs_colorscreen_halftone * pht)
110 {
111     gs_halftone ht;
112 
113     ht.type = ht_type_colorscreen;
114     ht.params.colorscreen = *pht;
115     return gs_sethalftone(pgs, &ht);
116 }
117 
118 /* currentcolorscreen */
119 int
gs_currentcolorscreen(gs_gstate * pgs,gs_colorscreen_halftone * pht)120 gs_currentcolorscreen(gs_gstate * pgs, gs_colorscreen_halftone * pht)
121 {
122     int code;
123 
124     switch (pgs->halftone->type) {
125         case ht_type_colorscreen:
126             *pht = pgs->halftone->params.colorscreen;
127             return 0;
128         default:
129             code = gs_currentscreen(pgs, &pht->screens.colored.gray);
130             if (code < 0)
131                 return code;
132             pht->screens.colored.red = pht->screens.colored.gray;
133             pht->screens.colored.green = pht->screens.colored.gray;
134             pht->screens.colored.blue = pht->screens.colored.gray;
135             return 0;
136     }
137 }
138 
139 /* Set the halftone in the graphics state. */
140 int
gs_sethalftone(gs_gstate * pgs,gs_halftone * pht)141 gs_sethalftone(gs_gstate * pgs, gs_halftone * pht)
142 {
143     gs_halftone ht;
144 
145     ht = *pht;
146     ht.rc.memory = pgs->memory;
147     return gs_sethalftone_allocated(pgs, &ht);
148 }
149 int
gs_sethalftone_allocated(gs_gstate * pgs,gs_halftone * pht)150 gs_sethalftone_allocated(gs_gstate * pgs, gs_halftone * pht)
151 {
152     gx_device_halftone dev_ht;
153     int code = gs_sethalftone_prepare(pgs, pht, &dev_ht);
154 
155     if (code < 0)
156         return code;
157     dev_ht.rc.memory = pht->rc.memory;
158     if ((code = gx_ht_install(pgs, pht, &dev_ht)) < 0)
159         gx_device_halftone_release(&dev_ht, pht->rc.memory);
160     return code;
161 }
162 
163 /* Prepare the halftone, but don't install it. */
164 int
gs_sethalftone_prepare(gs_gstate * pgs,gs_halftone * pht,gx_device_halftone * pdht)165 gs_sethalftone_prepare(gs_gstate * pgs, gs_halftone * pht,
166                        gx_device_halftone * pdht)
167 {
168     gs_memory_t *mem = pht->rc.memory;
169     gx_ht_order_component *pocs = 0;
170     int code = 0;
171 
172     switch (pht->type) {
173         case ht_type_colorscreen:
174             {
175                 gs_screen_halftone *phc =
176                     pht->params.colorscreen.screens.indexed;
177                 static const int cindex[4] = {3, 0, 1, 2};
178                 static const char * color_names[4] = {"Gray", "Red", "Green", "Blue"};
179                 int i;
180 
181                 pocs = gs_alloc_struct_array(mem, 4,
182                                              gx_ht_order_component,
183                                              &st_ht_order_component_element,
184                                              "gs_sethalftone");
185                 if (pocs == 0)
186                     return_error(gs_error_VMerror);
187                 for (i = 0; i < 4; i++) {
188                     gs_screen_enum senum;
189                     int ci = cindex[i];
190                     gx_ht_order_component *poc = &pocs[i];
191 
192                     code = gx_ht_process_screen_memory(&senum, pgs, &phc[ci],
193                                         gs_currentaccuratescreens(mem), mem);
194                     if (code < 0)
195                         break;
196                     poc->corder = senum.order;
197                     poc->comp_number = gs_color_name_component_number(pgs->device,
198                                 color_names[i], strlen(color_names[i]), pht->type);
199                     poc->cname = 0;  /* name index values are not known (or needed) */
200                     if (i == 0)	/* Gray = Default */
201                         pdht->order = poc->corder;	/* Save default value */
202                 }
203                 if (code < 0)
204                     break;
205                 pdht->components = pocs;
206                 pdht->num_comp = 4;
207             }
208             break;
209         case ht_type_spot:
210             code = process_spot(&pdht->order, pgs, &pht->params.spot, mem);
211             if (code < 0)
212                 return code;
213             pdht->components = 0;
214             break;
215         case ht_type_threshold:
216             code = process_threshold(&pdht->order, pgs,
217                                      &pht->params.threshold, mem);
218             if (code < 0)
219                 return code;
220             pdht->components = 0;
221             break;
222         case ht_type_threshold2:
223             code = process_threshold2(&pdht->order, pgs,
224                                       &pht->params.threshold2, mem);
225             if (code < 0)
226                 return code;
227             pdht->components = 0;
228             break;
229         case ht_type_client_order:
230             code = process_client_order(&pdht->order, pgs,
231                                         &pht->params.client_order, mem);
232             if (code < 0)
233                 return code;
234             pdht->components = 0;
235             break;
236         case ht_type_multiple:
237         case ht_type_multiple_colorscreen:
238             {
239                 uint count = pht->params.multiple.num_comp;
240                 bool have_Default = false;
241                 uint i;
242                 gs_halftone_component *phc = pht->params.multiple.components;
243                 gx_ht_order_component *poc_next;
244 
245                 pocs = gs_alloc_struct_array(mem, count,
246                                              gx_ht_order_component,
247                                              &st_ht_order_component_element,
248                                              "gs_sethalftone");
249                 if (pocs == 0)
250                     return_error(gs_error_VMerror);
251                 poc_next = pocs + 1;
252                 for (i = 0; i < count; i++, phc++) {
253                     gx_ht_order_component *poc;
254 
255                     if (phc->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
256                         if (have_Default) {
257                             /* Duplicate Default */
258                             code = gs_note_error(gs_error_rangecheck);
259                             break;
260                         }
261                         poc = pocs;
262                         have_Default = true;
263                     } else if (i == count - 1 && !have_Default) {
264                         /* No Default */
265                         code = gs_note_error(gs_error_rangecheck);
266                         break;
267                     } else
268                         poc = poc_next++;
269 
270                     poc->comp_number = phc->comp_number;
271                     poc->cname = phc->cname;
272                     switch (phc->type) {
273                         case ht_type_spot:
274                             code = process_spot(&poc->corder, pgs,
275                                                 &phc->params.spot, mem);
276                             break;
277                         case ht_type_threshold:
278                             code = process_threshold(&poc->corder, pgs,
279                                                 &phc->params.threshold, mem);
280                             break;
281                         case ht_type_threshold2:
282                             code = process_threshold2(&poc->corder, pgs,
283                                                 &phc->params.threshold2, mem);
284                             break;
285                         case ht_type_client_order:
286                             code = process_client_order(&poc->corder, pgs,
287                                             &phc->params.client_order, mem);
288                             break;
289                         default:
290                             code = gs_note_error(gs_error_rangecheck);
291                             break;
292                     }
293                     if (code < 0)
294                         break;
295                 }
296                 if (code < 0)
297                     break;
298                 pdht->order = pocs[0].corder;	/* Default */
299                 if (count == 1) {
300                     /* We have only a Default; */
301                     /* we don't need components. */
302                     gs_free_object(mem, pocs, "gs_sethalftone");
303                     pdht->components = 0;
304                     pdht->num_comp = 0;
305                 } else {
306                     pdht->components = pocs;
307                     pdht->num_comp = count;
308                 }
309             }
310             break;
311         default:
312             return_error(gs_error_rangecheck);
313     }
314     if (code < 0)
315         gs_free_object(mem, pocs, "gs_sethalftone");
316     return code;
317 }
318 
319 /* ------ Internal routines ------ */
320 
321 /* Process a transfer function override, if any. */
322 static int
process_transfer(gx_ht_order * porder,gs_gstate * pgs,gs_mapping_proc proc,gs_mapping_closure_t * pmc,gs_memory_t * mem)323 process_transfer(gx_ht_order * porder, gs_gstate * pgs,
324                  gs_mapping_proc proc, gs_mapping_closure_t * pmc,
325                  gs_memory_t * mem)
326 {
327     gx_transfer_map *pmap;
328 
329     if (proc == 0 && pmc->proc == 0)
330         return 0;
331     /*
332      * The transfer funtion is referenced by the order, so start the
333      * reference count at 1.
334      */
335     rc_alloc_struct_1(pmap, gx_transfer_map, &st_transfer_map, mem,
336                       return_error(gs_error_VMerror),
337                       "process_transfer");
338     pmap->proc = proc;		/* 0 => use closure */
339     pmap->closure = *pmc;
340     pmap->id = gs_next_ids(mem, 1);
341     porder->transfer = pmap;
342     if (proc == gs_mapped_transfer)
343         return 0; /* nothing to load, the source is uninitialzed */
344     load_transfer_map(pgs, pmap, 0.0);
345     return 0;
346 }
347 
348 /* Process a spot plane. */
349 static int
process_spot(gx_ht_order * porder,gs_gstate * pgs,gs_spot_halftone * phsp,gs_memory_t * mem)350 process_spot(gx_ht_order * porder, gs_gstate * pgs,
351              gs_spot_halftone * phsp, gs_memory_t * mem)
352 {
353     gs_screen_enum senum;
354 
355     int code = gx_ht_process_screen_memory(&senum, pgs, &phsp->screen,
356                                            phsp->accurate_screens, mem);
357 
358     if (code < 0)
359         return code;
360     *porder = senum.order;
361     return process_transfer(porder, pgs, phsp->transfer,
362                             &phsp->transfer_closure, mem);
363 }
364 
365 /* Construct the halftone order from a threshold array. */
366 void
gx_ht_complete_threshold_order(gx_ht_order * porder)367 gx_ht_complete_threshold_order(gx_ht_order * porder)
368 {
369     int num_levels = porder->num_levels;
370     uint *levels = porder->levels;
371     uint size = porder->num_bits;
372     gx_ht_bit *bits = porder->bit_data;
373     uint i, j;
374 
375     /* The caller has set bits[i] = max(1, thresholds[i]). */
376     gx_sort_ht_order(bits, size);
377     /* We want to set levels[j] to the lowest value of i */
378     /* such that bits[i].mask > j. */
379     for (i = 0, j = 0; i < size; i++) {
380         if (bits[i].mask != j) {
381             if_debug3('h', "[h]levels[%u..%u] = %u\n",
382                       j, (uint) bits[i].mask, i);
383             while (j < bits[i].mask)
384                 levels[j++] = i;
385         }
386     }
387     while (j < num_levels)
388         levels[j++] = size;
389     gx_ht_construct_bits(porder);
390 }
391 int
gx_ht_construct_threshold_order(gx_ht_order * porder,const byte * thresholds)392 gx_ht_construct_threshold_order(gx_ht_order * porder, const byte * thresholds)
393 {
394     return porder->procs->construct_order(porder, thresholds);
395 }
396 
397 /* Process a threshold plane. */
398 static int
process_threshold(gx_ht_order * porder,gs_gstate * pgs,gs_threshold_halftone * phtp,gs_memory_t * mem)399 process_threshold(gx_ht_order * porder, gs_gstate * pgs,
400                   gs_threshold_halftone * phtp, gs_memory_t * mem)
401 {
402     int code;
403 
404     porder->params.M = phtp->width, porder->params.N = 0;
405     porder->params.R = 1;
406     porder->params.M1 = phtp->height, porder->params.N1 = 0;
407     porder->params.R1 = 1;
408     code = gx_ht_alloc_threshold_order(porder, phtp->width, phtp->height,
409                                        256, mem);
410     if (code < 0)
411         return code;
412     gx_ht_construct_threshold_order(porder, phtp->thresholds.data);
413     return process_transfer(porder, pgs, phtp->transfer,
414                             &phtp->transfer_closure, mem);
415 }
416 
417 /* Process an extended threshold plane. */
418 static int
process_threshold2(gx_ht_order * porder,gs_gstate * pgs,gs_threshold2_halftone * phtp,gs_memory_t * mem)419 process_threshold2(gx_ht_order * porder, gs_gstate * pgs,
420                    gs_threshold2_halftone * phtp, gs_memory_t * mem)
421 {
422     int code;
423     /*
424      * There are potentially 64K different levels for this plane, but this
425      * is more than we're willing to handle.  Try to reduce the number of
426      * levels by dropping leading or trailing zero bits from the thresholds;
427      * as a last resort, drop (possibly significant) trailing bits.
428      */
429 #define LOG2_MAX_HT_LEVELS 14
430 #define MAX_HT_LEVELS (1 << LOG2_MAX_HT_LEVELS)
431     int bps = phtp->bytes_per_sample;
432     const byte *data = phtp->thresholds.data;
433     const int w1 = phtp->width, h1 = phtp->height, size1 = w1 * h1;
434     const int w2 = phtp->width2, h2 = phtp->height2, size2 = w2 * h2;
435     const uint size = size1 + size2;
436     const int d = (h2 == 0 ? h1 : igcd(h1, h2));
437     const int sod = size / d;
438     uint num_levels;
439     uint i;
440     int rshift = 0;
441     int shift;
442 
443     {
444         uint mask = 0, max_thr = 0;
445 
446         for (i = 0; i < size; ++i) {
447             uint thr =
448                 (bps == 1 ? data[i] : (data[i * 2] << 8) + data[i * 2 + 1]);
449 
450             mask |= thr;
451             max_thr = max(max_thr, thr);
452         }
453         if (mask == 0)
454             mask = 1, max_thr = 1;
455         while (!(mask & 1) || max_thr > MAX_HT_LEVELS)
456             mask >>= 1, max_thr >>= 1, rshift++;
457         num_levels = max_thr + 1;
458     }
459     /*
460      * Set nominal values for the params, and don't bother to call
461      * gx_compute_cell_values -- the values are only needed for spot
462      * halftones.
463      */
464     porder->params.M = sod, porder->params.N = d;
465     porder->params.R = 1;
466     porder->params.M1 = d, porder->params.N1 = sod;
467     porder->params.R1 = 1;
468     /*
469      * Determine the shift between strips.  We don't know a closed formula
470      * for this, so we do it by enumeration.
471      */
472     shift = 0;
473     {
474         int x = 0, y = 0;
475 
476         do {
477             if (y < h1)
478                 x += w1, y += h2;
479             else
480                 x += w2, y -= h1;
481         } while (y > d);
482         if (y)
483             shift = x;
484     }
485     code = gx_ht_alloc_ht_order(porder, sod, d, num_levels, size, shift,
486                                 &ht_order_procs_default, mem);
487     if (code < 0)
488         return code;
489     {
490         gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
491         int row, di;
492 
493         if_debug7m('h', mem, "[h]rect1=(%d,%d), rect2=(%d,%d), strip=(%d,%d), shift=%d\n",
494                    w1, h1, w2, h2, sod, d, shift);
495         for (row = 0, di = 0; row < d; ++row) {
496             /* Iterate over destination rows. */
497             int dx, sy = row;	/* sy = row mod d */
498             int w;
499 
500             for (dx = 0; dx < sod; dx += w) {
501                 /* Iterate within a destination row, over source rows. */
502                 int si, j;
503 
504                 if (sy < h1) {
505                     /* Copy a row from rect1. */
506                     si = sy * w1;
507                     w = w1;
508                     sy += h2;
509                 } else {
510                     /* Copy a row from rect2. */
511                     si = size1 + (sy - h1) * w2;
512                     w = w2;
513                     sy -= h1;
514                 }
515                 for (j = 0; j < w; ++j, ++si, ++di) {
516                     uint thr =
517                         (bps == 1 ? data[si] :
518                          (data[si * 2] << 8) + data[si * 2 + 1])
519                                        >> rshift;
520 
521                     if_debug3('H', "[H]sy=%d, si=%d, di=%d\n", sy, si, di);
522                     bits[di].mask = max(thr, 1);
523                 }
524             }
525         }
526     }
527     gx_ht_complete_threshold_order(porder);
528     return process_transfer(porder, pgs, phtp->transfer, &phtp->transfer_closure, mem);
529 #undef LOG2_MAX_HT_LEVELS
530 #undef MAX_HT_LEVELS
531 }
532 
533 /* Process a client-order plane. */
534 static int
process_client_order(gx_ht_order * porder,gs_gstate * pgs,gs_client_order_halftone * phcop,gs_memory_t * mem)535 process_client_order(gx_ht_order * porder, gs_gstate * pgs,
536                      gs_client_order_halftone * phcop, gs_memory_t * mem)
537 {
538     int code = (*phcop->procs->create_order) (porder, pgs, phcop, mem);
539 
540     if (code < 0)
541         return code;
542     return process_transfer(porder, pgs, NULL,
543                             &phcop->transfer_closure, mem);
544 }
545