d69ba5 | 2001-09-03 | Martin Nilsson | |
|
2e0a35 | 1999-12-09 | Martin Nilsson | |
|
37bdda | 1999-05-18 | Per Hedbor | | #include <module.h>
inherit "module";
|
3b85e9 | 1999-11-15 | Per Hedbor | | constant thread_safe=1;
|
37bdda | 1999-05-18 | Per Hedbor | |
roxen.ImageCache the_cache;
|
b99658 | 2004-06-21 | Martin Stjernholm | | constant cvs_version = "$Id: cimg.pike,v 1.66 2004/06/21 12:43:48 mast Exp $";
|
b3281f | 2000-09-10 | Martin Nilsson | | constant module_type = MODULE_TAG;
|
bc0fa0 | 2001-03-08 | Per Hedbor | | constant module_name = "Graphics: Image converter";
|
739058 | 2000-06-01 | Martin Nilsson | | constant module_doc = "Provides the tag <tt><cimg></tt> that can be used "
"to convert images between different image formats.";
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
4b3fc0 | 2001-03-12 | Johan Sundström | | mapping tagdocumentation()
{
|
739058 | 2000-06-01 | Martin Nilsson | | Stdio.File file=Stdio.File();
if(!file->open(__FILE__,"r")) return 0;
|
b99658 | 2004-06-21 | Martin Stjernholm | | mapping doc = compile_string("#define manual\n"+file->read(), __FILE__)->tagdoc;
|
4b3fc0 | 2001-03-12 | Johan Sundström | | foreach(({ "cimg", "cimg-url" }), string tag)
doc[tag] += the_cache->documentation(tag +
" src='/internal-roxen-testimage'");
|
739058 | 2000-06-01 | Martin Nilsson | | return doc;
}
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
739058 | 2000-06-01 | Martin Nilsson | | #ifdef manual
|
9b0365 | 2001-03-07 | Kenneth Johansson | | constant tagdoc=(["cimg":#"<desc tag='tag'><p><short>
Manipulates and converts images between different image
formats.</short> Provides the tag <tag>cimg</tag> that makes it is
possible to convert, resize, crop and in other ways transform
images.</p>
</desc>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
4b3fc0 | 2001-03-12 | Johan Sundström | | <attr name='src' value='url' required='required'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | The path to the indata file.</p>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
4b3fc0 | 2001-03-12 | Johan Sundström | | <ex><cimg src='/internal-roxen-testimage'/></ex>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | | </attr>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | <attr name='data' value='imagedata'><p>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | | Insert images from other sources, e.g. databases through entities or
|
9b0365 | 2001-03-07 | Kenneth Johansson | | variables.</p>
|
cba1fa | 2001-08-30 | Johan Sundström | | <ex-box><emit source='sql' query='select imagedata from images where id=37'>
|
79f3f1 | 2003-09-08 | Anders Johansson | | <cimg data='&sql.imagedata:none;'/>
|
cba1fa | 2001-08-30 | Johan Sundström | | </emit></ex-box>
|
ce011f | 2003-09-19 | Jonas Wallden | | </attr>
<attr name='process-all-layers'><p>Set this flag to make all image layers
visible regardless of their original state.</p>
</attr>
<attr name='include-layers' value='layer-glob-list'><p>Comma-separated list
of glob expressions which is matched against layer names. All matching
layers are made visible regardless of their original state.</p>
</attr>
<attr name='exclude-layers' value='layer-glob-list'><p>Comma-separated list
of glob expressions which is matched against layer names. All matching
layers are hidden regardless of their original state.</p>
|
739058 | 2000-06-01 | Martin Nilsson | | </attr>",
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
9b0365 | 2001-03-07 | Kenneth Johansson | | "cimg-url":#"<desc tag='tag'><p><short>
|
4b3fc0 | 2001-03-12 | Johan Sundström | | This tag generates an URL to the manipulated picture.</short>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | <tag>cimg-url</tag> takes the same attributes as <xref
href='cimg.tag' />, including the image cache attributes. The use for
|
4b3fc0 | 2001-03-12 | Johan Sundström | | the tag is to insert image-URLs into various places, e.g. a
|
9b0365 | 2001-03-07 | Kenneth Johansson | | submit-box.</p>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | | </desc>
|
4b3fc0 | 2001-03-12 | Johan Sundström | | <attr name='src' value='url' required='required'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | The path to the indata file.</p>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | |
|
4b3fc0 | 2001-03-12 | Johan Sundström | | <ex><cimg-url src='/internal-roxen-testimage'/></ex>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | | </attr>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | <attr name='data' value='imagedata'><p>
|
2fafd2 | 2000-05-18 | Kenneth Johansson | | Insert images from other sources, e.g. databases through entities or
|
9b0365 | 2001-03-07 | Kenneth Johansson | | variables.</p>
|
cba1fa | 2001-08-30 | Johan Sundström | | <ex-box><emit source='sql' query='select imagedata from images where id=37'>
<cimg-url data='&sql.imagedata;'/>
</emit></ex-box>
|
739058 | 2000-06-01 | Martin Nilsson | | </attr>",
|
0783ea | 2000-08-29 | Kenneth Johansson | |
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "emit#cimg":({ #"<desc type='plugin'><p><short>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Entitybased version of <xref href='../graphics/cimg.tag' />.</short>
Takes the same attributes as <tag>cimg</tag>.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
([
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.type;":#"<desc type='entity'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Returns the image's content-type.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.src;":#"<desc type='entity'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Returns the path to the indata file.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.file-size;":#"<desc type='entity'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Returns the image's file size.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.xsize;":#"<desc type='entity'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Returns the width of the image.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.ysize;":#"<desc type='entity'><p>
|
9b0365 | 2001-03-07 | Kenneth Johansson | | Returns the height of the image.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>",
|
ce8fb0 | 2001-09-21 | Johan Sundström | | "&_.data;":#"<desc type='entity'><p>
|
08b567 | 2000-09-19 | Kenneth Johansson | | Returns the imagedata given through other sources, like databases
|
9b0365 | 2001-03-07 | Kenneth Johansson | | through entities.</p>
|
0783ea | 2000-08-29 | Kenneth Johansson | | </desc>"
])
}),
|
739058 | 2000-06-01 | Martin Nilsson | | ]);
|
2e0a35 | 1999-12-09 | Martin Nilsson | | #endif
|
4afee2 | 2001-04-03 | Per Hedbor | | int do_ext;
|
fe32ad | 2001-03-30 | Johan Sundström | | void create()
{
defvar("ext", Variable.Flag(0, VAR_MORE,
"Append format to generated images",
"Append the image format (.gif, .png, "
".jpg, etc) to the generated images. "
"This is not necessary, but might seem "
"nicer, especially to people who try "
"to mirror your site."));
}
|
739058 | 2000-06-01 | Martin Nilsson | |
|
37bdda | 1999-05-18 | Per Hedbor | | void start()
{
the_cache = roxen.ImageCache( "cimg", generate_image );
|
4afee2 | 2001-04-03 | Per Hedbor | | do_ext = query("ext");
|
37bdda | 1999-05-18 | Per Hedbor | | }
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | mapping(string:function) query_action_buttons() {
|
5f13d5 | 2000-06-03 | Martin Nilsson | | return ([ "Clear cache":flush_cache ]);
}
void flush_cache() {
the_cache->flush();
|
3cca1c | 2004-05-21 | Jonas Wallden | |
cache.flush_memory_cache();
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | }
string status() {
array s=the_cache->status();
|
482ba7 | 2000-12-30 | Per Hedbor | | return sprintf("<b>Images in cache:</b> %d images<br />\n"
"<b>Cache size:</b> %s",
s[0], Roxen.sizetostring(s[1]));
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | }
|
6a613a | 2002-06-17 | Anders Johansson | | array(Image.Layer)|mapping generate_image( mapping args, RequestID id )
|
37bdda | 1999-05-18 | Per Hedbor | | {
|
689f3a | 2000-11-21 | Per Hedbor | | array layers;
|
13b35c | 2003-07-04 | Jonas Wallden | |
mapping opts = ([ "crop_to_bounds" : 1 ]);
|
689f3a | 2000-11-21 | Per Hedbor | | if( args["process-all-layers"] )
opts->draw_all_layers = 1;
|
bd2fd0 | 2001-08-15 | Per Hedbor | | if( args["jpeg-shrink" ] )
{
opts->scale_denom = (int)args["jpeg-shrink" ];
opts->scale_num = 1;
}
|
34a9b8 | 1999-08-06 | Peter Bortas | | if( args->data )
|
689f3a | 2000-11-21 | Per Hedbor | | layers = roxen.decode_layers( args->data, opts );
|
34a9b8 | 1999-08-06 | Peter Bortas | | else
|
6a613a | 2002-06-17 | Anders Johansson | | {
|
5ae0a3 | 2002-10-24 | Jonas Wallden | | mixed tmp;
#if constant(Sitebuilder)
if (Sitebuilder.sb_start_use_imagecache) {
Sitebuilder.sb_start_use_imagecache(args, id);
tmp = roxen.load_layers(args->src, id, opts);
Sitebuilder.sb_end_use_imagecache(args, id);
} else
#endif
{
tmp = roxen.load_layers(args->src, id, opts);
}
|
d86e71 | 2002-07-01 | Anders Johansson | | if (mappingp(tmp)) {
|
02d09b | 2004-05-05 | Anders Johansson | | if (tmp->error == Protocols.HTTP.HTTP_UNAUTH)
|
d86e71 | 2002-07-01 | Anders Johansson | | return tmp;
else
layers = 0;
}
|
6a613a | 2002-06-17 | Anders Johansson | | else layers = tmp;
}
|
689f3a | 2000-11-21 | Per Hedbor | |
|
7b5675 | 2001-06-25 | Marcus Wellhardh | | if(!layers)
|
bd2fd0 | 2001-08-15 | Per Hedbor | | {
if( args->data )
error("Failed to decode specified data\n");
else
error("Failed to load specified image [%O]\n", args->src);
}
|
d86e71 | 2002-07-01 | Anders Johansson | |
|
02d09b | 2004-05-05 | Anders Johansson | | if (!sizeof(filter(layers->image(), objectp)))
|
d86e71 | 2002-07-01 | Anders Johansson | | error("Failed to decode layers in specified image [%O]\n", args->src);
|
930b63 | 2000-12-10 | Per Hedbor | | layers->set_misc_value( "visible",1 );
foreach( layers, Image.Layer lay )
if( !lay->get_misc_value( "name" ) )
lay->set_misc_value( "name", "Background" );
|
689f3a | 2000-11-21 | Per Hedbor | |
if( args["exclude-layers"] )
{
foreach( args["exclude-layers"] / ",", string match )
foreach( layers, Image.Layer lay )
if( glob( match, lay->get_misc_value( "name" ) ) )
lay->set_misc_value( "visible", 0 );
}
if( args["include-layers"] )
{
foreach( args["include-layers"] / ",", string match )
foreach( layers, Image.Layer lay )
if( glob( match, lay->get_misc_value( "name" ) ) )
lay->set_misc_value( "visible", 1 );
}
array res = ({});
foreach( layers, Image.Layer l )
{
if( l->get_misc_value( "visible" ) )
res += ({ l });
}
return res;
|
37bdda | 1999-05-18 | Per Hedbor | | }
mapping find_internal( string f, RequestID id )
{
|
4afee2 | 2001-04-03 | Per Hedbor | |
return the_cache->http_file_answer( (f/".")[0], id );
|
37bdda | 1999-05-18 | Per Hedbor | | }
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | mapping get_my_args( mapping args, RequestID id )
|
37bdda | 1999-05-18 | Per Hedbor | | {
|
36eceb | 2000-01-30 | Per Hedbor | | mapping a=
([
|
37bdda | 1999-05-18 | Per Hedbor | | "quant":args->quant,
|
77926b | 2000-04-11 | Per Hedbor | | "crop":args->crop,
|
c52692 | 1999-05-18 | Per Hedbor | | "format":args->format,
"maxwidth":args->maxwidth,
"maxheight":args->maxheight,
"scale":args->scale,
"dither":args->dither,
|
b941aa | 1999-06-25 | Per Hedbor | | "gamma":args->gamma,
|
34a9b8 | 1999-08-06 | Peter Bortas | | "data":args->data,
|
37bdda | 1999-05-18 | Per Hedbor | | ]);
|
77926b | 2000-04-11 | Per Hedbor | |
|
7c4b6b | 2003-09-15 | Jonas Wallden | | if( args->src ) {
mixed err = catch
|
1c10ca | 2000-07-05 | Per Hedbor | | {
|
a6f956 | 2000-09-19 | Per Hedbor | | a->src = Roxen.fix_relative( args->src, id );
|
742477 | 2002-11-05 | Anders Johansson | | array(int)|Stat st = (id->conf->try_stat_file(a->src, id) ||
file_stat(a->src));
|
689f3a | 2000-11-21 | Per Hedbor | | if (st)
{
string fn = id->conf->real_file( a->src, id );
if( fn ) Roxen.add_cache_stat_callback( id, fn, st[ST_MTIME] );
a->mtime = (string) (a->stat = st[ST_MTIME]);
|
1133a7 | 2000-07-07 | Henrik Grubbström (Grubba) | | a->filesize = (string) st[ST_SIZE];
|
5ae0a3 | 2002-10-24 | Jonas Wallden | |
#if constant(Sitebuilder)
|
5d41d1 | 2002-11-06 | Anders Johansson | |
|
5ae0a3 | 2002-10-24 | Jonas Wallden | |
if (Sitebuilder.sb_prepare_imagecache)
|
200780 | 2002-10-24 | Jonas Wallden | | a = Sitebuilder.sb_prepare_imagecache(a, a->src, id);
|
5ae0a3 | 2002-10-24 | Jonas Wallden | | #endif
|
1133a7 | 2000-07-07 | Henrik Grubbström (Grubba) | | }
|
1c10ca | 2000-07-05 | Per Hedbor | | };
|
7c4b6b | 2003-09-15 | Jonas Wallden | | #ifdef DEBUG
if (err)
report_error("<cimg> or <emit#cimg>: error in get_my_args(): %s\n",
describe_backtrace(err));
#endif
}
|
2fa8d5 | 2000-06-02 | Martin Nilsson | |
|
1c10ca | 2000-07-05 | Per Hedbor | | a["background-color"] = id->misc->defines->bgcolor || "#eeeeee";
|
77926b | 2000-04-11 | Per Hedbor | |
|
c52692 | 1999-05-18 | Per Hedbor | | foreach( glob( "*-*", indices(args)), string n )
a[n] = args[n];
|
77926b | 2000-04-11 | Per Hedbor | |
|
34a9b8 | 1999-08-06 | Peter Bortas | | return a;
}
|
a49dae | 2000-08-17 | Per Hedbor | | mapping check_args( mapping args )
{
if( !args->format )
args->format = "png";
if( !(args->src || args->data) )
RXML.parse_error("Required attribute 'src' or 'data' missing\n");
if( args->src && args->data )
RXML.parse_error("Only one of 'src' and 'data' may be specified\n");
return args;
}
class TagCimgplugin
{
inherit RXML.Tag;
constant name = "emit";
constant plugin_name = "cimg";
array get_dataset( mapping args, RequestID id )
{
mapping res = ([ ]);
mapping a = get_my_args( check_args( args ), id );
string data;
|
7c4b6b | 2003-09-15 | Jonas Wallden | | mixed err = catch
|
eac60f | 2001-01-26 | Per Hedbor | | {
|
21bd60 | 2004-06-16 | Anders Johansson | |
int cacheable = id->misc->cacheable;
int no_proto_cache = id->misc->no_proto_cache;
#ifdef DEBUG_CACHEABLE
report_debug("%s:%d saved cacheable flags\n", __FILE__, __LINE__);
#endif
|
eac60f | 2001-01-26 | Per Hedbor | | res->src=(query_absolute_internal_location(id)+the_cache->store( a,id ));
|
4afee2 | 2001-04-03 | Per Hedbor | | if(do_ext)
|
fe32ad | 2001-03-30 | Johan Sundström | | res->src += "." + (a->format || "gif");
|
eac60f | 2001-01-26 | Per Hedbor | | data = the_cache->data( a, id , 0 );
res["file-size"] = strlen(data);
res["file-size-kb"] = strlen(data)/1024;
res["data"] = data;
res |= the_cache->metadata( a, id, 0 );
|
21bd60 | 2004-06-16 | Anders Johansson | | #ifdef DEBUG_CACHEABLE
report_debug("%s:%d restored cacheable flags\n", __FILE__, __LINE__);
#endif
id->misc->cacheable = cacheable;
id->misc->no_proto_cache = no_proto_cache;
|
eac60f | 2001-01-26 | Per Hedbor | | return ({ res });
};
|
7c4b6b | 2003-09-15 | Jonas Wallden | | #ifdef DEBUG
report_error("<emit#cimg> error in get_dataset(): %s\n",
describe_backtrace(err));
#endif
|
f61ece | 2001-08-11 | Martin Stjernholm | | RXML.parse_error( "Illegal arguments or image\n" );
|
eac60f | 2001-01-26 | Per Hedbor | | return ({});
|
a49dae | 2000-08-17 | Per Hedbor | | }
}
class TagCImg
{
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | inherit RXML.Tag;
constant name = "cimg";
|
1b2d74 | 2001-10-08 | Anders Johansson | | constant flags = RXML.FLAG_EMPTY_ELEMENT;
|
2fa8d5 | 2000-06-02 | Martin Nilsson | |
|
fe32ad | 2001-03-30 | Johan Sundström | | class Frame
|
a49dae | 2000-08-17 | Per Hedbor | | {
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | inherit RXML.Frame;
|
a49dae | 2000-08-17 | Per Hedbor | | array do_return(RequestID id)
{
mapping a = get_my_args( check_args( args ), id );
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | args -= a;
|
fe32ad | 2001-03-30 | Johan Sundström | | string ext = "";
|
4afee2 | 2001-04-03 | Per Hedbor | | if(do_ext)
|
fe32ad | 2001-03-30 | Johan Sundström | | ext = "." + (a->format || "gif");
args->src = query_absolute_internal_location( id )
+ the_cache->store( a, id ) + ext;
|
5701ac | 2003-10-17 | Anders Johansson | | int no_draw = !id->misc->generate_images;
|
cf5b11 | 2003-10-16 | Anders Johansson | | if( mapping size = the_cache->metadata( a, id, no_draw ) )
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | {
|
cf5b11 | 2003-10-16 | Anders Johansson | |
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | args->width = size->xsize;
args->height = size->ysize;
}
|
0023a6 | 2000-08-22 | Martin Nilsson | | int xml=!args->noxml;
m_delete(args, "noxml");
result = Roxen.make_tag( "img", args, xml );
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | return 0;
}
|
37bdda | 1999-05-18 | Per Hedbor | | }
}
|
698c12 | 1999-05-19 | Peter Bortas | |
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | class TagCImgURL {
inherit RXML.Tag;
constant name = "cimg-url";
|
1b2d74 | 2001-10-08 | Anders Johansson | | constant flags = RXML.FLAG_EMPTY_ELEMENT;
|
2fa8d5 | 2000-06-02 | Martin Nilsson | |
|
a49dae | 2000-08-17 | Per Hedbor | | class Frame
{
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | inherit RXML.Frame;
|
4b3fc0 | 2001-03-12 | Johan Sundström | | array do_return(RequestID id)
|
a49dae | 2000-08-17 | Per Hedbor | | {
|
fe32ad | 2001-03-30 | Johan Sundström | | result = query_absolute_internal_location(id)
+ the_cache->store(get_my_args(check_args( args ), id ), id)
|
4afee2 | 2001-04-03 | Per Hedbor | | + (do_ext ? "." + (args->format || "gif") : "");
|
2fa8d5 | 2000-06-02 | Martin Nilsson | | return 0;
}
}
|
698c12 | 1999-05-19 | Peter Bortas | | }
|