xref: /plan9/sys/src/cmd/gs/src/gxdhtserial.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 2002 artofcode LLC.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxdhtserial.c,v 1.8 2005/03/14 18:08:37 dan Exp $ */
18 /* Serialization and de-serialization for (traditional) halftones */
19 
20 #include "memory_.h"
21 #include <assert.h>
22 #include "gx.h"
23 #include "gscdefs.h"
24 #include "gserrors.h"
25 #include "gsstruct.h"
26 #include "gsutil.h"             /* for gs_next_ids */
27 #include "gzstate.h"
28 #include "gxdevice.h"           /* for gzht.h */
29 #include "gzht.h"
30 #include "gswts.h"
31 #include "gxdhtres.h"
32 #include "gsserial.h"
33 #include "gxdhtserial.h"
34 
35 
36 /*
37  * Declare the set of procedures that return resident halftones. This
38  * declares both the array of procedures and their type. It is used
39  * only to check if a transmitted halftone order matches one in ROM.
40  */
41 extern_gx_device_halftone_list();
42 
43 
44 /*
45  * An enumeration of halftone transfer functions. These must distinguish
46  * between cases in which no transfer function is present, and when one
47  * is present but provides the identity transformation (an empty
48  * PostScript array).
49  */
50 typedef enum {
51     gx_ht_tf_none = 0,
52     gx_ht_tf_identity,
53     gx_ht_tf_complete
54 } gx_ht_tf_type_t;
55 
56 /* enumeration to distinguish well-tempered screening orders from others */
57 typedef enum {
58     gx_ht_traditional,
59     gx_ht_wts
60 } gx_ht_order_type_t;
61 
62 
63 /*
64  * Serialize a transfer function. These will occupy one byte if they are
65  * not present or provide an identity mapping,
66  * 1 + transfer_map_size * sizeof(frac) otherwise.
67  *
68  * Returns:
69  *
70  *    0, with *psize set the the amount of space required, if successful
71  *
72  *    gs_error_rangecheck, with *psize set to the size required, if the
73  *        original *psize was not large enough
74  */
75 private int
gx_ht_write_tf(const gx_transfer_map * pmap,byte * data,uint * psize)76 gx_ht_write_tf(
77     const gx_transfer_map * pmap,
78     byte *                  data,
79     uint *                  psize )
80 {
81     int                     req_size = 1;   /* minimum of one byte */
82 
83     /* check for sufficient space */
84     if ( pmap != 0 && pmap->proc != gs_identity_transfer)
85         req_size += sizeof(pmap->values);
86     if (req_size > *psize) {
87         *psize = req_size;
88         return gs_error_rangecheck;
89     }
90 
91     if (req_size == 1)
92         *data = (byte)(pmap == 0 ? gx_ht_tf_none : gx_ht_tf_identity);
93     else {
94         *data++ = (byte)gx_ht_tf_complete;
95         memcpy(data, pmap->values, sizeof(pmap->values));
96     }
97 
98     *psize = req_size;
99     return 0;
100 }
101 
102 /*
103  * Reconstruct a transfer function from its serial representation. The
104  * buffer provided is expected to be large enough to hold the entire
105  * transfer function.
106  *
107  * Returns the number of bytes read, or < 0 in the event of an error.
108  */
109 private int
gx_ht_read_tf(gx_transfer_map ** ppmap,const byte * data,uint size,gs_memory_t * mem)110 gx_ht_read_tf(
111     gx_transfer_map **  ppmap,
112     const byte *        data,
113     uint                size,
114     gs_memory_t *       mem )
115 {
116     gx_ht_tf_type_t     tf_type;
117     gx_transfer_map *   pmap;
118 
119     /* read the type byte */
120     if (size == 0)
121         return_error(gs_error_rangecheck);
122     --size;
123     tf_type = (gx_ht_tf_type_t)*data++;
124 
125     /* if no transfer function, exit now */
126     if (tf_type == gx_ht_tf_none) {
127         *ppmap = 0;
128         return 1;
129     }
130 
131     /* allocate a transfer map */
132     rc_alloc_struct_1( pmap,
133                        gx_transfer_map,
134                        &st_transfer_map,
135                        mem,
136                        return_error(gs_error_VMerror),
137                        "gx_ht_read_tf" );
138 
139     pmap->id = gs_next_ids(mem, 1);
140     pmap->closure.proc = 0;
141     pmap->closure.data = 0;
142     if (tf_type == gx_ht_tf_identity) {
143         gx_set_identity_transfer(pmap);
144         return 1;
145     } else if (tf_type == gx_ht_tf_complete && size >= sizeof(pmap->values)) {
146         memcpy(pmap->values, data, sizeof(pmap->values));
147         pmap->proc = gs_mapped_transfer;
148         *ppmap = pmap;
149         return 1 + sizeof(pmap->values);
150     } else {
151         rc_decrement(pmap, "gx_ht_read_tf");
152         return_error(gs_error_rangecheck);
153     }
154 }
155 
156 
157 /*
158  * Serialize a halftone component. The only part that is serialized is the
159  * halftone order; the other two components are only required during
160  * halftone construction.
161  *
162  * Returns:
163  *
164  *    0, with *psize set the the amount of space required, if successful
165  *
166  *    gs_error_rangecheck, with *psize set to the size required, if the
167  *        original *psize was not large enough
168  *
169  *    some other error code, with *psize unchange, in the event of an
170  *        error other than lack of space
171  */
172 private int
gx_ht_write_component(const gx_ht_order_component * pcomp,byte * data,uint * psize)173 gx_ht_write_component(
174     const gx_ht_order_component *   pcomp,
175     byte *                          data,
176     uint *                          psize )
177 {
178     const gx_ht_order *             porder = &pcomp->corder;
179     byte *                          data0 = data;
180     int                             code, levels_size, bits_size;
181     uint			    tmp_size = 0;
182     int                             req_size;
183 
184     /*
185      * There is no need to transmit the comp_number field, as this must be
186      * the same as the index in the component array (see gx_ht_write).
187      *
188      * There is also no reason to transmit the colorant name (cname), as
189      * this is only used by some high-level devices that would not be targets
190      * of the command list device (and even those devices should be able to
191      * get the information from their color models).
192      *
193      * This leaves the order itself.
194      *
195      * Check if we are a well-tempered-screening order. Serialization of these
196      * is not yet implemented.
197      */
198     if (porder->wts != 0)
199        return_error(gs_error_unknownerror);     /* not yet supported */
200 
201     /*
202      * The following order fields are not transmitted:
203      *
204      *  params          Only required during halftone cell construction
205      *
206      *  wse, wts        Only used for well-tempered screens (see above)
207      *
208      *  raster          Can be re-calculated by the renderer from the width
209      *
210      *  orig_height,    The only potential use for these parameters is in
211      *  orig_shift      this routine; they are not useful to the renderer.
212      *
213      *  full_height     Can be re-calculated by the renderer from the
214      *                  height, width, and shift values.
215      *
216      *  data_memory     Must be provided by the renderer.
217      *
218      *  cache           Must be provided by the renderer.
219      *
220      *  screen_params   Ony required during halftone cell construction
221      *
222      * In addition, the procs parameter is passed as an index into the
223      * ht_order_procs_table, as the renderer may not be in the same address
224      * space as the writer.
225      *
226      * Calculate the size required.
227      */
228     levels_size = porder->num_levels * sizeof(porder->levels[0]);
229     bits_size = porder->num_bits * porder->procs->bit_data_elt_size;
230     req_size =   1          /* gx_ht_type_t */
231                + enc_u_sizew(porder->width)
232                + enc_u_sizew(porder->height)
233                + enc_u_sizew(porder->shift)
234                + enc_u_sizew(porder->num_levels)
235                + enc_u_sizew(porder->num_bits)
236                + 1          /* order procs, as index into table */
237                + levels_size
238                + bits_size;
239     code = gx_ht_write_tf(porder->transfer, data, &tmp_size);
240     if (code < 0 && code != gs_error_rangecheck)
241         return code;
242     req_size += tmp_size;
243     if (req_size > *psize) {
244         *psize = req_size;
245         return gs_error_rangecheck;
246     }
247 
248     /* identify this as a traditional halftone */
249     *data++ = (byte)gx_ht_traditional;
250 
251     /* write out the dimensional data */
252     enc_u_putw(porder->width, data);
253     enc_u_putw(porder->height, data);
254     enc_u_putw(porder->shift, data);
255     enc_u_putw(porder->num_levels, data);
256     enc_u_putw(porder->num_bits, data);
257 
258     /* white out the procs index */
259     *data++ = porder->procs - ht_order_procs_table;
260 
261     /* copy the levels array and whitening order array */
262     memcpy(data, porder->levels, levels_size);
263     data += levels_size;
264     memcpy(data, porder->bit_data, bits_size);
265     data += bits_size;
266 
267     /* write out the transfer function */
268     tmp_size = *psize - (data - data0);
269     if ((code = gx_ht_write_tf(porder->transfer, data, &tmp_size)) == 0)
270         *psize = tmp_size + (data - data0);
271     return code;
272 }
273 
274 /*
275  * Reconstruct a halftone component from its serial representation. The
276  * buffer provided is expected to be large enough to hold the entire
277  * halftone component.
278  *
279  * Because halftone components are allocated in arrays (an unfortunate
280  * arrangement, as it prevents component sharing), a pointer to an
281  * already allocated component structure is passed as an operand, as
282  * opposed to the more normal mechanism that would have a read routine
283  * allocate the component. The memory pointer is still passed, however,
284  * as the levels and bit_data arrays must be allocated.
285  *
286  * Returns the number of bytes read, or < 0 in the event of an error.
287  */
288 private int
gx_ht_read_component(gx_ht_order_component * pcomp,const byte * data,uint size,gs_memory_t * mem)289 gx_ht_read_component(
290     gx_ht_order_component * pcomp,
291     const byte *            data,
292     uint                    size,
293     gs_memory_t *           mem )
294 {
295     gx_ht_order             new_order;
296     const byte *            data0 = data;
297     const byte *            data_lim = data + size;
298     gx_ht_order_type_t      order_type;
299     int                     i, code, levels_size, bits_size;
300     const gx_dht_proc *     phtrp = gx_device_halftone_list;
301 
302     /* check the order type */
303     if (size == 0)
304         return_error(gs_error_rangecheck);
305     --size;
306     order_type = (gx_ht_order_type_t)*data++;
307 
308     /* currently only the traditional halftone order are supported */
309     if (order_type != gx_ht_traditional)
310        return_error(gs_error_unknownerror);
311 
312     /*
313      * For performance reasons, the number encoding macros do not
314      * support full buffer size verification. The code below verifies
315      * that a minimum number of bytes is available, then converts
316      * blindly and does not check again until the various integers are
317      * read. Obviously this can be hazardous, but should not be a
318      * problem in practice, as the calling code should have verified
319      * that the data provided holds the entire halftone.
320      */
321     if (size < 7)
322         return_error(gs_error_rangecheck);
323     enc_u_getw(new_order.width, data);
324     enc_u_getw(new_order.height, data);
325     enc_u_getw(new_order.shift, data);
326     enc_u_getw(new_order.num_levels, data);
327     enc_u_getw(new_order.num_bits, data);
328     if (data >= data_lim)
329         return_error(gs_error_rangecheck);
330     new_order.procs = &ht_order_procs_table[*data++];
331 
332     /* calculate the space required for levels and bit data */
333     levels_size = new_order.num_levels * sizeof(new_order.levels[0]);
334     bits_size = new_order.num_bits * new_order.procs->bit_data_elt_size;
335 
336     /* + 1 below is for the minimal transfer function */
337     if (data + bits_size + levels_size + 1 > data_lim)
338         return_error(gs_error_rangecheck);
339 
340     /*
341      * Allocate the levels and bit data structures. The gx_ht_alloc_ht_order
342      * has a name that is both strange and misleading. The routine does
343      * not allocate a halftone order. Rather, it initializes the order,
344      * and allocates the levels and bit data arrays. In particular, it
345      * sets all of the following fields:
346      *
347      *    wse = 0,
348      *    wts = 0,
349      *    width = operand width
350      *    height = operand height
351      *    raster = bitmap_raster(operand width)
352      *    shift = operand shift
353      *    orig_height = operand height
354      *    orig_shift = operand strip_shift
355      *    num_levels = operand num_levels
356      *    num_bits = operand num_bits
357      *    procs = operand procs
358      *    levels = newly allocated array
359      *    bit_data = new allocated array
360      *    cache = 0
361      *    transfer = 0
362      *
363      * Since several of the list fields are already set, this call
364      * effectively sets them to the values they already have. This is a
365      * bit peculiar but not otherwise harmful.
366      *
367      * For reasons that are not known and are probably historical, the
368      * procedure does not initialize the params or screen_params fields.
369      * In the unlikely event that these fields are ever contain pointers,
370      * we initialize them explicitly here. Wse, params, and scrren_params
371      * probably should not occur in the device halftone at all; they are
372      * themselves historical artifacts.
373      */
374     code = gx_ht_alloc_ht_order( &new_order,
375                                  new_order.width,
376                                  new_order.height,
377                                  new_order.num_levels,
378                                  new_order.num_bits,
379                                  new_order.shift,
380                                  new_order.procs,
381                                  mem );
382     if (code < 0)
383         return code;
384     memset(&new_order.params, 0, sizeof(new_order.params));
385     memset(&new_order.screen_params, 0, sizeof(new_order.screen_params));
386 
387     /* fill in the levels and bit_data arrays */
388     memcpy(new_order.levels, data, levels_size);
389     data += levels_size;
390     memcpy(new_order.bit_data, data, bits_size);
391     data += bits_size;
392 
393     /* process the transfer function */
394     code = gx_ht_read_tf(&new_order.transfer, data, data_lim - data, mem);
395     if (code < 0) {
396         gx_ht_order_release(&new_order, mem, false);
397         return code;
398     }
399     data += code;
400 
401     /*
402      * Check to see if the order is in ROM. Since it is possible (if not
403      * particularly likely) that the command list writer and renderer do
404      * not have the same set of ROM-based halftones, the full halftone
405      * order is transmitted and compared against the set ROM set provided
406      * by the renderer. If there is a match, the transmitted version is
407      * discarded and the ROM version used.
408      *
409      * It is not clear which, if any or the currently used devices
410      * provide a ROM-based halftone order set.
411      */
412     for (i = 0; phtrp[i] != 0; i++) {
413         const gx_device_halftone_resource_t *const *    pphtr = phtrp[i]();
414         const gx_device_halftone_resource_t *           phtr;
415 
416         while ((phtr = *pphtr++) != 0) {
417             /*
418              * This test does not check for strict equality of the order,
419              * nor is strict equality necessary. The ROM data will replace
420              * just the levels and bit_data arrays of the transmitted
421              * order, so only these must be the same. We don't even care
422              * if the ROM's levels and bit_data arrays are larger; we
423              * will never check values beyond the range required by the
424              * current order.
425              */
426             if ( phtr->num_levels * sizeof(phtr->levels[0]) >= levels_size &&
427                  phtr->Width * phtr->Height * phtr->elt_size >= bits_size  &&
428                  memcmp(phtr->levels, new_order.levels, levels_size) == 0  &&
429                  memcmp(phtr->bit_data, new_order.bit_data, bits_size) == 0  ) {
430                 /* the casts below are required to discard const qualifiers */
431                 gs_free_object(mem, new_order.bit_data, "gx_ht_read_component");
432                 new_order.bit_data = (void *)phtr->bit_data;
433                 gs_free_object(mem, new_order.levels, "gx_ht_read_component");
434                 new_order.levels = (uint *)phtr->levels;
435                 goto done;
436             }
437         }
438     }
439 
440   done:
441     /* everything OK, save the order and return the # of bytes read */
442     pcomp->corder = new_order;
443     pcomp->cname = 0;
444     return data - data0;
445 }
446 
447 
448 /*
449  * Serialize a halftone. The essential step is the serialization of the
450  * halftone orders; beyond this only the halftone type must be
451  * transmitted.
452  *
453  * Returns:
454  *
455  *    0, with *psize set the the amount of space required, if successful
456  *
457  *    gs_error_rangecheck, with *psize set to the size required, if the
458  *        original *psize was not large enough
459  *
460  *    some other error code, with *psize unchange, in the event of an
461  *        error other than lack of space
462  */
463 int
gx_ht_write(const gx_device_halftone * pdht,const gx_device * dev,byte * data,uint * psize)464 gx_ht_write(
465     const gx_device_halftone *  pdht,
466     const gx_device *           dev,
467     byte *                      data,
468     uint *                      psize )
469 {
470     int                         num_dev_comps = pdht->num_dev_comp;
471     int                         i, code;
472     uint                        req_size = 2, used_size = 2;
473                                 /* 1 for halftone type, 1 for num_dev_comps */
474 
475     /*
476      * With the introduction of color models, there should never be a
477      * halftone that includes just one component. Enforce this
478      * restriction, even though it is not present in much of the rest
479      * of the code.
480      *
481      * NB: the pdht->order field is ignored by this code.
482      */
483     assert(pdht != 0 && pdht->components != 0);
484 
485     /*
486      * The following fields do not need to be transmitted:
487      *
488      *  order       Ignored by this code (see above).
489      *
490      *  rc, id      Recreated by the allocation code on the renderer.
491      *
492      *  lcm_width,  Can be recreated by the de-serialization code on the
493      *  lcm_height  the renderer. Since halftones are transmitted
494      *              infrequently (for normal jobs), the time required
495      *              for re-calculation is not significant.
496      *
497      * Hence, the only fields that must be serialized are the type,and
498      * the number of components.  (The number of components for the halftone
499      * may not match the device's if we are compositing with a process color
500      * model which does not match the output device.
501      *
502      * Several halftone components may be identical, but there is
503      * currently no simple way to determine this. Halftones are normally
504      * transmitted only once per page, so it is not clear that use of
505      * such information would significantly reduce command list size.
506      */
507 
508     /* calculate the required data space */
509     for ( i = 0, code = gs_error_rangecheck;
510           i < num_dev_comps && code == gs_error_rangecheck;
511           i++) {
512         uint     tmp_size = 0;
513 
514         /* sanity check */
515         assert(i == pdht->components[i].comp_number);
516 
517         code = gx_ht_write_component( &pdht->components[i],
518                                       data,
519                                       &tmp_size );
520         req_size += tmp_size;
521     }
522     if (code < 0 && code != gs_error_rangecheck)
523         return code;
524     else if (*psize < req_size) {
525         *psize = req_size;
526         return 0;
527     }
528     req_size = *psize;
529 
530     /* the halftone type is known to fit in a byte */
531     *data++ = (byte)pdht->type;
532     /* the number of components is known to fit in a byte */
533     *data++ = (byte)num_dev_comps;
534 
535     /* serialize the halftone components */
536     for (i = 0, code = 0; i < num_dev_comps && code == 0; i++) {
537         uint    tmp_size = req_size - used_size;
538 
539         code = gx_ht_write_component( &pdht->components[i],
540                                       data,
541                                       &tmp_size );
542         used_size += tmp_size;
543         data += tmp_size;
544     }
545 
546     if (code < 0) {
547         if (code == gs_error_rangecheck)
548             code = gs_error_unknownerror;
549         return code;
550     }
551 
552     *psize = used_size;
553     return 0;
554 }
555 
556 /*
557  * Reconstruct a halftone from its serial representation, and install it
558  * as the current halftone. The buffer provided is expected to be large
559  * enough to hold the entire halftone.
560  *
561  * The reading and installation phases are combined in this routine so as
562  * to avoid unnecessarily allocating a device halftone and its component
563  * array, just to release them immediately after installation is complete.
564  * There is also not much reason to reconstuct a halftone except to make
565  * it the current halftone.
566  *
567  * Returns the number of bytes read, or <0 in the event of an error.
568  */
569 int
gx_ht_read_and_install(gs_imager_state * pis,const gx_device * dev,const byte * data,uint size,gs_memory_t * mem)570 gx_ht_read_and_install(
571     gs_imager_state *       pis,
572     const gx_device *       dev,
573     const byte *            data,
574     uint                    size,
575     gs_memory_t *           mem )
576 {
577     gx_ht_order_component   components[GX_DEVICE_COLOR_MAX_COMPONENTS];
578     const byte *            data0 = data;
579     gx_device_halftone      dht;
580     int                     num_dev_comps;
581     int                     i, code;
582 
583     /* fill in some fixed fields */
584     memset(&dht.order, 0, sizeof(dht.order));
585     memset(&dht.rc, 0, sizeof(dht.rc));
586     dht.id = gs_no_id;      /* updated during installation */
587     dht.components = components;
588     dht.lcm_width = 1;      /* recalculated during installation */
589     dht.lcm_height = 1;
590 
591     /* clear pointers in the components array in case we need to abort */
592     memset(components, 0, sizeof(components));
593 
594     /* get the halftone type */
595     if (size-- < 1)
596         return_error(gs_error_rangecheck);
597     dht.type = (gs_halftone_type)(*data++);
598     num_dev_comps = dht.num_dev_comp = dht.num_comp = *data++;
599 
600     /* process the component orders */
601     for (i = 0, code = 0; i < num_dev_comps && code >= 0; i++) {
602         components[i].comp_number = i;
603         code = gx_ht_read_component(&components[i], data, size, mem);
604         if (code >= 0) {
605             size -= code;
606             data += code;
607         }
608     }
609 
610     /* if everything is OK, install the halftone */
611     if (code >= 0)
612         code = gx_imager_dev_ht_install(pis, &dht, dht.type, dev);
613 
614     /*
615      * If installation failed, discard the allocated elements. We can't
616      * use the gx_device_halftone_release procedure, as the components
617      * array is on the stack rather than in the heap.
618      */
619     if (code < 0) {
620         for (i = 0; i < num_dev_comps; i++)
621             gx_ht_order_release(&components[i].corder, mem, false);
622     }
623 
624     return code < 0 ? code : data - data0;
625 }
626