From 452607fa7cd2e757bbe740f3b89cc7f3be1c91aa Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Tue, 21 Dec 1999 17:45:53 +0100 Subject: [PATCH] Image._load() and Image.load() can now load (http-)URLs and .gz and .bz etc compressed files, Image._decode can now decode all formats known to pike, except XFace, since it is hard to detect if a string is an XFace image or just random data. Rev: lib/modules/_Image.pmod/module.pmod:1.3 --- lib/modules/_Image.pmod/module.pmod | 122 ++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 9 deletions(-) diff --git a/lib/modules/_Image.pmod/module.pmod b/lib/modules/_Image.pmod/module.pmod index 32da7cee66..4136c0dabc 100644 --- a/lib/modules/_Image.pmod/module.pmod +++ b/lib/modules/_Image.pmod/module.pmod @@ -1,6 +1,5 @@ //! module Image -//! $Id: module.pmod,v 1.2 1999/05/28 13:35:02 mirar Exp $ - +//! $Id: module.pmod,v 1.3 1999/12/21 16:45:53 per Exp $ //! method object(Image.Image) load() //! method object(Image.Image) load(object file) @@ -19,17 +18,122 @@ //! All data is read, ie nothing happens until the file is closed. //! Throws upon error. -mapping _load(void|object|string file) +mapping _decode( string data, mixed|void tocolor ) +{ + Image.image i, a; + string format; + mapping opts; + if(!data) + return 0; + + if( mappingp( tocolor ) ) + { + opts = tocolor; + tocolor = 0; + } + // Use the low-level decode function to get the alpha channel. + catch + { + array chunks = Image["GIF"]->_decode( data ); + + // If there is more than one render chunk, the image is probably + // an animation. Handling animations is left as an exercise for + // the reader. :-) + foreach(chunks, mixed chunk) + if(arrayp(chunk) && chunk[0] == Image.GIF.RENDER ) + [i,a] = chunk[3..4]; + format = "GIF"; + }; + + if(!i) + foreach( ({ "GIF", "JPEG", "XWD", "PNM" }), string fmt ) + { + catch { + i = Image[fmt]->decode( data ); + format = fmt; + }; + if( i ) + break; + } + + if(!i) + foreach( ({ "XCF", "PSD", "PNG", "BMP", "TGA", "PCX", + "XBM", "XPM", "TIFF", "ILBM", "PS", + /* Image formats low on headers below this mark */ + "HRZ", "AVS", "WBF", + /* "XFace" Always succeds*/ + }), string fmt ) + { + catch { + mixed q = Image[fmt]->_decode( data ); + format = fmt; + i = q->image; + a = q->alpha; + }; + if( i ) + break; + } + + if(!i) // No image could be decoded at all. + return 0; + + if( arrayp(tocolor) && (sizeof(tocolor)==3) && objectp(i) && objectp(a) ) + { + Image.Image o = Image.Image( i->xsize(), i->ysize(), @tocolor ); + i = o->paste_mask( i, a ); + } + + return ([ + "format":format, + "alpha":a, + "img":i, + ]); + +} + +string read_file(string file) { + string ext=""; + sscanf(reverse(file),"%s.%s",ext,string rest); + string dcc; + + switch(lower_case(reverse(ext))) + { + case "gz": + case "z": + dcc="gzip"; + break; + case "bz": + case "bz2": + dcc = "bzip2"; + break; + } + + if( dcc ) + { + object f = Stdio.File(); + object p=f->pipe(Stdio.PROP_IPC); + Process.create_process(({dcc,"-c","-d",file}),(["stdout":p])); + destruct( p ); + return f->read(); + } + return Stdio.read_file( file ); +} + +mapping _load(void|object|string file, mixed|void opts) +{ + string data; if (!file) file=Stdio.stdin; - else if (stringp(file)) + if (objectp(file)) + data = file->read(); + else { - object f=Stdio.File(); - if (!f->open(file,"r")) - error("Image._load: Can't open %O for input.\n",file); - file=f; + if( catch( data = read_file( file ) ) || !data || !strlen(data) ) + catch( data = Protocols.HTTP.get_url_nice( file )[ 1 ] ); } - return Image.ANY._decode(file->read()); + if( !data ) + error("Image._load: Can't open %O for input.\n",file); + return _decode( data,opts ); } object(Image.Layer) load_layer(void|object|string file) -- GitLab