96
97
stream_band_read_state *const ss = (stream_band_read_state *) st;
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 . */
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;
114
115
ss->skip_first = true;
119
120
s_band_read_dnit_offset_map(gx_device_clist_reader *crdev, stream_state * st)
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;
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;
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)
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;
145
145
while ((count = wlimit - q) != 0) {
146
if (left) { /* Read more data for the current run. */
146
if (left) { /* Read more data for the current run. */
151
ss->offset_map[ss->offset_map_length - 1].buffered += count;
151
ss->offset_map[ss->offset_map_length - 1].buffered += count;
153
io_procs->fread_chars(q + 1, count, cfile);
154
if (io_procs->ferror_code(cfile) < 0) {
160
process_interrupts(st->memory);
153
io_procs->fread_chars(q + 1, count, cfile);
154
if (io_procs->ferror_code(cfile) < 0) {
160
process_interrupts(st->memory);
165
* Scan for the next run for the current bands (or a band range
166
* that includes a current band).
168
if (ss->b_this.band_min == cmd_band_end &&
169
io_procs->ftell(bfile) == ss->page_bfile_end_pos
174
int bmin = ss->b_this.band_min;
175
int bmax = ss->b_this.band_max;
176
int64_t pos = ss->b_this.pos;
165
* Scan for the next run for the current bands (or a band range
166
* that includes a current band).
168
if (ss->b_this.band_min == cmd_band_end &&
169
io_procs->ftell(bfile) == ss->page_bfile_end_pos
174
int bmin = ss->b_this.band_min;
175
int bmax = ss->b_this.band_max;
176
int64_t pos = ss->b_this.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. */
184
if (!(ss->band_last >= bmin && ss->band_first <= bmax))
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. */
184
if (!(ss->band_last >= bmin && ss->band_first <= bmax))
186
io_procs->fseek(cfile, pos, SEEK_SET, ss->page_cfname);
187
left = (uint) (ss->b_this.pos - pos);
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. */
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++;
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. */
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++;
200
"[l]reading for bands (%d,%d) at bfile %ld, cfile %ld, length %u color %d rop %d\n",
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);
200
"[l]reading for bands (%d,%d) at bfile %ld, cfile %ld, length %u color %d rop %d\n",
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);
240
240
int i = buffer_segment_index(ss, buffer_offset, &offset0);
244
244
return ss->offset_map[i].file_offset + (uint)(buffer_offset - offset0);
248
248
top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end)
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.
254
254
stream_band_read_state *const ss = (stream_band_read_state *) st;
256
256
if (!gs_debug_c('L')) {
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;
259
/* Work around the trick with initializing the buffer pointer with the buffer end. */
260
ss->skip_first = false;
262
262
} else if (ptr == buf)
265
uint buffer_offset = ptr - buf;
266
uint offset0, consumed;
267
int i = buffer_segment_index(ss, buffer_offset, &offset0);
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;
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;
265
uint buffer_offset = ptr - buf;
266
uint offset0, consumed;
267
int i = buffer_segment_index(ss, buffer_offset, &offset0);
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;
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;
282
282
#endif /* DEBUG */
285
284
/* ------ Reading/rendering ------ */
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)
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));
296
295
/* Select full-pixel rendering if required for RasterOp. */
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)
301
300
if (index >= 0) {
302
gx_colors_used_t colors_used;
301
gx_colors_used_t colors_used;
305
gdev_prn_colors_used(dev, y, height, &colors_used, &ignore_start);
306
if (colors_used.slow_rop)
304
gdev_prn_colors_used(dev, y, height, &colors_used, &ignore_start);
305
if (colors_used.slow_rop)
310
render_plane->index = index;
309
render_plane->index = index;
312
gx_render_plane_init(render_plane, dev, index);
311
gx_render_plane_init(render_plane, dev, index);
341
340
clist_close_writer_and_init_reader(gx_device_clist *cldev)
343
342
gx_device_clist_reader * const crdev = &cldev->reader;
343
gs_memory_t *base_mem = crdev->memory->thread_safe_memory;
344
gs_memory_status_t mem_status;
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);
352
code = clist_render_init(cldev);
349
code = clist_end_page(&cldev->writer);
352
code = clist_render_init(cldev);
353
355
/* Check for and get ICC profile table */
354
356
code = clist_read_icctable(crdev);
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);
367
code = (crdev->icc_cache_cl = gsicc_cache_new(base_mem)) == NULL ? gs_error_VMerror : code;
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");
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,
439
&st_clist_icctable, "clist_read_icctable");
440
if (icc_table == NULL)
449
icc_table = gs_alloc_struct(crdev->memory,
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");
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");
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;
521
538
int lines_rasterized;
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;
533
550
if (prect->p.x < 0 || prect->q.x > dev->width ||
534
y < 0 || end_y > dev->height
536
return_error(gs_error_rangecheck);
551
y < 0 || end_y > dev->height
553
return_error(gs_error_rangecheck);
537
554
if (line_count <= 0 || prect->p.x >= prect->q.x)
541
558
* Calculate the render_plane from the params. There are two cases:
544
561
plane_index = -1;
545
562
if (options & GB_SELECT_PLANES) {
546
/* Look for the one selected plane. */
563
/* Look for the one selected plane. */
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,
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,
558
575
if (0 > (code = clist_close_writer_and_init_reader(cldev)))
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));
567
584
code = clist_rasterize_lines(dev, y, line_count, bdev, &render_plane, &my);
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)
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.
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;
597
gs_get_bits_params_t band_params;
598
uint raster = gx_device_raster(bdev, true);
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));
605
band_params = *params;
606
while ((y += lines_rasterized) < end_y) {
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,
618
lines_rasterized = min(code, line_count);
620
band_rect.q.y = my + lines_rasterized;
621
code = dev_proc(bdev, get_bits_rectangle)
622
(bdev, &band_rect, &band_params, unread);
625
params->options = options = band_params.options;
626
if (lines_rasterized == line_count)
629
cdev->buf_procs.destroy_buf_device(bdev);
614
gs_get_bits_params_t band_params;
615
uint raster = gx_device_raster(bdev, true);
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));
622
band_params = *params;
623
while ((y += lines_rasterized) < end_y) {
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,
635
lines_rasterized = min(code, line_count);
637
band_rect.q.y = my + lines_rasterized;
638
code = dev_proc(bdev, get_bits_rectangle)
639
(bdev, &band_rect, &band_params, unread);
642
params->options = options = band_params.options;
643
if (lines_rasterized == line_count)
646
cdev->buf_procs.destroy_buf_device(bdev);
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)
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;
658
gs_int_rect band_rect;
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;
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);
672
band_rect.p.y = band_begin_line;
673
band_rect.q.x = dev->width;
674
band_rect.q.y = band_end_line;
676
code = clist_render_rectangle(cldev, &band_rect, bdev, render_plane,
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;
668
!(y >= crdev->ymin && y < crdev->ymax)
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;
675
gs_int_rect band_rect;
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;
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);
689
band_rect.p.y = band_begin_line;
690
band_rect.q.x = dev->width;
691
band_rect.q.y = band_end_line;
693
code = clist_render_rectangle(cldev, &band_rect, bdev, render_plane,
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;
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);
696
713
return line_count;
719
736
if (render_plane)
720
crdev->yplane = *render_plane;
737
crdev->yplane = *render_plane;
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. */
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));
735
752
ppages = crdev->pages;
736
753
if (ppages == 0) {
737
current_page.info = crdev->page_info;
738
placed_page.page = ¤t_page;
739
placed_page.offset.x = placed_page.offset.y = 0;
740
ppages = &placed_page;
754
current_page.info = crdev->page_info;
755
placed_page.page = ¤t_page;
756
placed_page.offset.x = placed_page.offset.y = 0;
757
ppages = &placed_page;
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];
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.
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
759
* The following sets the band_offset_? relative to the
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,
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.
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
776
* The following sets the band_offset_? relative to the
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,
773
790
/* Playback the band file, taking the indicated action w/ its contents. */
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)
781
798
bool opened_bfile = false;
784
801
/* We have to pick some allocator for rendering.... */
785
802
gs_memory_t *mem =crdev->memory;
787
804
stream_band_read_state rs;
789
806
/* setup stream */
790
807
s_init_state((stream_state *)&rs, &s_band_read_template,
792
809
rs.band_first = band_first;
793
810
rs.band_last = band_last;
794
811
rs.page_info = *page_info;
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);
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);
809
826
if (rs.page_cfile != 0 && rs.page_bfile != 0) {
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
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
817
s_band_read_init((stream_state *)&rs);
834
s_band_read_init((stream_state *)&rs);
819
s_band_read_init_offset_map(crdev, (stream_state *)&rs);
836
s_band_read_init_offset_map(crdev, (stream_state *)&rs);
821
/* The stream doesn't need a memory, but we'll need to access s.memory->gs_lib_ctx. */
823
s_std_init(&s, sbuf, cbuf_size, &no_procs, s_mode_read);
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. */
840
s_std_init(&s, sbuf, cbuf_size, &no_procs, s_mode_read);
842
s.state = (stream_state *)&rs;
827
if (vd_allowed('s')) {
829
} else if (vd_allowed('i')) {
835
code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
844
if (vd_allowed('s')) {
846
} else if (vd_allowed('i')) {
852
code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
838
s_band_read_dnit_offset_map(crdev, (stream_state *)&rs);
855
s_band_read_dnit_offset_map(crdev, (stream_state *)&rs);
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);
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 )
884
gx_device_clist_reader * const crdev = &cldev->reader;
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;
901
gx_device_clist_reader * const crdev = &cldev->reader;
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;
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
897
914
gx_clist_reader_read_band_complexity(gx_device_clist *dev)
899
916
int code = -1; /* no dev bad call */
902
gx_device_clist *cldev = (gx_device_clist *)dev;
903
gx_device_clist_reader * const crdev = &cldev->reader;
905
stream_band_read_state rs;
911
s_init_state((stream_state *)&rs, &s_band_read_template, (gs_memory_t *)0);
913
rs.band_last = crdev->nbands;
914
rs.page_info = crdev->page_info;
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);
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" );
924
if ( crdev->band_complexity_array == NULL )
925
return_error(gs_error_VMerror);
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;
932
crdev->page_info.io_procs->fseek(rs.page_bfile, save_pos, SEEK_SET, rs.page_bfname);
919
gx_device_clist *cldev = (gx_device_clist *)dev;
920
gx_device_clist_reader * const crdev = &cldev->reader;
922
stream_band_read_state rs;
928
s_init_state((stream_state *)&rs, &s_band_read_template, (gs_memory_t *)0);
930
rs.band_last = crdev->nbands;
931
rs.page_info = crdev->page_info;
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);
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" );
941
if ( crdev->band_complexity_array == NULL )
942
return_error(gs_error_VMerror);
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;
949
crdev->page_info.io_procs->fseek(rs.page_bfile, save_pos, SEEK_SET, rs.page_bfname);