Fix for 687916: permute zsethalftone5 transfer functions
Raph Levien <[email protected]> Thu, 3 Feb 2005 16:39:47 -0800
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Reviewers,
I tracked down the nondeterminism in bug 687916: the enumeration
of the halftone dictionary was listing elements in different order
depending on trivial differences in interpreter state. Ordinarily,
this wouldn't be a problem, but there's a permutation that depends on
the order of enumeration that wasn't being consistently applied. The
patch below fixes this.
In particular, gs_sethalftone_prepare generates a components array
for the resulting pdht which is slightly permuted from the input pht
array when the /Default element is not the first element in the pht's
components array (/Default is always first in the result). However,
when enumerating the spot and transfer functions, zsethalftone5 uses
the same index for both the original order (as captured in the tprocs[]
and sprocs[] arrays, which are PostScript ref's to transfer functions
and spot functions, respectively) and to index the pdht->components
array.
The patch simply searches the comp_number field of the
pdht->components array to find the component that matches the tprocs
and sprocs entries.
Incidentally, the problem only shows up if the transfer functions
(or spot functions, for that matter) differ for each of the halftone
components. It's easy to see why users haven't tripped across this
before. It's a good thing we caught this before trying to build serious
color profiles for the color laser printer project!
Raph
Index: src/zht2.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zht2.c,v
retrieving revision 1.12
diff -C2 -r1.12 zht2.c
*** src/zht2.c 4 Aug 2004 19:36:13 -0000 1.12
--- src/zht2.c 4 Feb 2005 00:28:15 -0000
***************
*** 284,291 ****
make_op_estack(esp, sethalftone_finish);
for (j = 0; j < count; j++) {
! gx_ht_order *porder =
! (pdht->components == 0 ? &pdht->order :
! &pdht->components[j].corder);
switch (phtc[j].type) {
case ht_type_spot:
--- 284,303 ----
make_op_estack(esp, sethalftone_finish);
for (j = 0; j < count; j++) {
! gx_ht_order *porder = NULL;
+ if (pdht->components == 0)
+ porder = &pdht->order;
+ else {
+ /* Find the component in pdht that matches component j in
+ the pht; gs_sethalftone_prepare() may permute these. */
+ int k;
+ int comp_number = phtc[j].comp_number;
+ for (k = 0; k < count; k++) {
+ if (pdht->components[k].comp_number == comp_number) {
+ porder = &pdht->components[k].corder;
+ break;
+ }
+ }
+ }
switch (phtc[j].type) {
case ht_type_spot: