PostScript output of images: use now RunLengthEncode followed by ASCII85Encode filters.
This is what Mac OS X does for its PostScript output, so there must be some good in that. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10597 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
00a7e2d576
commit
966ca9faa3
@ -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--){
|
||||
|
127
src/ps_image.cxx
127
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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user