diff --git a/src/modules/Image/encodings/_xpm.c b/src/modules/Image/encodings/_xpm.c index 6cf3b77332bd4cc52e59d974de8ec19230b1074c..0ed6a25ca3648de631d130d9b46445e1e3a5969e 100644 --- a/src/modules/Image/encodings/_xpm.c +++ b/src/modules/Image/encodings/_xpm.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: _xpm.c,v 1.1 1999/04/06 11:37:17 per Exp $"); +RCSID("$Id: _xpm.c,v 1.2 1999/04/09 04:08:06 per Exp $"); #include "config.h" @@ -51,7 +51,13 @@ static int hextoint( int what ) return 0; } -static rgba_group decode_color( struct pike_string *s ) +struct buffer +{ + int len; + char *str; +}; + +static rgba_group decode_color( struct buffer *s ) { static struct svalue _parse_color; static struct svalue *parse_color; @@ -87,19 +93,21 @@ static rgba_group decode_color( struct pike_string *s ) } if(!parse_color) { - push_text("Colors"); + push_text("Image"); push_int(0); SAFE_APPLY_MASTER( "resolv", 2 ); - if(IS_ZERO(sp-1)) error("Internal error: No Colors module!\n"); - push_text("parse_color"); + if(IS_ZERO(sp-1)) error("Internal error: No Image module!\n"); + push_text("`[]"); f_index(2); - if(IS_ZERO(sp-1)) error("Internal error: No Colors.parse_color function!\n"); + if(IS_ZERO(sp-1)) error("Internal error: No Image[] function!\n"); _parse_color = sp[-1]; parse_color = &_parse_color; sp--; } - ref_push_string( s ); + push_string(make_shared_binary_string(s->str,s->len)); apply_svalue( parse_color, 1 ); + push_text( "array" ); + apply( sp[-2].u.object, "cast", 1 ); if(sp[-1].type == T_ARRAY && sp[-1].u.array->size == 3) { res.r = sp[-1].u.array->item[0].u.integer; @@ -108,12 +116,40 @@ static rgba_group decode_color( struct pike_string *s ) } else { res.r = res.g = res.b = 0; } - pop_stack(); + pop_stack(); /* array */ + pop_stack(); /* object */ + return res; +} + + +static rgba_group parse_color_line( struct pike_string *cn, int sl ) +{ + int toggle = 0; + int i; + rgba_group res; + for(i=sl; i<cn->len; i++) + { + switch(cn->str[i]) + { + case ' ': + case '\t': + if(toggle) + { + struct buffer s; + s.str = cn->str+i+1; + s.len = cn->len-i-1; + return decode_color(&s); + } + default: + toggle=1; + } + } + res.r = res.g = res.b = 0; + res.alpha = 255; return res; } -static rgba_group qsearch( struct pike_string *s, - struct array *c ) +static rgba_group qsearch( char *s,int sl, struct array *c ) { int start = c->size/2; int lower = 0; @@ -123,14 +159,14 @@ static rgba_group qsearch( struct pike_string *s, { int i, ok=1; cn = c->item[start].u.string; - for(i=0; i<s->len; i++) - if(cn->str[i] < s->str[i]) + for(i=0; i<sl; i++) + if(cn->str[i] < s[i]) { lower = start; start += (upper-start)/2; ok=0; break; - } else if(cn->str[i] > s->str[i]) { + } else if(cn->str[i] > s[i]) { upper = start; start -= (start-lower)/2; ok=0; @@ -138,27 +174,7 @@ static rgba_group qsearch( struct pike_string *s, } if(ok) - { - int toggle = 0; - for(i=s->len; i<cn->len; i++) - { - switch(cn->str[i]) - { - case ' ': - case '\t': - if(toggle) - { - rgba_group res; - push_string(make_shared_binary_string(cn->str+i+1,cn->len-i-1)); - res=decode_color(sp[-1].u.string); - pop_stack(); - return res; - } - default: - toggle=1; - } - } - } + return parse_color_line( cn,sl ); if(upper-lower < 2) { rgba_group res; @@ -169,82 +185,97 @@ static rgba_group qsearch( struct pike_string *s, } } - - -static rgba_group mapsearch( struct pike_string *s, - struct mapping *in ) -{ - struct svalue *res; - if((res = low_mapping_string_lookup( in, s ))) - { - switch(res->type) - { - case T_STRING: - return decode_color(res->u.string); - case T_MAPPING: - if((res = simple_mapping_string_lookup( res->u.mapping, "c" ) )) - return decode_color(res->u.string); - if((res = simple_mapping_string_lookup( res->u.mapping, "g" ) )) - return decode_color(res->u.string); - if((res = simple_mapping_string_lookup( res->u.mapping, "g4" ) )) - return decode_color(res->u.string); - if((res = simple_mapping_string_lookup( res->u.mapping, "m" ) )) - return decode_color(res->u.string); - } - } - { - rgba_group res; - res.r=res.g=res.b=0; - res.alpha = 255; - return res; - } -} - -void f__xpm_write_row( INT32 args ) +void f__xpm_write_rows( INT32 args ) { struct object *img; struct object *alpha; struct array *pixels; - struct svalue *colors; + struct array *colors; struct image *iimg, *ialpha; rgb_group *dst, *adst; - int x, row; - get_all_args( "_xpm_write_row", args, "%d%o%o%a%*", &row, - &img, &alpha, &pixels,&colors); + int y,x, bpc; + + get_all_args("_xpm_write_rows",args,"%o%o%d%a%a", + &img,&alpha,&bpc,&colors,&pixels); iimg = (struct image *)get_storage( img, image_program ); ialpha = (struct image *)get_storage( alpha, image_program ); if(!iimg || !ialpha) error("Sluta pilla p� interna saker..\n"); - if(iimg->xsize != pixels->size || - ialpha->xsize != pixels->size) - error("Sluta pilla p� interna saker..\n"); - dst = iimg->img + (iimg->xsize * row); - adst = ialpha->img + (ialpha->xsize * row); + dst = iimg->img; + adst = ialpha->img; + + + if(bpc > 2) + { + for(y = 0; y<iimg->ysize; y++) + { + char *ss = (char *)pixels->item[y+colors->size+1].u.string->str; + for(x = 0; x<iimg->xsize; x++) + { + rgba_group color=qsearch(ss,bpc,colors); ss+=bpc; + dst->r = color.r; + dst->g = color.g; + (dst++)->b = color.b; + if(!color.alpha) + adst->r = adst->g = adst->b = color.alpha; + adst++; + } + } + } else { + rgba_group p_colors[65536]; + int i; + + for(i=0; i<colors->size; i++) + { + short id = *((short *)colors->item[i].u.string->str); + p_colors[id] = parse_color_line( colors->item[i].u.string, bpc ); + } + for(y = 0; y<iimg->ysize; y++) + { + char *ss = (char *)pixels->item[y+colors->size+1].u.string->str; + for(x = 0; x<iimg->xsize; x++) + { + rgba_group color=p_colors[*((short *)ss)]; + dst->r = color.r; + dst->g = color.g; + (dst++)->b = color.b; + if(!color.alpha) + adst->r = adst->g = adst->b = 0; + ss+=bpc; + adst++; + } + } + } +} - switch(colors->type) +void f__xpm_trim_rows( INT32 args ) +{ + struct array *a; + int i,j=0; + get_all_args("___", args, "%a", &a ); + for(i=0; i<a->size; i++) { - case T_ARRAY: - for(x = 0; x<pixels->size; x++) - { - rgba_group color = qsearch(pixels->item[x].u.string, colors->u.array); - dst->r = color.r; - dst->g = color.g; - (dst++)->b = color.b; - adst->r = adst->g = (adst++)->b = color.alpha; - } - break; - case T_MAPPING: - for(x = 0; x<pixels->size; x++) - { - rgba_group color = mapsearch(pixels->item[x].u.string, colors->u.mapping); - dst->r = color.r; - dst->g = color.g; - dst->b = color.b; - adst->r = adst->g = adst->b = color.alpha; - } - break; + char *ns; + int len,start; + struct pike_string *s = a->item[i].u.string; + if(s->len > 4) + { + for(start=0; start<s->len; start++) + if(s->str[start] == '/' || s->str[start] == '"') + break; + if(s->str[start] == '/') + continue; + for(len=start+1; len<s->len; len++) + if(s->str[len] == '"') + break; + if(len>=s->len || s->str[len] != '"') + continue; + a->item[j].u.string=make_shared_binary_string(s->str+start+1,len-start-1); + free_string(s); + j++; + } } } @@ -252,7 +283,8 @@ static struct program *image_encoding__xpm_program=NULL; void init_image__xpm( ) { start_new_program(); - add_function( "_xpm_write_row", f__xpm_write_row, "function(mixed...:void)", 0); + add_function( "_xpm_write_rows", f__xpm_write_rows, "mixed", 0); + add_function( "_xpm_trim_rows", f__xpm_trim_rows, "mixed", 0); image_encoding__xpm_program=end_program(); push_object(clone_object(image_encoding__xpm_program,0));