diff options
| -rw-r--r-- | src/Fl_PostScript.cxx | 22 | ||||
| -rw-r--r-- | src/ps_image.cxx | 127 |
2 files changed, 114 insertions, 35 deletions
diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx index da805bd84..7262d7dd2 100644 --- a/src/Fl_PostScript.cxx +++ b/src/Fl_PostScript.cxx @@ -236,13 +236,15 @@ static const char * prolog = "/GL { setgray } bind def\n" "/SRGB { setrgbcolor } bind def\n" +"/A85RLE { /ASCII85Decode filter /RunLengthDecode filter } bind def\n" // ASCII85Decode followed by RunLengthDecode filters + // color images "/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n" "translate \n" "sx sy scale px py 8 \n" "[ px 0 0 py neg 0 py ]\n" -"currentfile /ASCII85Decode filter\n false 3" +"currentfile A85RLE\n false 3" " colorimage GR\n" "} bind def\n" @@ -254,7 +256,7 @@ static const char * prolog = "[ px 0 0 py neg 0 py ]\n" -"currentfile /ASCII85Decode filter\n" +"currentfile A85RLE\n" "image GR\n" "} bind def\n" @@ -264,7 +266,7 @@ static const char * prolog = "translate \n" "sx sy scale px py true \n" "[ px 0 0 py neg 0 py ]\n" -"currentfile filtername filter\n" +"currentfile filtername\n" "imagemask GR\n" "} bind def\n" @@ -315,7 +317,7 @@ static const char * prolog_2 = // prolog relevant only if lang_level >1 "/Height py def\n" "/BitsPerComponent 8 def\n" "/Interpolate inter def\n" -"/DataSource currentfile /ASCII85Decode filter def\n" +"/DataSource currentfile A85RLE def\n" "/MultipleDataSources false def\n" "/ImageMatrix [ px 0 0 py neg 0 py ] def\n" "/Decode [ 0 1 0 1 0 1 ] def\n" @@ -335,7 +337,7 @@ static const char * prolog_2 = // prolog relevant only if lang_level >1 "/BitsPerComponent 8 def\n" "/Interpolate inter def\n" -"/DataSource currentfile /ASCII85Decode filter def\n" +"/DataSource currentfile A85RLE def\n" "/MultipleDataSources false def\n" "/ImageMatrix [ px 0 0 py neg 0 py ] def\n" "/Decode [ 0 1 ] def\n" @@ -440,7 +442,7 @@ static const char * prolog_2_pixmap = // prolog relevant only if lang_level == "pixmap_w pixmap_h scale " "pixmap_sx pixmap_sy 8 " "pixmap_mat " -"currentfile /ASCII85Decode filter " +"currentfile A85RLE " "false 3 " "colorimage " "end " @@ -458,7 +460,7 @@ static const char * prolog_2_pixmap = // prolog relevant only if lang_level == "pixmap_sx pixmap_sy\n" "true\n" "pixmap_mat\n" -"currentfile /ASCII85Decode filter\n" +"currentfile A85RLE\n" "imagemask\n" "GR\n" "} bind def\n" @@ -480,7 +482,7 @@ static const char * prolog_3 = // prolog relevant only if lang_level >2 "/Height py def\n" "/BitsPerComponent 8 def\n" "/Interpolate inter def\n" -"/DataSource currentfile /ASCII85Decode filter def\n" +"/DataSource currentfile A85RLE def\n" "/MultipleDataSources false def\n" "/ImageMatrix [ px 0 0 py neg 0 py ] def\n" @@ -521,7 +523,7 @@ static const char * prolog_3 = // prolog relevant only if lang_level >2 "/Height py def\n" "/BitsPerComponent 8 def\n" "/Interpolate inter def\n" -"/DataSource currentfile /ASCII85Decode filter def\n" +"/DataSource currentfile A85RLE def\n" "/MultipleDataSources false def\n" "/ImageMatrix [ px 0 0 py neg 0 py ] def\n" @@ -1106,7 +1108,7 @@ static void transformed_draw_extra(const char* str, int n, double x, double y, i delete[] img; // write the string image to PostScript as a scaled bitmask scale = w2 / float(w); - driver->clocale_printf("%g %g %g %g %d %d /ASCIIHexDecode MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h); + driver->clocale_printf("%g %g %g %g %d %d {/ASCIIHexDecode filter} MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h); uchar *di; int wmask = (w2+7)/8; for (int j = h - 1; j >= 0; j--){ diff --git a/src/ps_image.cxx b/src/ps_image.cxx index 02dded8bf..0b69212da 100644 --- a/src/ps_image.cxx +++ b/src/ps_image.cxx @@ -50,7 +50,7 @@ static struct85 *prepare85(FILE *outfile) // prepare to produce ASCII85-encoded return big; } -// encodes 4 input bytes from bytes4 into chars5 array +// ASCII85-encodes 4 input bytes from bytes4 into chars5 array // returns # of output chars static int convert85(const uchar *bytes4, uchar *chars5) { @@ -71,7 +71,7 @@ static int convert85(const uchar *bytes4, uchar *chars5) } -static void write85(const uchar *p, struct85 *big, int len) // sends len input bytes for encoding +static void write85(struct85 *big, const uchar *p, int len) // sends len input bytes for ASCII85 encoding { const uchar *last = p + len; while (p < last) { @@ -108,6 +108,86 @@ static void close85(struct85 *big) // stops ASCII85-encoding after processing r // End of implementation of the /ASCII85Encode PostScript filter // +// +// Implementation of the /RunLengthEncode + /ASCII85Encode PostScript filter +// as described in "PostScript LANGUAGE REFERENCE third edition" p. 142 +// + +struct struct_rle85 { + struct85 *data85; // aux data for ASCII85 encoding + uchar buffer[128]; // holds non-run data + int count; // current buffer length + int run_length; // current length of run +}; + +static struct_rle85 *prepare_rle85(FILE *out) // prepare to produce RLE+ASCII85-encoded output +{ + struct_rle85 *rle = new struct_rle85; + rle->count = 0; + rle->run_length = 0; + rle->data85 = prepare85(out); + return rle; +} + + +static void write_rle85(uchar b, struct_rle85 *rle) // sends one input byte to RLE+ASCII85 encoding +{ + uchar c; + if (rle->run_length > 0) { // if within a run + if (b == rle->buffer[0] && rle->run_length < 128) { // the run can be extended + rle->run_length++; + return; + } else { // output the run + uchar c = (uchar)(257 - rle->run_length); + write85(rle->data85, &c, 1); // the run-length info + write85(rle->data85, rle->buffer, 1); // the byte of the run + rle->run_length = 0; + } + } + if (rle->count >= 2 && b == rle->buffer[rle->count-1] && b == rle->buffer[rle->count-2]) { + // about to begin a run + if (rle->count > 2) { // there is non-run data before the run in the buffer + c = (uchar)(rle->count-2 - 1); + write85(rle->data85, &c, 1); // length of non-run data + write85(rle->data85, rle->buffer, rle->count-2); // non-run data + } + rle->run_length = 3; + rle->buffer[0] = b; + rle->count = 0; + return; + } + if (rle->count >= 128) { // the non-run buffer is full, output it + c = (uchar)(rle->count - 1); + write85(rle->data85, &c, 1); // length of non-run data + write85(rle->data85, rle->buffer, rle->count); // non-run data + rle->count = 0; + } + rle->buffer[rle->count++] = b; // add byte to end of non-run buffer +} + + +static void close_rle85(struct_rle85 *rle) // stop doing RLE+ASCII85 encoding +{ + uchar c; + if (rle->run_length > 0) { // if within a run, output it + c = (uchar)(257 - rle->run_length); + write85(rle->data85, &c, 1); + write85(rle->data85, rle->buffer, 1); + } else if (rle->count) { // output the non-run buffer, if not empty + c = (uchar)(rle->count - 1); + write85(rle->data85, &c, 1); + write85(rle->data85, rle->buffer, rle->count); + } + c = (uchar)128; + write85(rle->data85, &c, 1); // output EOD mark + close85(rle->data85); // close ASCII85 encoding process + delete rle; +} + +// +// End of implementation of the /RunLengthEncode + /ASCII85Encode PostScript filter +// + int Fl_PostScript_Graphics_Driver::alpha_mask(const uchar * data, int w, int h, int D, int LD){ @@ -328,37 +408,35 @@ void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data int LD=iw*D; uchar *rgbdata=new uchar[LD]; uchar *curmask=mask; - uchar line[3]; - struct85 *big = prepare85(output); + struct_rle85 *big = prepare_rle85(output); if (level2_mask) { for (j = ih - 1; j >= 0; j--) { // output full image data call(data, 0, j, iw, rgbdata); uchar *curdata = rgbdata; for (i=0 ; i<iw ; i++) { - write85(curdata, big, 3); + write_rle85(curdata[0], big); write_rle85(curdata[1], big); write_rle85(curdata[2], big); curdata += D; } } - close85(big); - big = prepare85(output); + close_rle85(big); + big = prepare_rle85(output); for (j = ih - 1; j >= 0; j--) { // output mask data curmask = mask + j * (my/ih) * ((mx+7)/8); for (k=0; k < my/ih; k++) { for (i=0; i < ((mx+7)/8); i++) { - line[0] = swap_byte(*curmask); write85(line, big, 1); + write_rle85(swap_byte(*curmask), big); curmask++; } } } - close85(big); } else { for (j=0; j<ih;j++) { if (mask && lang_level_ > 2) { // InterleaveType 2 mask data for (k=0; k<my/ih;k++) { //for alpha pseudo-masking for (i=0; i<((mx+7)/8);i++) { - line[0] = swap_byte(*curmask); write85(line, big, 1); + write_rle85(swap_byte(*curmask), big); curmask++; } } @@ -378,14 +456,13 @@ void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data b = (a2 * b + bg_b * a)/255; } - line[0]=r; line[1]=g; line[2]=b; write85(line, big, 3); - + write_rle85(r, big); write_rle85(g, big); write_rle85(b, big); curdata +=D; } } - close85(big); } + close_rle85(big); fprintf(output,"restore\n"); delete[] rgbdata; @@ -418,12 +495,12 @@ void Fl_PostScript_Graphics_Driver::draw_image_mono(const uchar *data, int ix, i int bg = (bg_r + bg_g + bg_b)/3; uchar *curmask=mask; - struct85 *big = prepare85(output); + struct_rle85 *big = prepare_rle85(output); for (j=0; j<ih;j++){ if (mask){ for (k=0;k<my/ih;k++){ for (i=0; i<((mx+7)/8);i++){ - uchar c = swap_byte(*curmask); write85(&c, big, 1); + write_rle85(swap_byte(*curmask), big); curmask++; } } @@ -437,12 +514,12 @@ void Fl_PostScript_Graphics_Driver::draw_image_mono(const uchar *data, int ix, i unsigned int a = 255-a2; r = (a2 * r + bg * a)/255; } - write85(&r, big, 1); + write_rle85(r, big); curdata +=D; } } - close85(big); + close_rle85(big); fprintf(output,"restore\n"); } @@ -467,13 +544,13 @@ void Fl_PostScript_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb call, void int LD=iw*D; uchar *rgbdata=new uchar[LD]; uchar *curmask=mask; - struct85 *big = prepare85(output); + struct_rle85 *big = prepare_rle85(output); for (j=0; j<ih;j++){ if (mask && lang_level_>2){ // InterleaveType 2 mask data for (k=0; k<my/ih;k++){ //for alpha pseudo-masking for (i=0; i<((mx+7)/8);i++){ - uchar c = swap_byte(*curmask); write85(&c, big, 1); + write_rle85(swap_byte(*curmask), big); curmask++; } } @@ -481,11 +558,11 @@ void Fl_PostScript_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb call, void call(data,0,j,iw,rgbdata); uchar *curdata=rgbdata; for (i=0 ; i<iw ; i++) { - write85(curdata, big, 1); + write_rle85(curdata[0], big); curdata +=D; } } - close85(big); + close_rle85(big); fprintf(output,"restore\n"); delete[] rgbdata; } @@ -547,16 +624,16 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int int i,j; push_clip(XP, YP, WP, HP); - fprintf(output , "%i %i %i %i %i %i /ASCII85Decode MI\n", XP - si, YP + HP , WP , -HP , w , h); + fprintf(output , "%i %i %i %i %i %i {A85RLE} MI\n", XP - si, YP + HP , WP , -HP , w , h); - struct85 *big = prepare85(output); + struct_rle85 *big = prepare_rle85(output); for (j=0; j<HP; j++){ for (i=0; i<xx; i++){ - uchar c = swap_byte(*di); write85(&c, big, 1); + write_rle85(swap_byte(*di), big); di++; } } - close85(big); + close_rle85(big); pop_clip(); } |
