From 07c73c4c2953aa5052b0d3b6bcb220a0bbe26279 Mon Sep 17 00:00:00 2001 From: Marcus Comstedt <marcus@mc.pp.se> Date: Fri, 22 Oct 1999 00:39:02 +0200 Subject: [PATCH] Sun Rasterfile support added. Rev: src/modules/Image/encodings/Makefile.in:1.28 Rev: src/modules/Image/encodings/any.c:1.13 Rev: src/modules/Image/encodings/ras.c:1.1 Rev: src/modules/Image/initstuff.h:1.7 --- .gitattributes | 1 + src/modules/Image/encodings/Makefile.in | 4 +- src/modules/Image/encodings/any.c | 18 +- src/modules/Image/encodings/ras.c | 328 ++++++++++++++++++++++++ src/modules/Image/initstuff.h | 1 + 5 files changed, 347 insertions(+), 5 deletions(-) create mode 100644 src/modules/Image/encodings/ras.c diff --git a/.gitattributes b/.gitattributes index 143260fc7b..10224e0de6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -219,6 +219,7 @@ testfont binary /src/modules/Image/encodings/png.c foreign_ident /src/modules/Image/encodings/pnm.c foreign_ident /src/modules/Image/encodings/psd.c foreign_ident +/src/modules/Image/encodings/ras.c foreign_ident /src/modules/Image/encodings/tga.c foreign_ident /src/modules/Image/encodings/wbf.c foreign_ident /src/modules/Image/encodings/x.c foreign_ident diff --git a/src/modules/Image/encodings/Makefile.in b/src/modules/Image/encodings/Makefile.in index cdd40dc2b6..01363e87d8 100644 --- a/src/modules/Image/encodings/Makefile.in +++ b/src/modules/Image/encodings/Makefile.in @@ -1,7 +1,7 @@ -# $Id: Makefile.in,v 1.27 1999/10/21 22:18:44 per Exp $ +# $Id: Makefile.in,v 1.28 1999/10/21 22:39:01 marcus 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 _xpm.o ilbm.o iff.o xcf.o hrz.o avs.o psd.o gd.o wbf.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 ilbm.o iff.o xcf.o hrz.o avs.o psd.o gd.o wbf.o ras.o @SET_MAKE@ diff --git a/src/modules/Image/encodings/any.c b/src/modules/Image/encodings/any.c index 872d5d4f38..58b84416a5 100644 --- a/src/modules/Image/encodings/any.c +++ b/src/modules/Image/encodings/any.c @@ -1,9 +1,9 @@ -/* $Id: any.c,v 1.12 1999/08/27 12:50:23 mirar Exp $ */ +/* $Id: any.c,v 1.13 1999/10/21 22:39:01 marcus Exp $ */ /* **! module Image **! note -**! $Id: any.c,v 1.12 1999/08/27 12:50:23 mirar Exp $ +**! $Id: any.c,v 1.13 1999/10/21 22:39:01 marcus Exp $ **! submodule ANY **! **! This method calls the other decoding methods @@ -23,7 +23,7 @@ #include <ctype.h> #include "stralloc.h" -RCSID("$Id: any.c,v 1.12 1999/08/27 12:50:23 mirar Exp $"); +RCSID("$Id: any.c,v 1.13 1999/10/21 22:39:01 marcus Exp $"); #include "pike_macros.h" #include "operators.h" #include "builtin_functions.h" @@ -41,6 +41,8 @@ RCSID("$Id: any.c,v 1.12 1999/08/27 12:50:23 mirar Exp $"); void image_gif__decode(INT32 args); void image_pnm_decode(INT32 args); void image_xwd__decode(INT32 args); +void image_ilbm_decode(INT32 args); +void image_ras_decode(INT32 args); /* **! method mapping _decode(string data) @@ -139,6 +141,12 @@ void image_any__decode(INT32 args) img_bmp__decode(1); return; + case CHAR2(0x59,0xa6): + /* RAS */ + img_ras_decode(1); + push_text("image/x-sun-raster"); + goto simple_image; + case CHAR2(0,0): switch (CHAR2(sp[-args].u.string->str[2],sp[-args].u.string->str[3])) { @@ -239,6 +247,10 @@ void image_any_decode_header(INT32 args) img_bmp_decode_header(1); return; + case CHAR2(0x59,0xa6): + /* RAS */ + error("Image.ANY.decode: decoding of RAS header unimplemented\n"); + case CHAR2(0,0): switch (CHAR2(sp[-args].u.string->str[2],sp[-args].u.string->str[3])) { diff --git a/src/modules/Image/encodings/ras.c b/src/modules/Image/encodings/ras.c new file mode 100644 index 0000000000..01410b73e7 --- /dev/null +++ b/src/modules/Image/encodings/ras.c @@ -0,0 +1,328 @@ +/* $Id: ras.c,v 1.1 1999/10/21 22:39:02 marcus Exp $ */ + +/* +**! module Image +**! note +**! $Id: ras.c,v 1.1 1999/10/21 22:39:02 marcus Exp $ +**! submodule RAS +**! +**! This submodule keep the RAS encode/decode capabilities +**! of the <ref>Image</ref> module. +**! +**! see also: Image, Image.Image, Image.Colortable +*/ +#include "global.h" + +#include "stralloc.h" +RCSID("$Id: ras.c,v 1.1 1999/10/21 22:39:02 marcus Exp $"); +#include "pike_macros.h" +#include "object.h" +#include "constants.h" +#include "interpret.h" +#include "svalue.h" +#include "array.h" +#include "mapping.h" +#include "error.h" +#include "threads.h" +#include "builtin_functions.h" +#include "module_support.h" + +#include "image.h" +#include "colortable.h" + +extern struct program *image_colortable_program; +extern struct program *image_program; + + +struct rasterfile { + INT32 ras_magic; /* magic number */ + INT32 ras_width; /* width (pixels) of image */ + INT32 ras_height; /* height (pixels) of image */ + INT32 ras_depth; /* depth (1, 8, or 24 bits) of pixel */ + INT32 ras_length; /* length (bytes) of image */ + INT32 ras_type; /* type of file; see RT_* below */ + INT32 ras_maptype; /* type of colormap; see RMT_* below */ + INT32 ras_maplength; /* length (bytes) of following map */ + /* color map follows for ras_maplength bytes, followed by image */ +}; + +#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */ +#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */ +#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */ +#define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */ +#define RT_FORMAT_TIFF 4 /* tiff <-> standard rasterfile */ +#define RT_FORMAT_IFF 5 /* iff (TAAC format) <-> standard rasterfile */ +#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */ + +#define RMT_NONE 0 /* ras_maplength is expected to be 0 */ +#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */ +#define RMT_RAW 2 + + +/** decoding *****************************************/ + +/* +**! method object decode(string data) +**! Decodes RAS data and creates an image object. +**! +**! see also: encode +**! +**! note +**! This function may throw errors upon illegal RAS data. +**! +**! returns the decoded image as an image object +*/ + +static void decode_ras_header(struct rasterfile *rs, unsigned char *p) +{ + INT32 *rp = (INT32*)rs; + int i; + for(i=0; i<8; i++) { + *rp++ = (((p[0]&0x80)? p[0]-0x100:p[0])<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; + p += 4; + } +} + +void img_ras_decode(INT32 args) +{ + struct pike_string *str; + struct rasterfile rs; + struct object *o, *ctab=NULL; + struct image *img; + rgb_group *rgb; + unsigned char *src; + INT32 len, x, y; + unsigned int numcolors = 0; + struct nct_flat_entry *entries; + + get_all_args("Image.RAS.decode", args, "%S", &str); + + if(str->len < 32) + error("Image.RAS.decode: header too small\n"); + + decode_ras_header(&rs, str->str); + + if(rs.ras_magic != 0x59a66a95) + error("Image.RAS.decode: bad magic\n"); + + if(rs.ras_type < 0 || rs.ras_type > RT_BYTE_ENCODED) + error("Image.RAS.decode: unsupported ras_type %d\n", rs.ras_type); + + if(rs.ras_maptype < 0 || rs.ras_maptype > RMT_EQUAL_RGB) + error("Image.RAS.decode: unsupported ras_maptype %d\n", rs.ras_maptype); + + if(rs.ras_depth != 1 && rs.ras_depth != 8 && rs.ras_depth != 24) + error("Image.RAS.decode: unsupported ras_depth %d\n", rs.ras_depth); + + if(rs.ras_width < 0) + error("Image.RAS.decode: negative ras_width\n"); + + if(rs.ras_height < 0) + error("Image.RAS.decode: negative ras_height\n"); + + if(rs.ras_length < 0) + error("Image.RAS.decode: negative ras_length\n"); + + if(rs.ras_maplength < 0) + error("Image.RAS.decode: negative ras_maplength\n"); + + src = (unsigned char *)(str->str+32); + len = str->len - 32; + + if(rs.ras_maplength != 0) { + + unsigned char *map = src; + + if(len < rs.ras_maplength) + error("Image.RAS.decode: colormap truncated\n"); + + src += rs.ras_maplength; + len -= rs.ras_maplength; + if(len && (rs.ras_maplength&1)) { + src++; + --len; + } + + switch(rs.ras_maptype) { + case RMT_NONE: + error("Image.RAS.decode: RMT_NONE colormap has length != 0 ( == %d )\n", rs.ras_maplength); + break; + case RMT_EQUAL_RGB: + { + INT32 col, ncol = rs.ras_maplength / 3; + unsigned char *red = map; + unsigned char *green = red + ncol; + unsigned char *blue = green + ncol; + for(col=0; col<ncol; col++) { + push_int(*red++); + push_int(*green++); + push_int(*blue++); + f_aggregate(3); + } + f_aggregate(ncol); + ctab = clone_object(image_colortable_program,1); + } + break; + } + + } + + if(rs.ras_type == RT_BYTE_ENCODED) { + if(ctab != NULL) + free_object(ctab); + error("Image.RAS.decode: RT_BYTE_ENCODED unimplemented\n"); + } + + if(rs.ras_length) + if(rs.ras_length > len) { + if(ctab != NULL) + free_object(ctab); + error("Image.RAS.decode: image data truncated\n"); + } else + len = rs.ras_length; + + push_int(rs.ras_width); + push_int(rs.ras_height); + o=clone_object(image_program,2); + img=(struct image*)get_storage(o,image_program); + rgb=img->img; + if(ctab != NULL) { + struct neo_colortable *ctable = + (struct neo_colortable*)get_storage(ctab, image_colortable_program); + if(ctable!=NULL && ctable->type==NCT_FLAT) { + numcolors = ctable->u.flat.numentries; + entries = ctable->u.flat.entries; + } + } + + for(y=0; y<rs.ras_height; y++) + switch(rs.ras_depth) { + case 24: + for(x=0; x<rs.ras_width; x++) { + if(len<3) { + if(ctab != NULL) + free_object(ctab); + free_object(o); + error("Image.RAS.decode: image data too short\n"); + } + rgb->b = *src++; + rgb->g = *src++; + rgb->r = *src++; + rgb++; + len -= 3; + } + if(rs.ras_width & 1) { + src++; + --len; + } + break; + case 8: + for(x=0; x<rs.ras_width; x++) { + if(len<1) { + if(ctab != NULL) + free_object(ctab); + free_object(o); + error("Image.RAS.decode: image data too short\n"); + } + if(*src<numcolors) + *rgb++ = entries[*src++].color; + else { + rgb++; + src++; + } + --len; + } + if(rs.ras_width & 1) { + src++; + --len; + } + break; + case 1: + { + int bits = 0, data; + for(x=0; x<rs.ras_width; x++) { + if(!bits) { + if(len<2) { + if(ctab != NULL) + free_object(ctab); + free_object(o); + error("Image.RAS.decode: image data too short\n"); + } + data = (src[0]<<8)|src[1]; + src += 2; + len -= 2; + bits = 16; + } + if(data&0x8000) + if(numcolors>1) + *rgb = entries[1].color; + else + rgb->r = rgb->g = rgb->b = 0; + else + if(numcolors>0) + *rgb = entries[0].color; + else + rgb->r = rgb->g = rgb->b = ~0; + rgb++; + data<<=1; + --bits; + } + if(rs.ras_width & 1) { + src++; + --len; + } + } + break; + default: + if(ctab != NULL) + free_object(ctab); + free_object(o); + error("Not implemented depth %d\n", rs.ras_depth); + } + + if(ctab != NULL) + free_object(ctab); + pop_n_elems(args); + push_object(o); +} + + +/** encoding *****************************************/ + +/* +**! method string encode(object image) +**! method string encode(object image, mapping options) +**! Encodes a RAS image. +**! +**! The <tt>options</tt> argument may be a mapping +**! containing zero or more encoding options: +**! +**! <pre> +**! normal options: +**! +**! "palette":colortable object +**! Use this as palette for pseudocolor encoding +**! +**! </pre> +*/ + +static void image_ras_encode(INT32 args) +{ + pop_n_elems(args); + push_text(""); +} + + +/** module *******************************************/ + +void init_image_ras(void) +{ + add_function("decode",img_ras_decode, + "function(string:object)",0); + add_function("encode",image_ras_encode, + "function(object,void|mapping(string:mixed):string)",0); +} + +void exit_image_ras(void) +{ +} diff --git a/src/modules/Image/initstuff.h b/src/modules/Image/initstuff.h index 1612eb35df..b57ec2234d 100644 --- a/src/modules/Image/initstuff.h +++ b/src/modules/Image/initstuff.h @@ -32,6 +32,7 @@ IMAGE_SUBMODULE("ILBM", init_image_ilbm, exit_image_ilbm ) IMAGE_SUBMODULE("PCX", init_image_pcx, exit_image_pcx ) IMAGE_SUBMODULE("PNM", init_image_pnm, exit_image_pnm ) IMAGE_SUBMODULE("_PSD", init_image_psd, exit_image_psd ) +IMAGE_SUBMODULE("RAS", init_image_ras, exit_image_ras ) IMAGE_SUBMODULE("TGA", init_image_tga, exit_image_tga ) IMAGE_SUBMODULE("X", init_image_x, exit_image_x ) IMAGE_SUBMODULE("XBM", init_image_xbm, exit_image_xbm ) -- GitLab