~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gsht1.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 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, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/*$Id: gsht1.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* Extended halftone operators for Ghostscript library */
16
 
#include "memory_.h"
17
 
#include "string_.h"
18
 
#include "gx.h"
19
 
#include "gserrors.h"
20
 
#include "gsstruct.h"
21
 
#include "gsutil.h"             /* for gs_next_ids */
22
 
#include "gzstate.h"
23
 
#include "gxdevice.h"           /* for gzht.h */
24
 
#include "gzht.h"
25
 
 
26
 
#include "gxwts.h"
27
 
#include "gswts.h"
28
 
 
29
 
/* Imports from gscolor.c */
30
 
void load_transfer_map(gs_state *, gx_transfer_map *, floatp);
31
 
 
32
 
/* Forward declarations */
33
 
static int process_spot(gx_ht_order *, gs_state *,
34
 
                         gs_spot_halftone *, gs_memory_t *);
35
 
static int process_threshold(gx_ht_order *, gs_state *,
36
 
                              gs_threshold_halftone *, gs_memory_t *);
37
 
static int process_threshold2(gx_ht_order *, gs_state *,
38
 
                               gs_threshold2_halftone *, gs_memory_t *);
39
 
static int process_client_order(gx_ht_order *, gs_state *,
40
 
                                 gs_client_order_halftone *, gs_memory_t *);
41
 
static int
42
 
gs_sethalftone_try_wts(gs_halftone *pht, gs_state *pgs,
43
 
                       gx_device_halftone *pdht);
44
 
 
45
 
/* Structure types */
46
 
public_st_halftone_component();
47
 
public_st_ht_component_element();
48
 
 
49
 
/* GC procedures */
50
 
 
51
 
static 
52
 
ENUM_PTRS_WITH(halftone_component_enum_ptrs, gs_halftone_component *hptr) return 0;
53
 
case 0:
54
 
switch (hptr->type)
55
 
{
56
 
    case ht_type_spot:
57
 
ENUM_RETURN((hptr->params.spot.transfer == 0 ?
58
 
             hptr->params.spot.transfer_closure.data :
59
 
             0));
60
 
    case ht_type_threshold:
61
 
ENUM_RETURN_CONST_STRING_PTR(gs_halftone_component,
62
 
                             params.threshold.thresholds);
63
 
    case ht_type_threshold2:
64
 
return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds);
65
 
    case ht_type_client_order:
66
 
ENUM_RETURN(hptr->params.client_order.client_data);
67
 
    default:                    /* not possible */
68
 
return 0;
69
 
}
70
 
case 1:
71
 
switch (hptr->type) {
72
 
    case ht_type_threshold:
73
 
        ENUM_RETURN((hptr->params.threshold.transfer == 0 ?
74
 
                     hptr->params.threshold.transfer_closure.data :
75
 
                     0));
76
 
    case ht_type_threshold2:
77
 
        ENUM_RETURN(hptr->params.threshold2.transfer_closure.data);
78
 
    case ht_type_client_order:
79
 
        ENUM_RETURN(hptr->params.client_order.transfer_closure.data);
80
 
    default:
81
 
        return 0;
82
 
}
83
 
ENUM_PTRS_END
84
 
static RELOC_PTRS_WITH(halftone_component_reloc_ptrs, gs_halftone_component *hptr)
85
 
{
86
 
    switch (hptr->type) {
87
 
        case ht_type_spot:
88
 
            if (hptr->params.spot.transfer == 0)
89
 
                RELOC_VAR(hptr->params.spot.transfer_closure.data);
90
 
            break;
91
 
        case ht_type_threshold:
92
 
            RELOC_CONST_STRING_VAR(hptr->params.threshold.thresholds);
93
 
            if (hptr->params.threshold.transfer == 0)
94
 
                RELOC_VAR(hptr->params.threshold.transfer_closure.data);
95
 
            break;
96
 
        case ht_type_threshold2:
97
 
            RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds);
98
 
            RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data);
99
 
            break;
100
 
        case ht_type_client_order:
101
 
            RELOC_VAR(hptr->params.client_order.client_data);
102
 
            RELOC_VAR(hptr->params.client_order.transfer_closure.data);
103
 
            break;
104
 
        default:
105
 
            break;
106
 
    }
107
 
}
108
 
RELOC_PTRS_END
109
 
 
110
 
/* setcolorscreen */
111
 
int
112
 
gs_setcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht)
113
 
{
114
 
    gs_halftone ht;
115
 
 
116
 
    ht.type = ht_type_colorscreen;
117
 
    ht.params.colorscreen = *pht;
118
 
    return gs_sethalftone(pgs, &ht);
119
 
}
120
 
 
121
 
/* currentcolorscreen */
122
 
int
123
 
gs_currentcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht)
124
 
{
125
 
    int code;
126
 
 
127
 
    switch (pgs->halftone->type) {
128
 
        case ht_type_colorscreen:
129
 
            *pht = pgs->halftone->params.colorscreen;
130
 
            return 0;
131
 
        default:
132
 
            code = gs_currentscreen(pgs, &pht->screens.colored.gray);
133
 
            if (code < 0)
134
 
                return code;
135
 
            pht->screens.colored.red = pht->screens.colored.gray;
136
 
            pht->screens.colored.green = pht->screens.colored.gray;
137
 
            pht->screens.colored.blue = pht->screens.colored.gray;
138
 
            return 0;
139
 
    }
140
 
}
141
 
 
142
 
/* Set the halftone in the graphics state. */
143
 
int
144
 
gs_sethalftone(gs_state * pgs, gs_halftone * pht)
145
 
{
146
 
    gs_halftone ht;
147
 
 
148
 
    ht = *pht;
149
 
    ht.rc.memory = pgs->memory;
150
 
    return gs_sethalftone_allocated(pgs, &ht);
151
 
}
152
 
int
153
 
gs_sethalftone_allocated(gs_state * pgs, gs_halftone * pht)
154
 
{
155
 
    gx_device_halftone dev_ht;
156
 
    int code = gs_sethalftone_prepare(pgs, pht, &dev_ht);
157
 
 
158
 
    if (code < 0)
159
 
        return code;
160
 
    dev_ht.rc.memory = pht->rc.memory;
161
 
    if ((code = gx_ht_install(pgs, pht, &dev_ht)) < 0)
162
 
        gx_device_halftone_release(&dev_ht, pht->rc.memory);
163
 
    return code;
164
 
}
165
 
 
166
 
/* Prepare the halftone, but don't install it. */
167
 
int
168
 
gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht,
169
 
                       gx_device_halftone * pdht)
170
 
{
171
 
    gs_memory_t *mem = pht->rc.memory;
172
 
    gx_ht_order_component *pocs = 0;
173
 
    int code = 0;
174
 
 
175
 
    if (gs_currentusewts() && gs_sethalftone_try_wts(pht, pgs, pdht) == 0)
176
 
        return 0;
177
 
 
178
 
    switch (pht->type) {
179
 
        case ht_type_colorscreen:
180
 
            {
181
 
                gs_screen_halftone *phc =
182
 
                    pht->params.colorscreen.screens.indexed;
183
 
                static const int cindex[4] = {3, 0, 1, 2};
184
 
                static const char * color_names[4] = {"Gray", "Red", "Green", "Blue"};
185
 
                int i;
186
 
 
187
 
                pocs = gs_alloc_struct_array(mem, 4,
188
 
                                             gx_ht_order_component,
189
 
                                             &st_ht_order_component_element,
190
 
                                             "gs_sethalftone");
191
 
                if (pocs == 0)
192
 
                    return_error(gs_error_VMerror);
193
 
                for (i = 0; i < 4; i++) {
194
 
                    gs_screen_enum senum;
195
 
                    int ci = cindex[i];
196
 
                    gx_ht_order_component *poc = &pocs[i];
197
 
 
198
 
                    code = gx_ht_process_screen_memory(&senum, pgs,
199
 
                                &phc[ci], gs_currentaccuratescreens(), mem);
200
 
                    if (code < 0)
201
 
                        break;
202
 
                    poc->corder = senum.order;
203
 
                    poc->comp_number = gs_color_name_component_number(pgs->device,
204
 
                                color_names[i], strlen(color_names[i]), pht->type);
205
 
                    poc->cname = 0;  /* name index values are not known (or needed) */
206
 
                    if (i == 0) /* Gray = Default */
207
 
                        pdht->order = poc->corder;      /* Save default value */
208
 
                }
209
 
                if (code < 0)
210
 
                    break;
211
 
                pdht->components = pocs;
212
 
                pdht->num_comp = 4;
213
 
            }
214
 
            break;
215
 
        case ht_type_spot:
216
 
            code = process_spot(&pdht->order, pgs, &pht->params.spot, mem);
217
 
            if (code < 0)
218
 
                return code;
219
 
            pdht->components = 0;
220
 
            break;
221
 
        case ht_type_threshold:
222
 
            code = process_threshold(&pdht->order, pgs,
223
 
                                     &pht->params.threshold, mem);
224
 
            if (code < 0)
225
 
                return code;
226
 
            pdht->components = 0;
227
 
            break;
228
 
        case ht_type_threshold2:
229
 
            code = process_threshold2(&pdht->order, pgs,
230
 
                                      &pht->params.threshold2, mem);
231
 
            if (code < 0)
232
 
                return code;
233
 
            pdht->components = 0;
234
 
            break;
235
 
        case ht_type_client_order:
236
 
            code = process_client_order(&pdht->order, pgs,
237
 
                                        &pht->params.client_order, mem);
238
 
            if (code < 0)
239
 
                return code;
240
 
            pdht->components = 0;
241
 
            break;
242
 
        case ht_type_multiple:
243
 
        case ht_type_multiple_colorscreen:
244
 
            {
245
 
                uint count = pht->params.multiple.num_comp;
246
 
                bool have_Default = false;
247
 
                uint i;
248
 
                gs_halftone_component *phc = pht->params.multiple.components;
249
 
                gx_ht_order_component *poc_next;
250
 
 
251
 
                pocs = gs_alloc_struct_array(mem, count,
252
 
                                             gx_ht_order_component,
253
 
                                             &st_ht_order_component_element,
254
 
                                             "gs_sethalftone");
255
 
                if (pocs == 0)
256
 
                    return_error(gs_error_VMerror);
257
 
                poc_next = pocs + 1;
258
 
                for (i = 0; i < count; i++, phc++) {
259
 
                    gx_ht_order_component *poc = poc_next;                  
260
 
 
261
 
                    if (phc->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
262
 
                        if (have_Default) {
263
 
                            /* Duplicate Default */
264
 
                            code = gs_note_error(gs_error_rangecheck);
265
 
                            break;
266
 
                        }
267
 
                        poc = pocs;
268
 
                        have_Default = true;
269
 
                    } else if (i == count - 1 && !have_Default) {
270
 
                        /* No Default */
271
 
                        code = gs_note_error(gs_error_rangecheck);
272
 
                        break;
273
 
                    } else
274
 
                        poc = poc_next++;
275
 
 
276
 
                    poc->comp_number = phc->comp_number;
277
 
                    poc->cname = phc->cname;
278
 
                    switch (phc->type) {
279
 
                        case ht_type_spot:
280
 
                            code = process_spot(&poc->corder, pgs,
281
 
                                                &phc->params.spot, mem);
282
 
                            break;
283
 
                        case ht_type_threshold:
284
 
                            code = process_threshold(&poc->corder, pgs,
285
 
                                                &phc->params.threshold, mem);
286
 
                            break;
287
 
                        case ht_type_threshold2:
288
 
                            code = process_threshold2(&poc->corder, pgs,
289
 
                                                &phc->params.threshold2, mem);
290
 
                            break;
291
 
                        case ht_type_client_order:
292
 
                            code = process_client_order(&poc->corder, pgs,
293
 
                                            &phc->params.client_order, mem);
294
 
                            break;
295
 
                        default:
296
 
                            code = gs_note_error(gs_error_rangecheck);
297
 
                            break;
298
 
                    }
299
 
                    if (code < 0)
300
 
                        break;
301
 
                }
302
 
                if (code < 0)
303
 
                    break;
304
 
                pdht->order = pocs[0].corder;   /* Default */
305
 
                if (count == 1) {
306
 
                    /* We have only a Default; */
307
 
                    /* we don't need components. */
308
 
                    gs_free_object(mem, pocs, "gs_sethalftone");
309
 
                    pdht->components = 0;
310
 
                    pdht->num_comp = 0;
311
 
                } else {
312
 
                    pdht->components = pocs;
313
 
                    pdht->num_comp = count;
314
 
                }
315
 
            }
316
 
            break;
317
 
        default:
318
 
            return_error(gs_error_rangecheck);
319
 
    }
320
 
    if (code < 0)
321
 
        gs_free_object(mem, pocs, "gs_sethalftone");
322
 
    return code;
323
 
}
324
 
 
325
 
/* ------ Internal routines ------ */
326
 
 
327
 
/* Process a transfer function override, if any. */
328
 
static int
329
 
process_transfer(gx_ht_order * porder, gs_state * pgs,
330
 
                 gs_mapping_proc proc, gs_mapping_closure_t * pmc,
331
 
                 gs_memory_t * mem)
332
 
{
333
 
    gx_transfer_map *pmap;
334
 
 
335
 
    if (proc == 0 && pmc->proc == 0)
336
 
        return 0;
337
 
    /*
338
 
     * The transfer funtion is referenced by the order, so start the
339
 
     * reference count at 1.
340
 
     */
341
 
    rc_alloc_struct_1(pmap, gx_transfer_map, &st_transfer_map, mem,
342
 
                      return_error(gs_error_VMerror),
343
 
                      "process_transfer");
344
 
    pmap->proc = proc;          /* 0 => use closure */
345
 
    pmap->closure = *pmc;
346
 
    pmap->id = gs_next_ids(mem, 1);
347
 
    load_transfer_map(pgs, pmap, 0.0);
348
 
    porder->transfer = pmap;
349
 
    return 0;
350
 
}
351
 
 
352
 
/* Process a spot plane. */
353
 
static int
354
 
process_spot(gx_ht_order * porder, gs_state * pgs,
355
 
             gs_spot_halftone * phsp, gs_memory_t * mem)
356
 
{
357
 
    gs_screen_enum senum;
358
 
 
359
 
    int code = gx_ht_process_screen_memory(&senum, pgs, &phsp->screen,
360
 
                                           phsp->accurate_screens, mem);
361
 
 
362
 
    if (code < 0)
363
 
        return code;
364
 
    *porder = senum.order;
365
 
    return process_transfer(porder, pgs, phsp->transfer,
366
 
                            &phsp->transfer_closure, mem);
367
 
}
368
 
 
369
 
/* Construct the halftone order from a threshold array. */
370
 
void
371
 
gx_ht_complete_threshold_order(gx_ht_order * porder)
372
 
{
373
 
    int num_levels = porder->num_levels;
374
 
    uint *levels = porder->levels;
375
 
    uint size = porder->num_bits;
376
 
    gx_ht_bit *bits = porder->bit_data;
377
 
    uint i, j;
378
 
 
379
 
    /* The caller has set bits[i] = max(1, thresholds[i]). */
380
 
    gx_sort_ht_order(bits, size);
381
 
    /* We want to set levels[j] to the lowest value of i */
382
 
    /* such that bits[i].mask > j. */
383
 
    for (i = 0, j = 0; i < size; i++) {
384
 
        if (bits[i].mask != j) {
385
 
            if_debug3('h', "[h]levels[%u..%u] = %u\n",
386
 
                      j, (uint) bits[i].mask, i);
387
 
            while (j < bits[i].mask)
388
 
                levels[j++] = i;
389
 
        }
390
 
    }
391
 
    while (j < num_levels)
392
 
        levels[j++] = size;
393
 
    gx_ht_construct_bits(porder);
394
 
}
395
 
int
396
 
gx_ht_construct_threshold_order(gx_ht_order * porder, const byte * thresholds)
397
 
{
398
 
    return porder->procs->construct_order(porder, thresholds);
399
 
}
400
 
 
401
 
/* Process a threshold plane. */
402
 
static int
403
 
process_threshold(gx_ht_order * porder, gs_state * pgs,
404
 
                  gs_threshold_halftone * phtp, gs_memory_t * mem)
405
 
{
406
 
    int code;
407
 
 
408
 
    porder->params.M = phtp->width, porder->params.N = 0;
409
 
    porder->params.R = 1;
410
 
    porder->params.M1 = phtp->height, porder->params.N1 = 0;
411
 
    porder->params.R1 = 1;
412
 
    code = gx_ht_alloc_threshold_order(porder, phtp->width, phtp->height,
413
 
                                       256, mem);
414
 
    if (code < 0)
415
 
        return code;
416
 
    gx_ht_construct_threshold_order(porder, phtp->thresholds.data);
417
 
    return process_transfer(porder, pgs, phtp->transfer,
418
 
                            &phtp->transfer_closure, mem);
419
 
}
420
 
 
421
 
/* Process an extended threshold plane. */
422
 
static int
423
 
process_threshold2(gx_ht_order * porder, gs_state * pgs,
424
 
                   gs_threshold2_halftone * phtp, gs_memory_t * mem)
425
 
{
426
 
    int code;
427
 
    /*
428
 
     * There are potentially 64K different levels for this plane, but this
429
 
     * is more than we're willing to handle.  Try to reduce the number of
430
 
     * levels by dropping leading or trailing zero bits from the thresholds;
431
 
     * as a last resort, drop (possibly significant) trailing bits.
432
 
     */
433
 
#define LOG2_MAX_HT_LEVELS 14
434
 
#define MAX_HT_LEVELS (1 << LOG2_MAX_HT_LEVELS)
435
 
    int bps = phtp->bytes_per_sample;
436
 
    const byte *data = phtp->thresholds.data;
437
 
    const int w1 = phtp->width, h1 = phtp->height, size1 = w1 * h1;
438
 
    const int w2 = phtp->width2, h2 = phtp->height2, size2 = w2 * h2;
439
 
    const uint size = size1 + size2;
440
 
    const int d = (h2 == 0 ? h1 : igcd(h1, h2));
441
 
    const int sod = size / d;
442
 
    uint num_levels;
443
 
    uint i;
444
 
    int rshift = 0;
445
 
    int shift;
446
 
 
447
 
    {
448
 
        uint mask = 0, max_thr = 0;
449
 
 
450
 
        for (i = 0; i < size; ++i) {
451
 
            uint thr =
452
 
                (bps == 1 ? data[i] : (data[i * 2] << 8) + data[i * 2 + 1]);
453
 
 
454
 
            mask |= thr;
455
 
            max_thr = max(max_thr, thr);
456
 
        }
457
 
        if (mask == 0)
458
 
            mask = 1, max_thr = 1;
459
 
        while (!(mask & 1) || max_thr > MAX_HT_LEVELS)
460
 
            mask >>= 1, max_thr >>= 1, rshift++;
461
 
        num_levels = max_thr + 1;
462
 
    }
463
 
    /*
464
 
     * Set nominal values for the params, and don't bother to call
465
 
     * gx_compute_cell_values -- the values are only needed for spot
466
 
     * halftones.
467
 
     */
468
 
    porder->params.M = sod, porder->params.N = d;
469
 
    porder->params.R = 1;
470
 
    porder->params.M1 = d, porder->params.N1 = sod;
471
 
    porder->params.R1 = 1;
472
 
    /*
473
 
     * Determine the shift between strips.  We don't know a closed formula
474
 
     * for this, so we do it by enumeration.
475
 
     */
476
 
    shift = 0;
477
 
    {
478
 
        int x = 0, y = 0;
479
 
 
480
 
        do {
481
 
            if (y < h1)
482
 
                x += w1, y += h2;
483
 
            else
484
 
                x += w2, y -= h1;
485
 
        } while (y > d);
486
 
        if (y)
487
 
            shift = x;
488
 
    }
489
 
    code = gx_ht_alloc_ht_order(porder, sod, d, num_levels, size, shift,
490
 
                                &ht_order_procs_default, mem);
491
 
    if (code < 0)
492
 
        return code;
493
 
    {
494
 
        gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
495
 
        int row, di;
496
 
 
497
 
        if_debug7('h', "[h]rect1=(%d,%d), rect2=(%d,%d), strip=(%d,%d), shift=%d\n",
498
 
                  w1, h1, w2, h2, sod, d, shift);
499
 
        for (row = 0, di = 0; row < d; ++row) {
500
 
            /* Iterate over destination rows. */
501
 
            int dx, sy = row;   /* sy = row mod d */
502
 
            int w;
503
 
 
504
 
            for (dx = 0; dx < sod; dx += w) {
505
 
                /* Iterate within a destination row, over source rows. */
506
 
                int si, j;
507
 
 
508
 
                if (sy < h1) {
509
 
                    /* Copy a row from rect1. */
510
 
                    si = sy * w1;
511
 
                    w = w1;
512
 
                    sy += h2;
513
 
                } else {
514
 
                    /* Copy a row from rect2. */
515
 
                    si = size1 + (sy - h1) * w2;
516
 
                    w = w2;
517
 
                    sy -= h1;
518
 
                }
519
 
                for (j = 0; j < w; ++j, ++si, ++di) {
520
 
                    uint thr =
521
 
                        (bps == 1 ? data[si] :
522
 
                         (data[si * 2] << 8) + data[si * 2 + 1])
523
 
                                       >> rshift;
524
 
 
525
 
                    if_debug3('H', "[H]sy=%d, si=%d, di=%d\n", sy, si, di);
526
 
                    bits[di].mask = max(thr, 1);
527
 
                }
528
 
            }
529
 
        }
530
 
    }
531
 
    gx_ht_complete_threshold_order(porder);
532
 
    return process_transfer(porder, pgs, NULL, &phtp->transfer_closure, mem);
533
 
#undef LOG2_MAX_HT_LEVELS
534
 
#undef MAX_HT_LEVELS
535
 
}
536
 
 
537
 
/* Process a client-order plane. */
538
 
static int
539
 
process_client_order(gx_ht_order * porder, gs_state * pgs,
540
 
                     gs_client_order_halftone * phcop, gs_memory_t * mem)
541
 
{
542
 
    int code = (*phcop->procs->create_order) (porder, pgs, phcop, mem);
543
 
 
544
 
    if (code < 0)
545
 
        return code;
546
 
    return process_transfer(porder, pgs, NULL,
547
 
                            &phcop->transfer_closure, mem);
548
 
}
549
 
 
550
 
static const gx_ht_order_procs_t wts_order_procs = { 0
551
 
};
552
 
 
553
 
/**
554
 
 * gs_sethalftone_try_wts: Try creating a wts-based device halftone.
555
 
 * @pht: Client halftone.
556
 
 * @pdht: Device halftone to initialize.
557
 
 *
558
 
 * Tries initializing @pdht based on data from @pht, using WTS.
559
 
 *
560
 
 * Return value: 0 on success, 1 to indicate that the initialization
561
 
 * was not done, and that the legacy initialization code path should
562
 
 * be used.
563
 
 **/
564
 
static int
565
 
gs_sethalftone_try_wts(gs_halftone *pht, gs_state *pgs,
566
 
                       gx_device_halftone *pdht)
567
 
{
568
 
    gx_device *dev = pgs->device;
569
 
    int num_comps = dev->color_info.num_components;
570
 
    int depth = dev->color_info.depth;
571
 
 
572
 
    if (pht->type != ht_type_multiple)
573
 
        /* Only work with Type 5 halftones. todo: we probably want
574
 
           to relax this. */
575
 
        return 1;
576
 
 
577
 
    if_debug2('h', "[h]%s, num_comp = %d\n",
578
 
              dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ? "Separable and linear" : "Not separable and linear!",
579
 
              pht->params.multiple.num_comp);
580
 
 
581
 
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN &&
582
 
        pht->params.multiple.num_comp > 1)
583
 
        /* WTS is only enabled for separable or monochrome devices. */
584
 
        return 1;
585
 
 
586
 
    /* only work with bilevel (not multilevel) devices */
587
 
    if (depth > num_comps) {
588
 
        if (depth >= 2 * num_comps)
589
 
            return 1;
590
 
        if (dev->color_info.gray_index != GX_CINFO_COMP_NO_INDEX &&
591
 
            (dev->color_info.max_gray > 1 || 
592
 
            (num_comps > 1 && dev->color_info.max_color > 1)))
593
 
            return 1;
594
 
    }
595
 
 
596
 
    if (pht->type == ht_type_multiple) {
597
 
        gs_halftone_component *components = pht->params.multiple.components;
598
 
        uint num_comp = pht->params.multiple.num_comp;
599
 
        int i;
600
 
        gx_ht_order_component *pocs;
601
 
        gx_ht_order_component *poc_next;
602
 
        int code = 0;
603
 
        bool have_Default = false;
604
 
 
605
 
        for (i = 0; i < num_comp; i++) {
606
 
            if (components[i].type != ht_type_spot)
607
 
                return 1;
608
 
            else {
609
 
                gs_spot_halftone *spot = &components[i].params.spot;
610
 
                if (!spot->accurate_screens)
611
 
                    return 1;
612
 
            }
613
 
        }
614
 
 
615
 
        pocs = gs_alloc_struct_array( pgs->memory,
616
 
                                      num_comp,
617
 
                                      gx_ht_order_component,
618
 
                                      &st_ht_order_component_element,
619
 
                                      "gs_sethalftone_try_wts" );
620
 
        /* pocs = malloc(num_comp * sizeof(gx_ht_order_component)); */
621
 
        poc_next = &pocs[1];
622
 
        for (i = 0; i < num_comp; i++) {
623
 
            gs_halftone_component *component = &components[i];
624
 
            gs_spot_halftone *spot = &component->params.spot;
625
 
            gs_screen_halftone *h = &spot->screen;
626
 
            gx_wts_cell_params_t *wcp;
627
 
            gs_wts_screen_enum_t *wse;
628
 
            gs_matrix imat;
629
 
            gx_ht_order_component *poc;
630
 
 
631
 
            if (component->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
632
 
                if (have_Default) {
633
 
                    /* Duplicate Default */
634
 
                    code = gs_note_error(gs_error_rangecheck);
635
 
                    break;
636
 
                }
637
 
                poc = pocs;
638
 
                have_Default = true;
639
 
            } else if (i == num_comp - 1 && !have_Default) {
640
 
                /* No Default */
641
 
                code = gs_note_error(gs_error_rangecheck);
642
 
                break;
643
 
            } else
644
 
                poc = poc_next++;
645
 
 
646
 
            gs_deviceinitialmatrix(gs_currentdevice(pgs), &imat);
647
 
 
648
 
            wcp = wts_pick_cell_size(h, &imat);
649
 
            wse = gs_wts_screen_enum_new(wcp);
650
 
 
651
 
            poc->corder.wse = wse;
652
 
            poc->corder.wts = NULL;
653
 
            poc->corder.procs = &wts_order_procs;
654
 
            poc->corder.data_memory = NULL;
655
 
            poc->corder.num_levels = 0;
656
 
            poc->corder.num_bits = 0;
657
 
            poc->corder.levels = NULL;
658
 
            poc->corder.bit_data = NULL;
659
 
            poc->corder.cache = NULL;
660
 
            poc->corder.transfer = NULL;
661
 
            poc->comp_number = component->comp_number;
662
 
            poc->cname = component->cname;
663
 
            code = process_transfer( &poc->corder,
664
 
                                     pgs,
665
 
                                     spot->transfer,
666
 
                                     &spot->transfer_closure,
667
 
                                     pgs->memory );
668
 
            if (code < 0)
669
 
                break;
670
 
        }
671
 
        /* todo: cleanup on error */
672
 
        pdht->components = pocs;
673
 
        pdht->num_comp = num_comp;
674
 
        return code;
675
 
    }
676
 
    return 1;
677
 
}