f668602000-03-02Martin Nilsson // This is a roxen module. Copyright © 1999 - 2000, Roxen IS.
2e0a351999-12-09Martin Nilsson //
37bdda1999-05-18Per Hedbor #include <module.h> inherit "module";
3b85e91999-11-15Per Hedbor constant thread_safe=1;
37bdda1999-05-18Per Hedbor  roxen.ImageCache the_cache;
9b03652001-03-07Kenneth Johansson constant cvs_version = "$Id: cimg.pike,v 1.37 2001/03/07 13:40:43 kuntri Exp $";
b3281f2000-09-10Martin Nilsson constant module_type = MODULE_TAG;
c043f82000-02-10Martin Nilsson constant module_name = "Image converter";
7390582000-06-01Martin Nilsson constant module_doc = "Provides the tag <tt>&lt;cimg&gt;</tt> that can be used " "to convert images between different image formats.";
2fafd22000-05-18Kenneth Johansson 
7390582000-06-01Martin Nilsson mapping tagdocumentation() { Stdio.File file=Stdio.File(); if(!file->open(__FILE__,"r")) return 0; mapping doc=compile_string("#define manual\n"+file->read())->tagdoc;
a4390b2000-09-05Martin Nilsson  string imagecache=the_cache->documentation("cimg src='internal-roxen-testimage'");
2fafd22000-05-18Kenneth Johansson 
7390582000-06-01Martin Nilsson  doc->cimg+=imagecache; doc["cimg-url"]=imagecache; return doc; }
2fafd22000-05-18Kenneth Johansson 
7390582000-06-01Martin Nilsson #ifdef manual
9b03652001-03-07Kenneth 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>
2fafd22000-05-18Kenneth Johansson 
9b03652001-03-07Kenneth Johansson <attr name='src' value='uri' required='required'><p> The path to the indata file.</p>
2fafd22000-05-18Kenneth Johansson 
a4390b2000-09-05Martin Nilsson <ex><cimg src='internal-roxen-testimage'/></ex>
2fafd22000-05-18Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='data' value='imagedata'><p>
2fafd22000-05-18Kenneth Johansson  Insert images from other sources, e.g. databases through entities or
9b03652001-03-07Kenneth Johansson  variables.</p>
2fafd22000-05-18Kenneth Johansson <ex type='box'>
2fa8d52000-06-02Martin Nilsson <emit source='sql' query='select imagedata from images where id=37'>
9b03652001-03-07Kenneth Johansson <cimg data='&sql.imagedata;'/>
2fa8d52000-06-02Martin Nilsson </emit>
2fafd22000-05-18Kenneth Johansson </ex>
7390582000-06-01Martin Nilsson </attr>",
2fafd22000-05-18Kenneth Johansson 
9b03652001-03-07Kenneth Johansson "cimg-url":#"<desc tag='tag'><p><short> This tag generates an URI to the manipulated picture.</short> <tag>cimg-url</tag> takes the same attributes as <xref href='cimg.tag' />, including the image cache attributes. The use for the tag is to insert image-URI's into various places, e.g. a submit-box.</p>
2fafd22000-05-18Kenneth Johansson </desc>
9b03652001-03-07Kenneth Johansson <attr name='src' value='uri' required='required'><p> The path to the indata file.</p>
2fafd22000-05-18Kenneth Johansson 
a4390b2000-09-05Martin Nilsson <ex><cimg-url src='internal-roxen-testimage'/></ex>
2fafd22000-05-18Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='data' value='imagedata'><p>
2fafd22000-05-18Kenneth Johansson  Insert images from other sources, e.g. databases through entities or
9b03652001-03-07Kenneth Johansson  variables.</p>
2fafd22000-05-18Kenneth Johansson <ex type='box'>
2fa8d52000-06-02Martin Nilsson <emit source='sql' query='select imagedata from images where id=37'>
9b03652001-03-07Kenneth Johansson <cimg data='&sql.imagedata;'/>
2fa8d52000-06-02Martin Nilsson </emit>
2fafd22000-05-18Kenneth Johansson </ex>
7390582000-06-01Martin Nilsson </attr>",
0783ea2000-08-29Kenneth Johansson 
9b03652001-03-07Kenneth Johansson "emit#cimg":({ #"<desc plugin='plugin'><p><short> Entitybased version of <xref href='../graphics/cimg.tag' />.</short> Takes the same attributes as <tag>cimg</tag>.</p>
0783ea2000-08-29Kenneth Johansson </desc>", ([
9b03652001-03-07Kenneth Johansson "&_.type;":#"<desc ent='ent'><p> Returns the image's content-type.</p>
0783ea2000-08-29Kenneth Johansson </desc>",
9b03652001-03-07Kenneth Johansson "&_.src;":#"<desc ent='ent'><p> Returns the path to the indata file.</p>
0783ea2000-08-29Kenneth Johansson </desc>",
9b03652001-03-07Kenneth Johansson "&_.file-size;":#"<desc ent='ent'><p> Returns the image's file size.</p>
0783ea2000-08-29Kenneth Johansson </desc>",
9b03652001-03-07Kenneth Johansson "&_.xsize;":#"<desc ent='ent'><p> Returns the width of the image.</p>
0783ea2000-08-29Kenneth Johansson </desc>",
9b03652001-03-07Kenneth Johansson "&_.ysize;":#"<desc ent='ent'><p> Returns the height of the image.</p>
0783ea2000-08-29Kenneth Johansson </desc>",
9b03652001-03-07Kenneth Johansson "&_.data;":#"<desc ent='ent'><p>
08b5672000-09-19Kenneth Johansson  Returns the imagedata given through other sources, like databases
9b03652001-03-07Kenneth Johansson  through entities.</p>
0783ea2000-08-29Kenneth Johansson </desc>" ]) }),
7390582000-06-01Martin Nilsson ]);
2e0a351999-12-09Martin Nilsson #endif
7390582000-06-01Martin Nilsson 
37bdda1999-05-18Per Hedbor void start() { the_cache = roxen.ImageCache( "cimg", generate_image ); }
2fa8d52000-06-02Martin Nilsson mapping(string:function) query_action_buttons() {
5f13d52000-06-03Martin Nilsson  return ([ "Clear cache":flush_cache ]); } void flush_cache() { the_cache->flush();
2fa8d52000-06-02Martin Nilsson } string status() { array s=the_cache->status();
482ba72000-12-30Per Hedbor  return sprintf("<b>Images in cache:</b> %d images<br />\n" "<b>Cache size:</b> %s", s[0], Roxen.sizetostring(s[1]));
2fa8d52000-06-02Martin Nilsson }
689f3a2000-11-21Per Hedbor array(Image.Layer) generate_image( mapping args, RequestID id )
37bdda1999-05-18Per Hedbor {
689f3a2000-11-21Per Hedbor  array layers; mapping opts = ([]); if( args["process-all-layers"] ) opts->draw_all_layers = 1;
34a9b81999-08-06Peter Bortas  if( args->data )
689f3a2000-11-21Per Hedbor  layers = roxen.decode_layers( args->data, opts );
34a9b81999-08-06Peter Bortas  else
689f3a2000-11-21Per Hedbor  layers = roxen.load_layers( args->src, id, opts );
930b632000-12-10Per Hedbor  layers->set_misc_value( "visible",1 ); foreach( layers, Image.Layer lay ) if( !lay->get_misc_value( "name" ) ) lay->set_misc_value( "name", "Background" );
689f3a2000-11-21Per 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;
37bdda1999-05-18Per Hedbor } mapping find_internal( string f, RequestID id ) { return the_cache->http_file_answer( f, id ); }
2fa8d52000-06-02Martin Nilsson mapping get_my_args( mapping args, RequestID id )
37bdda1999-05-18Per Hedbor {
36eceb2000-01-30Per Hedbor  mapping a= ([
37bdda1999-05-18Per Hedbor  "quant":args->quant,
77926b2000-04-11Per Hedbor  "crop":args->crop,
c526921999-05-18Per Hedbor  "format":args->format, "maxwidth":args->maxwidth, "maxheight":args->maxheight, "scale":args->scale, "dither":args->dither,
b941aa1999-06-25Per Hedbor  "gamma":args->gamma,
34a9b81999-08-06Peter Bortas  "data":args->data,
37bdda1999-05-18Per Hedbor  ]);
77926b2000-04-11Per Hedbor 
a6f9562000-09-19Per Hedbor  if( args->src )
1c10ca2000-07-05Per Hedbor  catch {
a6f9562000-09-19Per Hedbor  a->src = Roxen.fix_relative( args->src, id );
1f4a6c2000-08-28Per Hedbor  Stat st = id->conf->stat_file(a->src, id) || file_stat(a->src);
689f3a2000-11-21Per 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]);
1133a72000-07-07Henrik Grubbström (Grubba)  a->filesize = (string) st[ST_SIZE]; }
1c10ca2000-07-05Per Hedbor  };
2fa8d52000-06-02Martin Nilsson 
1c10ca2000-07-05Per Hedbor  a["background-color"] = id->misc->defines->bgcolor || "#eeeeee";
77926b2000-04-11Per Hedbor 
c526921999-05-18Per Hedbor  foreach( glob( "*-*", indices(args)), string n ) a[n] = args[n];
77926b2000-04-11Per Hedbor 
34a9b81999-08-06Peter Bortas  return a; }
a49dae2000-08-17Per 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;
eac60f2001-01-26Per Hedbor  catch // This code will fail if the image does not exist. { res->src=(query_absolute_internal_location(id)+the_cache->store( a,id )); 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 ); // enforce generation return ({ res }); }; RXML.parse_error( "Illegal arguments or image" ); return ({});
a49dae2000-08-17Per Hedbor  } } class TagCImg {
2fa8d52000-06-02Martin Nilsson  inherit RXML.Tag; constant name = "cimg"; constant flags = RXML.FLAG_EMPTY_ELEMENT;
a49dae2000-08-17Per Hedbor  class Frame {
2fa8d52000-06-02Martin Nilsson  inherit RXML.Frame;
a49dae2000-08-17Per Hedbor  array do_return(RequestID id) { mapping a = get_my_args( check_args( args ), id );
2fa8d52000-06-02Martin Nilsson  args -= a;
930b632000-12-10Per Hedbor  args->src=query_absolute_internal_location(id)+the_cache->store( a,id );
2fa8d52000-06-02Martin Nilsson  if( mapping size = the_cache->metadata( a, id, 1 ) ) { // image in cache (1 above prevents generation on-the-fly) args->width = size->xsize; args->height = size->ysize; }
0023a62000-08-22Martin Nilsson  int xml=!args->noxml; m_delete(args, "noxml"); result = Roxen.make_tag( "img", args, xml );
2fa8d52000-06-02Martin Nilsson  return 0; }
37bdda1999-05-18Per Hedbor  } }
698c121999-05-19Peter Bortas 
2fa8d52000-06-02Martin Nilsson class TagCImgURL { inherit RXML.Tag; constant name = "cimg-url"; constant flags = RXML.FLAG_EMPTY_ELEMENT;
a49dae2000-08-17Per Hedbor  class Frame {
2fa8d52000-06-02Martin Nilsson  inherit RXML.Frame;
a49dae2000-08-17Per Hedbor  array do_return(RequestID id) {
db053e2000-12-05Martin Nilsson  result = query_absolute_internal_location(id)+
a49dae2000-08-17Per Hedbor  the_cache->store(get_my_args(check_args( args ), id ),id);
2fa8d52000-06-02Martin Nilsson  return 0; } }
698c121999-05-19Peter Bortas }