summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcl/pxl/pximage.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/pcl/pxl/pximage.c b/pcl/pxl/pximage.c
index d1ec1053c..707786377 100644
--- a/pcl/pxl/pximage.c
+++ b/pcl/pxl/pximage.c
@@ -84,6 +84,28 @@ px_purge_pattern_cache(px_state_t * pxs, pxePatternPersistence_t max_persist)
84 px_pattern_purge_proc, (void *)&max_persist); 84 px_pattern_purge_proc, (void *)&max_persist);
85} 85}
86 86
87/* active decompression types */
88typedef enum
89{
90 unset = 0,
91 nocomp = 1,
92 rle = 2,
93 jpeg = 4,
94 delta = 8,
95} decomp_init_t;
96
97static inline bool nocomp_init(uint comp) {return comp & nocomp;}
98static inline bool rle_init(uint comp) {return comp & rle;}
99static inline bool jpeg_init(uint comp) {return comp & jpeg;}
100static inline bool delta_init(uint comp) {return comp & delta;}
101
102static inline void nocomp_set(uint *comp) {*comp |= nocomp;}
103static inline void rle_set(uint *comp) {*comp |= rle;}
104static inline void jpeg_set(uint *comp) {*comp |= jpeg;}
105static inline void delta_set(uint *comp) {*comp |= delta;}
106
107static inline void comp_unset(uint *comp) {*comp = unset;}
108
87/* pxl delta row decompression state machine states */ 109/* pxl delta row decompression state machine states */
88typedef enum 110typedef enum
89{ 111{
@@ -110,8 +132,7 @@ typedef struct px_bitmap_enum_s
110{ 132{
111 gs_memory_t *mem; /* used only for the jpeg filter */ 133 gs_memory_t *mem; /* used only for the jpeg filter */
112 uint data_per_row; /* ditto minus possible trailing padding */ 134 uint data_per_row; /* ditto minus possible trailing padding */
113 bool initialized; 135 uint initialized;
114 pxeCompressMode_t compress_type;
115 stream_RLD_state rld_stream_state; /* decompressor states */ 136 stream_RLD_state rld_stream_state; /* decompressor states */
116 stream_DCT_state dct_stream_state; 137 stream_DCT_state dct_stream_state;
117 jpeg_decompress_data jdd; 138 jpeg_decompress_data jdd;
@@ -171,7 +192,7 @@ px_jpeg_init(px_bitmap_enum_t * benum, px_bitmap_params_t * params, px_args_t *
171 uint avail = par->source.available; 192 uint avail = par->source.available;
172 int code = 0; 193 int code = 0;
173 194
174 if (benum->initialized == false) { 195 if (!jpeg_init(benum->initialized)) {
175 s_init_state((stream_state *)ss, &s_DCTD_template, benum->mem); 196 s_init_state((stream_state *)ss, &s_DCTD_template, benum->mem);
176 ss->report_error = stream_error; 197 ss->report_error = stream_error;
177 s_DCTD_template.set_defaults((stream_state *)ss); 198 s_DCTD_template.set_defaults((stream_state *)ss);
@@ -190,7 +211,7 @@ px_jpeg_init(px_bitmap_enum_t * benum, px_bitmap_params_t * params, px_args_t *
190 return_error(errorInsufficientMemory); 211 return_error(errorInsufficientMemory);
191 212
192 (*s_DCTD_template.init) ((stream_state *)ss); 213 (*s_DCTD_template.init) ((stream_state *)ss);
193 benum->initialized = true; 214 jpeg_set(&benum->initialized);
194 } 215 }
195 216
196 r.ptr = data - 1; 217 r.ptr = data - 1;
@@ -207,11 +228,11 @@ px_jpeg_init(px_bitmap_enum_t * benum, px_bitmap_params_t * params, px_args_t *
207 used = r.ptr + 1 - data; 228 used = r.ptr + 1 - data;
208 par->source.data = r.ptr + 1; 229 par->source.data = r.ptr + 1;
209 par->source.available = avail - used; 230 par->source.available = avail - used;
210 231
211 /* Needs more data to complete reading the header */ 232 /* Needs more data to complete reading the header */
212 if (ss->phase < 2) 233 if (ss->phase < 2)
213 return pxNeedData; 234 return pxNeedData;
214 235
215 params->width = jddp->dinfo.output_width; 236 params->width = jddp->dinfo.output_width;
216 params->height = jddp->dinfo.output_height; 237 params->height = jddp->dinfo.output_height;
217 { 238 {
@@ -242,7 +263,7 @@ begin_bitmap(px_bitmap_params_t * params, px_bitmap_enum_t * benum,
242 int depth; 263 int depth;
243 int num_components; 264 int num_components;
244 px_gstate_t *pxgs = pxs->pxgs; 265 px_gstate_t *pxgs = pxs->pxgs;
245 266
246 benum->mem = pxs->memory; 267 benum->mem = pxs->memory;
247 benum->grayscale = false; 268 benum->grayscale = false;
248 if (is_jpeg) { 269 if (is_jpeg) {
@@ -291,7 +312,7 @@ begin_rebuffered_bitmap(px_bitmap_params_t * params, px_bitmap_enum_t * benum,
291 312
292 if (code < 0 || code == pxNeedData) 313 if (code < 0 || code == pxNeedData)
293 return_error(code); 314 return_error(code);
294 315
295 if (params->width == 1 && params->height > 1) { 316 if (params->width == 1 && params->height > 1) {
296 benum->rebuffered_data_per_row = benum->data_per_row * params->height; 317 benum->rebuffered_data_per_row = benum->data_per_row * params->height;
297 benum->rebuffered = 1; 318 benum->rebuffered = 1;
@@ -326,7 +347,7 @@ read_jpeg_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
326 /* consumed all of the data */ 347 /* consumed all of the data */
327 if ((par->source.position >= end_pos) && (ss->phase != 4) && (par->source.available == 0)) { 348 if ((par->source.position >= end_pos) && (ss->phase != 4) && (par->source.available == 0)) {
328 /* shutdown jpeg filter if necessary */ 349 /* shutdown jpeg filter if necessary */
329 if (benum->initialized) 350 if (jpeg_init(benum->initialized))
330 gs_jpeg_destroy((&benum->dct_stream_state)); 351 gs_jpeg_destroy((&benum->dct_stream_state));
331 return 0; 352 return 0;
332 } 353 }
@@ -334,9 +355,12 @@ read_jpeg_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
334 if (last) 355 if (last)
335 return_error(errorIllegalDataLength); 356 return_error(errorIllegalDataLength);
336 357
337 if (!benum->initialized) { 358 if (!jpeg_init(benum->initialized)) {
338 jpeg_decompress_data *jddp = &(benum->jdd); 359 jpeg_decompress_data *jddp = &(benum->jdd);
339 360
361 /* we do not allow switching from other compression schemes to jpeg */
362 if (benum->initialized != unset)
363 return_error(errorIllegalAttributeValue);
340 /* use the graphics library support for DCT streams */ 364 /* use the graphics library support for DCT streams */
341 ss->memory = benum->mem; 365 ss->memory = benum->mem;
342 ss->templat = &s_DCTD_template; 366 ss->templat = &s_DCTD_template;
@@ -354,7 +378,7 @@ read_jpeg_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
354 return_error(errorInsufficientMemory); 378 return_error(errorInsufficientMemory);
355 (*s_DCTD_template.init) ((stream_state *) ss); 379 (*s_DCTD_template.init) ((stream_state *) ss);
356 jddp->templat = s_DCTD_template; 380 jddp->templat = s_DCTD_template;
357 benum->initialized = true; 381 jpeg_set(&benum->initialized);
358 } 382 }
359 r.ptr = data - 1; 383 r.ptr = data - 1;
360 r.limit = r.ptr + avail; 384 r.limit = r.ptr + avail;
@@ -422,7 +446,7 @@ read_uncompressed_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
422 446
423 if (last) 447 if (last)
424 return_error(errorIllegalDataLength); 448 return_error(errorIllegalDataLength);
425 449
426 if (avail >= data_per_row_padded && pos_in_row == 0) { 450 if (avail >= data_per_row_padded && pos_in_row == 0) {
427 /* Use the data directly from the input buffer. */ 451 /* Use the data directly from the input buffer. */
428 *pdata = (byte *) data; 452 *pdata = (byte *) data;
@@ -465,12 +489,12 @@ read_rle_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata, px_args_t * par, b
465 489
466 if (last) 490 if (last)
467 return_error(errorIllegalDataLength); 491 return_error(errorIllegalDataLength);
468 492
469 if (!benum->initialized) { 493 if (!rle_init(benum->initialized)) {
470 ss->EndOfData = false; 494 ss->EndOfData = false;
471 ss->templat = &s_RLD_template; 495 ss->templat = &s_RLD_template;
472 s_RLD_init_inline(ss); 496 s_RLD_init_inline(ss);
473 benum->initialized = true; 497 rle_set(&benum->initialized);
474 } 498 }
475 r.ptr = data - 1; 499 r.ptr = data - 1;
476 r.limit = r.ptr + avail; 500 r.limit = r.ptr + avail;
@@ -565,7 +589,7 @@ read_deltarow_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
565 const byte *pout_start = pout; 589 const byte *pout_start = pout;
566 bool end_of_row = false; 590 bool end_of_row = false;
567 591
568 if (benum->initialized && deltarow->rowwritten == par->pv[1]->value.i) { 592 if (delta_init(benum->initialized) && deltarow->rowwritten == par->pv[1]->value.i) {
569 deltarow->rowwritten = 0; 593 deltarow->rowwritten = 0;
570 return 0; 594 return 0;
571 } 595 }
@@ -574,7 +598,7 @@ read_deltarow_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
574 return_error(errorIllegalDataLength); 598 return_error(errorIllegalDataLength);
575 599
576 /* initialize at begin of image */ 600 /* initialize at begin of image */
577 if (!benum->initialized) { 601 if (!delta_init(benum->initialized)) {
578 /* zero seed row */ 602 /* zero seed row */
579 deltarow->seedrow = 603 deltarow->seedrow =
580 gs_alloc_bytes(benum->mem, benum->data_per_row, 604 gs_alloc_bytes(benum->mem, benum->data_per_row,
@@ -585,7 +609,7 @@ read_deltarow_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
585 deltarow->short_offset = 0; 609 deltarow->short_offset = 0;
586 deltarow->state = next_is_bytecount; 610 deltarow->state = next_is_bytecount;
587 deltarow->rowwritten = 0; 611 deltarow->rowwritten = 0;
588 benum->initialized = true; 612 delta_set(&benum->initialized);
589 } 613 }
590 614
591 if (deltarow->row_byte_count == 0) { 615 if (deltarow->row_byte_count == 0) {
@@ -701,13 +725,7 @@ read_deltarow_bitmap_data(px_bitmap_enum_t * benum, byte ** pdata,
701static int 725static int
702read_bitmap(px_bitmap_enum_t * benum, byte ** pdata, px_args_t * par, bool last) 726read_bitmap(px_bitmap_enum_t * benum, byte ** pdata, px_args_t * par, bool last)
703{ 727{
704 /* Changing compression within an image is unimplemented */ 728 switch (par->pv[2]->value.i) {
705 /* but for now we return an error. */
706 if ((benum->compress_type != par->pv[2]->value.i) && (par->pv[2]->value.i != eNoCompression))
707 return_error(errorIllegalAttributeValue);
708 else
709 benum->compress_type = par->pv[2]->value.i;
710 switch (benum->compress_type) {
711 case eRLECompression: 729 case eRLECompression:
712 return read_rle_bitmap_data(benum, pdata, par, last); 730 return read_rle_bitmap_data(benum, pdata, par, last);
713 case eJPEGCompression: 731 case eJPEGCompression:
@@ -781,7 +799,7 @@ pxBeginImage(px_args_t * par, px_state_t * pxs)
781 * revised depending on the color parameters in the JPEG data. 799 * revised depending on the color parameters in the JPEG data.
782 * We defer image set up until we read the image data. 800 * We defer image set up until we read the image data.
783 */ 801 */
784 802
785 bi_args.mapping = par->pv[0]->value.i; 803 bi_args.mapping = par->pv[0]->value.i;
786 bi_args.depth = par->pv[1]->value.i; 804 bi_args.depth = par->pv[1]->value.i;
787 bi_args.width = par->pv[2]->value.i; 805 bi_args.width = par->pv[2]->value.i;
@@ -791,9 +809,9 @@ pxBeginImage(px_args_t * par, px_state_t * pxs)
791 809
792 pxenum->bi_args = bi_args; 810 pxenum->bi_args = bi_args;
793 pxenum->enum_started = false; 811 pxenum->enum_started = false;
794 pxenum->benum.initialized = false; 812 comp_unset(&pxenum->benum.initialized);
795 pxs->image_enum = pxenum; 813 pxs->image_enum = pxenum;
796 814
797 return 0; 815 return 0;
798} 816}
799 817
@@ -807,7 +825,7 @@ px_begin_image(px_state_t * pxs, bool is_jpeg, px_args_t * par)
807 px_image_enum_t *pxenum = pxs->image_enum; 825 px_image_enum_t *pxenum = pxs->image_enum;
808 px_bitmap_enum_t *pbenum = &pxenum->benum; 826 px_bitmap_enum_t *pbenum = &pxenum->benum;
809 int code; 827 int code;
810 828
811 if (gs_currentpoint(pgs, &origin) < 0) 829 if (gs_currentpoint(pgs, &origin) < 0)
812 return_error(errorCurrentCursorUndefined); 830 return_error(errorCurrentCursorUndefined);
813 /* 831 /*
@@ -832,7 +850,7 @@ px_begin_image(px_state_t * pxs, bool is_jpeg, px_args_t * par)
832 code = begin_rebuffered_bitmap(&params, pbenum, &pxenum->bi_args, pxs, is_jpeg, par); 850 code = begin_rebuffered_bitmap(&params, pbenum, &pxenum->bi_args, pxs, is_jpeg, par);
833 if (code < 0 || code == pxNeedData) 851 if (code < 0 || code == pxNeedData)
834 return_error(code); 852 return_error(code);
835 853
836 pxenum->row = gs_alloc_byte_array(pxs->memory, 1, pbenum->rebuffered_data_per_row, 854 pxenum->row = gs_alloc_byte_array(pxs->memory, 1, pbenum->rebuffered_data_per_row,
837 "pxReadImage(row)"); 855 "pxReadImage(row)");
838 if (pxenum->row == 0) 856 if (pxenum->row == 0)
@@ -841,13 +859,13 @@ px_begin_image(px_state_t * pxs, bool is_jpeg, px_args_t * par)
841 code = 859 code =
842 px_image_color_space(&pxenum->image, &params, 860 px_image_color_space(&pxenum->image, &params,
843 (const gs_string *)&pxgs->palette, pgs); 861 (const gs_string *)&pxgs->palette, pgs);
844 862
845 if (code < 0) { 863 if (code < 0) {
846 gs_free_object(pxs->memory, pxenum->row, "pxReadImage(row)"); 864 gs_free_object(pxs->memory, pxenum->row, "pxReadImage(row)");
847 gs_free_object(pxs->memory, pxenum, "pxReadImage(pxenum)"); 865 gs_free_object(pxs->memory, pxenum, "pxReadImage(pxenum)");
848 return code; 866 return code;
849 } 867 }
850 868
851 /* Set up the image parameters. */ 869 /* Set up the image parameters. */
852 pxenum->image.Width = pbenum->rebuffered_width; 870 pxenum->image.Width = pbenum->rebuffered_width;
853 pxenum->image.Height = pbenum->rebuffered_height; 871 pxenum->image.Height = pbenum->rebuffered_height;
@@ -895,7 +913,7 @@ pxReadImage(px_args_t * par, px_state_t * pxs)
895{ 913{
896 px_image_enum_t *pxenum = pxs->image_enum; 914 px_image_enum_t *pxenum = pxs->image_enum;
897 int code = 0; 915 int code = 0;
898 916
899 if (par->pv[1]->value.i == 0) 917 if (par->pv[1]->value.i == 0)
900 return 0; /* no data */ 918 return 0; /* no data */
901 /* Make a quick check for the first call, when no data is available. */ 919 /* Make a quick check for the first call, when no data is available. */
@@ -903,7 +921,6 @@ pxReadImage(px_args_t * par, px_state_t * pxs)
903 return pxNeedData; 921 return pxNeedData;
904 if (!pxenum->enum_started) { 922 if (!pxenum->enum_started) {
905 bool is_jpeg = par->pv[2]->value.i == eJPEGCompression; 923 bool is_jpeg = par->pv[2]->value.i == eJPEGCompression;
906 pxenum->benum.compress_type = par->pv[2]->value.i;
907 code = px_begin_image(pxs, is_jpeg, par); 924 code = px_begin_image(pxs, is_jpeg, par);
908 if (code < 0 || code == pxNeedData) 925 if (code < 0 || code == pxNeedData)
909 return code; 926 return code;
@@ -932,7 +949,7 @@ pxReadImage(px_args_t * par, px_state_t * pxs)
932 pxenum->benum.rebuffered_data_per_row, 1); 949 pxenum->benum.rebuffered_data_per_row, 1);
933 if (code < 0) 950 if (code < 0)
934 return code; 951 return code;
935 952
936 pxs->have_page = true; 953 pxs->have_page = true;
937 } 954 }
938} 955}
@@ -946,7 +963,7 @@ pxEndImage(px_args_t * par, px_state_t * pxs)
946 int code = pl_end_image(pxs->pgs, pxenum->info, true); 963 int code = pl_end_image(pxs->pgs, pxenum->info, true);
947 964
948 gs_free_object(pxs->memory, pxenum->row, "pxEndImage(row)"); 965 gs_free_object(pxs->memory, pxenum->row, "pxEndImage(row)");
949 if (pbenum->compress_type == eDeltaRowCompression) 966 if (delta_init(pxenum->benum.initialized))
950 gs_free_object(pbenum->mem, pbenum->deltarow_state.seedrow, 967 gs_free_object(pbenum->mem, pbenum->deltarow_state.seedrow,
951 "pxEndImage(seedrow)"); 968 "pxEndImage(seedrow)");
952 if (pxenum->image.ColorSpace) 969 if (pxenum->image.ColorSpace)
@@ -996,14 +1013,14 @@ pxBeginRastPattern(px_args_t * par, px_state_t * pxs)
996 static const gs_memory_struct_type_t st_px_pattern = 1013 static const gs_memory_struct_type_t st_px_pattern =
997 { sizeof(px_pattern_t), "", 0, 0, 0, 0, 0 }; 1014 { sizeof(px_pattern_t), "", 0, 0, 0, 0, 0 };
998 1015
999 1016
1000 bi_args.mapping = par->pv[0]->value.i; 1017 bi_args.mapping = par->pv[0]->value.i;
1001 bi_args.depth = par->pv[1]->value.i; 1018 bi_args.depth = par->pv[1]->value.i;
1002 bi_args.width = par->pv[2]->value.i; 1019 bi_args.width = par->pv[2]->value.i;
1003 bi_args.height = par->pv[3]->value.i; 1020 bi_args.height = par->pv[3]->value.i;
1004 bi_args.dest_width = real_value(par->pv[4], 0); 1021 bi_args.dest_width = real_value(par->pv[4], 0);
1005 bi_args.dest_height = real_value(par->pv[4], 1); 1022 bi_args.dest_height = real_value(par->pv[4], 1);
1006 1023
1007 1024
1008 code = begin_bitmap(&params, &benum, &bi_args, pxs, false, par); 1025 code = begin_bitmap(&params, &benum, &bi_args, pxs, false, par);
1009 1026
@@ -1034,7 +1051,7 @@ pxBeginRastPattern(px_args_t * par, px_state_t * pxs)
1034 return_error(errorInsufficientMemory); 1051 return_error(errorInsufficientMemory);
1035 } 1052 }
1036 pxenum->benum = benum; 1053 pxenum->benum = benum;
1037 pxenum->benum.initialized = false; 1054 comp_unset(&pxenum->benum.initialized);
1038 pxenum->pattern_id = par->pv[5]->value.i; 1055 pxenum->pattern_id = par->pv[5]->value.i;
1039 pxenum->persistence = par->pv[6]->value.i; 1056 pxenum->persistence = par->pv[6]->value.i;
1040 pxenum->lines_rendered = 0; 1057 pxenum->lines_rendered = 0;
@@ -1068,14 +1085,6 @@ pxReadRastPattern(px_args_t * par, px_state_t * pxs)
1068 if (par->source.available == 0) 1085 if (par->source.available == 0)
1069 pxenum->lines_rendered = 0; 1086 pxenum->lines_rendered = 0;
1070 1087
1071 {
1072 pxeCompressMode_t c = par->pv[2]->value.i;
1073
1074 if (!pxenum->benum.initialized)
1075 pxenum->benum.compress_type = c;
1076
1077 }
1078
1079 for (;;) { 1088 for (;;) {
1080 byte *data = pxenum->pattern->data + 1089 byte *data = pxenum->pattern->data +
1081 (par->pv[0]->value.i + pxenum->lines_rendered) * pxenum->benum.data_per_row; 1090 (par->pv[0]->value.i + pxenum->lines_rendered) * pxenum->benum.data_per_row;