diff --git a/.gitattributes b/.gitattributes index 964fc17b4db4780d7b6ec0c5f3fa25dac2799f27..a0d3457305f4f70bec2bcc93afdaebb0f9ff791c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -176,6 +176,7 @@ testfont binary /src/modules/Image/configure.in foreign_ident /src/modules/Image/dct.c foreign_ident /src/modules/Image/encodings/Makefile.in foreign_ident +/src/modules/Image/encodings/_xpm.c foreign_ident /src/modules/Image/encodings/any.c foreign_ident /src/modules/Image/encodings/bmp.c foreign_ident /src/modules/Image/encodings/configure.in foreign_ident diff --git a/src/modules/Image/encodings/Makefile.in b/src/modules/Image/encodings/Makefile.in index 5151fefcdebf061bbdf1ebb527399d174567e56a..127352fb0e093a27759aea3e1b7d37d8f91aa57c 100644 --- a/src/modules/Image/encodings/Makefile.in +++ b/src/modules/Image/encodings/Makefile.in @@ -1,7 +1,7 @@ -# $Id: Makefile.in,v 1.20 1999/04/06 06:23:56 per Exp $ +# $Id: Makefile.in,v 1.21 1999/04/06 11:37:16 per Exp $ SRCDIR=@srcdir@ VPATH=@srcdir@:@srcdir@/../../..:../../.. -OBJS = gif.o gif_lzw.o pnm.o x.o xwd.o png.o any.o bmp.o tga.o pcx.o xbm.o +OBJS = gif.o gif_lzw.o pnm.o x.o xwd.o png.o any.o bmp.o tga.o pcx.o xbm.o _xpm.o @SET_MAKE@ diff --git a/src/modules/Image/encodings/_xpm.c b/src/modules/Image/encodings/_xpm.c new file mode 100644 index 0000000000000000000000000000000000000000..6cf3b77332bd4cc52e59d974de8ec19230b1074c --- /dev/null +++ b/src/modules/Image/encodings/_xpm.c @@ -0,0 +1,273 @@ +#include "global.h" +RCSID("$Id: _xpm.c,v 1.1 1999/04/06 11:37:17 per Exp $"); + +#include "config.h" + +#include "interpret.h" +#include "svalue.h" +#include "pike_macros.h" +#include "object.h" +#include "program.h" +#include "array.h" +#include "error.h" +#include "constants.h" +#include "mapping.h" +#include "stralloc.h" +#include "multiset.h" +#include "pike_types.h" +#include "rusage.h" +#include "operators.h" +#include "fsort.h" +#include "callback.h" +#include "gc.h" +#include "backend.h" +#include "main.h" +#include "pike_memory.h" +#include "threads.h" +#include "time_stuff.h" +#include "version.h" +#include "encode.h" +#include "module_support.h" +#include "module.h" +#include "opcodes.h" +#include "cyclic.h" +#include "signal_handler.h" +#include "security.h" + + +#include "image.h" +#include "colortable.h" + +extern struct program *image_program; + +static int hextoint( int what ) +{ + if(what >= '0' && what <= '9') + return what-'0'; + if(what >= 'a' && what <= 'f') + return 10+what-'a'; + if(what >= 'A' && what <= 'F') + return 10+what-'A'; + return 0; +} + +static rgba_group decode_color( struct pike_string *s ) +{ + static struct svalue _parse_color; + static struct svalue *parse_color; + rgba_group res; + res.alpha = 255; + + if(!s->len) + { + res.r=res.g=res.b = 0; + return res; + } + if(s->str[0] == '#' && s->len>3) + { + switch(s->len) + { + default: + res.r = hextoint(s->str[1])*0x10; + res.g = hextoint(s->str[2])*0x10; + res.b = hextoint(s->str[3])*0x10; + break; + case 7: + res.r = hextoint(s->str[1])*0x10 + hextoint(s->str[2]); + res.g = hextoint(s->str[3])*0x10 + hextoint(s->str[4]); + res.b = hextoint(s->str[5])*0x10 + hextoint(s->str[6]); + break; + case 13: + res.r = hextoint(s->str[1])*0x10 + hextoint(s->str[2]); + res.g = hextoint(s->str[5])*0x10 + hextoint(s->str[6]); + res.b = hextoint(s->str[9])*0x10 + hextoint(s->str[10]); + break; + } + return res; + } + if(!parse_color) + { + push_text("Colors"); + push_int(0); + SAFE_APPLY_MASTER( "resolv", 2 ); + if(IS_ZERO(sp-1)) error("Internal error: No Colors module!\n"); + push_text("parse_color"); + f_index(2); + if(IS_ZERO(sp-1)) error("Internal error: No Colors.parse_color function!\n"); + _parse_color = sp[-1]; + parse_color = &_parse_color; + sp--; + } + ref_push_string( s ); + apply_svalue( parse_color, 1 ); + if(sp[-1].type == T_ARRAY && sp[-1].u.array->size == 3) + { + res.r = sp[-1].u.array->item[0].u.integer; + res.g = sp[-1].u.array->item[1].u.integer; + res.b = sp[-1].u.array->item[2].u.integer; + } else { + res.r = res.g = res.b = 0; + } + pop_stack(); + return res; +} + +static rgba_group qsearch( struct pike_string *s, + struct array *c ) +{ + int start = c->size/2; + int lower = 0; + int upper = c->size-1; + struct pike_string *cn; + while( 1 ) + { + int i, ok=1; + cn = c->item[start].u.string; + for(i=0; i<s->len; i++) + if(cn->str[i] < s->str[i]) + { + lower = start; + start += (upper-start)/2; + ok=0; + break; + } else if(cn->str[i] > s->str[i]) { + upper = start; + start -= (start-lower)/2; + ok=0; + break; + } + + 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; + } + } + } + if(upper-lower < 2) + { + rgba_group res; + res.r = res.g = res.b = 0; + res.alpha = 0; + return res; + } + } +} + + + +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 ) +{ + struct object *img; + struct object *alpha; + struct array *pixels; + struct svalue *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); + + 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); + + switch(colors->type) + { + 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; + } +} + +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); + image_encoding__xpm_program=end_program(); + + push_object(clone_object(image_encoding__xpm_program,0)); + { + struct pike_string *s=make_shared_string("_XPM"); + add_constant(s,sp-1,0); + free_string(s); + } +} + +void exit_image__xpm(void) +{ + if(image_encoding__xpm_program) + { + free_program(image_encoding__xpm_program); + image_encoding__xpm_program=0; + } +}