diff options
-rw-r--r-- | gs/base/sdctd.c | 30 | ||||
-rw-r--r-- | pxl/pximage.c | 22 |
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 | ||
228 | static int | 243 | static 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) | |||
654 | const byte apxEndImage[] = {0, 0}; | 670 | const byte apxEndImage[] = {0, 0}; |
655 | int | 671 | int |
656 | pxEndImage(px_args_t *par, px_state_t *pxs) | 672 | pxEndImage(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); |