~ubuntu-branches/ubuntu/oneiric/ghostscript/oneiric

« back to all changes in this revision

Viewing changes to base/gxclread.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2011-07-15 16:49:55 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715164955-uga6qibao6kez05c
Tags: 9.04~dfsg~20110715-0ubuntu1
* New upstream release
   - GIT snapshot from Jult, 12 2011.
* debian/patches/020110406~a54df2d.patch,
  debian/patches/020110408~0791cc8.patch,
  debian/patches/020110408~507cbee.patch,
  debian/patches/020110411~4509a49.patch,
  debian/patches/020110412~78bb9a6.patch,
  debian/patches/020110418~a05ab8a.patch,
  debian/patches/020110420~20b6c78.patch,
  debian/patches/020110420~4ddefa2.patch: Removed upstream patches.
* debian/rules: Generate ABI version number (variable "abi") correctly,
  cutting off repackaging and pre-release parts.
* debian/rules: Added ./lcms2/ directory to DEB_UPSTREAM_REPACKAGE_EXCLUDES.
* debian/copyright: Added lcms2/* to the list of excluded files.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
2
   All Rights Reserved.
3
 
  
 
3
 
4
4
   This software is provided AS-IS with no warranty, either express or
5
5
   implied.
6
6
 
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: gxclread.c 11346 2010-06-01 17:41:20Z mvrhel $ */
 
14
/* $Id$ */
15
15
/* Command list reading for Ghostscript. */
16
16
#include "memory_.h"
17
17
#include "gx.h"
27
27
#include "gxhttile.h"
28
28
#include "gdevplnx.h"
29
29
#include "gsmemory.h"
 
30
#include "gsmemlok.h"
30
31
#include "vdtrace.h"
31
32
#include "gsicc_cache.h"
32
33
/*
96
97
    stream_band_read_state *const ss = (stream_band_read_state *) st;
97
98
 
98
99
    if (gs_debug_c('L')) {
99
 
        ss->offset_map_length = 0;
100
 
        ss->offset_map_max_length = cbuf_size + 1; /* fixme: Wanted a more accurate implementation. */
101
 
        ss->offset_map = (cbuf_offset_map_elem *)gs_alloc_byte_array(crdev->memory, 
102
 
                    ss->offset_map_max_length, sizeof(*ss->offset_map), "s_band_read_init_offset_map");
103
 
        if (ss->offset_map == NULL)
104
 
            return_error(gs_error_VMerror);
105
 
        ss->offset_map[0].buffered = 0;
106
 
        crdev->offset_map = ss->offset_map; /* Prevent collecting it as garbage. 
107
 
                                            Debugged with ppmraw -r300 014-09.ps . */
 
100
        ss->offset_map_length = 0;
 
101
        ss->offset_map_max_length = cbuf_size + 1; /* fixme: Wanted a more accurate implementation. */
 
102
        ss->offset_map = (cbuf_offset_map_elem *)gs_alloc_byte_array(crdev->memory,
 
103
                    ss->offset_map_max_length, sizeof(*ss->offset_map), "s_band_read_init_offset_map");
 
104
        if (ss->offset_map == NULL)
 
105
            return_error(gs_error_VMerror);
 
106
        ss->offset_map[0].buffered = 0;
 
107
        crdev->offset_map = ss->offset_map; /* Prevent collecting it as garbage.
 
108
                                            Debugged with ppmraw -r300 014-09.ps . */
108
109
    } else {
109
 
        ss->offset_map_length = 0;
110
 
        ss->offset_map_max_length = 0;
111
 
        ss->offset_map = NULL;
112
 
        crdev->offset_map = NULL;
 
110
        ss->offset_map_length = 0;
 
111
        ss->offset_map_max_length = 0;
 
112
        ss->offset_map = NULL;
 
113
        crdev->offset_map = NULL;
113
114
    }
114
115
    ss->skip_first = true;
115
116
    return 0;
119
120
s_band_read_dnit_offset_map(gx_device_clist_reader *crdev, stream_state * st)
120
121
{
121
122
    if (gs_debug_c('L')) {
122
 
        stream_band_read_state *const ss = (stream_band_read_state *) st;
 
123
        stream_band_read_state *const ss = (stream_band_read_state *) st;
123
124
 
124
 
        gs_free_object(crdev->memory, ss->offset_map, "s_band_read_dnit_offset_map");
125
 
        crdev->offset_map = 0;
 
125
        gs_free_object(crdev->memory, ss->offset_map, "s_band_read_dnit_offset_map");
 
126
        crdev->offset_map = 0;
126
127
    }
127
128
}
128
129
#endif
129
130
 
130
 
 
131
131
static int
132
132
s_band_read_process(stream_state * st, stream_cursor_read * ignore_pr,
133
 
                    stream_cursor_write * pw, bool last)
 
133
                    stream_cursor_write * pw, bool last)
134
134
{
135
135
    stream_band_read_state *const ss = (stream_band_read_state *) st;
136
136
    register byte *q = pw->ptr;
143
143
    const clist_io_procs_t *io_procs = ss->page_info.io_procs;
144
144
 
145
145
    while ((count = wlimit - q) != 0) {
146
 
        if (left) {             /* Read more data for the current run. */
147
 
            if (count > left)
148
 
                count = left;
 
146
        if (left) {             /* Read more data for the current run. */
 
147
            if (count > left)
 
148
                count = left;
149
149
#           ifdef DEBUG
150
 
                if (gs_debug_c('L'))
151
 
                    ss->offset_map[ss->offset_map_length - 1].buffered += count;
 
150
                if (gs_debug_c('L'))
 
151
                    ss->offset_map[ss->offset_map_length - 1].buffered += count;
152
152
#           endif
153
 
            io_procs->fread_chars(q + 1, count, cfile);
154
 
            if (io_procs->ferror_code(cfile) < 0) {
155
 
                status = ERRC;
156
 
                break;
157
 
            }
158
 
            q += count;
159
 
            left -= count;
160
 
            process_interrupts(st->memory);
161
 
            continue;
162
 
        }
 
153
            io_procs->fread_chars(q + 1, count, cfile);
 
154
            if (io_procs->ferror_code(cfile) < 0) {
 
155
                status = ERRC;
 
156
                break;
 
157
            }
 
158
            q += count;
 
159
            left -= count;
 
160
            process_interrupts(st->memory);
 
161
            continue;
 
162
        }
163
163
rb:
164
 
        /*
165
 
         * Scan for the next run for the current bands (or a band range
166
 
         * that includes a current band).
167
 
         */
168
 
        if (ss->b_this.band_min == cmd_band_end &&
169
 
            io_procs->ftell(bfile) == ss->page_bfile_end_pos
170
 
            ) {
171
 
            status = EOFC;
172
 
            break;
173
 
        } {
174
 
            int bmin = ss->b_this.band_min;
175
 
            int bmax = ss->b_this.band_max;
176
 
            int64_t pos = ss->b_this.pos;
177
 
            int nread;
 
164
        /*
 
165
         * Scan for the next run for the current bands (or a band range
 
166
         * that includes a current band).
 
167
         */
 
168
        if (ss->b_this.band_min == cmd_band_end &&
 
169
            io_procs->ftell(bfile) == ss->page_bfile_end_pos
 
170
            ) {
 
171
            status = EOFC;
 
172
            break;
 
173
        } {
 
174
            int bmin = ss->b_this.band_min;
 
175
            int bmax = ss->b_this.band_max;
 
176
            int64_t pos = ss->b_this.pos;
 
177
            int nread;
178
178
 
179
 
            nread = io_procs->fread_chars(&ss->b_this, sizeof(ss->b_this), bfile);
180
 
            if (nread < sizeof(ss->b_this)) {
181
 
                DISCARD(gs_note_error(gs_error_unregistered)); /* Must not happen. */
182
 
                return ERRC;
183
 
            }
184
 
            if (!(ss->band_last >= bmin && ss->band_first <= bmax))
185
 
                goto rb;
186
 
            io_procs->fseek(cfile, pos, SEEK_SET, ss->page_cfname);
187
 
            left = (uint) (ss->b_this.pos - pos);
 
179
            nread = io_procs->fread_chars(&ss->b_this, sizeof(ss->b_this), bfile);
 
180
            if (nread < sizeof(ss->b_this)) {
 
181
                DISCARD(gs_note_error(gs_error_unregistered)); /* Must not happen. */
 
182
                return ERRC;
 
183
            }
 
184
            if (!(ss->band_last >= bmin && ss->band_first <= bmax))
 
185
                goto rb;
 
186
            io_procs->fseek(cfile, pos, SEEK_SET, ss->page_cfname);
 
187
            left = (uint) (ss->b_this.pos - pos);
188
188
#           ifdef DEBUG
189
 
            if (left > 0  && gs_debug_c('L')) {
190
 
                if (ss->offset_map_length >= ss->offset_map_max_length) {
191
 
                    DISCARD(gs_note_error(gs_error_unregistered)); /* Must not happen. */
192
 
                    return ERRC;
193
 
                }
194
 
                ss->offset_map[ss->offset_map_length].file_offset = pos;
195
 
                ss->offset_map[ss->offset_map_length].buffered = 0;
196
 
                ss->offset_map_length++;
197
 
            }
 
189
            if (left > 0  && gs_debug_c('L')) {
 
190
                if (ss->offset_map_length >= ss->offset_map_max_length) {
 
191
                    DISCARD(gs_note_error(gs_error_unregistered)); /* Must not happen. */
 
192
                    return ERRC;
 
193
                }
 
194
                ss->offset_map[ss->offset_map_length].file_offset = pos;
 
195
                ss->offset_map[ss->offset_map_length].buffered = 0;
 
196
                ss->offset_map_length++;
 
197
            }
198
198
#           endif
199
 
            if_debug7('l', 
200
 
                      "[l]reading for bands (%d,%d) at bfile %ld, cfile %ld, length %u color %d rop %d\n",
201
 
                      bmin, bmax,
202
 
                      (long)(io_procs->ftell(bfile) - sizeof(ss->b_this)), /* stefan foo was: 2 * sizeof ?? */
203
 
                      (long)pos, left, ss->b_this.band_complexity.uses_color,
204
 
                      ss->b_this.band_complexity.nontrivial_rops);
205
 
        }
 
199
            if_debug7('l',
 
200
                      "[l]reading for bands (%d,%d) at bfile %ld, cfile %ld, length %u color %d rop %d\n",
 
201
                      bmin, bmax,
 
202
                      (long)(io_procs->ftell(bfile) - sizeof(ss->b_this)), /* stefan foo was: 2 * sizeof ?? */
 
203
                      (long)pos, left, ss->b_this.band_complexity.uses_color,
 
204
                      ss->b_this.band_complexity.nontrivial_rops);
 
205
        }
206
206
    }
207
207
    pw->ptr = q;
208
208
    ss->left = left;
221
221
    uint i, offset0, offset = 0;
222
222
 
223
223
    for (i = 0; i < ss->offset_map_length; i++) {
224
 
        offset0 = offset;
225
 
        offset += ss->offset_map[i].buffered;
226
 
        if (buffer_offset < offset) {
227
 
            *poffset0 = offset0;
228
 
            return i;
229
 
        }
 
224
        offset0 = offset;
 
225
        offset += ss->offset_map[i].buffered;
 
226
        if (buffer_offset < offset) {
 
227
            *poffset0 = offset0;
 
228
            return i;
 
229
        }
230
230
    }
231
231
    gs_note_error(gs_error_unregistered); /* Must not happen. */
232
232
    return -1;
240
240
    int i = buffer_segment_index(ss, buffer_offset, &offset0);
241
241
 
242
242
    if (i < 0)
243
 
        return -1;
 
243
        return -1;
244
244
    return ss->offset_map[i].file_offset + (uint)(buffer_offset - offset0);
245
245
}
246
246
 
247
247
int
248
248
top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end)
249
249
{
250
 
    /* NOTE: The clist data are buffered in the clist reader buffer and in the 
 
250
    /* NOTE: The clist data are buffered in the clist reader buffer and in the
251
251
       internal buffer of the clist stream. Since the 1st buffer is not accessible
252
252
       from s_band_read_process, offset_map corresponds the union of the 2 buffers.
253
253
     */
254
254
    stream_band_read_state *const ss = (stream_band_read_state *) st;
255
255
 
256
256
    if (!gs_debug_c('L')) {
257
 
        return 0;
 
257
        return 0;
258
258
    } else if (ss->skip_first) {
259
 
        /* Work around the trick with initializing the buffer pointer with the buffer end. */
260
 
        ss->skip_first = false;
261
 
        return 0;
 
259
        /* Work around the trick with initializing the buffer pointer with the buffer end. */
 
260
        ss->skip_first = false;
 
261
        return 0;
262
262
    } else if (ptr == buf)
263
 
        return 0;
 
263
        return 0;
264
264
    else {
265
 
        uint buffer_offset = ptr - buf;
266
 
        uint offset0, consumed;
267
 
        int i = buffer_segment_index(ss, buffer_offset, &offset0);
268
 
        
269
 
        if (i < 0)
270
 
            return_error(gs_error_unregistered); /* Must not happen. */
271
 
        consumed = buffer_offset - offset0;
272
 
        ss->offset_map[i].buffered -= consumed;
273
 
        ss->offset_map[i].file_offset += consumed;
274
 
        if (i) {
275
 
            memmove(ss->offset_map, ss->offset_map + i, 
276
 
                (ss->offset_map_length - i) * sizeof(*ss->offset_map));
277
 
            ss->offset_map_length -= i;
278
 
        }
 
265
        uint buffer_offset = ptr - buf;
 
266
        uint offset0, consumed;
 
267
        int i = buffer_segment_index(ss, buffer_offset, &offset0);
 
268
 
 
269
        if (i < 0)
 
270
            return_error(gs_error_unregistered); /* Must not happen. */
 
271
        consumed = buffer_offset - offset0;
 
272
        ss->offset_map[i].buffered -= consumed;
 
273
        ss->offset_map[i].file_offset += consumed;
 
274
        if (i) {
 
275
            memmove(ss->offset_map, ss->offset_map + i,
 
276
                (ss->offset_map_length - i) * sizeof(*ss->offset_map));
 
277
            ss->offset_map_length -= i;
 
278
        }
279
279
    }
280
280
    return 0;
281
281
}
282
282
#endif /* DEBUG */
283
283
 
284
 
 
285
284
/* ------ Reading/rendering ------ */
286
285
 
287
286
/* Calculate the raster for a chunky or planar device. */
289
288
clist_plane_raster(const gx_device *dev, const gx_render_plane_t *render_plane)
290
289
{
291
290
    return bitmap_raster(dev->width *
292
 
                         (render_plane && render_plane->index >= 0 ?
293
 
                          render_plane->depth : dev->color_info.depth));
 
291
                         (render_plane && render_plane->index >= 0 ?
 
292
                          render_plane->depth : dev->color_info.depth));
294
293
}
295
294
 
296
295
/* Select full-pixel rendering if required for RasterOp. */
297
296
void
298
297
clist_select_render_plane(gx_device *dev, int y, int height,
299
 
                          gx_render_plane_t *render_plane, int index)
 
298
                          gx_render_plane_t *render_plane, int index)
300
299
{
301
300
    if (index >= 0) {
302
 
        gx_colors_used_t colors_used;
303
 
        int ignore_start;
 
301
        gx_colors_used_t colors_used;
 
302
        int ignore_start;
304
303
 
305
 
        gdev_prn_colors_used(dev, y, height, &colors_used,  &ignore_start);
306
 
        if (colors_used.slow_rop)
307
 
            index = -1;
 
304
        gdev_prn_colors_used(dev, y, height, &colors_used,  &ignore_start);
 
305
        if (colors_used.slow_rop)
 
306
            index = -1;
308
307
    }
309
308
    if (index < 0)
310
 
        render_plane->index = index;
 
309
        render_plane->index = index;
311
310
    else
312
 
        gx_render_plane_init(render_plane, dev, index);
 
311
        gx_render_plane_init(render_plane, dev, index);
313
312
}
314
313
 
315
314
/*
326
325
    int code = clist_render_init(cldev);
327
326
 
328
327
    if (code < 0)
329
 
        return code;
 
328
        return code;
330
329
 
331
330
    code = clist_playback_file_bands(playback_action_setup,
332
 
                                     crdev, &crdev->page_info, 0, 0, 0, 0, 0);
 
331
                                     crdev, &crdev->page_info, 0, 0, 0, 0, 0);
333
332
 
334
333
    /* put_params may have reinitialized device into a writer */
335
334
    clist_render_init(cldev);
337
336
    return code;
338
337
}
339
338
 
340
 
int 
 
339
int
341
340
clist_close_writer_and_init_reader(gx_device_clist *cldev)
342
341
{
343
342
    gx_device_clist_reader * const crdev = &cldev->reader;
344
 
    
 
343
    gs_memory_t *base_mem = crdev->memory->thread_safe_memory;
 
344
    gs_memory_status_t mem_status;
345
345
    int code = 0;
346
346
 
347
347
    /* Initialize for rendering if we haven't done so yet. */
348
348
    if (crdev->ymin < 0) {
349
 
        code = clist_end_page(&cldev->writer);
350
 
        if (code < 0)
351
 
            return code;
352
 
        code = clist_render_init(cldev);
 
349
        code = clist_end_page(&cldev->writer);
 
350
        if (code < 0)
 
351
            return code;
 
352
        code = clist_render_init(cldev);
 
353
        if (code < 0)
 
354
            return code;
353
355
         /* Check for and get ICC profile table */
354
356
        code = clist_read_icctable(crdev);
 
357
        if (code < 0)
 
358
            return code;
355
359
        /* Allocate the icc cache for the clist reader */
356
 
        crdev->icc_cache_cl = gsicc_cache_new(crdev->memory);
 
360
        /* Since we may be rendering in multiple threads, make sure the memory */
 
361
        /* is thread safe by using a known thread_safe memory allocator */
 
362
        gs_memory_status(base_mem, &mem_status);
 
363
        if (mem_status.is_thread_safe == false) {
 
364
            return_error(gs_error_VMerror);
 
365
        }
 
366
 
 
367
        code = (crdev->icc_cache_cl = gsicc_cache_new(base_mem)) == NULL ? gs_error_VMerror : code;
357
368
    }
358
369
    return code;
359
370
}
380
391
        if (cb->band_max == band && cb->band_min == band) {
381
392
            crdev->page_info.io_procs->fseek(bfile, save_pos, SEEK_SET, crdev->page_info.bfname);
382
393
            return(0);  /* Found it */
383
 
        } 
 
394
        }
384
395
        start_pos -= sizeof(cmd_block);
385
396
        if (start_pos < 0) {
386
397
           crdev->page_info.io_procs->fseek(bfile, save_pos, SEEK_SET, crdev->page_info.bfname);
417
428
    clist_icctable_t *icc_table = crdev->icc_table;
418
429
    int64_t save_pos;
419
430
    int number_entries, size_data;
420
 
    unsigned char *buf;
 
431
    unsigned char *buf, *buf_start;
421
432
    clist_icctable_entry_t *curr_entry;
422
433
    int k;
423
434
 
424
 
    if ( icc_table != NULL ) 
 
435
    if ( icc_table != NULL )
425
436
        return(0);
426
437
    save_pos = crdev->page_info.io_procs->ftell(cfile);
427
438
    crdev->page_info.io_procs->fseek(cfile, cb->pos, SEEK_SET, crdev->page_info.cfname);
430
441
    /* Allocate the space */
431
442
    size_data = number_entries*sizeof(clist_icc_serial_entry_t);
432
443
    buf = gs_alloc_bytes(crdev->memory, size_data, "clist_read_icctable");
 
444
    buf_start = buf;
433
445
    if (buf == NULL)
434
446
        return gs_rethrow(-1, "insufficient memory for icc table buffer reader");
435
447
    /* Get the data */
436
448
    clist_read_chunk(crdev, cb->pos + 4, size_data, buf);
437
 
    icc_table = gs_alloc_struct(crdev->memory, 
438
 
                clist_icctable_t,
439
 
                &st_clist_icctable, "clist_read_icctable");
440
 
    if (icc_table == NULL)
 
449
    icc_table = gs_alloc_struct(crdev->memory,
 
450
                clist_icctable_t,
 
451
                &st_clist_icctable, "clist_read_icctable");
 
452
    if (icc_table == NULL) {
 
453
        gs_free_object(crdev->memory, buf_start, "clist_read_icctable");
441
454
        return gs_rethrow(-1, "insufficient memory for icc table buffer reader");
 
455
    }
442
456
    icc_table->head = NULL;
443
457
    icc_table->final = NULL;
444
458
   /* Allocate and fill each entry */
445
459
    icc_table->tablesize = number_entries;
446
460
    crdev->icc_table = icc_table;
447
461
    for (k = 0; k < number_entries; k++) {
448
 
        curr_entry = gs_alloc_struct(crdev->memory, 
449
 
                clist_icctable_entry_t,
450
 
                &st_clist_icctable_entry, "clist_read_icctable");
451
 
        if (curr_entry == NULL)
 
462
        curr_entry = gs_alloc_struct(crdev->memory,
 
463
                clist_icctable_entry_t,
 
464
                &st_clist_icctable_entry, "clist_read_icctable");
 
465
        if (curr_entry == NULL) {
 
466
            gs_free_object(crdev->memory, buf_start, "clist_read_icctable");
452
467
            return gs_rethrow(-1, "insufficient memory for icc table entry");
 
468
        }
453
469
        memcpy(&(curr_entry->serial_data), buf, sizeof(clist_icc_serial_entry_t));
454
470
        buf += sizeof(clist_icc_serial_entry_t);
455
471
        curr_entry->icc_profile = NULL;
462
478
        }
463
479
        curr_entry->next = NULL;
464
480
    }
 
481
    gs_free_object(crdev->memory, buf_start, "clist_read_icctable");
465
482
    crdev->page_info.io_procs->fseek(cfile, save_pos, SEEK_SET, crdev->page_info.cfname);
466
483
    return(0);
467
484
}
474
491
    cmd_block cb;
475
492
    int code;
476
493
 
477
 
    /* First get the command block which will tell us where the 
 
494
    /* First get the command block which will tell us where the
478
495
       information is stored in the cfile */
479
496
    code = clist_find_pseudoband(crdev, crdev->nbands + ICC_BAND_OFFSET - 1, &cb);
480
497
    if (code < 0)
509
526
/* Copy a rasterized rectangle to the client, rasterizing if needed. */
510
527
int
511
528
clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect,
512
 
                         gs_get_bits_params_t *params, gs_int_rect **unread)
 
529
                         gs_get_bits_params_t *params, gs_int_rect **unread)
513
530
{
514
531
    gx_device_clist *cldev = (gx_device_clist *)dev;
515
532
    gx_device_clist_common *cdev = (gx_device_clist_common *)dev;
521
538
    int lines_rasterized;
522
539
    gx_device *bdev;
523
540
    int num_planes =
524
 
        (options & GB_PACKING_CHUNKY ? 1 :
525
 
         options & GB_PACKING_PLANAR ? dev->color_info.num_components :
526
 
         options & GB_PACKING_BIT_PLANAR ? dev->color_info.depth :
527
 
         0 /****** NOT POSSIBLE ******/);
 
541
        (options & GB_PACKING_CHUNKY ? 1 :
 
542
         options & GB_PACKING_PLANAR ? dev->color_info.num_components :
 
543
         options & GB_PACKING_BIT_PLANAR ? dev->color_info.depth :
 
544
         0 /****** NOT POSSIBLE ******/);
528
545
    gx_render_plane_t render_plane;
529
546
    int plane_index;
530
547
    int my;
531
548
    int code;
532
549
 
533
550
    if (prect->p.x < 0 || prect->q.x > dev->width ||
534
 
        y < 0 || end_y > dev->height
535
 
        )
536
 
        return_error(gs_error_rangecheck);
 
551
        y < 0 || end_y > dev->height
 
552
        )
 
553
        return_error(gs_error_rangecheck);
537
554
    if (line_count <= 0 || prect->p.x >= prect->q.x)
538
 
        return 0;
 
555
        return 0;
539
556
 
540
557
    /*
541
558
     * Calculate the render_plane from the params.  There are two cases:
543
560
     */
544
561
    plane_index = -1;
545
562
    if (options & GB_SELECT_PLANES) {
546
 
        /* Look for the one selected plane. */
547
 
        int i;
 
563
        /* Look for the one selected plane. */
 
564
        int i;
548
565
 
549
 
        for (i = 0; i < num_planes; ++i)
550
 
            if (params->data[i]) {
551
 
                if (plane_index >= 0)  /* >1 plane requested */
552
 
                    return gx_default_get_bits_rectangle(dev, prect, params,
553
 
                                                         unread);
554
 
                plane_index = i;
555
 
            }
 
566
        for (i = 0; i < num_planes; ++i)
 
567
            if (params->data[i]) {
 
568
                if (plane_index >= 0)  /* >1 plane requested */
 
569
                    return gx_default_get_bits_rectangle(dev, prect, params,
 
570
                                                         unread);
 
571
                plane_index = i;
 
572
            }
556
573
    }
557
574
 
558
575
    if (0 > (code = clist_close_writer_and_init_reader(cldev)))
559
 
        return code;
 
576
        return code;
560
577
 
561
578
    clist_select_render_plane(dev, y, line_count, &render_plane, plane_index);
562
579
    code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
563
 
                                  &bdev, cdev->target, y, &render_plane,
564
 
                                  dev->memory, clist_get_band_complexity(dev,y));
 
580
                                  &bdev, cdev->target, y, &render_plane,
 
581
                                  dev->memory, clist_get_band_complexity(dev,y));
565
582
    if (code < 0)
566
 
        return code;
 
583
        return code;
567
584
    code = clist_rasterize_lines(dev, y, line_count, bdev, &render_plane, &my);
568
585
    if (code < 0)
569
 
        return code;
 
586
        return code;
570
587
    lines_rasterized = min(code, line_count);
571
588
    /* Return as much of the rectangle as falls within the rasterized lines. */
572
589
    band_rect = *prect;
573
590
    band_rect.p.y = my;
574
591
    band_rect.q.y = my + lines_rasterized;
575
592
    code = dev_proc(bdev, get_bits_rectangle)
576
 
        (bdev, &band_rect, params, unread);
 
593
        (bdev, &band_rect, params, unread);
577
594
    cdev->buf_procs.destroy_buf_device(bdev);
578
595
    if (code < 0 || lines_rasterized == line_count)
579
 
        return code;
 
596
        return code;
580
597
    /*
581
598
     * We'll have to return the rectangle in pieces.  Force GB_RETURN_COPY
582
599
     * rather than GB_RETURN_POINTER, and require all subsequent pieces to
585
602
     * rectangles, punt.
586
603
     */
587
604
    if (!(options & GB_RETURN_COPY) || code > 0)
588
 
        return gx_default_get_bits_rectangle(dev, prect, params, unread);
 
605
        return gx_default_get_bits_rectangle(dev, prect, params, unread);
589
606
    options = params->options;
590
607
    if (!(options & GB_RETURN_COPY)) {
591
 
        /* Redo the first piece with copying. */
592
 
        params->options = options =
593
 
            (params->options & ~GB_RETURN_ALL) | GB_RETURN_COPY;
594
 
        lines_rasterized = 0;
 
608
        /* Redo the first piece with copying. */
 
609
        params->options = options =
 
610
            (params->options & ~GB_RETURN_ALL) | GB_RETURN_COPY;
 
611
        lines_rasterized = 0;
595
612
    }
596
613
    {
597
 
        gs_get_bits_params_t band_params;
598
 
        uint raster = gx_device_raster(bdev, true);
599
 
 
600
 
        code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
601
 
                                      &bdev, cdev->target, y, &render_plane,
602
 
                                      dev->memory, clist_get_band_complexity(dev, y));
603
 
        if (code < 0)
604
 
            return code;
605
 
        band_params = *params;
606
 
        while ((y += lines_rasterized) < end_y) {
607
 
            int i;
608
 
 
609
 
            /* Increment data pointers by lines_rasterized. */
610
 
            for (i = 0; i < num_planes; ++i)
611
 
                if (band_params.data[i])
612
 
                    band_params.data[i] += raster * lines_rasterized;
613
 
            line_count = end_y - y;
614
 
            code = clist_rasterize_lines(dev, y, line_count, bdev,
615
 
                                         &render_plane, &my);
616
 
            if (code < 0)
617
 
                break;
618
 
            lines_rasterized = min(code, line_count);
619
 
            band_rect.p.y = my;
620
 
            band_rect.q.y = my + lines_rasterized;
621
 
            code = dev_proc(bdev, get_bits_rectangle)
622
 
                (bdev, &band_rect, &band_params, unread);
623
 
            if (code < 0)
624
 
                break;
625
 
            params->options = options = band_params.options;
626
 
            if (lines_rasterized == line_count)
627
 
                break;
628
 
        }
629
 
        cdev->buf_procs.destroy_buf_device(bdev);
 
614
        gs_get_bits_params_t band_params;
 
615
        uint raster = gx_device_raster(bdev, true);
 
616
 
 
617
        code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
 
618
                                      &bdev, cdev->target, y, &render_plane,
 
619
                                      dev->memory, clist_get_band_complexity(dev, y));
 
620
        if (code < 0)
 
621
            return code;
 
622
        band_params = *params;
 
623
        while ((y += lines_rasterized) < end_y) {
 
624
            int i;
 
625
 
 
626
            /* Increment data pointers by lines_rasterized. */
 
627
            for (i = 0; i < num_planes; ++i)
 
628
                if (band_params.data[i])
 
629
                    band_params.data[i] += raster * lines_rasterized;
 
630
            line_count = end_y - y;
 
631
            code = clist_rasterize_lines(dev, y, line_count, bdev,
 
632
                                         &render_plane, &my);
 
633
            if (code < 0)
 
634
                break;
 
635
            lines_rasterized = min(code, line_count);
 
636
            band_rect.p.y = my;
 
637
            band_rect.q.y = my + lines_rasterized;
 
638
            code = dev_proc(bdev, get_bits_rectangle)
 
639
                (bdev, &band_rect, &band_params, unread);
 
640
            if (code < 0)
 
641
                break;
 
642
            params->options = options = band_params.options;
 
643
            if (lines_rasterized == line_count)
 
644
                break;
 
645
        }
 
646
        cdev->buf_procs.destroy_buf_device(bdev);
630
647
    }
631
648
    return code;
632
649
}
635
652
/* Processes min(requested # lines, # lines available thru end of band) */
636
653
int     /* returns -ve error code, or # scan lines copied */
637
654
clist_rasterize_lines(gx_device *dev, int y, int line_count,
638
 
                      gx_device *bdev, const gx_render_plane_t *render_plane,
639
 
                      int *pmy)
 
655
                      gx_device *bdev, const gx_render_plane_t *render_plane,
 
656
                      int *pmy)
640
657
{
641
658
    gx_device_clist * const cldev = (gx_device_clist *)dev;
642
659
    gx_device_clist_reader * const crdev = &cldev->reader;
648
665
 
649
666
    /* Render a band if necessary, and copy it incrementally. */
650
667
    if (crdev->ymin < 0 || crdev->yplane.index != plane_index ||
651
 
        !(y >= crdev->ymin && y < crdev->ymax)
652
 
        ) {
653
 
        int band_height = crdev->page_band_height;
654
 
        int band = y / band_height;
655
 
        int band_begin_line = band * band_height;
656
 
        int band_end_line = band_begin_line + band_height;
657
 
        int band_num_lines;
658
 
        gs_int_rect band_rect;
659
 
 
660
 
        if (band_end_line > dev->height)
661
 
            band_end_line = dev->height;
662
 
        /* Clip line_count to current band */
663
 
        if (line_count > band_end_line - y)
664
 
            line_count = band_end_line - y;
665
 
        band_num_lines = band_end_line - band_begin_line;
666
 
 
667
 
        if (y < 0 || y > dev->height)
668
 
            return_error(gs_error_rangecheck);
669
 
        code = crdev->buf_procs.setup_buf_device
670
 
            (bdev, mdata, raster, NULL, 0, band_num_lines, band_num_lines);
671
 
        band_rect.p.x = 0;
672
 
        band_rect.p.y = band_begin_line;
673
 
        band_rect.q.x = dev->width;
674
 
        band_rect.q.y = band_end_line;
675
 
        if (code >= 0)
676
 
            code = clist_render_rectangle(cldev, &band_rect, bdev, render_plane,
677
 
                                          true);
678
 
        /* Reset the band boundaries now, so that we don't get */
679
 
        /* an infinite loop. */
680
 
        crdev->ymin = band_begin_line;
681
 
        crdev->ymax = band_end_line;
682
 
        crdev->offset_map = NULL;
683
 
        if (code < 0)
684
 
            return code;
 
668
        !(y >= crdev->ymin && y < crdev->ymax)
 
669
        ) {
 
670
        int band_height = crdev->page_band_height;
 
671
        int band = y / band_height;
 
672
        int band_begin_line = band * band_height;
 
673
        int band_end_line = band_begin_line + band_height;
 
674
        int band_num_lines;
 
675
        gs_int_rect band_rect;
 
676
 
 
677
        if (band_end_line > dev->height)
 
678
            band_end_line = dev->height;
 
679
        /* Clip line_count to current band */
 
680
        if (line_count > band_end_line - y)
 
681
            line_count = band_end_line - y;
 
682
        band_num_lines = band_end_line - band_begin_line;
 
683
 
 
684
        if (y < 0 || y > dev->height)
 
685
            return_error(gs_error_rangecheck);
 
686
        code = crdev->buf_procs.setup_buf_device
 
687
            (bdev, mdata, raster, NULL, 0, band_num_lines, band_num_lines);
 
688
        band_rect.p.x = 0;
 
689
        band_rect.p.y = band_begin_line;
 
690
        band_rect.q.x = dev->width;
 
691
        band_rect.q.y = band_end_line;
 
692
        if (code >= 0)
 
693
            code = clist_render_rectangle(cldev, &band_rect, bdev, render_plane,
 
694
                                          true);
 
695
        /* Reset the band boundaries now, so that we don't get */
 
696
        /* an infinite loop. */
 
697
        crdev->ymin = band_begin_line;
 
698
        crdev->ymax = band_end_line;
 
699
        crdev->offset_map = NULL;
 
700
        if (code < 0)
 
701
            return code;
685
702
    }
686
703
 
687
704
    if (line_count > crdev->ymax - y)
688
 
        line_count = crdev->ymax - y;
 
705
        line_count = crdev->ymax - y;
689
706
    code = crdev->buf_procs.setup_buf_device
690
 
        (bdev, mdata, raster, NULL, y - crdev->ymin, line_count,
691
 
         crdev->ymax - crdev->ymin);
 
707
        (bdev, mdata, raster, NULL, y - crdev->ymin, line_count,
 
708
         crdev->ymax - crdev->ymin);
692
709
    if (code < 0)
693
 
        return code;
 
710
        return code;
694
711
 
695
712
    *pmy = 0;
696
713
    return line_count;
702
719
 */
703
720
int
704
721
clist_render_rectangle(gx_device_clist *cldev, const gs_int_rect *prect,
705
 
                       gx_device *bdev,
706
 
                       const gx_render_plane_t *render_plane, bool clear)
 
722
                       gx_device *bdev,
 
723
                       const gx_render_plane_t *render_plane, bool clear)
707
724
{
708
725
    gx_device_clist_reader * const crdev = &cldev->reader;
709
726
    const gx_placed_page *ppages;
717
734
    int i;
718
735
 
719
736
    if (render_plane)
720
 
        crdev->yplane = *render_plane;
 
737
        crdev->yplane = *render_plane;
721
738
    else
722
 
        crdev->yplane.index = -1;
 
739
        crdev->yplane.index = -1;
723
740
    if_debug2('l', "[l]rendering bands (%d,%d)\n", band_first, band_last);
724
741
#if 0 /* Disabled because it is slow and appears to have no useful effect. */
725
742
    if (clear)
726
 
        dev_proc(bdev, fill_rectangle)
727
 
            (bdev, 0, 0, bdev->width, bdev->height, gx_device_white(bdev));
 
743
        dev_proc(bdev, fill_rectangle)
 
744
            (bdev, 0, 0, bdev->width, bdev->height, gx_device_white(bdev));
728
745
#endif
729
746
 
730
747
    /*
734
751
     */
735
752
    ppages = crdev->pages;
736
753
    if (ppages == 0) {
737
 
        current_page.info = crdev->page_info;
738
 
        placed_page.page = &current_page;
739
 
        placed_page.offset.x = placed_page.offset.y = 0;
740
 
        ppages = &placed_page;
741
 
        num_pages = 1;
 
754
        current_page.info = crdev->page_info;
 
755
        placed_page.page = &current_page;
 
756
        placed_page.offset.x = placed_page.offset.y = 0;
 
757
        ppages = &placed_page;
 
758
        num_pages = 1;
742
759
    }
743
760
    for (i = 0; i < num_pages && code >= 0; ++i) {
744
 
        const gx_placed_page *ppage = &ppages[i];
 
761
        const gx_placed_page *ppage = &ppages[i];
745
762
 
746
 
        /*
747
 
         * Set the band_offset_? values in case the buffer device
748
 
         * needs this. Example, wtsimdi device needs to adjust the 
749
 
         * phase of the dithering based on the page position, NOT
750
 
         * the position within the band buffer to avoid band stitch
751
 
         * lines in the dither pattern.
752
 
         *
753
 
         * The band_offset_x is not important for placed pages that
754
 
         * are nested on a 'master' page (imposition) since each
755
 
         * page expects to be dithered independently, but setting
756
 
         * this allows pages to be contiguous without a dithering
757
 
         * shift.
758
 
         *
759
 
         * The following sets the band_offset_? relative to the
760
 
         * master page.
761
 
         */
762
 
        bdev->band_offset_x = ppage->offset.x;
763
 
        bdev->band_offset_y = ppage->offset.y + (band_first * band_height);
764
 
        code = clist_playback_file_bands(playback_action_render,
765
 
                                         crdev, &ppage->page->info,
766
 
                                         bdev, band_first, band_last,
767
 
                                         prect->p.x - ppage->offset.x,
768
 
                                         prect->p.y);
 
763
        /*
 
764
         * Set the band_offset_? values in case the buffer device
 
765
         * needs this. Example, wtsimdi device needs to adjust the
 
766
         * phase of the dithering based on the page position, NOT
 
767
         * the position within the band buffer to avoid band stitch
 
768
         * lines in the dither pattern.
 
769
         *
 
770
         * The band_offset_x is not important for placed pages that
 
771
         * are nested on a 'master' page (imposition) since each
 
772
         * page expects to be dithered independently, but setting
 
773
         * this allows pages to be contiguous without a dithering
 
774
         * shift.
 
775
         *
 
776
         * The following sets the band_offset_? relative to the
 
777
         * master page.
 
778
         */
 
779
        bdev->band_offset_x = ppage->offset.x;
 
780
        bdev->band_offset_y = ppage->offset.y + (band_first * band_height);
 
781
        code = clist_playback_file_bands(playback_action_render,
 
782
                                         crdev, &ppage->page->info,
 
783
                                         bdev, band_first, band_last,
 
784
                                         prect->p.x - ppage->offset.x,
 
785
                                         prect->p.y);
769
786
    }
770
787
    return code;
771
788
}
772
789
 
773
790
/* Playback the band file, taking the indicated action w/ its contents. */
774
791
int
775
 
clist_playback_file_bands(clist_playback_action action, 
776
 
                          gx_device_clist_reader *crdev,
777
 
                          gx_band_page_info_t *page_info, gx_device *target,
778
 
                          int band_first, int band_last, int x0, int y0)
 
792
clist_playback_file_bands(clist_playback_action action,
 
793
                          gx_device_clist_reader *crdev,
 
794
                          gx_band_page_info_t *page_info, gx_device *target,
 
795
                          int band_first, int band_last, int x0, int y0)
779
796
{
780
797
    int code = 0;
781
798
    bool opened_bfile = false;
783
800
 
784
801
    /* We have to pick some allocator for rendering.... */
785
802
    gs_memory_t *mem =crdev->memory;
786
 
 
 
803
 
787
804
    stream_band_read_state rs;
788
805
 
789
806
    /* setup stream */
790
807
    s_init_state((stream_state *)&rs, &s_band_read_template,
791
 
                 (gs_memory_t *)0);
 
808
                 (gs_memory_t *)0);
792
809
    rs.band_first = band_first;
793
810
    rs.band_last = band_last;
794
811
    rs.page_info = *page_info;
795
812
 
796
813
    /* If this is a saved page, open the files. */
797
814
    if (rs.page_cfile == 0) {
798
 
        code = crdev->page_info.io_procs->fopen(rs.page_cfname,
799
 
                           gp_fmode_rb, &rs.page_cfile, crdev->bandlist_memory,
800
 
                           crdev->bandlist_memory, true);
801
 
        opened_cfile = (code >= 0);
 
815
        code = crdev->page_info.io_procs->fopen(rs.page_cfname,
 
816
                           gp_fmode_rb, &rs.page_cfile, crdev->bandlist_memory,
 
817
                           crdev->bandlist_memory, true);
 
818
        opened_cfile = (code >= 0);
802
819
    }
803
820
    if (rs.page_bfile == 0 && code >= 0) {
804
 
        code = crdev->page_info.io_procs->fopen(rs.page_bfname,
805
 
                           gp_fmode_rb, &rs.page_bfile, crdev->bandlist_memory,
806
 
                           crdev->bandlist_memory, false);
807
 
        opened_bfile = (code >= 0);
 
821
        code = crdev->page_info.io_procs->fopen(rs.page_bfname,
 
822
                           gp_fmode_rb, &rs.page_bfile, crdev->bandlist_memory,
 
823
                           crdev->bandlist_memory, false);
 
824
        opened_bfile = (code >= 0);
808
825
    }
809
826
    if (rs.page_cfile != 0 && rs.page_bfile != 0) {
810
 
        stream s;
811
 
        byte sbuf[cbuf_size];
812
 
        static const stream_procs no_procs = {
813
 
            s_std_noavailable, s_std_noseek, s_std_read_reset,
814
 
            s_std_read_flush, s_std_close, s_band_read_process
815
 
        };
 
827
        stream s;
 
828
        byte sbuf[cbuf_size];
 
829
        static const stream_procs no_procs = {
 
830
            s_std_noavailable, s_std_noseek, s_std_read_reset,
 
831
            s_std_read_flush, s_std_close, s_band_read_process
 
832
        };
816
833
 
817
 
        s_band_read_init((stream_state *)&rs);
 
834
        s_band_read_init((stream_state *)&rs);
818
835
#       ifdef DEBUG
819
 
        s_band_read_init_offset_map(crdev, (stream_state *)&rs);
 
836
        s_band_read_init_offset_map(crdev, (stream_state *)&rs);
820
837
#       endif
821
 
          /* The stream doesn't need a memory, but we'll need to access s.memory->gs_lib_ctx. */
822
 
        s_init(&s, mem);
823
 
        s_std_init(&s, sbuf, cbuf_size, &no_procs, s_mode_read);
824
 
        s.foreign = 1;
825
 
        s.state = (stream_state *)&rs;
 
838
          /* The stream doesn't need a memory, but we'll need to access s.memory->gs_lib_ctx. */
 
839
        s_init(&s, mem);
 
840
        s_std_init(&s, sbuf, cbuf_size, &no_procs, s_mode_read);
 
841
        s.foreign = 1;
 
842
        s.state = (stream_state *)&rs;
826
843
 
827
 
        if (vd_allowed('s')) {
828
 
            vd_get_dc('s');
829
 
        } else if (vd_allowed('i')) {
830
 
            vd_get_dc('i');
831
 
        }
832
 
        vd_set_shift(0, 0);
833
 
        vd_set_scale(0.01);
834
 
        vd_set_origin(0, 0);
835
 
        code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
836
 
        vd_release_dc;
 
844
        if (vd_allowed('s')) {
 
845
            vd_get_dc('s');
 
846
        } else if (vd_allowed('i')) {
 
847
            vd_get_dc('i');
 
848
        }
 
849
        vd_set_shift(0, 0);
 
850
        vd_set_scale(0.01);
 
851
        vd_set_origin(0, 0);
 
852
        code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
 
853
        vd_release_dc;
837
854
#       ifdef DEBUG
838
 
        s_band_read_dnit_offset_map(crdev, (stream_state *)&rs);
 
855
        s_band_read_dnit_offset_map(crdev, (stream_state *)&rs);
839
856
#       endif
840
857
    }
841
858
 
842
859
    /* Close the files if we just opened them. */
843
860
    if (opened_bfile && rs.page_bfile != 0)
844
 
        crdev->page_info.io_procs->fclose(rs.page_bfile, rs.page_bfname, false);
 
861
        crdev->page_info.io_procs->fclose(rs.page_bfile, rs.page_bfname, false);
845
862
    if (opened_cfile && rs.page_cfile != 0)
846
 
        crdev->page_info.io_procs->fclose(rs.page_cfile, rs.page_cfname, false);
 
863
        crdev->page_info.io_procs->fclose(rs.page_cfile, rs.page_cfname, false);
847
864
 
848
865
    return code;
849
866
}
856
873
clist_get_band_complexity(gx_device *dev, int y)
857
874
{
858
875
    if (dev != NULL) {
859
 
        gx_device_clist *cldev = (gx_device_clist *)dev;
860
 
        gx_device_clist_reader * const crdev = &cldev->reader;
861
 
        int band_number = y / crdev->page_info.band_params.BandHeight;
862
 
    
863
 
        if (crdev->band_complexity_array == NULL)
864
 
            return NULL;
 
876
        gx_device_clist *cldev = (gx_device_clist *)dev;
 
877
        gx_device_clist_reader * const crdev = &cldev->reader;
 
878
        int band_number = y / crdev->page_info.band_params.BandHeight;
 
879
 
 
880
        if (crdev->band_complexity_array == NULL)
 
881
            return NULL;
865
882
 
866
883
        {
867
884
            /* NB this is a temporary workaround until the band
872
889
            crdev->band_complexity_array[band_number].nontrivial_rops = (int)colors_used.slow_rop;
873
890
            crdev->band_complexity_array[band_number].uses_color = (int)colors_used.or;
874
891
        }
875
 
        return &crdev->band_complexity_array[band_number];
 
892
        return &crdev->band_complexity_array[band_number];
876
893
    }
877
894
    return NULL;
878
895
}
880
897
/* Free any band_complexity_array memory used by the clist reader device */
881
898
void gx_clist_reader_free_band_complexity_array( gx_device_clist *cldev )
882
899
{
883
 
        if (cldev != NULL) {
884
 
            gx_device_clist_reader * const crdev = &cldev->reader;
885
 
            
886
 
            if ( crdev->band_complexity_array ) {
887
 
                gs_free_object( crdev->memory, crdev->band_complexity_array,
888
 
                  "gx_clist_reader_free_band_complexity_array" );
889
 
                crdev->band_complexity_array = NULL;
890
 
            }
891
 
        }
 
900
        if (cldev != NULL) {
 
901
            gx_device_clist_reader * const crdev = &cldev->reader;
 
902
 
 
903
            if ( crdev->band_complexity_array ) {
 
904
                gs_free_object( crdev->memory, crdev->band_complexity_array,
 
905
                  "gx_clist_reader_free_band_complexity_array" );
 
906
                crdev->band_complexity_array = NULL;
 
907
            }
 
908
        }
892
909
}
893
910
 
894
 
/* call once per read page to read the band complexity from clist file 
 
911
/* call once per read page to read the band complexity from clist file
895
912
 */
896
913
static int
897
914
gx_clist_reader_read_band_complexity(gx_device_clist *dev)
899
916
    int code = -1;  /* no dev bad call */
900
917
 
901
918
    if (dev) {
902
 
        gx_device_clist *cldev = (gx_device_clist *)dev;
903
 
        gx_device_clist_reader * const crdev = &cldev->reader;
904
 
        int i;
905
 
        stream_band_read_state rs;
906
 
        cmd_block cb;
907
 
        int64_t save_pos;
908
 
        int pos = 0;
909
 
 
910
 
        /* setup stream */
911
 
        s_init_state((stream_state *)&rs, &s_band_read_template, (gs_memory_t *)0);
912
 
        rs.band_first = 0;
913
 
        rs.band_last = crdev->nbands;
914
 
        rs.page_info = crdev->page_info;
915
 
 
916
 
        save_pos = crdev->page_info.io_procs->ftell(rs.page_bfile);
917
 
        crdev->page_info.io_procs->fseek(rs.page_bfile, pos, SEEK_SET, rs.page_bfname);
918
 
 
919
 
        if ( crdev->band_complexity_array == NULL )
920
 
                crdev->band_complexity_array = (gx_band_complexity_t*)
921
 
                  gs_alloc_byte_array( crdev->memory, crdev->nbands,
922
 
                  sizeof( gx_band_complexity_t ), "gx_clist_reader_read_band_complexity" );
923
 
 
924
 
        if ( crdev->band_complexity_array == NULL )
925
 
                return_error(gs_error_VMerror);
926
 
 
927
 
        for (i=0; i < crdev->nbands; i++) {
928
 
            crdev->page_info.io_procs->fread_chars(&cb, sizeof(cb), rs.page_bfile);
929
 
            crdev->band_complexity_array[i] = cb.band_complexity;
930
 
        }
931
 
 
932
 
        crdev->page_info.io_procs->fseek(rs.page_bfile, save_pos, SEEK_SET, rs.page_bfname);
933
 
        code = 0;  
 
919
        gx_device_clist *cldev = (gx_device_clist *)dev;
 
920
        gx_device_clist_reader * const crdev = &cldev->reader;
 
921
        int i;
 
922
        stream_band_read_state rs;
 
923
        cmd_block cb;
 
924
        int64_t save_pos;
 
925
        int pos = 0;
 
926
 
 
927
        /* setup stream */
 
928
        s_init_state((stream_state *)&rs, &s_band_read_template, (gs_memory_t *)0);
 
929
        rs.band_first = 0;
 
930
        rs.band_last = crdev->nbands;
 
931
        rs.page_info = crdev->page_info;
 
932
 
 
933
        save_pos = crdev->page_info.io_procs->ftell(rs.page_bfile);
 
934
        crdev->page_info.io_procs->fseek(rs.page_bfile, pos, SEEK_SET, rs.page_bfname);
 
935
 
 
936
        if ( crdev->band_complexity_array == NULL )
 
937
                crdev->band_complexity_array = (gx_band_complexity_t*)
 
938
                  gs_alloc_byte_array( crdev->memory, crdev->nbands,
 
939
                  sizeof( gx_band_complexity_t ), "gx_clist_reader_read_band_complexity" );
 
940
 
 
941
        if ( crdev->band_complexity_array == NULL )
 
942
                return_error(gs_error_VMerror);
 
943
 
 
944
        for (i=0; i < crdev->nbands; i++) {
 
945
            crdev->page_info.io_procs->fread_chars(&cb, sizeof(cb), rs.page_bfile);
 
946
            crdev->band_complexity_array[i] = cb.band_complexity;
 
947
        }
 
948
 
 
949
        crdev->page_info.io_procs->fseek(rs.page_bfile, save_pos, SEEK_SET, rs.page_bfname);
 
950
        code = 0;
934
951
    }
935
952
    return code;
936
953
}