summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gs/base/sdctd.c30
-rw-r--r--pxl/pximage.c22
2 files changed, 36 insertions, 16 deletions
diff --git a/gs/base/sdctd.c b/gs/base/sdctd.c
index 134803694..5feb49bfd 100644
--- a/gs/base/sdctd.c
+++ b/gs/base/sdctd.c
@@ -107,7 +107,7 @@ compact_jpeg_buffer(stream_cursor_read *pr)
107 byte *o, *i; 107 byte *o, *i;
108 108
109 /* Search backwards from the end for 2 consecutive 0xFFs */ 109 /* Search backwards from the end for 2 consecutive 0xFFs */
110 o = pr->limit; 110 o = (byte *)pr->limit;
111 while (o - pr->ptr >= 2) { 111 while (o - pr->ptr >= 2) {
112 if (*o-- == 0xFF) { 112 if (*o-- == 0xFF) {
113 if (*o == 0xFF) 113 if (*o == 0xFF)
@@ -271,18 +271,22 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr,
271 pr->ptr = 271 pr->ptr =
272 (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); 272 (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1);
273 if (!read) { 273 if (!read) {
274 if (src->next_input_byte-1 == pr->ptr) { 274 /* We are suspending. If nothing was consumed, and the
275 /* Suspending, and nothing was consumed. Compact the 275 * buffer was full, compact the data in the buffer. If
276 * data in the buffer (i.e. strip out long runs of 276 * this fails to save anything, then we'll never succeed;
277 * 0xFF that cause the stream to jam up). */ 277 * throw an error to avoid an infinite loop.
278 /* FIXME: This is still not ideal. What we *ought* to 278 * The tricky part here is knowing "if the buffer is
279 * do here is to spot that the buffer was is full 279 * full"; we do that by comparing the number of bytes in
280 * (i.e. subsequent fetches cannot possibly fit any 280 * the buffer with the min_in_size set for the stream.
281 * more data in), and then if compact_jpeg_buffer 281 */
282 * returns 0 (no bytes saved), we should return an 282 /* TODO: If we ever find a file with valid data that trips
283 * error code to prevent an infinite loop. */ 283 * this test, we should implement a scheme whereby we keep
284 compact_jpeg_buffer(pr); 284 * a local buffer and copy the data into it. The local
285 } 285 * buffer can be grown as required. */
286 if ((src->next_input_byte-1 == pr->ptr) &&
287 (pr->limit - pr->ptr >= ss->template->min_in_size) &&
288 (compact_jpeg_buffer(pr) == 0))
289 return ERRC;
286 return 0; /* need more data */ 290 return 0; /* need more data */
287 } 291 }
288 if (jddp->scanline_buffer != NULL) { 292 if (jddp->scanline_buffer != NULL) {
diff --git a/pxl/pximage.c b/pxl/pximage.c
index 314972bb9..1a1ce241c 100644
--- a/pxl/pximage.c
+++ b/pxl/pximage.c
@@ -193,6 +193,7 @@ read_jpeg_bitmap_data(px_bitmap_enum_t *benum, byte **pdata, px_args_t *par)
193 jpeg_decompress_data *jddp = &(benum->jdd); 193 jpeg_decompress_data *jddp = &(benum->jdd);
194 /* use the graphics library support for DCT streams */ 194 /* use the graphics library support for DCT streams */
195 ss->memory = benum->mem; 195 ss->memory = benum->mem;
196 ss->template = &s_DCTD_template;
196 s_DCTD_template.set_defaults((stream_state *)ss); 197 s_DCTD_template.set_defaults((stream_state *)ss);
197 ss->report_error = stream_error; 198 ss->report_error = stream_error;
198 ss->data.decompress = jddp; 199 ss->data.decompress = jddp;
@@ -215,14 +216,28 @@ read_jpeg_bitmap_data(px_bitmap_enum_t *benum, byte **pdata, px_args_t *par)
215 w.ptr = data + pos_in_row - 1; 216 w.ptr = data + pos_in_row - 1;
216 w.limit = data + data_per_row - 1; 217 w.limit = data + data_per_row - 1;
217 code = (*s_DCTD_template.process)((stream_state *)ss, &r, &w, false); 218 code = (*s_DCTD_template.process)((stream_state *)ss, &r, &w, false);
219 /* code = num scanlines processed (0=need more data, -ve=error) */
218 used = w.ptr + 1 - data - pos_in_row; 220 used = w.ptr + 1 - data - pos_in_row;
221 if ((code == EOFC) && (used > 0))
222 code = 1;
219 pos_in_row += used; 223 pos_in_row += used;
220 par->source.position += used; 224 par->source.position += used;
221 } 225 }
222 used = r.ptr + 1 - data; 226 used = r.ptr + 1 - data;
223 par->source.data = r.ptr + 1; 227 par->source.data = r.ptr + 1;
224 par->source.available = avail - used; 228 par->source.available = avail - used;
225 return ( code == 0 ? pxNeedData : 1); 229 /* The spec for this function says: Return 0 if we've processed all the
230 * data in the block, 1 if we have a complete scan line, pxNeedData for
231 * an incomplete scan line, or <0 for an error condition. The only way
232 * we can return 0 currently is if we get an EOF from the underlying
233 * decoder. */
234 if (code == 0)
235 return pxNeedData;
236 if (code == EOFC)
237 return 0;
238 if (code > 0)
239 return 1;
240 return code;
226} 241}
227 242
228static int 243static int
@@ -289,6 +304,7 @@ read_rle_bitmap_data(px_bitmap_enum_t *benum, byte **pdata, px_args_t *par)
289 304
290 if ( !benum->initialized ) { 305 if ( !benum->initialized ) {
291 ss->EndOfData = false; 306 ss->EndOfData = false;
307 ss->template = &s_RLD_template;
292 s_RLD_init_inline(ss); 308 s_RLD_init_inline(ss);
293 benum->initialized = true; 309 benum->initialized = true;
294 } 310 }
@@ -643,7 +659,7 @@ pxReadImage(px_args_t *par, px_state_t *pxs)
643 int code = read_bitmap(&pxenum->benum, &data, par); 659 int code = read_bitmap(&pxenum->benum, &data, par);
644 if ( code != 1 ) 660 if ( code != 1 )
645 return code; 661 return code;
646 code = pl_image_data(pxs->pgs, pxenum->info, (const byte **)&data, 0, 662 code = pl_image_data(pxs->pgs, pxenum->info, (const byte **)&data, 0,
647 pxenum->benum.data_per_row, 1); 663 pxenum->benum.data_per_row, 1);
648 if ( code < 0 ) 664 if ( code < 0 )
649 return code; 665 return code;
@@ -654,7 +670,7 @@ pxReadImage(px_args_t *par, px_state_t *pxs)
654const byte apxEndImage[] = {0, 0}; 670const byte apxEndImage[] = {0, 0};
655int 671int
656pxEndImage(px_args_t *par, px_state_t *pxs) 672pxEndImage(px_args_t *par, px_state_t *pxs)
657{ 673{
658 px_image_enum_t *pxenum = pxs->image_enum; 674 px_image_enum_t *pxenum = pxs->image_enum;
659 px_bitmap_enum_t *pbenum = &pxenum->benum; 675 px_bitmap_enum_t *pbenum = &pxenum->benum;
660 int code = pl_end_image(pxs->pgs, pxenum->info, true); 676 int code = pl_end_image(pxs->pgs, pxenum->info, true);