diff --git a/.gitattributes b/.gitattributes index dccbac979631c3ba601824a7c15bc1d3a5dab9dd..964fc17b4db4780d7b6ec0c5f3fa25dac2799f27 100644 --- a/.gitattributes +++ b/.gitattributes @@ -187,6 +187,7 @@ testfont binary /src/modules/Image/encodings/pnm.c foreign_ident /src/modules/Image/encodings/tga.c foreign_ident /src/modules/Image/encodings/x.c foreign_ident +/src/modules/Image/encodings/xbm.c foreign_ident /src/modules/Image/encodings/xwd.c foreign_ident /src/modules/Image/font.c foreign_ident /src/modules/Image/illustration.pike foreign_ident diff --git a/src/modules/Image/encodings/Makefile.in b/src/modules/Image/encodings/Makefile.in index 9fe449b2fe0f38cdac47d777cc7cd5163672b6e5..5151fefcdebf061bbdf1ebb527399d174567e56a 100644 --- a/src/modules/Image/encodings/Makefile.in +++ b/src/modules/Image/encodings/Makefile.in @@ -1,7 +1,7 @@ -# $Id: Makefile.in,v 1.19 1999/04/06 03:50:51 per Exp $ +# $Id: Makefile.in,v 1.20 1999/04/06 06:23:56 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 +OBJS = gif.o gif_lzw.o pnm.o x.o xwd.o png.o any.o bmp.o tga.o pcx.o xbm.o @SET_MAKE@ diff --git a/src/modules/Image/encodings/xbm.c b/src/modules/Image/encodings/xbm.c new file mode 100644 index 0000000000000000000000000000000000000000..0a72c0fc560a90a55a1251efc582f972d0eb1f84 --- /dev/null +++ b/src/modules/Image/encodings/xbm.c @@ -0,0 +1,456 @@ +#include "global.h" +RCSID("$Id: xbm.c,v 1.1 1999/04/06 06:23:57 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_colortable_program; +extern struct program *image_program; + +/* +**! module Image +**! submodule XBM +**! +*/ + + +#define SWAP_S(x) ((unsigned short)((((x)&0x00ff)<<8) | ((x)&0xff00)>>8)) +#define SWAP_L(x) (SWAP_S((x)>>16)|SWAP_S((x)&0xffff)<<16) + +struct buffer +{ + unsigned int len; + char *str; +}; + +int buf_search( struct buffer *b, unsigned char match ) +{ + unsigned int off = 0; + if(b->len <= 1) + return 0; + while(off < b->len) + { + if(b->str[off] == match) + break; + off++; + } + off++; + if(off >= b->len) + return 0; + b->str += off; + b->len -= off; + return 1; +} + +static int buf_getc( struct buffer *fp ) +{ + if(fp->len >= 1) + { + fp->len--; + return (int)*((unsigned char *)fp->str++); + } + return '0'; +} + +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 struct object *load_xbm( struct pike_string *data ) +{ + int width, height; + int x, y; + struct buffer buff; + struct buffer *b = &buff; + rgb_group *dest; + struct object *io; + + buff.str = data->str; + buff.len = data->len; + + if(!buf_search( b, '#' ) || !buf_search( b, ' ' ) || !buf_search( b, ' ' )) + error("This is not a XBM image!\n"); + width = atoi(b->str); + if(width <= 0) + error("This is not a XBM image!\n"); + if(!buf_search( b, '#' ) || !buf_search( b, ' ' ) || !buf_search( b, ' ' )) + error("This is not a XBM image!\n"); + height = atoi(b->str); + if(height <= 0) + error("This is not a XBM image!\n"); + + if(!buf_search( b, '{' )) + error("This is not a XBM image!\n"); + + + push_int( width ); + push_int( height ); + io = clone_object( image_program, 2 ); + dest = ((struct image *)get_storage(io, image_program))->img; + /* .. the code below asumes black if the read fails.. */ + for(y=0; y<height; y++) + { + int next_byte, cnt; + for(x=0; x<width;) + { + if(buf_search( b, 'x' )) + { + next_byte = (hextoint(buf_getc( b ))*0x10) | hextoint(buf_getc( b )); + for(cnt=0; cnt<8&&x<width; cnt++,x++) + { + if((next_byte&(1<<(x%8)))) + dest->r = dest->g = dest->b = 255; + dest++; + } + } + } + } + return io; +} + +static struct pike_string *save_xbm( struct image *i, struct pike_string *name ) +{ + dynamic_buffer buf; + char size[32]; + int x, y, first=-1; + +#define ccat( X ) low_my_binary_strcat( X, (sizeof(X)-sizeof("")), &buf ); + +#define cname() do{ \ + if(name) \ + low_my_binary_strcat( name->str, name->len, &buf ); \ + else \ + ccat( "image" ); \ + } while(0) \ + + + +#define OUTPUT_BYTE(X) do{ \ + if(!++first) \ + sprintf( size, " 0x%02x", (X) ); \ + else \ + sprintf( size, ",%s0x%02x", (first%12?" ":"\n "), (X) ); \ + (X)=0; \ + low_my_binary_strcat( size, strlen(size), &buf ); \ + } while(0) + + + initialize_buf(&buf); + ccat( "#define "); cname(); ccat( "_width " ); + sprintf( size, "%d\n", i->xsize ); + low_my_binary_strcat( size, strlen(size), &buf ); + + ccat( "#define "); cname(); ccat( "_height " ); + sprintf( size, "%d\n", i->ysize ); + low_my_binary_strcat( size, strlen(size), &buf ); + + ccat( "static char " ); cname(); ccat( "_bits[] = {\n" ); + + for(y=0; y<i->ysize; y++) + { + rgb_group *p = i->img+y*i->xsize; + int next_byte = 0; + for(x=0; x<i->xsize; x++) + { + if((p->r || p->g || p->b )) + next_byte |= (1<<(x%8)); + if((x % 8) == 7) + OUTPUT_BYTE( next_byte ); + p++; + } + if(i->xsize%8) + OUTPUT_BYTE( next_byte ); + } + ccat( "};\n" ); + return low_free_buf(&buf); +} + + + +/* +**! method object decode(string data) +**! Decodes a XBM image. +**! +**! note +**! Throws upon error in data. +*/ +static void image_xbm_decode( INT32 args ) +{ + struct pike_string *data; + struct object *o; + get_all_args( "Image.XBM.decode", args, "%S", &data ); + o = load_xbm( data ); + pop_n_elems(args); + push_object( o ); +} + + +/* +**! method object _decode(string data) +**! method object _decode(string data, mapping options) +**! Decodes a XBM image to a mapping. +**! +**! <pre> +**! Supported options: +**! ([ +**! "fg":({fgcolor}), // Foreground color. Default black +**! "bg":({bgcolor}), // Background color. Default white +**! "invert":1, // Invert the mask +**! ]) +**! +**! note +**! Throws upon error in data. +*/ + + +static struct pike_string *param_fg; +static struct pike_string *param_bg; +static struct pike_string *param_invert; +static void image_xbm__decode( INT32 args ) +{ + extern void f_aggregate(INT32 args); + struct array *fg = NULL; + struct array *bg = NULL; + int invert=0, ele; + struct pike_string *data; + struct object *i=NULL, *a; + get_all_args( "Image.XBM.decode", args, "%S", &data ); + + + if (args>1) + { + if (sp[1-args].type!=T_MAPPING) + error("Image.XBM._decode: illegal argument 2\n"); + + push_svalue(sp+1-args); + ref_push_string(param_fg); + f_index(2); + if(!IS_ZERO(sp-1)) + { + if(sp[-1].type != T_ARRAY || sp[-1].u.array->size != 3) + error("Wrong type for foreground. Should be array(int(0..255))" + " with 3 elements\n"); + for(ele=0; ele<3; ele++) + if(sp[-1].u.array->item[ele].type != T_INT + ||sp[-1].u.array->item[ele].u.integer < 0 + ||sp[-1].u.array->item[ele].u.integer > 255) + error("Wrong type for foreground. Should be array(int(0..255))" + " with 3 elements\n"); + fg = sp[-1].u.array; + } + sp--; + + push_svalue(sp+1-args); + ref_push_string(param_bg); + f_index(2); + if(!IS_ZERO(sp-1)) + { + if(sp[-1].type != T_ARRAY || sp[-1].u.array->size != 3) + error("Wrong type for background. Should be array(int(0..255))" + " with 3 elements\n"); + for(ele=0; ele<3; ele++) + if(sp[-1].u.array->item[ele].type != T_INT + ||sp[-1].u.array->item[ele].u.integer < 0 + ||sp[-1].u.array->item[ele].u.integer > 255) + error("Wrong type for background. Should be array(int(0..255))" + " with 3 elements\n"); + bg = sp[-1].u.array; + } + sp--; + + push_svalue(sp+1-args); + ref_push_string(param_invert); + f_index(2); + invert = !IS_ZERO(sp-1); + sp--; + } + + a = load_xbm( data ); + + if(!fg) + { + if(invert) + { + apply(a, "invert", 0); + i = sp[-1].u.object; + sp--; + } + else + { + i = a; + a->refs++; + } + } else { + if(!bg) + { + push_int(255); + push_int(255); + push_int(255); + f_aggregate(3); + bg = sp[-1].u.array; + sp--; + } + if(invert) + { + struct array *tmp = fg; + fg = bg; + bg = fg; + } + apply(a, "xsize", 0); + apply(a, "ysize", 0); + push_int( bg->item[0].u.integer ); + push_int( bg->item[1].u.integer ); + push_int( bg->item[2].u.integer ); + i = clone_object( image_program, 5 ); + ref_push_object( i ); + push_int( fg->item[0].u.integer ); + push_int( fg->item[1].u.integer ); + push_int( fg->item[2].u.integer ); + + apply( i, "paste_alpha_color", 4 ); + } + + pop_n_elems(args); + push_constant_text( "alpha" ); + push_object( a ); + push_constant_text( "image" ); + if(i) + push_object( i ); + else + push_int( 0 ); + f_aggregate_mapping(4); +} + + + + +/* +**! method string encode(object image) +**! method string encode(object image, mapping options) +**! Encodes a XBM image. +**! +**! The <tt>options</tt> argument may be a mapping +**! containing zero or more encoding options. +**! +**! <pre> +**! normal options: +**! "name":"xbm_image_name" +**! The name of the XBM. Defaults to 'image' +*/ + +static struct pike_string *param_name; +void image_xbm_encode( INT32 args ) +{ + struct image *img = NULL; + struct pike_string *name = NULL, *buf; + if (!args) + error("Image.XBM.encode: too few arguments\n"); + + if (sp[-args].type!=T_OBJECT || + !(img=(struct image*) + get_storage(sp[-args].u.object,image_program))) + error("Image.XBM.encode: illegal argument 1\n"); + + if (!img->img) + error("Image.XBM.encode: no image\n"); + + if (args>1) + { + if (sp[1-args].type!=T_MAPPING) + error("Image.XBM.encode: illegal argument 2\n"); + + push_svalue(sp+1-args); + ref_push_string(param_name); + f_index(2); + if(sp[-1].type == T_STRING) + { + if(sp[-1].u.string->size_shift) + error("The name of the image must be a normal non-wide string (sorry, not my fault)\n"); + name = sp[-1].u.string; + } + pop_stack(); + } + + buf = save_xbm( img, name ); + pop_n_elems(args); + push_string( buf ); +} + + +static struct program *image_encoding_xbm_program=NULL; +void init_image_xbm( ) +{ + start_new_program(); + add_function( "_decode", image_xbm__decode, + "function(string,mapping|void:mapping(string:object))", 0); + add_function( "decode", image_xbm_decode, + "function(string:object)", 0); + add_function( "encode", image_xbm_encode, + "function(object,mapping|void:string)", 0); + image_encoding_xbm_program=end_program(); + + push_object(clone_object(image_encoding_xbm_program,0)); + { + struct pike_string *s=make_shared_string("XBM"); + add_constant(s,sp-1,0); + free_string(s); + } + param_name=make_shared_string("name"); + param_fg=make_shared_string("fg"); + param_bg=make_shared_string("bg"); + param_invert=make_shared_string("invert"); +} + +void exit_image_xbm(void) +{ + if(image_encoding_xbm_program) + { + free_program(image_encoding_xbm_program); + image_encoding_xbm_program=0; + free_string(param_name); + free_string(param_fg); + free_string(param_bg); + free_string(param_invert); + } +} diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c index dc23245c942c9a7a08db584675968e0dc7ed17da..756f1170d8ac091fc388613cf6075bfd1b151a78 100644 --- a/src/modules/Image/image.c +++ b/src/modules/Image/image.c @@ -1,9 +1,9 @@ -/* $Id: image.c,v 1.117 1999/04/06 03:51:34 per Exp $ */ +/* $Id: image.c,v 1.118 1999/04/06 06:23:31 per Exp $ */ /* **! module Image **! note -**! $Id: image.c,v 1.117 1999/04/06 03:51:34 per Exp $ +**! $Id: image.c,v 1.118 1999/04/06 06:23:31 per Exp $ **! class image **! **! The main object of the <ref>Image</ref> module, this object @@ -97,7 +97,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: image.c,v 1.117 1999/04/06 03:51:34 per Exp $"); +RCSID("$Id: image.c,v 1.118 1999/04/06 06:23:31 per Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -3482,6 +3482,10 @@ extern void init_image_tga(void); extern void exit_image_tga(void); extern void init_image_pcx(void); extern void exit_image_pcx(void); +extern void init_image_xpm(void); +extern void exit_image_xpm(void); +extern void exit_image_xbm(void); +extern void init_image_xbm(void); /* dynamic encoders (dependent on other modules, loaded dynamically) */ @@ -3490,7 +3494,7 @@ extern void exit_image_png(void); static struct pike_string *magic_JPEG, - *magic_XFace, + *magic_XFace, *magic_PNG, *magic_TTF; @@ -3843,6 +3847,8 @@ void pike_module_init(void) init_image_any(); init_image_tga(); init_image_pcx(); + init_image_xbm(); +/* init_image_xpm(); */ init_image_x(); } @@ -3864,6 +3870,8 @@ void pike_module_exit(void) exit_image_any(); exit_image_tga(); exit_image_pcx(); +/* exit_image_xpm(); */ + exit_image_xbm(); if (png_object) { free_object(png_object);