diff --git a/lib/modules/_Image_PSD.pmod b/lib/modules/_Image_PSD.pmod new file mode 100644 index 0000000000000000000000000000000000000000..53a7b60e494bb8eafce947ad5901a0a5f10656e1 --- /dev/null +++ b/lib/modules/_Image_PSD.pmod @@ -0,0 +1,211 @@ +inherit Image._PSD; + +class Layer +{ + string mode; + int opacity; + object image; + object alpha; + + int flags; + int xoffset, yoffset; + int width, height; + + + Layer copy() + { + Layer l = Layer(); + l->mode = mode; + l->opacity = opacity; + l->image = image; + l->alpha = alpha; + l->flags = flags; + l->xoffset = xoffset; + l->yoffset = yoffset; + l->width = width; + l->height = height; + return l; + } + + + Layer get_opaqued( int opaque_value ) + { + Layer res = copy(); + if(opaque_value != 255) + { + if(res->alpha) + res->alpha *= opaque_value/255.0; + else + res->alpha = Image.image(width,height, + opaque_value,opaque_value,opaque_value); + } + return res; + } +} + +Layer decode_layer(mapping layer, mapping i) +{ + Layer l = Layer(); + int use_cmap; + l->opacity = layer->opacity; + l->width = layer->right-layer->left; + l->height = layer->bottom-layer->top; + l->xoffset = layer->left; + l->yoffset = layer->top; + l->image = Image.image( l->width, l->height ); + l->mode = layer->mode; + l->flags = layer->flags; + + array colors; + switch(i->mode) + { + case Greyscale: + colors = ({ + 255,255,255 + })*24; + break; + case RGB: + colors = ({ ({255,0,0,}), + ({0,255,0,}), + ({0,0,255,}), + }) + ({ 255,255,255 }) * 24; + break; + case Indexed: + use_cmap = 1; + error("Tell per to fix colormap support\n"); + break; + default: + werror("Unsupported mode (for now), using greyscale\n"); + colors = ({ + 255,255,255 + })*24; + break; + } + foreach(layer->channels, mapping c) + { + object tmp =___decode_image_channel(l->width,l->height,c->data); + + switch(c->id) + { + default: + l->image->paste_alpha_color( tmp, @colors[c->id%24] ); + break; + case -1: /* alpha */ + l->alpha = tmp; + break; + case -2: /* user mask */ + if(!l->alpha) + l->alpha = tmp; + else + l->alpha *= tmp; + break; + } + } + return l; +} + +mapping __decode( mapping|string what, mapping|void options ) +{ + mapping data; + if(mappingp(what)) + data = what; + else + data = ___decode( what ); + what=0; + array rl = ({}); + foreach( data->layers, mapping l ) + rl += ({ decode_layer( l,data ) }); + data->layers = rl; + return data; +} + +#define PASTE_ALPHA(X,Y) \ + if(Y) \ + img->paste_mask( X, Y, l->xoffset, l->yoffset ); \ + else \ + img->paste( X, l->xoffset, l->yoffset ); \ + if(Y&&alpha&&++alpha_used) \ + alpha->paste_alpha_color(Y,255,255,255,l->xoffset, l->yoffset ); \ + else if(alpha) \ + alpha->box(l->xoffset,l->yoffset,l->xoffset+l->width-1,l->yoffset+l->height-1,255,255,255) + +#define IMG_SLICE(l,h) img->copy(l->xoffset,l->yoffset,l->xoffset+h->width-1,l->yoffset+h->height-1) + + +array(object) decode_background( mapping data, array bg ) +{ + object img, alpha; + if( !bg ) + alpha = Image.image(data->width, data->height); + +// if( data->image_data ) +// img = ___decode_image_data(data->width, data->height, +// data->channels, data->image_data); +// else + img = Image.image( data->width, data->height, + @((bg&&(array)bg)||({255,255,255}))); + return ({ img, alpha }); +} + +mapping _decode( string|mapping what, mapping|void opts ) +{ + mapping data; + if(!opts) opts = ([]); + if(mappingp(what)) + data = what; + else + data = __decode( what ); + what=0; + object alpha, img; + int alpha_used; + [img,alpha] = decode_background( data, opts->background ); + + foreach(reverse(data->layers), object l) + { +// if((l->flags & LAYER_FLAG_VISIBLE)|| opts->draw_all_layers) + { + Layer h = l->get_opaqued( l->opacity ); + + switch( l->mode ) + { + case "norm": + PASTE_ALPHA(h->image,h->alpha); + break; + + + case "mult": + object oi = IMG_SLICE(l,h); + oi *= h->image; + PASTE_ALPHA(oi,h->alpha); + break; + + case "add ": + object oi = IMG_SLICE(l,h); + oi += h->image; + PASTE_ALPHA(oi,h->alpha); + break; + + case "diff": + object oi = IMG_SLICE(l,h); + oi -= h->image; + PASTE_ALPHA(oi,h->alpha); + break; + + default: + if(!opts->ignore_unknown_layer_modes) + { + werror("Layer mode "+l->mode+" not yet implemented, " + " asuming 'norm'\n"); + PASTE_ALPHA(h->image,h->alpha); + } + break; + } + } + } + + return + ([ + "image":img, + "alpha":alpha, + ]); +} diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c index 3bd4a59f60c2a7612f04f26919667608c48d9d72..4b6f988e6fca5ed85e03fc2b25c5bc6a0b4800b3 100644 --- a/src/modules/Image/image.c +++ b/src/modules/Image/image.c @@ -1,9 +1,9 @@ -/* $Id: image.c,v 1.128 1999/04/13 12:32:22 mirar Exp $ */ +/* $Id: image.c,v 1.129 1999/04/15 02:40:47 per Exp $ */ /* **! module Image **! note -**! $Id: image.c,v 1.128 1999/04/13 12:32:22 mirar Exp $ +**! $Id: image.c,v 1.129 1999/04/15 02:40:47 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.128 1999/04/13 12:32:22 mirar Exp $"); +RCSID("$Id: image.c,v 1.129 1999/04/15 02:40:47 per Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -3540,6 +3540,8 @@ extern void exit_image_ilbm(void); extern void init_image_ilbm(void); extern void init_image_xcf(void); extern void exit_image_xcf(void); +extern void init_image_psd(void); +extern void exit_image_psd(void); extern void init_image_hrz(void); extern void exit_image_hrz(void); extern void init_image_avs(void); @@ -3555,6 +3557,7 @@ static struct pike_string *magic_XFace, *magic_XPM, *magic_XCF, + *magic_PSD, *magic_TIFF, *magic_PNG, *magic_PS, @@ -3601,6 +3604,14 @@ static void image_index_magic(INT32 args) SAFE_APPLY_MASTER("resolv",2); return; } + else if (sp[-1].u.string==magic_PSD) + { + pop_stack(); + push_string(make_shared_string("_Image_PSD")); + push_int(0); + SAFE_APPLY_MASTER("resolv",2); + return; + } else if (sp[-1].u.string==magic_TIFF) { pop_stack(); @@ -3650,6 +3661,7 @@ void pike_module_init(void) magic_XFace=make_shared_string("XFace"); magic_XPM=make_shared_string("XPM"); magic_XCF=make_shared_string("XCF"); + magic_PSD=make_shared_string("PSD"); magic_TIFF=make_shared_string("TIFF"); image_noise_init(); @@ -3984,6 +3996,7 @@ void pike_module_init(void) init_image__xpm(); init_image_ilbm(); init_image_xcf(); + init_image_psd(); init_image_x(); init_image_hrz(); init_image_avs(); @@ -4011,6 +4024,7 @@ void pike_module_exit(void) exit_image_xbm(); exit_image_ilbm(); exit_image_xcf(); + exit_image_psd(); exit_image_hrz(); exit_image_avs(); if (png_object) @@ -4026,6 +4040,7 @@ void pike_module_exit(void) free_string(magic_XFace); free_string(magic_XPM); free_string(magic_XCF); + free_string(magic_PSD); free_string(magic_TIFF); free_string(magic_TTF); free_string(magic_PS);