--- parser3/src/classes/image.C 2001/04/10 14:18:28 1.4 +++ parser3/src/classes/image.C 2001/04/11 15:45:48 1.7 @@ -5,14 +5,15 @@ Author: Alexander Petrosyan (http://design.ru/paf) - $Id: image.C,v 1.4 2001/04/10 14:18:28 paf Exp $ + $Id: image.C,v 1.7 2001/04/11 15:45:48 paf Exp $ */ #include "pa_config_includes.h" -#ifdef WIN32 -# include "smtp/smtp.h" -#endif +#include + +#include "Imaging.h" +#include "Gif.h" #include "pa_common.h" #include "pa_request.h" @@ -269,7 +270,7 @@ static void _measure(Request& r, const S int width, height; measure(pool, *file_name, reader, width, height); - static_cast(r.self)->set(*file_name, width, height); + static_cast(r.self)->set(file_name, width, height); } struct Attrib_info { @@ -285,14 +286,8 @@ static void append_attrib_pair(const Has Value& value=*static_cast(val); // src="a.gif" width=123 ismap[=-1] *ai.tag << " " << key; - if(value.is_string() || value.as_double()>=0) { - *ai.tag << "="; - if(value.is_string()) - *ai.tag << "\""; - *ai.tag << value.as_string(); - if(value.is_string()) - *ai.tag << "\""; - } + if(value.is_string() || value.as_double()>=0) + *ai.tag << "=\"" << value.as_string() << "\""; } /// ^image.html[] /// ^image.html[hash] @@ -303,23 +298,126 @@ static void _html(Request& r, const Stri tag << "(r.self)->fields(); - Hash *temporary=0; + Hash *attribs=0; - if(params->size()) { - if(temporary=static_cast(params->get(0))->get_hash()) { + if(params->size()) + if(attribs=static_cast(params->get(0))->get_hash()) { Attrib_info attrib_info={&tag, 0}; - temporary->for_each(append_attrib_pair, &attrib_info); + attribs->for_each(append_attrib_pair, &attrib_info); } else PTHROW(0, 0, &method_name, - "parameter must be hash"); - } + "attributes must be must be hash"); - Attrib_info attrib_info={&tag, temporary}; + Attrib_info attrib_info={&tag, attribs}; fields.for_each(append_attrib_pair, &attrib_info); - tag << ">"; + tag << " />"; r.write_pass_lang(tag); } +/* +/// ^image.load[background.gif] +static void _load(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + Value& vfile_name=*static_cast(params->get(0)); + // forcing [this body type] + r.fail_if_junction_(true, vfile_name, method_name, "file name must not be code"); + const String& file_name=vfile_name.as_string(); + + const char *file_name_cstr=r.absolute(file_name).cstr(String::UL_FILE_NAME); + if(FILE *f=fopen(file_name_cstr, "rb")) { + gdImagePtr image=gdImageCreateFromGif(f); + int width=gdImageSX(image); + int height=gdImageSY(image); + fclose(f); + + static_cast(r.self)->set(&file_name, width, height, image); + } else + PTHROW(0, 0, + &method_name, + "can not open background image '%s'", file_name_cstr); +} +*/ + +inline void v2rgb(int v, int& r, int& g, int& b) { + r=v>>8*2 & 0xFF; + g=v>>8*1 & 0xFF; + b=v & 0xFF; +} +/// ^image.create[width;height] bgcolor=white +/// ^image.create[width;height;bgcolor] +/// @test ImagingDelete +static void _create(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + int width=(int)r.process(*static_cast(params->get(0))).as_double(); + int height=(int)r.process(*static_cast(params->get(1))).as_double(); + int bgcolor_value=0xFFFFFF; + if(params->size()>2) + bgcolor_value= + (int)r.process(*static_cast(params->get(2))).as_double(); + Imaging im=ImagingNew("P", width, height); + ImagingPalette palette=ImagingPaletteNew("RGB"); + ImagingPaletteCachePrepare(palette); + { + int r,g,b; v2rgb(bgcolor_value, r,g,b); + ImagingPaletteCacheUpdate(palette, r,g,b); + int bgcolor_index=ImagingPaletteCache(palette, r,g,b); + ImagingDrawRectangle(im, 0, 0, width-1, height-1, + bgcolor_index, bgcolor_index); + } + static_cast(r.self)->set(0, width, height, im); +} + +/// ^image.gif[] +/// ^image.gif[user-file-name] +static void _gif(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + Imaging im=static_cast(r.self)->im; + if(!im) + PTHROW(0, 0, + &method_name, + "does not contain image"); + + char *file_name_cstr=0; + if(params->size()) { + Value& vfile_name=*static_cast(params->get(0)); + // forcing [this body type] + r.fail_if_junction_(true, vfile_name, method_name, "file name must not be code"); + + file_name_cstr=vfile_name.as_string().cstr(String::UL_FILE_NAME); + } + // could _ but don't thing it's wise to use $image.src for vfile.name + + ImagingCodecStateInstance codec_state={0}; + GIFENCODERSTATE encoder_state={0}; + int bits; + codec_state.shuffle=ImagingFindPacker("P", &bits); + codec_state.bits=codec_state.bits=bits; + codec_state.xsize = im->xsize; + codec_state.ysize = im->ysize; + /* Allocate memory buffer (if bits field is set) */ + codec_state.bytes = (codec_state.bits * codec_state.xsize+7)/8; + codec_state.buffer = (UINT8*) malloc(codec_state.bytes); + codec_state.context=&encoder_state; + + String result(pool); + do { + const int buf_size=10*0x400; + UINT8 *buf=(UINT8 *)pool.malloc(buf_size); + int encoded_size=ImagingGifEncode(im, &codec_state, buf, buf_size); + if(encoded_size>0) + result.APPEND_CLEAN((const char *)buf, encoded_size, 0, 0); + } while(codec_state.errcode==0); + + VFile& vfile=*new(pool) VFile(pool); + String& image_gif=*new(pool) String(pool, "image/gif"); + vfile.set(false/*not tainted*/, result.cstr(), result.size(), + file_name_cstr, &image_gif); + + r.write_no_lang(vfile); +} // initialize void initialize_image_class(Pool& pool, VStateless_class& vclass) { @@ -329,4 +427,15 @@ void initialize_image_class(Pool& pool, /// ^image.html[] /// ^image.html[hash] vclass.add_native_method("html", Method::CT_DYNAMIC, _html, 0, 1); + + /// ^image.load[background.gif] +// vclass.add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1); + + /// ^image.create[width;height] bgcolor=white + /// ^image.create[width;height;bgcolor] + vclass.add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3); + + /// ^image.gif[] + /// ^image.gif[user-file-name] + vclass.add_native_method("gif", Method::CT_DYNAMIC, _gif, 0, 1); }