diff --git a/.gitattributes b/.gitattributes index fe3afe58e94a91d649447c433cfd77d69f8efb76..baf80fbcea108b21b74847a918e6b655265fcc86 100644 --- a/.gitattributes +++ b/.gitattributes @@ -177,6 +177,7 @@ testfont binary /src/modules/Image/dct.c foreign_ident /src/modules/Image/encodings/Makefile.in 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 /src/modules/Image/encodings/gif.c foreign_ident /src/modules/Image/encodings/gif_lzw.c foreign_ident diff --git a/src/modules/Image/encodings/bmp.c b/src/modules/Image/encodings/bmp.c new file mode 100644 index 0000000000000000000000000000000000000000..f6fa09670573fe8b3b6b9c007c86ae18c5386854 --- /dev/null +++ b/src/modules/Image/encodings/bmp.c @@ -0,0 +1,268 @@ +/* $Id: bmp.c,v 1.1 1999/03/22 14:35:25 mirar Exp $ */ + +/* +**! module Image +**! note +**! $Id: bmp.c,v 1.1 1999/03/22 14:35:25 mirar Exp $ +**! submodule BMP +**! +**! This submodule keeps the BMP (Windows Bitmap) +**! encode/decode capabilities of the <ref>Image</ref> module. +**! +**! BMP is common in the Windows environment. +**! +**! Simple encoding:<br> +**! <ref>encode</ref> +**! +**! Advanced encoding:<br> +**! <ref>encode_P1</ref>, <br> +**! <ref>encode_P2</ref>, <br> +**! <ref>encode_P3</ref>, <br> +**! <ref>encode_P4</ref>, <br> +**! <ref>encode_P5</ref>, <br> +**! <ref>encode_P6</ref> +**! +**! see also: Image, Image.image, Image.colortable +*/ +#include "global.h" + +#include <math.h> +#include <ctype.h> + +#include "stralloc.h" +RCSID("$Id: bmp.c,v 1.1 1999/03/22 14:35:25 mirar Exp $"); +#include "pike_macros.h" +#include "object.h" +#include "constants.h" +#include "interpret.h" +#include "svalue.h" +#include "threads.h" +#include "array.h" +#include "error.h" + + +#include "image.h" +#include "colortable.h" + +#include "builtin_functions.h" + +extern void f_add(INT32 args); + +extern struct program *image_colortable_program; +extern struct program *image_program; + +static INLINE void push_ubo_32bit(unsigned long x) +{ + char buf[4]; + + buf[0]=(char)(x); + buf[1]=(char)(x>>8); + buf[2]=(char)(x>>16); + buf[3]=(char)(x>>24); + push_string(make_shared_binary_string(buf,4)); +} + +static INLINE void push_ubo_16bit(unsigned long x) +{ + char buf[2]; + buf[0]=(char)(x); + buf[1]=(char)(x>>8); + push_string(make_shared_binary_string(buf,2)); +} + +static INLINE unsigned long int_from_32bit(unsigned char *data) +{ + return (data[0])|(data[1]<<8)|(data[2]<<16)|(data[3]<<24); +} + +#define int_from_16bit(X) _int_from_16bit((unsigned char*)(X)) +static INLINE unsigned long _int_from_16bit(unsigned char *data) +{ + return (data[0])|(data[1]<<8); + +} + +/* +**! method string encode(object image) +**! method string encode(object image,object colortable) +**! Make a BMP. It default to a 24 bpp BMP file, +**! but if a colortable is given, it will be 8bpp +**! with a palette entry. +**! +**! arg object image +**! Source image. +**! arg object colortable +**! Colortable object. +**! +** see also: decode +**! +**! returns the encoded image as a string +**! +**! bugs +**! Doesn't support all BMP modes. At all. +*/ + +void img_bmp_encode(INT32 args) +{ + struct object *o,*oc; + struct image *img; + struct neo_colortable *nct; + int n=0,bpp; + int size,offs; + struct pike_string *ps; + + if (!args) + error("Image.BMP.encode: Illegal number of arguments\n"); + + if (sp[-args].type!=T_OBJECT || + !(img=(struct image*)get_storage(o=sp[-args].u.object,image_program))) + error("Image.BMP.encode: Illegal argument 1, expected image object\n"); + + if (args==1) + nct=NULL,oc=NULL; + else + if (sp[-args].type!=T_OBJECT || + !(nct=(struct neo_colortable*) + get_storage(oc=sp[1-args].u.object,image_colortable_program))) + error("Image.BMP.encode: Illegal argument 2, " + "expected colortable object\n"); + + if (!nct) + bpp=24; + else if (image_colortable_size(nct)<=256) + bpp=8; /* only supports this for now */ + else + error("Image.BMP.encode: Illegal argument 2, " + "can only handle less or equal then 256 colors\n"); + + if (oc) oc->refs++; + o->refs++; + pop_n_elems(args); + + apply(o,"mirrory",0); + free_object(o); + if (sp[-1].type!=T_OBJECT || + !(img=(struct image*)get_storage(o=sp[-1].u.object,image_program))) + error("Image.BMP.encode: wierd result from ->mirrory()\n"); + if (nct) push_object(oc); + + /* bitmapinfo */ + push_ubo_32bit(40); /* size of info structure */ + push_ubo_32bit(img->xsize); /* width */ + push_ubo_32bit(img->ysize); /* height */ + push_ubo_16bit(1); /* "number of planes for the target device" */ + push_ubo_16bit(bpp); /* bits per pixel (see above) */ + push_ubo_32bit(0); /* compression: none */ + push_ubo_32bit(0); /* size of image (0 is valid if no compression) */ + push_ubo_32bit(0); /* horisontal resolution in pixels/meter */ + push_ubo_32bit(0); /* vertical resolution in pixels/meter */ + + if (nct) /* size of colortable */ + push_ubo_32bit(image_colortable_size(nct)); + else + push_ubo_32bit(0); + + push_ubo_32bit(0); /* number of important colors or zero */ + n=11; + + /* palette */ + + if (nct) + { + ps=begin_shared_string((1<<bpp)*4); + MEMSET(ps->str,0,(1<<bpp)*4); + image_colortable_write_bgra(nct,(unsigned char *)ps->str); + push_string(end_shared_string(ps)); + n++; + } + + f_add(n); + n=1; + /* the image */ + offs=sp[-1].u.string->len; + + if (nct) + { + ps=begin_shared_string(img->xsize*img->ysize); + image_colortable_index_8bit_image(nct,img->img,(unsigned char *)ps->str, + img->xsize*img->ysize,img->xsize); + push_string(ps=end_shared_string(ps)); + n++; + } + else + { + if (sizeof(rgb_group)==3) + push_string(make_shared_binary_string((char*)img->img, + img->xsize*img->ysize*3)); + else + { + unsigned char *c; + int n=img->xsize*img->ysize; + rgb_group *s=img->img; + c=(unsigned char*)((ps=begin_shared_string(n*3))->str); + while (n--) + { + *(c++)=s->r; + *(c++)=s->g; + *(c++)=s->b; + s++; + } + push_string(end_shared_string(ps)); + } + n++; + } + + /* done */ + f_add(n); + + /* "bitmapfileheader" */ + /* this is last, since we need to know the size of the file here */ + + size=sp[-1].u.string->len; + + push_text("BM"); /* "BM" */ + push_ubo_32bit(size+14); /* "size of file" */ + push_ubo_16bit(0); /* reserved */ + push_ubo_16bit(0); /* reserved */ + push_ubo_32bit(offs+14); /* offset to bitmap data */ + + f_add(5); + stack_swap(); + f_add(2); + + if (nct) + { + stack_swap(); + pop_stack(); + } + stack_swap(); + pop_stack(); /* get rid of colortable & source objects */ +} + +struct program *image_bmp_module_program=NULL; + +void init_image_bmp(void) +{ + start_new_program(); + + add_function("encode",img_bmp_encode, + "function(object,void|object:string)",0); + + image_bmp_module_program=end_program(); + push_object(clone_object(image_bmp_module_program,0)); + { + struct pike_string *s=make_shared_string("BMP"); + add_constant(s,sp-1,0); + free_string(s); + } + pop_stack(); +} + +void exit_image_bmp(void) +{ + if(image_bmp_module_program) + { + free_program(image_bmp_module_program); + image_bmp_module_program=0; + } +}