e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
415c0f1999-01-22Mirar (Pontus Hagland) /* **! module Image
448c201999-04-13Mirar (Pontus Hagland) **! submodule Color
415c0f1999-01-22Mirar (Pontus Hagland) **!
13670c2015-05-25Martin Nilsson **! This module keeps names and easy handling
5e94231999-01-23Mirar (Pontus Hagland) **! for easy color support. It gives you an easy **! way to get colors from names.
415c0f1999-01-22Mirar (Pontus Hagland) **!
5e94231999-01-23Mirar (Pontus Hagland) **! A color is here an object, containing color **! information and methods for conversion, see below.
4d21f91999-01-24Mirar (Pontus Hagland) **!
448c201999-04-13Mirar (Pontus Hagland) **! <ref>Image.Color</ref> can be called to make a color object. **! <ref>Image.Color()</ref> takes the following arguments:
4d21f91999-01-24Mirar (Pontus Hagland) **! <pre>
448c201999-04-13Mirar (Pontus Hagland) **! Image.Color(string name) // "red" **! Image.Color(string prefix_string) // "lightblue" **! Image.Color(string hex_name) // "#ff00ff" **! Image.Color(string cmyk_string) // "%17,42,0,19.4" **! Image.Color(string hsv_string) // "%@327,90,32"
13670c2015-05-25Martin Nilsson **! Image.Color(int red, int green, int blue)
4d21f91999-01-24Mirar (Pontus Hagland) **! </pre> **!
13670c2015-05-25Martin Nilsson **! The color names available can be listed by using indices **! on Image.Color. The colors are available by name directly
448c201999-04-13Mirar (Pontus Hagland) **! as <tt>Image.Color.name</tt>, too:
4d21f91999-01-24Mirar (Pontus Hagland) **! <pre>
448c201999-04-13Mirar (Pontus Hagland) **! ...Image.Color.red... **! ...Image.Color.green...
4d21f91999-01-24Mirar (Pontus Hagland) **! or, maybe
448c201999-04-13Mirar (Pontus Hagland) **! import Image.Color;
4d21f91999-01-24Mirar (Pontus Hagland) **! ...red... **! ...green... **! ...lightgreen... **! </pre> **! **! Giving red, green and blue values is equal to calling
448c201999-04-13Mirar (Pontus Hagland) **! <ref>Image.Color.rgb</ref>().
13670c2015-05-25Martin Nilsson **! **! The prefix_string method is a form for getting modified
4d21f91999-01-24Mirar (Pontus Hagland) **! colors, it understands all modifiers
16602f2001-11-07Martin Nilsson **! (<link to=Color.light>light</link>, **! <link to=Color.dark>dark</link>, **! <link to=Color.bright>bright</link>, **! <link to=Color.dull>dull</link> and **! <link to=Color.neon>neon</link>). Simply use
13670c2015-05-25Martin Nilsson **! "method"+"color"; (as in <tt>lightgreen</tt>,
4d21f91999-01-24Mirar (Pontus Hagland) **! <tt>dullmagenta</tt>, <tt>lightdullorange</tt>). **!
13670c2015-05-25Martin Nilsson **! The <tt>hex_name</tt> form is a simple
2f5efe1999-01-24Mirar (Pontus Hagland) **! <tt>#rrggbb</tt> form, as in HTML or X-program argument. **! A shorter form (<tt>#rgb</tt>) is also accepted. This
448c201999-04-13Mirar (Pontus Hagland) **! is the inverse to the <ref>Image.Color.Color->hex</ref>()
2f5efe1999-01-24Mirar (Pontus Hagland) **! method. **! **! The <tt>cmyk_string</tt> is a string form of giving **! <i>cmyk</i> (cyan, magenta, yellow, black) color. These **! values are floats representing percent. **! **! The <tt>hsv_string</tt> is another hue, saturation, value **! representation, but in floats; hue is in degree range (0..360), **! and saturation and value is given in percent. <i>This is not **! the same as returned or given to the <ref>hsv</ref>() methods!</i> **!
5810332001-07-30Martin Nilsson **! This table lists all the different named colors available in Image.Color. **! The first column shows the actual color while the five following columns **! demonstrates the modifiers neon, light, dark, bright and dull. The color **! begind the name of the color is produced by calling neon()->dark()->dark()->dark() **! from the color object itself, i.e. Image.Color.mintcream->neon()->dark()->dark()->dark(). **!
47897e2001-07-17Martin Nilsson **! <execute>
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! import Image;
13670c2015-05-25Martin Nilsson **!
3127342000-08-11Mirar (Pontus Hagland) **! array modifiers=({"neon","light","dark","bright","dull"});
13670c2015-05-25Martin Nilsson **!
400f921999-06-22Mirar (Pontus Hagland) **! object F=Font(); **! **! mixed color_info(array(object) ac)
696b511999-06-15Mirar (Pontus Hagland) **! {
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! #define YZ 14
400f921999-06-22Mirar (Pontus Hagland) **! #define YZz (YZ+1)
696b511999-06-15Mirar (Pontus Hagland) **! #define MODX 32
400f921999-06-22Mirar (Pontus Hagland) **! #define CXZ 64
696b511999-06-15Mirar (Pontus Hagland) **! #define CSP 8 **! #define MSP 4 **! #define LSP 4
400f921999-06-22Mirar (Pontus Hagland) **! #define XTEXT 100 **! #define XSP 4 **! #define cPOS (XTEXT+XSP) **! #define tPOS 0 **! #define txPOS(t) (XSP*2) **! #define XZ (CXZ+CSP+(MSP+MODX)*sizeof(modifiers)-MSP)
13670c2015-05-25Martin Nilsson **!
400f921999-06-22Mirar (Pontus Hagland) **! object i=Image(XZ+XTEXT,YZz*sizeof(ac),Color.black); **! object a=Image(XZ+XTEXT,YZz*sizeof(ac),Color.black); **! **! int y=0; **! foreach (ac,object c)
696b511999-06-15Mirar (Pontus Hagland) **! {
400f921999-06-22Mirar (Pontus Hagland) **! i->box(cPOS+0, y, cPOS+CXZ-1,y+YZ-1,c); **! i->box(cPOS+CXZ,y+YZ-LSP,cPOS+XZ, y+YZ-1,c); **! a->box(cPOS+0, y, cPOS+CXZ-1,y+YZ-1,Color.white); **! a->box(cPOS+CXZ,y+YZ-LSP,cPOS+XZ, y+YZ-1,Color.white);
13670c2015-05-25Martin Nilsson **!
400f921999-06-22Mirar (Pontus Hagland) **! int x=CXZ+CSP+cPOS; **! foreach (modifiers,string mod) **! { **! i->box(x,y,x+MODX-1,y+YZ-LSP-1,c[mod]()); **! a->box(x,y,x+MODX-1,y+YZ-LSP-1,Color.white); **! x+=MSP+MODX; **! } **! i->box(tPOS,y,tPOS+XTEXT-XSP-1,y+YZ-1, **! c->neon()->dark()->dark()->dark()); **! a->box(tPOS,y,tPOS+XTEXT-XSP-1,y+YZ-1,Color.white);
13670c2015-05-25Martin Nilsson **! i->paste_alpha_color(F->write(c->name()), Color.white,
400f921999-06-22Mirar (Pontus Hagland) **! txPOS(c->name()),y+1); **! y+=YZz;
696b511999-06-15Mirar (Pontus Hagland) **! }
13670c2015-05-25Martin Nilsson **!
0368cc1999-07-15Fredrik Hübinette (Hubbe) **! write(illustration(i,(["alpha":a])));
8c91632001-09-17Martin Nilsson **! write(mktag("br")+"\n");
696b511999-06-15Mirar (Pontus Hagland) **! }
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! void main() **! { **! array cs=values(Color);
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! array orig=({Color.black,Color.red,Color.green,Color.yellow, **! Color.blue,Color.violet,Color.cyan,Color.white}); **! cs-=orig;
5810332001-07-30Martin Nilsson **! cs-=({Color.pikegreen,Color.avantgardepikegreen,Color.roxenorange, **! Color.pikeblue}); // Lame sort of easter egg.
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! array grey=Array.filter(cs,lambda(object c) { return c->s==0; }); **! array colored=cs-grey;
eb45812012-04-08Henrik Grubbström (Grubba) **! **! sort(grey->name(), grey);
696b511999-06-15Mirar (Pontus Hagland) **! sort(grey->v,grey);
eb45812012-04-08Henrik Grubbström (Grubba) **! sort(colored->name(), colored);
696b511999-06-15Mirar (Pontus Hagland) **! sort(Array.map(colored,lambda(object c) **! { **! return (c->h*50-c->s)*10+c->v; **! }),colored);
13670c2015-05-25Martin Nilsson **!
400f921999-06-22Mirar (Pontus Hagland) **! Array.map(({orig}),color_info);
5810332001-07-30Martin Nilsson **! // write("\240");
400f921999-06-22Mirar (Pontus Hagland) **! Array.map(({grey}),color_info);
5810332001-07-30Martin Nilsson **! // write("\240");
400f921999-06-22Mirar (Pontus Hagland) **! Array.map(colored/8.0,color_info);
696b511999-06-15Mirar (Pontus Hagland) **! }
13670c2015-05-25Martin Nilsson **!
696b511999-06-15Mirar (Pontus Hagland) **! </execute>
4d21f91999-01-24Mirar (Pontus Hagland) **!
f84c3f2003-11-07Martin Nilsson **! **! see also: Image.Color.Color->name, Image.Color.Color->rgb, colors **! **! added: **! pike 0.7
13670c2015-05-25Martin Nilsson **! **! note: **! <tt>Image.Color["something"]</tt> will never(!) generate an error,
f84c3f2003-11-07Martin Nilsson **! but a zero_type 0, if the color is unknown. This is enough
13670c2015-05-25Martin Nilsson **! to give the error "not present in module", if used
f84c3f2003-11-07Martin Nilsson **! as <tt>Image.Color.something</tt>, though. **! **! If you are using colors from for instance a webpage, you might **! want to create the color from <ref>Image.Color.guess</ref>(), **! since that method is more tolerant for mistakes and errors. **! **! <tt>Image.Color</tt>() is case- and space-sensitive. **! Use <ref>Image.Color.guess</ref>() to catch all variants. **! **! and subtract with a space (lower_case(x)-" ") to make **! sure you get all variants.
13670c2015-05-25Martin Nilsson **!
f84c3f2003-11-07Martin Nilsson **! see also: Image.Color.Color, Image.Color.guess, Image, Image.Colortable **!
448c201999-04-13Mirar (Pontus Hagland) **! class Color
5e94231999-01-23Mirar (Pontus Hagland) **! This is the color object. It has six readable variables,
13670c2015-05-25Martin Nilsson **! <tt>r</tt>, <tt>g</tt>, <tt>b</tt>, for the <i>red</i>, **! <i>green</i> and <i>blue</i> values,
5e94231999-01-23Mirar (Pontus Hagland) **! and <tt>h</tt>, <tt>s</tt>, <tt>v</tt>, for **! the <i>hue</i>, <i>saturation</i> anv <i>value</i> values.
415c0f1999-01-22Mirar (Pontus Hagland) */ #include "global.h"
d9db231999-05-30Mirar (Pontus Hagland) #include "image_machine.h"
415c0f1999-01-22Mirar (Pontus Hagland) 
5e94231999-01-23Mirar (Pontus Hagland) #include <math.h>
415c0f1999-01-22Mirar (Pontus Hagland) #include "stralloc.h" #include "pike_macros.h" #include "object.h" #include "interpret.h" #include "svalue.h" #include "array.h" #include "mapping.h" #include "builtin_functions.h"
5e94231999-01-23Mirar (Pontus Hagland) #include "operators.h"
415c0f1999-01-22Mirar (Pontus Hagland) #include "module_support.h"
a466762003-11-14Martin Stjernholm #include "sscanf.h"
e9ce612001-03-29Per Hedbor #include "program_id.h"
68ec3f2014-08-18Martin Nilsson #include "pike_types.h"
415c0f1999-01-22Mirar (Pontus Hagland)  #include "image.h" #include "colortable.h"
6dc2772000-07-28Fredrik Hübinette (Hubbe) 
415c0f1999-01-22Mirar (Pontus Hagland) 
6ad2372002-05-11Martin Nilsson #define sp Pike_sp
415c0f1999-01-22Mirar (Pontus Hagland) static struct mapping *colors=NULL; static struct object *colortable=NULL; static struct array *colornames=NULL; struct program *image_color_program=NULL; extern struct program *image_colortable_program; static struct pike_string *str_r; static struct pike_string *str_g; static struct pike_string *str_b; static struct pike_string *str_h; static struct pike_string *str_s; static struct pike_string *str_v;
7a49a11999-04-10Mirar (Pontus Hagland) static struct pike_string *no_name;
415c0f1999-01-22Mirar (Pontus Hagland) 
e405f01999-01-24Mirar (Pontus Hagland) /* forward */
13670c2015-05-25Martin Nilsson static void _image_make_rgbl_color(INT32 r,INT32 g,INT32 b);
ea7a4d2000-08-09Henrik Grubbström (Grubba) static void _image_make_rgbf_color(double r, double g, double b);
13670c2015-05-25Martin Nilsson static void image_make_hsv_color(INT32 args);
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_cmyk_color(INT32 args); static void image_make_color(INT32 args);
7a49a11999-04-10Mirar (Pontus Hagland) static void image_make_rgb_color(INT32 args);
5e94231999-01-23Mirar (Pontus Hagland) 
4d21f91999-01-24Mirar (Pontus Hagland) struct html_color { int r,g,b; char *name; struct pike_string *pname; } html_color[]= {{0,0,0,"black",NULL}, {255,255,255,"white",NULL}, {0,128,0,"green",NULL}, {192,192,192,"silver",NULL},
13670c2015-05-25Martin Nilsson  {0,255,0,"lime",NULL}, {128,128,128,"gray",NULL}, {128,128,0,"olive",NULL}, {255,255,0,"yellow",NULL}, {128,0,0,"maroon",NULL}, {0,0,128,"navy",NULL},
4d21f91999-01-24Mirar (Pontus Hagland)  {255,0,0,"red",NULL}, {0,0,255,"blue",NULL},
13670c2015-05-25Martin Nilsson  {128,0,128,"purple",NULL}, {0,128,128,"teal",NULL},
cded6a1999-01-26Mirar (Pontus Hagland)  {255,0,255,"fuchsia",NULL}, {0,255,255,"aqua",NULL}};
4d21f91999-01-24Mirar (Pontus Hagland) 
415c0f1999-01-22Mirar (Pontus Hagland) static void make_colors(void) {
5e94231999-01-23Mirar (Pontus Hagland)  static struct color { int r,g,b; char *name; struct pike_string *pname; } c[]={
415c0f1999-01-22Mirar (Pontus Hagland) #define COLOR(name,R,G,B) \
5e94231999-01-23Mirar (Pontus Hagland)  {R,G,B,name,NULL},
415c0f1999-01-22Mirar (Pontus Hagland) #include "colors.h" #undef COLOR
5e94231999-01-23Mirar (Pontus Hagland)  }; int i; const int n=sizeof(c)/sizeof(c[0]);
415c0f1999-01-22Mirar (Pontus Hagland) 
4d21f91999-01-24Mirar (Pontus Hagland)  for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++) html_color[i].pname=make_shared_string(html_color[i].name);
5e94231999-01-23Mirar (Pontus Hagland)  for (i=0;i<n;i++) {
e405f01999-01-24Mirar (Pontus Hagland)  struct color_struct *cs;
5e94231999-01-23Mirar (Pontus Hagland)  push_text(c[i].name); copy_shared_string(c[i].pname,sp[-1].u.string);
e405f01999-01-24Mirar (Pontus Hagland) 
13670c2015-05-25Martin Nilsson  push_object(clone_object(image_color_program,0));
13b5ed2014-05-26Per Hedbor  cs=get_storage(sp[-1].u.object,image_color_program);
e405f01999-01-24Mirar (Pontus Hagland)  cs->rgb.r=(COLORTYPE)c[i].r; cs->rgb.g=(COLORTYPE)c[i].g; cs->rgb.b=(COLORTYPE)c[i].b;
cded6a1999-01-26Mirar (Pontus Hagland)  RGB_TO_RGBL(cs->rgbl,cs->rgb);
e405f01999-01-24Mirar (Pontus Hagland)  copy_shared_string(cs->name,c[i].pname);
5e94231999-01-23Mirar (Pontus Hagland)  }
415c0f1999-01-22Mirar (Pontus Hagland)  f_aggregate_mapping(n*2); colors=sp[-1].u.mapping; sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
415c0f1999-01-22Mirar (Pontus Hagland) 
5e94231999-01-23Mirar (Pontus Hagland)  for (i=0;i<n;i++) { push_int(c[i].r); push_int(c[i].g); push_int(c[i].b); f_aggregate(3); }
415c0f1999-01-22Mirar (Pontus Hagland)  f_aggregate(n); colortable=clone_object(image_colortable_program,1);
7a49a11999-04-10Mirar (Pontus Hagland)  if (!colortable)
5aad932002-08-15Marcus Comstedt  Pike_fatal("couldn't create colortable\n");
415c0f1999-01-22Mirar (Pontus Hagland) 
7a49a11999-04-10Mirar (Pontus Hagland)  push_int(12); push_int(12); push_int(12);
415c0f1999-01-22Mirar (Pontus Hagland)  push_int(1); safe_apply(colortable,"cubicles",4); pop_stack();
5e94231999-01-23Mirar (Pontus Hagland)  for (i=0;i<n;i++) push_string(c[i].pname); f_aggregate(n);
415c0f1999-01-22Mirar (Pontus Hagland)  colornames=sp[-1].u.array; sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
415c0f1999-01-22Mirar (Pontus Hagland) } #ifdef THIS #undef THIS /* Needed for NT */ #endif
39221e2000-07-07Henrik Grubbström (Grubba) #define THIS ((struct color_struct*)(Pike_fp->current_storage)) #define THISOBJ (Pike_fp->current_object)
415c0f1999-01-22Mirar (Pontus Hagland) 
74dfe82012-12-30Jonas Walldén static void init_color_struct(struct object *UNUSED(dummy))
415c0f1999-01-22Mirar (Pontus Hagland) { THIS->rgb.r=THIS->rgb.g=THIS->rgb.b=0; THIS->name=NULL; }
74dfe82012-12-30Jonas Walldén static void exit_color_struct(struct object *UNUSED(dummy))
415c0f1999-01-22Mirar (Pontus Hagland) {
13670c2015-05-25Martin Nilsson  if (THIS->name)
415c0f1999-01-22Mirar (Pontus Hagland)  { free_string(THIS->name); THIS->name=NULL; } }
7a49a11999-04-10Mirar (Pontus Hagland) void _img_nct_map_to_flat_cubicles(rgb_group *s, rgb_group *d, int n, struct neo_colortable *nct, struct nct_dither *dith, int rowlen);
e405f01999-01-24Mirar (Pontus Hagland) static void try_find_name(struct color_struct *this)
415c0f1999-01-22Mirar (Pontus Hagland) { rgb_group d;
2d83c12001-07-01Martin Stjernholm  static struct nct_dither dith = { NCTD_NONE,NULL,NULL,NULL,NULL,-1, {{NULL,NULL,0.0,0.0,0.0,0.0,0,0}}, /* Only to avoid warnings. */ };
415c0f1999-01-22Mirar (Pontus Hagland)  if (!colors) make_colors();
13670c2015-05-25Martin Nilsson  if (this->name)
5aad932002-08-15Marcus Comstedt  Pike_fatal("try_find_name called twice\n");
415c0f1999-01-22Mirar (Pontus Hagland) 
cded6a1999-01-26Mirar (Pontus Hagland)  if (this->rgbl.r!=COLOR_TO_COLORL(this->rgb.r) || this->rgbl.g!=COLOR_TO_COLORL(this->rgb.g) || this->rgbl.b!=COLOR_TO_COLORL(this->rgb.b))
7a49a11999-04-10Mirar (Pontus Hagland)  { copy_shared_string(this->name,no_name);
13670c2015-05-25Martin Nilsson  return;
7a49a11999-04-10Mirar (Pontus Hagland)  }
cded6a1999-01-26Mirar (Pontus Hagland) 
7a49a11999-04-10Mirar (Pontus Hagland)  _img_nct_map_to_flat_cubicles(&(this->rgb),&d,1, (struct neo_colortable*)colortable->storage, &dith,1);
13670c2015-05-25Martin Nilsson 
e405f01999-01-24Mirar (Pontus Hagland)  if (d.r==this->rgb.r && d.g==this->rgb.g && d.b==this->rgb.b)
415c0f1999-01-22Mirar (Pontus Hagland)  { unsigned short d2; image_colortable_index_16bit_image( (struct neo_colortable*)colortable->storage,
e405f01999-01-24Mirar (Pontus Hagland)  &(this->rgb),&d2,1,1);
415c0f1999-01-22Mirar (Pontus Hagland)  if (d2<colornames->size) {
e405f01999-01-24Mirar (Pontus Hagland)  copy_shared_string(this->name,
415c0f1999-01-22Mirar (Pontus Hagland)  colornames->item[d2].u.string);
7a49a11999-04-10Mirar (Pontus Hagland)  return;
415c0f1999-01-22Mirar (Pontus Hagland)  } }
7a49a11999-04-10Mirar (Pontus Hagland)  copy_shared_string(this->name,no_name);
415c0f1999-01-22Mirar (Pontus Hagland) }
5e94231999-01-23Mirar (Pontus Hagland) /* **! method void create(int r,int g,int b)
448c201999-04-13Mirar (Pontus Hagland) **! This is the main <ref>Image.Color.Color</ref> creation
13670c2015-05-25Martin Nilsson **! method, mostly for internal use.
5e94231999-01-23Mirar (Pontus Hagland) **----- internal note: it takes a fourth argument, name of color --- **! */ /* **! method array(int) rgb()
16602f2001-11-07Martin Nilsson **! method array(float) rgbf()
5e94231999-01-23Mirar (Pontus Hagland) **! method array(int) hsv()
16602f2001-11-07Martin Nilsson **! method array(float) hsvf() **! method array(float) cmyk()
5e94231999-01-23Mirar (Pontus Hagland) **! method int greylevel() **! method int greylevel(int r, int g, int b) **! This is methods of getting information from an
13670c2015-05-25Martin Nilsson **! <ref>Image.Color.Color</ref> object. **! **! They give an array of
2f5efe1999-01-24Mirar (Pontus Hagland) **! red, green and blue (rgb) values (color value),<br> **! hue, saturation and value (hsv) values (range as color value), <br> **! cyan, magenta, yellow, black (cmyk) values (in percent) <br>
13670c2015-05-25Martin Nilsson **! or the greylevel value (range as color value).
5e94231999-01-23Mirar (Pontus Hagland) **! **! The greylevel is calculated by weighting red, green
13670c2015-05-25Martin Nilsson **! and blue. Default weights are 87, 127 and 41, respective,
5e94231999-01-23Mirar (Pontus Hagland) **! and could be given by argument. **! **! returns array(int) respective int
448c201999-04-13Mirar (Pontus Hagland) **! see also: Image.Color.Color, grey
5e94231999-01-23Mirar (Pontus Hagland) */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_rgb(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) { pop_n_elems(args); push_int(THIS->rgb.r); push_int(THIS->rgb.g); push_int(THIS->rgb.b); f_aggregate(3); }
7a49a11999-04-10Mirar (Pontus Hagland) static void image_color_rgbf(INT32 args) { pop_n_elems(args); push_float(COLORL_TO_FLOAT(THIS->rgbl.r)); push_float(COLORL_TO_FLOAT(THIS->rgbl.g)); push_float(COLORL_TO_FLOAT(THIS->rgbl.b)); f_aggregate(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_greylevel(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) {
65a5492000-08-10Per Hedbor  INT_TYPE r,g,b;
5e94231999-01-23Mirar (Pontus Hagland)  if (args==0) { r=87; g=127; b=41; } else {
69c0aa2014-08-25Martin Nilsson  get_all_args("greylevel",args,"%i%i%i",&r,&g,&b);
5e94231999-01-23Mirar (Pontus Hagland)  } pop_n_elems(args); if (r+g+b==0) r=g=b=1; push_int((r*THIS->rgb.r+g*THIS->rgb.g+b*THIS->rgb.b)/(r+g+b)); } #define MAX3(X,Y,Z) MAXIMUM(MAXIMUM(X,Y),Z)
4f45891999-05-20Mirar (Pontus Hagland) #define MIN3(X,Y,Z) MINIMUM(MINIMUM(X,Y),Z)
5e94231999-01-23Mirar (Pontus Hagland) 
cded6a1999-01-26Mirar (Pontus Hagland) static void image_color_hsvf(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) {
4e73012000-08-09Henrik Grubbström (Grubba)  double max, min; double r,g,b, delta;
36a00c2000-08-15Henrik Grubbström (Grubba)  double h, s = 0.0, v;
5e94231999-01-23Mirar (Pontus Hagland)  pop_n_elems(args);
13670c2015-05-25Martin Nilsson  if((THIS->rgb.r==THIS->rgb.g) && (THIS->rgb.g==THIS->rgb.b))
5e94231999-01-23Mirar (Pontus Hagland)  {
4f45891999-05-20Mirar (Pontus Hagland)  push_float(0.0); push_float(0.0);
cded6a1999-01-26Mirar (Pontus Hagland)  push_float(COLORL_TO_FLOAT(THIS->rgbl.r));
5e94231999-01-23Mirar (Pontus Hagland)  f_aggregate(3); return; }
13670c2015-05-25Martin Nilsson 
cded6a1999-01-26Mirar (Pontus Hagland)  r = COLORL_TO_FLOAT(THIS->rgbl.r); g = COLORL_TO_FLOAT(THIS->rgbl.g); b = COLORL_TO_FLOAT(THIS->rgbl.b);
4f45891999-05-20Mirar (Pontus Hagland) 
5e94231999-01-23Mirar (Pontus Hagland)  max = MAX3(r,g,b);
4f45891999-05-20Mirar (Pontus Hagland)  min = MIN3(r,g,b);
5e94231999-01-23Mirar (Pontus Hagland)  v = max; if(max != 0.0) s = (max - min)/max; else
a4a1722000-12-05Per Hedbor  Pike_error("internal error, max==0.0\n");
5e94231999-01-23Mirar (Pontus Hagland)  delta = max-min; if(r==max) h = (g-b)/delta; else if(g==max) h = 2+(b-r)/delta; else /*if(b==max)*/ h = 4+(r-g)/delta;
b411f71999-04-25Henrik Grubbström (Grubba)  h *= 60; /* now in degrees. */
5e94231999-01-23Mirar (Pontus Hagland)  if(h<0) h+=360;
cc7cf42015-10-14Martin Nilsson  push_float((FLOAT_TYPE)h); push_float((FLOAT_TYPE)s); push_float((FLOAT_TYPE)v);
cded6a1999-01-26Mirar (Pontus Hagland)  f_aggregate(3); }
8ab20f2016-02-12Martin Nilsson #define FLOAT_TO_COLOR(X) ((COLORTYPE)((X)*((float)COLORMAX+0.4)))
cded6a1999-01-26Mirar (Pontus Hagland) static void image_color_hsv(INT32 args) {
4e73012000-08-09Henrik Grubbström (Grubba)  double h,s,v;
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(args); h=sp[-1].u.array->item[0].u.float_number; s=sp[-1].u.array->item[1].u.float_number; v=sp[-1].u.array->item[2].u.float_number; pop_stack(); push_int(FLOAT_TO_COLOR(h/360.0)); push_int(FLOAT_TO_COLOR(s)); push_int(FLOAT_TO_COLOR(v));
5e94231999-01-23Mirar (Pontus Hagland)  f_aggregate(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_cmyk(INT32 args)
2f5efe1999-01-24Mirar (Pontus Hagland) {
4e73012000-08-09Henrik Grubbström (Grubba)  double c,m,y,k; double r,g,b;
2f5efe1999-01-24Mirar (Pontus Hagland)  pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  r=COLORL_TO_FLOAT(THIS->rgbl.r); g=COLORL_TO_FLOAT(THIS->rgbl.g); b=COLORL_TO_FLOAT(THIS->rgbl.b); k=1.0-MAX3(r,g,b);
2f5efe1999-01-24Mirar (Pontus Hagland) 
cded6a1999-01-26Mirar (Pontus Hagland)  c=1.0-r-k; m=1.0-g-k; y=1.0-b-k;
2f5efe1999-01-24Mirar (Pontus Hagland) 
cc7cf42015-10-14Martin Nilsson  push_float((FLOAT_TYPE)(c*100.0)); push_float((FLOAT_TYPE)(m*100.0)); push_float((FLOAT_TYPE)(y*100.0)); push_float((FLOAT_TYPE)(k*100.0));
2f5efe1999-01-24Mirar (Pontus Hagland)  f_aggregate(4); }
5e94231999-01-23Mirar (Pontus Hagland) /* **! method object grey() **! method object grey(int red,int green,int blue) **! Gives a new color, containing a grey color, **! which is calculated by the <ref>greylevel</ref> method.
448c201999-04-13Mirar (Pontus Hagland) **! returns a new <ref>Image.Color.Color</ref> object
5e94231999-01-23Mirar (Pontus Hagland) **! see also: greylevel */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_grey(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { image_color_greylevel(args); stack_dup(); stack_dup();
e405f01999-01-24Mirar (Pontus Hagland)  image_make_rgb_color(3);
5e94231999-01-23Mirar (Pontus Hagland) }
bf57c82000-09-10Per Hedbor /* **! method int bits( int rbits, int gbits, int bbits, int rshift, int gshift, int bshift )
3ed9d92002-06-05Johan Sundström **! Returns the color as an integer. The first three parameters state how **! many bits to use for red, green and blue respectively. The last three **! state how many bits each colour should be shifted. For instance, **! <tt>Image.Color("#AABBCC")-&gt;bits(8, 8, 8, 16, 8, 0)</tt> returns **! the integer 11189196, that is, 0xAABBCC.
bf57c82000-09-10Per Hedbor */ static void image_color_bits( INT32 args ) { INT_TYPE rb, gb, bb, rs, gs, bs;
a92ad62003-10-13Henrik Grubbström (Grubba)  get_all_args( "bits", args, "%i%i%i%i%i%i", &rb,&gb,&bb, &rs, &gs, &bs );
bf57c82000-09-10Per Hedbor  pop_n_elems( args ); /* Do it on the stack to support bignums (it's possible to get 2M * bits for each channel this way. Not that that's really useful,
13670c2015-05-25Martin Nilsson  * but...
bf57c82000-09-10Per Hedbor  */ #define push_int_bits( i, b, s ) \ if( b <= 31 ) \ { \ push_int( i ); \ push_int( 31-b ); \ f_rsh( 2 ); \ push_int( s ); \ f_lsh( 2 ); \ } \ else \ { \ int _b = b; \ int _i = i; \ push_int( 0 ); \ while( _b > -31 ) \ { \ push_int( _i ); \ if( _b > 0 ) \ { \ push_int( _b ); \ f_lsh( 2 ); \ } else { \ push_int( -_b ); \ f_rsh( 2 ); \ } \ f_or( 2 ); \ _b -= 31; \ } \ push_int( s ); \ f_lsh( 2 ); \ } push_int_bits( THIS->rgbl.r, rb, rs ); push_int_bits( THIS->rgbl.g, gb, gs ); push_int_bits( THIS->rgbl.b, bb, bs ); f_or( 2 ); f_or( 2 ); }
5e94231999-01-23Mirar (Pontus Hagland) /*
4d21f91999-01-24Mirar (Pontus Hagland) **! method string hex() **! method string hex(int n)
5e94231999-01-23Mirar (Pontus Hagland) **! method string name()
4d21f91999-01-24Mirar (Pontus Hagland) **! method string html() **! Information methods. **! **! <ref>hex</ref>() simply gives a string on the <tt>#rrggbb</tt> **! format. If <tt>n</tt> is given, the number of significant
13670c2015-05-25Martin Nilsson **! digits is set to this number.
4d21f91999-01-24Mirar (Pontus Hagland) **! (Ie, <tt>n=3</tt> gives <tt>#rrrgggbbb</tt>.) **!
13670c2015-05-25Martin Nilsson **! <ref>name</ref>() is a simplified method;
4d21f91999-01-24Mirar (Pontus Hagland) **! if the color exists in the database, the name is returned, **! per default is the <ref>hex</ref>() method use. **!
13670c2015-05-25Martin Nilsson **! <ref>html</ref>() gives the <tt>HTML</tt> name of
4d21f91999-01-24Mirar (Pontus Hagland) **! the color, or the <ref>hex</ref>(2) if it isn't one **! of the 16 <tt>HTML</tt> colors. **!
448c201999-04-13Mirar (Pontus Hagland) **! returns a new <ref>Image.Color.Color</ref> object **! see also: rgb, hsv, Image.Color
5e94231999-01-23Mirar (Pontus Hagland) */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_hex(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) {
4d21f91999-01-24Mirar (Pontus Hagland)  char buf[80];
65a5492000-08-10Per Hedbor  INT_TYPE i=sizeof(COLORTYPE)*2;
4d21f91999-01-24Mirar (Pontus Hagland)  if (args)
69c0aa2014-08-25Martin Nilsson  get_all_args("hex",args,"%i",&i);
4d21f91999-01-24Mirar (Pontus Hagland)  pop_n_elems(args); if (i<1)
415c0f1999-01-22Mirar (Pontus Hagland)  {
5e9fc02015-08-18Per Hedbor  push_static_text("#"); /* stupid */
4d21f91999-01-24Mirar (Pontus Hagland)  return;
415c0f1999-01-22Mirar (Pontus Hagland)  }
4d21f91999-01-24Mirar (Pontus Hagland)  else if (i!=sizeof(COLORTYPE)*2)
415c0f1999-01-22Mirar (Pontus Hagland)  {
8b31a92000-08-11Henrik Grubbström (Grubba)  ptrdiff_t sh;
4d21f91999-01-24Mirar (Pontus Hagland)  if (i>8) i=8; sh=4*(sizeof(COLORTYPE)*2-i); if (sh>0)
18099a2001-03-04Mirar (Pontus Hagland)  sprintf(buf,"#%0*x%0*x%0*x", (int)i,(unsigned)(THIS->rgb.r>>sh), (int)i,(unsigned)(THIS->rgb.g>>sh),
13670c2015-05-25Martin Nilsson  (int)i,(unsigned)(THIS->rgb.b>>sh));
4d21f91999-01-24Mirar (Pontus Hagland)  else {
cded6a1999-01-26Mirar (Pontus Hagland)  unsigned INT32 r=THIS->rgbl.r; unsigned INT32 g=THIS->rgbl.g; unsigned INT32 b=THIS->rgbl.b; sh=COLORLBITS-i*4;
13670c2015-05-25Martin Nilsson  if (sh<0)
cded6a1999-01-26Mirar (Pontus Hagland)  { r=(r<<-sh)+(r>>(COLORLBITS+sh)); g=(g<<-sh)+(g>>(COLORLBITS+sh)); b=(b<<-sh)+(b>>(COLORLBITS+sh)); sh=0; } sprintf(buf,"#%0*x%0*x%0*x",
18099a2001-03-04Mirar (Pontus Hagland)  (int)i,(unsigned)(r>>sh), (int)i,(unsigned)(g>>sh), (int)i,(unsigned)(b>>sh));
4d21f91999-01-24Mirar (Pontus Hagland)  } } else
cded6a1999-01-26Mirar (Pontus Hagland)  switch (sizeof(COLORTYPE)) /* constant */
415c0f1999-01-22Mirar (Pontus Hagland)  {
13670c2015-05-25Martin Nilsson  case 1: sprintf(buf,"#%02x%02x%02x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);
415c0f1999-01-22Mirar (Pontus Hagland)  break;
13670c2015-05-25Martin Nilsson  case 2: sprintf(buf,"#%04x%04x%04x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);
415c0f1999-01-22Mirar (Pontus Hagland)  break;
13670c2015-05-25Martin Nilsson  case 4: sprintf(buf,"#%08x%08x%08x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);
415c0f1999-01-22Mirar (Pontus Hagland)  break;
4d21f91999-01-24Mirar (Pontus Hagland)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("unknown size of colortype\n");
415c0f1999-01-22Mirar (Pontus Hagland)  }
4d21f91999-01-24Mirar (Pontus Hagland)  push_text(buf); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_html(INT32 args)
4d21f91999-01-24Mirar (Pontus Hagland) { int i; if (!colors) make_colors(); pop_n_elems(args); for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++)
13670c2015-05-25Martin Nilsson  if (THIS->rgb.r==html_color[i].r && THIS->rgb.g==html_color[i].g &&
4d21f91999-01-24Mirar (Pontus Hagland)  THIS->rgb.b==html_color[i].b) { ref_push_string(html_color[i].pname); return; }
13670c2015-05-25Martin Nilsson  push_int(2);
4d21f91999-01-24Mirar (Pontus Hagland)  image_color_hex(1); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_name(INT32 args)
4d21f91999-01-24Mirar (Pontus Hagland) { pop_n_elems(args);
7a49a11999-04-10Mirar (Pontus Hagland)  if (!THIS->name) try_find_name(THIS); if (THIS->name==no_name)
4d21f91999-01-24Mirar (Pontus Hagland)  image_color_hex(0);
7a49a11999-04-10Mirar (Pontus Hagland)  else ref_push_string(THIS->name);
415c0f1999-01-22Mirar (Pontus Hagland) }
5e94231999-01-23Mirar (Pontus Hagland) /* **! method array|string cast() **! cast the object to an array, representing red, green **! and blue (equal to <tt>-><ref>rgb</ref>()</tt>), or **! to a string, giving the name (equal to <tt>-><ref>name</ref>()</tt>). **! returns the name as string or rgb as array **! see also: rgb, name */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_cast(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) { if (args!=1 ||
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(sp[-1]) != T_STRING)
de22f72014-08-25Martin Nilsson  bad_arg_error("cast",sp-args,args,0,"",sp-args, "Bad arguments to cast.\n");
13670c2015-05-25Martin Nilsson 
68ec3f2014-08-18Martin Nilsson  if (sp[-1].u.string==literal_array_string)
415c0f1999-01-22Mirar (Pontus Hagland)  { image_color_rgb(args); return; }
68ec3f2014-08-18Martin Nilsson  if (sp[-1].u.string==literal_string_string)
415c0f1999-01-22Mirar (Pontus Hagland)  { image_color_name(args); return; }
68ec3f2014-08-18Martin Nilsson  if (sp[-1].u.string==literal_int_string)
0caad52011-04-08Martin Nilsson  { pop_stack(); push_int( (THIS->rgb.r << 8 | THIS->rgb.g) << 8 | THIS->rgb.b ); return; }
68ec3f2014-08-18Martin Nilsson  pop_stack(); push_undefined();
415c0f1999-01-22Mirar (Pontus Hagland) }
d99dbe1999-10-21Mirar (Pontus Hagland) static void image_color__sprintf(INT32 args) {
f034872001-07-12Henrik Grubbström (Grubba)  int prec,x;
d99dbe1999-10-21Mirar (Pontus Hagland)  if (args<2)
06bd612016-01-26Martin Nilsson  SIMPLE_WRONG_NUM_ARGS_ERROR("_sprintf",2);
d99dbe1999-10-21Mirar (Pontus Hagland) 
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-args]) != T_INT)
f982742016-01-26Martin Nilsson  SIMPLE_ARG_TYPE_ERROR("_sprintf",0,"int");
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[1-args]) != T_MAPPING)
f982742016-01-26Martin Nilsson  SIMPLE_ARG_TYPE_ERROR("_sprintf",1,"mapping");
d99dbe1999-10-21Mirar (Pontus Hagland)  pop_n_elems(args-2);
5e9fc02015-08-18Per Hedbor  push_static_text("precision");
d99dbe1999-10-21Mirar (Pontus Hagland)  f_index(2);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) != T_INT)
f982742016-01-26Martin Nilsson  SIMPLE_ARG_TYPE_ERROR("_sprintf",1,"mapping(\"precision\":int)");
d99dbe1999-10-21Mirar (Pontus Hagland)  prec=sp[-1].u.integer; x=sp[-2].u.integer; pop_n_elems(2); switch (x) { /* case 'c': */ /* case 'd': */ case 't':
5e9fc02015-08-18Per Hedbor  push_static_text("Image.Color.Color");
d99dbe1999-10-21Mirar (Pontus Hagland)  return; case 'O': if (!THIS->name) try_find_name(THIS); if (THIS->name==no_name) {
5e9fc02015-08-18Per Hedbor  push_static_text("Image.Color(\"");
d99dbe1999-10-21Mirar (Pontus Hagland)  if (prec) { push_int(prec); image_color_hex(1); } else image_color_hex(0);
5e9fc02015-08-18Per Hedbor  push_static_text("\")");
d99dbe1999-10-21Mirar (Pontus Hagland)  f_add(3); return; } else {
5e9fc02015-08-18Per Hedbor  push_static_text("Image.Color.");
d99dbe1999-10-21Mirar (Pontus Hagland)  ref_push_string(THIS->name); f_add(2); return; } break; case 's': if (prec) { push_int(prec); image_color_name(1); } else image_color_name(0); return; case 'x': if (prec) { push_int(prec); image_color_hex(1); } else image_color_hex(0);
0c49391999-12-06Mirar (Pontus Hagland)  push_int(1); push_int(0x7ffff); /* a lot */ f_index(3); /* remove the '#' */
d99dbe1999-10-21Mirar (Pontus Hagland)  return; default: push_int(0); return; } }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_index(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) {
5e94231999-01-23Mirar (Pontus Hagland)  struct svalue s; if (args!=1)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Image.Color[]: illegal number of arguments\n");
5e94231999-01-23Mirar (Pontus Hagland) 
9273742008-05-29Henrik Grubbström (Grubba)  object_index_no_free2(&s, THISOBJ, 0, sp-1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(s) == T_INT && TYPEOF(sp[-1]) == T_STRING)
5e94231999-01-23Mirar (Pontus Hagland)  { if (sp[-1].u.string==str_r) { pop_stack(); push_int(THIS->rgb.r); return; } if (sp[-1].u.string==str_g) { pop_stack(); push_int(THIS->rgb.g); return; } if (sp[-1].u.string==str_b) { pop_stack(); push_int(THIS->rgb.b); return; } if (sp[-1].u.string==str_h) { pop_stack(); image_color_hsv(0); push_int(0); f_index(2); return; } if (sp[-1].u.string==str_s) { pop_stack(); image_color_hsv(0); push_int(1); f_index(2); return; } if (sp[-1].u.string==str_v) { pop_stack(); image_color_hsv(0); push_int(2); f_index(2); return; } } pop_stack(); *(sp++)=s; } /*
4d21f91999-01-24Mirar (Pontus Hagland) **! method int `==(object other_color) **! method int `==(array(int) rgb) **! method int `==(int greylevel) **! method int `==(string name) **! Compares this object to another color, **! or color name. Example: **! <pre>
448c201999-04-13Mirar (Pontus Hagland) **! object red=Image.Color.red; **! object other=Image.Color. ...; **! object black=Image.Color.black;
13670c2015-05-25Martin Nilsson **!
4d21f91999-01-24Mirar (Pontus Hagland) **! if (red==other) ... **! if (red==({255,0,0})) ...
13670c2015-05-25Martin Nilsson **! if (black==0) ...
4d21f91999-01-24Mirar (Pontus Hagland) **! if (red=="red") ... **! </pre> **! **! returns 1 or 0 **! see also: rgb, grey, name **! note: **! The other datatype (not color object) must be to the right!
5e94231999-01-23Mirar (Pontus Hagland) */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_equal(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) {
13670c2015-05-25Martin Nilsson  if (args!=1)
6de0852004-01-23Martin Nilsson  Pike_error("Image.Color.Color->`==: illegal number of arguments\n");
5e94231999-01-23Mirar (Pontus Hagland) 
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_OBJECT)
5e94231999-01-23Mirar (Pontus Hagland)  { struct color_struct *other;
13b5ed2014-05-26Per Hedbor  other=get_storage(sp[-1].u.object,image_color_program);
5e94231999-01-23Mirar (Pontus Hagland)  if (other&&
cded6a1999-01-26Mirar (Pontus Hagland)  other->rgbl.r==THIS->rgbl.r && other->rgbl.g==THIS->rgbl.g && other->rgbl.b==THIS->rgbl.b)
5e94231999-01-23Mirar (Pontus Hagland)  { pop_stack(); push_int(1); return; } }
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(sp[-1]) == T_ARRAY)
5e94231999-01-23Mirar (Pontus Hagland)  { if (sp[-1].u.array->size==3 &&
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(sp[-1].u.array->item[0]) == T_INT && TYPEOF(sp[-1].u.array->item[1]) == T_INT && TYPEOF(sp[-1].u.array->item[2]) == T_INT &&
5e94231999-01-23Mirar (Pontus Hagland)  sp[-1].u.array->item[0].u.integer == THIS->rgb.r &&
9226111999-05-24Mirar (Pontus Hagland)  sp[-1].u.array->item[1].u.integer == THIS->rgb.g && sp[-1].u.array->item[2].u.integer == THIS->rgb.b)
5e94231999-01-23Mirar (Pontus Hagland)  { pop_stack(); push_int(1); return; } }
017b572011-10-28Henrik Grubbström (Grubba) /* else if (TYPEOF(sp[-1]) == T_INT) */
24a1e02005-03-15Per Hedbor /* { */ /* if (sp[-1].u.integer == THIS->rgb.r && */ /* THIS->rgb.r==THIS->rgb.g && */ /* THIS->rgb.r==THIS->rgb.b) */ /* { */ /* pop_stack(); */ /* push_int(1); */ /* return; */ /* } */ /* } */
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(sp[-1]) == T_STRING)
4d21f91999-01-24Mirar (Pontus Hagland)  {
7a49a11999-04-10Mirar (Pontus Hagland)  if (!THIS->name) try_find_name(THIS); if (sp[-1].u.string==THIS->name && THIS->name!=no_name)
4d21f91999-01-24Mirar (Pontus Hagland)  { pop_stack(); push_int(1); return; } }
5e94231999-01-23Mirar (Pontus Hagland)  pop_stack(); push_int(0); }
2d87fb1999-04-12Mirar (Pontus Hagland) static void image_color___hash(INT32 args) { pop_n_elems(args); push_int(((THIS->rgb.r<<16)+(THIS->rgb.g<<8)+THIS->rgb.b) +(THIS->rgbl.r+THIS->rgbl.g+THIS->rgbl.b)); }
5e94231999-01-23Mirar (Pontus Hagland) 
4d21f91999-01-24Mirar (Pontus Hagland) /* **! method object light() **! method object dark() **! method object neon() **! method object bright() **! method object dull() **! Color modification methods. These returns **! a new color. **! <table> **! <tr><th>method</th><th width=50%>effect</th> **! <th>h</th><th>s</th><th>v</th><th>as</th></tr>
7428421999-01-24Mirar (Pontus Hagland) **! <tr><td>light </td><td>raise light level</td><td>±0</td><td> ±0</td><td>+50</td>
c56e7d2001-07-18Martin Nilsson **! <td><illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"])</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->light())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->light()->light())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->light()->light()->light())</illustration></td></tr>
4d21f91999-01-24Mirar (Pontus Hagland) **!
7428421999-01-24Mirar (Pontus Hagland) **! <tr><td>dark </td><td>lower light level</td><td>±0</td><td> ±0</td><td>-50</td>
c56e7d2001-07-18Martin Nilsson **! <td><illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"])</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->dark())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->dark()->dark())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->dark()->dark()->dark())</illustration></td></tr>
4d21f91999-01-24Mirar (Pontus Hagland) **!
7428421999-01-24Mirar (Pontus Hagland) **! <tr><td>bright</td><td>brighter color </td><td>±0</td><td>+50</td><td>+50</td>
c56e7d2001-07-18Martin Nilsson **! <td><illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"])</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->bright())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->bright()->bright())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->bright()->bright()->bright())</illustration></td></tr>
4d21f91999-01-24Mirar (Pontus Hagland) **!
7428421999-01-24Mirar (Pontus Hagland) **! <tr><td>dull </td><td>greyer color </td><td>±0</td><td>-50</td><td>-50</td>
c56e7d2001-07-18Martin Nilsson **! <td><illustration>return Image.Image(20,20,@(array)Image.Color.red)</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color.red->dull())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color.red->dull()->dull())</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color.red->dull()->dull()->dull())</illustration></td></tr>
4d21f91999-01-24Mirar (Pontus Hagland) **!
7428421999-01-24Mirar (Pontus Hagland) **! <tr><td>neon </td><td>set to extreme </td><td>±0</td><td>max</td><td>max</td>
c56e7d2001-07-18Martin Nilsson **! <td><illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"])</illustration> **! <illustration>return Image.Image(20,20,@(array)Image.Color["#693e3e"]->neon())</illustration></td></tr>
4d21f91999-01-24Mirar (Pontus Hagland) **! **! </table>
4f45891999-05-20Mirar (Pontus Hagland) **! **! <ref>light</ref> and <ref>dark</ref> lower/highers saturation **! when value is min-/maximised respective. **!
4d21f91999-01-24Mirar (Pontus Hagland) **! returns the new color object **! note: **! The opposites may not always take each other out. **! The color is maximised at white and black levels,
13670c2015-05-25Martin Nilsson **! so, for instance
448c201999-04-13Mirar (Pontus Hagland) **! <ref>Image.Color</ref>.white-><ref>light</ref>()-><ref>dark</ref>()
4d21f91999-01-24Mirar (Pontus Hagland) **! doesn't give the white color back, but the equal to
448c201999-04-13Mirar (Pontus Hagland) **! <ref>Image.Color</ref>.white-><ref>dark</ref>(), since
4d21f91999-01-24Mirar (Pontus Hagland) **! white can't get any <ref>light</ref>er. */
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_light(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(0);
5e94231999-01-23Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5e94231999-01-23Mirar (Pontus Hagland)  push_array_items(sp->u.array); /* frees */
cc7cf42015-10-14Martin Nilsson  sp[-1].u.float_number += (FLOAT_TYPE)0.2;
9e3e5a2001-09-24Henrik Grubbström (Grubba)  if (((double)sp[-1].u.float_number) >= 1.0)
cc7cf42015-10-14Martin Nilsson  sp[-2].u.float_number -= (FLOAT_TYPE)(sp[-1].u.float_number - 1.0);
4f45891999-05-20Mirar (Pontus Hagland) 
5e94231999-01-23Mirar (Pontus Hagland)  image_make_hsv_color(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_dark(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(0);
5e94231999-01-23Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5e94231999-01-23Mirar (Pontus Hagland)  push_array_items(sp->u.array); /* frees */
cded6a1999-01-26Mirar (Pontus Hagland)  sp[-1].u.float_number-=0.2;
4f45891999-05-20Mirar (Pontus Hagland)  if (sp[-1].u.float_number<0.0) sp[-2].u.float_number-=sp[-1].u.float_number;
5e94231999-01-23Mirar (Pontus Hagland)  image_make_hsv_color(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_neon(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(0);
5e94231999-01-23Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5e94231999-01-23Mirar (Pontus Hagland)  push_array_items(sp->u.array); /* frees */
cded6a1999-01-26Mirar (Pontus Hagland)  if (sp[-1].u.float_number==0.0 || sp[-2].u.float_number==0.0) {
2158f21999-07-02Mirar (Pontus Hagland)  if (sp[-1].u.float_number<0.5) sp[-1].u.float_number=0.0;
cded6a1999-01-26Mirar (Pontus Hagland)  else
2158f21999-07-02Mirar (Pontus Hagland)  sp[-1].u.float_number=1.0;
cded6a1999-01-26Mirar (Pontus Hagland)  } else { sp[-1].u.float_number=1.0; sp[-2].u.float_number=1.0; }
5e94231999-01-23Mirar (Pontus Hagland)  image_make_hsv_color(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_dull(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(0);
5e94231999-01-23Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5e94231999-01-23Mirar (Pontus Hagland)  push_array_items(sp->u.array); /* frees */
cded6a1999-01-26Mirar (Pontus Hagland) 
2158f21999-07-02Mirar (Pontus Hagland)  if (sp[-2].u.float_number==0.0)
cded6a1999-01-26Mirar (Pontus Hagland)  {
cc7cf42015-10-14Martin Nilsson  sp[-1].u.float_number -= (FLOAT_TYPE)0.2;
2158f21999-07-02Mirar (Pontus Hagland)  } else {
cc7cf42015-10-14Martin Nilsson  sp[-2].u.float_number -= (FLOAT_TYPE)0.2; sp[-1].u.float_number -= (FLOAT_TYPE)0.2;
cded6a1999-01-26Mirar (Pontus Hagland)  }
5e94231999-01-23Mirar (Pontus Hagland)  image_make_hsv_color(3); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_bright(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) { pop_n_elems(args);
cded6a1999-01-26Mirar (Pontus Hagland)  image_color_hsvf(0);
5e94231999-01-23Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5e94231999-01-23Mirar (Pontus Hagland)  push_array_items(sp->u.array); /* frees */
cded6a1999-01-26Mirar (Pontus Hagland) 
2158f21999-07-02Mirar (Pontus Hagland)  if (sp[-2].u.float_number==0.0)
cded6a1999-01-26Mirar (Pontus Hagland)  {
2158f21999-07-02Mirar (Pontus Hagland)  sp[-1].u.float_number+=0.2; } else { sp[-2].u.float_number+=0.2; sp[-1].u.float_number+=0.2;
cded6a1999-01-26Mirar (Pontus Hagland)  }
5e94231999-01-23Mirar (Pontus Hagland)  image_make_hsv_color(3);
415c0f1999-01-22Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland)  static void image_color_mult(INT32 args) {
65a5492000-08-10Per Hedbor  FLOAT_TYPE x=0.0;
69c0aa2014-08-25Martin Nilsson  get_all_args("`*",args,"%f",&x);
e405f01999-01-24Mirar (Pontus Hagland)  pop_n_elems(args);
04a97d2016-02-12Martin Nilsson  _image_make_rgb_color((int)(THIS->rgb.r*x), (int)(THIS->rgb.g*x), (int)(THIS->rgb.b*x));
e405f01999-01-24Mirar (Pontus Hagland) }
7a49a11999-04-10Mirar (Pontus Hagland) int image_color_svalue(struct svalue *v,rgb_group *rgb)
e405f01999-01-24Mirar (Pontus Hagland) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*v) == T_OBJECT)
e405f01999-01-24Mirar (Pontus Hagland)  {
13b5ed2014-05-26Per Hedbor  struct color_struct *cs=get_storage(v->u.object,image_color_program);
e405f01999-01-24Mirar (Pontus Hagland) 
13670c2015-05-25Martin Nilsson  if (cs)
e405f01999-01-24Mirar (Pontus Hagland)  { *rgb=cs->rgb; return 1; } }
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(*v) == T_ARRAY)
e405f01999-01-24Mirar (Pontus Hagland)  {
7a49a11999-04-10Mirar (Pontus Hagland)  if (v->u.array->size==3 &&
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(v->u.array->item[0]) == T_INT && TYPEOF(v->u.array->item[1]) == T_INT && TYPEOF(v->u.array->item[2]) == T_INT)
e405f01999-01-24Mirar (Pontus Hagland)  {
7a49a11999-04-10Mirar (Pontus Hagland)  rgb->r=(COLORTYPE)(v->u.array->item[0].u.integer); rgb->g=(COLORTYPE)(v->u.array->item[1].u.integer); rgb->b=(COLORTYPE)(v->u.array->item[2].u.integer);
e405f01999-01-24Mirar (Pontus Hagland)  return 1; } }
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(*v) == T_STRING)
e405f01999-01-24Mirar (Pontus Hagland)  {
7a49a11999-04-10Mirar (Pontus Hagland)  push_svalue(v);
e405f01999-01-24Mirar (Pontus Hagland)  image_make_color(1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_OBJECT)
e405f01999-01-24Mirar (Pontus Hagland)  {
13b5ed2014-05-26Per Hedbor  struct color_struct *cs=get_storage(sp[-1].u.object,image_color_program);
e405f01999-01-24Mirar (Pontus Hagland)  *rgb=cs->rgb; pop_stack(); return 1; } pop_stack(); }
cded6a1999-01-26Mirar (Pontus Hagland)  return 0;
e405f01999-01-24Mirar (Pontus Hagland) }
7a49a11999-04-10Mirar (Pontus Hagland) int image_color_arg(INT32 args,rgb_group *rgb) {
4435801999-04-19Mirar (Pontus Hagland)  if (args>=0) return 0; return image_color_svalue(sp+args,rgb);
7a49a11999-04-10Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_color_add(INT32 args) { rgb_group rgb;
4435801999-04-19Mirar (Pontus Hagland)  if (!image_color_arg(-args,&rgb))
f982742016-01-26Martin Nilsson  SIMPLE_ARG_TYPE_ERROR("`+",1,"Image.Color");
e405f01999-01-24Mirar (Pontus Hagland)  pop_n_elems(args); _image_make_rgb_color((int)(THIS->rgb.r+rgb.r), (int)(THIS->rgb.g+rgb.g), (int)(THIS->rgb.b+rgb.b)); }
415c0f1999-01-22Mirar (Pontus Hagland) #define HEXTONUM(C) \ (((C)>='0' && (C)<='9')?(C)-'0': \ ((C)>='a' && (C)<='f')?(C)-'a'+10: \ ((C)>='A' && (C)<='F')?(C)-'A'+10:-1)
e405f01999-01-24Mirar (Pontus Hagland) static void image_get_color(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) { struct svalue s;
4d21f91999-01-24Mirar (Pontus Hagland)  int n;
d9197d2004-09-18Martin Nilsson  static const char *callables[]={"light","dark","neon","dull","bright"};
415c0f1999-01-22Mirar (Pontus Hagland) 
13670c2015-05-25Martin Nilsson  if (args!=1)
6de0852004-01-23Martin Nilsson  Pike_error("Image.Color[]: illegal number of args.\n");
13670c2015-05-25Martin Nilsson 
415c0f1999-01-22Mirar (Pontus Hagland)  if (!colors) make_colors();
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_STRING)
415c0f1999-01-22Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  mapping_index_no_free(&s,colors,sp-1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(s) == T_OBJECT)
5e94231999-01-23Mirar (Pontus Hagland)  { pop_stack(); *(sp++)=s; return; }
53371b1999-05-24Mirar (Pontus Hagland)  else free_svalue(&s); }
5e94231999-01-23Mirar (Pontus Hagland) 
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_STRING &&
53371b1999-05-24Mirar (Pontus Hagland)  sp[-1].u.string->size_shift==0) { if (sp[-1].u.string->len>=4 && sp[-1].u.string->str[0]=='#')
415c0f1999-01-22Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  /* #rgb, #rrggbb, #rrrgggbbb, etc */
13670c2015-05-25Martin Nilsson 
8b31a92000-08-11Henrik Grubbström (Grubba)  size_t i = sp[-1].u.string->len-1, j, k; unsigned INT32 rgb[3];
01a9572000-02-03Henrik Grubbström (Grubba)  unsigned char *src=(unsigned char *)sp[-1].u.string->str+1;
53371b1999-05-24Mirar (Pontus Hagland)  if (!(i%3)) { i/=3; for (j=0; j<3; j++)
415c0f1999-01-22Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  unsigned INT32 z=0; for (k=0; k<i; k++)
415c0f1999-01-22Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  if (HEXTONUM(*src)==-1)
5e94231999-01-23Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  pop_stack();
46b7502011-10-08Henrik Grubbström (Grubba)  push_undefined();
53371b1999-05-24Mirar (Pontus Hagland)  return;
5e94231999-01-23Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  z=z*16+HEXTONUM(*src),src++; } switch (i) { case 1: z=(z*0x11111111)>>(32-COLORLBITS); break; case 2: z=(z*0x01010101)>>(32-COLORLBITS); break; case 3: z=(z*0x00100100+(z>>8))>>(32-COLORLBITS); break; case 4:
13670c2015-05-25Martin Nilsson  case 5: case 6: case 7:
53371b1999-05-24Mirar (Pontus Hagland)  case 8: if (i*4<COLORLBITS) z=(z<<(COLORLBITS-i*4))+(z>>(i*8-COLORLBITS)); else z=z>>(i*4-COLORLBITS); break;
415c0f1999-01-22Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  rgb[j]=z;
5e94231999-01-23Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  pop_n_elems(args); _image_make_rgbl_color((INT32)rgb[0], (INT32)rgb[1], (INT32)rgb[2]); return;
5e94231999-01-23Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  } if (sp[-1].u.string->len>=4 && sp[-1].u.string->str[0]=='@') { /* @h,s,v; h=0..359, s,v=0..100 */ stack_dup();
5e9fc02015-08-18Per Hedbor  push_static_text("@%f,%f,%f\n");
53371b1999-05-24Mirar (Pontus Hagland)  f_sscanf(2);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_ARRAY &&
53371b1999-05-24Mirar (Pontus Hagland)  sp[-1].u.array->size==3)
2f5efe1999-01-24Mirar (Pontus Hagland)  {
65a5492000-08-10Per Hedbor  FLOAT_TYPE h,s,v;
53371b1999-05-24Mirar (Pontus Hagland)  stack_swap();
2f5efe1999-01-24Mirar (Pontus Hagland)  pop_stack();
53371b1999-05-24Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
53371b1999-05-24Mirar (Pontus Hagland)  push_array_items(sp->u.array);
69c0aa2014-08-25Martin Nilsson  get_all_args("create",3,"%f%f%f",&h,&s,&v);
53371b1999-05-24Mirar (Pontus Hagland)  pop_n_elems(3);
04a97d2016-02-12Martin Nilsson  push_int((int)(h/360.0*256.0)); push_int((int)(s/100.0*255.4)); push_int((int)(v/100.0*255.4));
53371b1999-05-24Mirar (Pontus Hagland)  image_make_hsv_color(3); return;
2f5efe1999-01-24Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  pop_stack(); } if (sp[-1].u.string->len>=4 && sp[-1].u.string->str[0]=='%') { /* @c,m,y,k; 0..100 */ stack_dup();
5e9fc02015-08-18Per Hedbor  push_static_text("%%%f,%f,%f,%f\n");
53371b1999-05-24Mirar (Pontus Hagland)  f_sscanf(2);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_ARRAY &&
53371b1999-05-24Mirar (Pontus Hagland)  sp[-1].u.array->size==4)
2f5efe1999-01-24Mirar (Pontus Hagland)  {
53371b1999-05-24Mirar (Pontus Hagland)  stack_swap();
2f5efe1999-01-24Mirar (Pontus Hagland)  pop_stack();
53371b1999-05-24Mirar (Pontus Hagland)  sp--;
01a9572000-02-03Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
53371b1999-05-24Mirar (Pontus Hagland)  push_array_items(sp->u.array); image_make_cmyk_color(4); return;
2f5efe1999-01-24Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  pop_stack(); } for (n=0; (size_t)n<sizeof(callables)/sizeof(callables[0]); n++)
bb7a842000-08-11Henrik Grubbström (Grubba)  if (sp[-1].u.string->len>(ptrdiff_t)strlen(callables[n]) &&
4d21f91999-01-24Mirar (Pontus Hagland)  memcmp(sp[-1].u.string->str,callables[n],strlen(callables[n]))==0)
5e94231999-01-23Mirar (Pontus Hagland)  {
cc7cf42015-10-14Martin Nilsson  push_int((INT32)strlen(callables[n]));
5e94231999-01-23Mirar (Pontus Hagland)  push_int(1000000); f_index(3); image_get_color(1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) != T_OBJECT) return; /* no way */
4d21f91999-01-24Mirar (Pontus Hagland)  safe_apply(sp[-1].u.object,callables[n],0);
5e94231999-01-23Mirar (Pontus Hagland)  stack_swap(); pop_stack();
415c0f1999-01-22Mirar (Pontus Hagland)  return; }
53371b1999-05-24Mirar (Pontus Hagland)  if (sp[-1].u.string->len>=4 && sp[-1].u.string->str[0]=='g') { /* greyx; x=0..99 */ stack_dup();
5e9fc02015-08-18Per Hedbor  push_static_text("gr%*[ea]y%f\n");
53371b1999-05-24Mirar (Pontus Hagland)  f_sscanf(2);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_ARRAY &&
53371b1999-05-24Mirar (Pontus Hagland)  sp[-1].u.array->size==1)
cded6a1999-01-26Mirar (Pontus Hagland)  {
13670c2015-05-25Martin Nilsson  double f;
4e73012000-08-09Henrik Grubbström (Grubba)  f = sp[-1].u.array->item[0].u.float_number;
cded6a1999-01-26Mirar (Pontus Hagland)  pop_stack();
f7f93a2001-01-04Mirar (Pontus Hagland)  pop_stack();
cc7cf42015-10-14Martin Nilsson  push_int( (int)(255*f/100) );
f7f93a2001-01-04Mirar (Pontus Hagland)  /* grey100 is white, grey0 is black */
a4dacc2001-01-03Mirar (Pontus Hagland)  stack_dup(); stack_dup(); image_make_rgb_color(3);
13670c2015-05-25Martin Nilsson 
53371b1999-05-24Mirar (Pontus Hagland)  return;
cded6a1999-01-26Mirar (Pontus Hagland)  }
53371b1999-05-24Mirar (Pontus Hagland)  pop_stack();
415c0f1999-01-22Mirar (Pontus Hagland)  } }
53371b1999-05-24Mirar (Pontus Hagland)  /* try other stuff here */
415c0f1999-01-22Mirar (Pontus Hagland)  pop_stack();
46b7502011-10-08Henrik Grubbström (Grubba)  push_undefined();
53371b1999-05-24Mirar (Pontus Hagland)  return;
415c0f1999-01-22Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_guess_color(INT32 args)
4d21f91999-01-24Mirar (Pontus Hagland) {
13670c2015-05-25Martin Nilsson  if (args!=1 && TYPEOF(sp[-args]) != T_STRING)
de22f72014-08-25Martin Nilsson  bad_arg_error("guess",sp-args,args,0,"",sp-args, "Bad arguments to guess.\n");
13670c2015-05-25Martin Nilsson 
4d21f91999-01-24Mirar (Pontus Hagland)  f_lower_case(1);
5e9fc02015-08-18Per Hedbor  push_static_text(" ");
4d21f91999-01-24Mirar (Pontus Hagland)  o_subtract(); stack_dup(); image_get_color(1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(sp[-1]) == T_OBJECT)
4d21f91999-01-24Mirar (Pontus Hagland)  { stack_swap(); pop_stack(); return; } pop_stack();
5e9fc02015-08-18Per Hedbor  push_static_text("#");
4d21f91999-01-24Mirar (Pontus Hagland)  stack_swap(); f_add(2); image_get_color(1); }
53371b1999-05-24Mirar (Pontus Hagland) static void image_colors_index(INT32 args) { struct svalue s;
9273742008-05-29Henrik Grubbström (Grubba)  object_index_no_free2(&s, THISOBJ, 0, sp-1);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(s) != T_INT)
53371b1999-05-24Mirar (Pontus Hagland)  { pop_stack(); *(sp++)=s; return; } image_get_color(args); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_color(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) {
13670c2015-05-25Martin Nilsson  if (args==1 && TYPEOF(sp[-args]) == T_STRING)
415c0f1999-01-22Mirar (Pontus Hagland)  { image_get_color(args); return; }
e405f01999-01-24Mirar (Pontus Hagland)  image_make_rgb_color(args);
415c0f1999-01-22Mirar (Pontus Hagland) }
4d21f91999-01-24Mirar (Pontus Hagland) 
13670c2015-05-25Martin Nilsson /*
4d21f91999-01-24Mirar (Pontus Hagland) **! module Image
448c201999-04-13Mirar (Pontus Hagland) **! submodule Color
4d21f91999-01-24Mirar (Pontus Hagland) **!
2849652001-07-19Martin Nilsson **! method object guess(string color)
4d21f91999-01-24Mirar (Pontus Hagland) **! This is equivalent to
448c201999-04-13Mirar (Pontus Hagland) **! <tt><ref>Image.Color</ref>(lower_case(str)-" ")</tt>,
13670c2015-05-25Martin Nilsson **! and tries the color with a prepending '#' if no
4d21f91999-01-24Mirar (Pontus Hagland) **! corresponding color is found. **! **! returns a color object or zero_type */ /* **! method object rgb(int red, int green, int blue) **! method object hsv(int hue, int saturation, int value)
2f5efe1999-01-24Mirar (Pontus Hagland) **! method object cmyk(float c,float m,float y,float k)
4d21f91999-01-24Mirar (Pontus Hagland) **! method object greylevel(int level) **! method object html(string html_color) **! Creates a new color object from given red, green and blue,
2f5efe1999-01-24Mirar (Pontus Hagland) **! hue, saturation and value, or greylevel, in color value range. **! It could also be created from <i>cmyk</i> values in percent.
4d21f91999-01-24Mirar (Pontus Hagland) **!
7428421999-01-24Mirar (Pontus Hagland) **! The <ref>html</ref>() method only understands the HTML color names, **! or the <tt>#rrggbb</tt> form. It is case insensitive.
4d21f91999-01-24Mirar (Pontus Hagland) **! **! returns the created object. */
cded6a1999-01-26Mirar (Pontus Hagland) static void _image_make_rgbl_color(INT32 r,INT32 g,INT32 b) { struct color_struct *cs; if (r<0) r=0; else if (r>COLORLMAX) r=COLORLMAX; /* >=2^31? no way... */ if (g<0) g=0; else if (g>COLORLMAX) g=COLORLMAX; if (b<0) b=0; else if (b>COLORLMAX) b=COLORLMAX; push_object(clone_object(image_color_program,0));
13b5ed2014-05-26Per Hedbor  cs=get_storage(sp[-1].u.object,image_color_program);
cded6a1999-01-26Mirar (Pontus Hagland)  cs->rgbl.r=(INT32)r; cs->rgbl.g=(INT32)g; cs->rgbl.b=(INT32)b; RGBL_TO_RGB(cs->rgb,cs->rgbl); }
74dfe82012-12-30Jonas Walldén static void image_color__encode( INT32 UNUSED(args) )
24a1e02005-03-15Per Hedbor { push_int( THIS->rgbl.r ); push_int( THIS->rgbl.g ); push_int( THIS->rgbl.b ); f_aggregate( 3 ); }
74dfe82012-12-30Jonas Walldén static void image_color__decode( INT32 UNUSED(args) )
24a1e02005-03-15Per Hedbor { struct svalue *a;
017b572011-10-28Henrik Grubbström (Grubba)  if( TYPEOF(Pike_sp[-1]) != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3 )
24a1e02005-03-15Per Hedbor  Pike_error("Illegal argument to _decode\n"); a=Pike_sp[-1].u.array->item; THIS->rgbl.r = a[0].u.integer; THIS->rgbl.g = a[1].u.integer; THIS->rgbl.b = a[2].u.integer; RGBL_TO_RGB(THIS->rgb,THIS->rgbl); pop_stack(); }
ea7a4d2000-08-09Henrik Grubbström (Grubba) static void _image_make_rgbf_color(double r, double g, double b)
cded6a1999-01-26Mirar (Pontus Hagland) { #define FOO(X) FLOAT_TO_COLORL((X)<0.0?0.0:(X)>1.0?1.0:(X)) _image_make_rgbl_color(FOO(r),FOO(g),FOO(b)); #undef FOO }
7a49a11999-04-10Mirar (Pontus Hagland) void _image_make_rgb_color(INT32 r,INT32 g,INT32 b)
5e94231999-01-23Mirar (Pontus Hagland) {
e405f01999-01-24Mirar (Pontus Hagland)  struct color_struct *cs;
5e94231999-01-23Mirar (Pontus Hagland) 
e405f01999-01-24Mirar (Pontus Hagland)  if (r<0) r=0; else if (r>COLORMAX) r=COLORMAX; if (g<0) g=0; else if (g>COLORMAX) g=COLORMAX; if (b<0) b=0; else if (b>COLORMAX) b=COLORMAX; push_object(clone_object(image_color_program,0));
13b5ed2014-05-26Per Hedbor  cs=get_storage(sp[-1].u.object,image_color_program);
e405f01999-01-24Mirar (Pontus Hagland)  cs->rgb.r=(COLORTYPE)r; cs->rgb.g=(COLORTYPE)g; cs->rgb.b=(COLORTYPE)b;
cded6a1999-01-26Mirar (Pontus Hagland)  RGB_TO_RGBL(cs->rgbl,cs->rgb);
5e94231999-01-23Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_rgb_color(INT32 args) {
65a5492000-08-10Per Hedbor  INT_TYPE r=0,g=0,b=0;
e405f01999-01-24Mirar (Pontus Hagland) 
017b572011-10-28Henrik Grubbström (Grubba)  if( args==1 && TYPEOF(sp[-1]) == T_INT )
0caad52011-04-08Martin Nilsson  { r = sp[-1].u.integer; b = r & 0xff; r >>= 8; g = r & 0xff; r >>= 8; r &= 0xff; } else
69c0aa2014-08-25Martin Nilsson  get_all_args("rgb",args,"%i%i%i",&r,&g,&b);
e405f01999-01-24Mirar (Pontus Hagland)  _image_make_rgb_color(r,g,b); } static void image_make_hsv_color(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) {
65a5492000-08-10Per Hedbor  FLOAT_TYPE h,s,v; FLOAT_TYPE r=0,g=0,b=0; /* to avoid warning */
5e94231999-01-23Mirar (Pontus Hagland) 
017b572011-10-28Henrik Grubbström (Grubba)  if (args && TYPEOF(sp[-args]) == T_INT)
cded6a1999-01-26Mirar (Pontus Hagland)  {
65a5492000-08-10Per Hedbor  INT_TYPE hi,si,vi;
69c0aa2014-08-25Martin Nilsson  get_all_args("hsv",args,"%i%i%i",&hi,&si,&vi);
cded6a1999-01-26Mirar (Pontus Hagland)  pop_n_elems(args);
13670c2015-05-25Martin Nilsson  if (hi<0) hi=(hi%COLORMAX)+COLORMAX;
cded6a1999-01-26Mirar (Pontus Hagland)  else if (hi>COLORMAX) hi%=COLORMAX; /* repeating */ if (si<0) si=0; else if (si>COLORMAX) si=COLORMAX; if (vi<0) vi=0; else if (vi>COLORMAX) vi=COLORMAX;
13670c2015-05-25Martin Nilsson 
4e73012000-08-09Henrik Grubbström (Grubba)  h = (hi/((double)COLORMAX))*(360.0/60.0); s = si/((double)COLORMAX); v = vi/((double)COLORMAX);
cded6a1999-01-26Mirar (Pontus Hagland)  } else {
69c0aa2014-08-25Martin Nilsson  get_all_args("hsv",args,"%f%f%f",&h,&s,&v);
cded6a1999-01-26Mirar (Pontus Hagland)  pop_n_elems(args);
04a97d2016-02-12Martin Nilsson  if (h<0) h = 360 + h - (((int)h/360)*360); if (h>360.0) h -= (((int)h/360)*360);
cded6a1999-01-26Mirar (Pontus Hagland)  h/=60; }
13670c2015-05-25Martin Nilsson 
cded6a1999-01-26Mirar (Pontus Hagland)  if(s==0.0)
5e94231999-01-23Mirar (Pontus Hagland)  { r = g = b = v; } else { #define i floor(h) #define f (h-i)
9e3e5a2001-09-24Henrik Grubbström (Grubba) #define p ((FLOAT_TYPE)(v * (1 - s))) #define q ((FLOAT_TYPE)(v * (1 - (s * f)))) #define t ((FLOAT_TYPE)(v * (1 - (s * (1 -f)))))
04a97d2016-02-12Martin Nilsson  switch((int)i)
5e94231999-01-23Mirar (Pontus Hagland)  {
2af7f01999-04-25Henrik Grubbström (Grubba)  case 6: /* 360 degrees. Same as 0.. */
5e94231999-01-23Mirar (Pontus Hagland)  case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break;
27ec272003-09-10Martin Stjernholm  default: Pike_error("internal error (hue=%d <= hsv[%"PRINTPIKEFLOAT"f," "%"PRINTPIKEFLOAT"f,%"PRINTPIKEFLOAT"f])\n",
04a97d2016-02-12Martin Nilsson  (int)i, h, s, v);
5e94231999-01-23Mirar (Pontus Hagland)  } } #undef i #undef f #undef p #undef q #undef t
cded6a1999-01-26Mirar (Pontus Hagland)  _image_make_rgbf_color(r,g,b);
2f5efe1999-01-24Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_cmyk_color(INT32 args)
2f5efe1999-01-24Mirar (Pontus Hagland) {
65a5492000-08-10Per Hedbor  FLOAT_TYPE c,m,y,k,r,g,b;
69c0aa2014-08-25Martin Nilsson  get_all_args("cmyk",args,"%F%F%F%F",&c,&m,&y,&k);
2f5efe1999-01-24Mirar (Pontus Hagland)  pop_n_elems(args); r=100-(c+k); g=100-(m+k); b=100-(y+k);
cded6a1999-01-26Mirar (Pontus Hagland)  _image_make_rgbf_color(r*0.01,g*0.01,b*0.01);
5e94231999-01-23Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_greylevel_color(INT32 args)
5e94231999-01-23Mirar (Pontus Hagland) {
65a5492000-08-10Per Hedbor  INT_TYPE i;
5e94231999-01-23Mirar (Pontus Hagland) 
69c0aa2014-08-25Martin Nilsson  get_all_args("greylevel",args,"%i",&i);
2f5efe1999-01-24Mirar (Pontus Hagland)  pop_n_elems(args);
5e94231999-01-23Mirar (Pontus Hagland) 
e405f01999-01-24Mirar (Pontus Hagland)  _image_make_rgb_color(i,i,i);
5e94231999-01-23Mirar (Pontus Hagland) }
e405f01999-01-24Mirar (Pontus Hagland) static void image_make_html_color(INT32 args)
4d21f91999-01-24Mirar (Pontus Hagland) { int i; if (args!=1 ||
13670c2015-05-25Martin Nilsson  TYPEOF(sp[-1]) != T_STRING)
4d21f91999-01-24Mirar (Pontus Hagland)  {
de22f72014-08-25Martin Nilsson  bad_arg_error("html",sp-args,args,0,"",sp-args, "Bad arguments to html.\n");
4d21f91999-01-24Mirar (Pontus Hagland)  return; }
13670c2015-05-25Martin Nilsson 
4d21f91999-01-24Mirar (Pontus Hagland)  f_lower_case(1); for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++) if (html_color[i].pname==sp[-1].u.string) {
e405f01999-01-24Mirar (Pontus Hagland)  _image_make_rgb_color(html_color[i].r, html_color[i].g, html_color[i].b);
4d21f91999-01-24Mirar (Pontus Hagland)  return; } if (sp[-1].u.string->len>0 && sp[-1].u.string->str[0]=='#')
e405f01999-01-24Mirar (Pontus Hagland)  image_get_color(1);
4d21f91999-01-24Mirar (Pontus Hagland)  else {
5e9fc02015-08-18Per Hedbor  push_static_text("#");
4d21f91999-01-24Mirar (Pontus Hagland)  stack_swap(); f_add(2);
e405f01999-01-24Mirar (Pontus Hagland)  image_get_color(1);
4d21f91999-01-24Mirar (Pontus Hagland)  } } /* **! method array(string) _indices() **! method array(object) _values()
448c201999-04-13Mirar (Pontus Hagland) **! (ie as <tt>indices(Image.Color)</tt> or <tt>values(Image.Color)</tt>)
4d21f91999-01-24Mirar (Pontus Hagland) **! <tt>indices</tt> gives a list of all the known color names, **! <tt>values</tt> gives there corresponding objects.
448c201999-04-13Mirar (Pontus Hagland) **! see also: Image.Color
4d21f91999-01-24Mirar (Pontus Hagland) */
e405f01999-01-24Mirar (Pontus Hagland) static void image_colors_indices(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) { pop_n_elems(args);
5e94231999-01-23Mirar (Pontus Hagland)  if (!colors) make_colors();
415c0f1999-01-22Mirar (Pontus Hagland)  ref_push_mapping(colors); f_indices(1); }
e405f01999-01-24Mirar (Pontus Hagland) static void image_colors_values(INT32 args)
415c0f1999-01-22Mirar (Pontus Hagland) { pop_n_elems(args);
5e94231999-01-23Mirar (Pontus Hagland)  if (!colors) make_colors();
415c0f1999-01-22Mirar (Pontus Hagland)  ref_push_mapping(colors); f_values(1); } void init_image_colors(void) { str_r=make_shared_string("r"); str_g=make_shared_string("g"); str_b=make_shared_string("b"); str_h=make_shared_string("h"); str_s=make_shared_string("s"); str_v=make_shared_string("v");
7a49a11999-04-10Mirar (Pontus Hagland)  no_name=make_shared_string("");
8db2c31999-05-23Mirar (Pontus Hagland)  /* make color object program */
415c0f1999-01-22Mirar (Pontus Hagland)  start_new_program();
90e9781999-01-31Fredrik Hübinette (Hubbe)  ADD_STORAGE(struct color_struct);
415c0f1999-01-22Mirar (Pontus Hagland)  set_init_callback(init_color_struct); set_exit_callback(exit_color_struct);
5e94231999-01-23Mirar (Pontus Hagland)  /* color info methods */
68ec3f2014-08-18Martin Nilsson  ADD_FUNCTION("cast",image_color_cast,tFunc(tStr,tOr(tArray,tStr)),ID_PROTECTED);
d99dbe1999-10-21Mirar (Pontus Hagland)  ADD_FUNCTION("_sprintf",image_color__sprintf, tFunc(tInt tMap(tStr,tMix),tStr),0);
2d87fb1999-04-12Mirar (Pontus Hagland)  ADD_FUNCTION("`[]",image_color_index,tFunc(tOr(tStr,tInt),tOr(tInt,tFunction)),0); ADD_FUNCTION("`->",image_color_index,tFunc(tOr(tStr,tInt),tOr(tInt,tFunction)),0);
d520932013-12-15Henrik Grubbström (Grubba)  ADD_FUNCTION("`==",image_color_equal,tFunc(tOr(tObjImpl_IMAGE_COLOR_COLOR,tInt),
4373ca2003-01-31Martin Stjernholm  tInt),0);
07228a1999-06-19Fredrik Hübinette (Hubbe)  ADD_FUNCTION("__hash",image_color___hash,tFunc(tNone,tInt),0);
2d87fb1999-04-12Mirar (Pontus Hagland) 
24a1e02005-03-15Per Hedbor  ADD_FUNCTION("_encode", image_color__encode,tFunc(tNone,tArr(tInt)),0); ADD_FUNCTION("_decode", image_color__decode,tFunc(tInt,tVoid),0);
07228a1999-06-19Fredrik Hübinette (Hubbe)  ADD_FUNCTION("name",image_color_name,tFunc(tNone,tStr),0); ADD_FUNCTION("hex",image_color_hex,tFunc(tNone,tStr),0); ADD_FUNCTION("html",image_color_html,tFunc(tNone,tStr),0);
2d87fb1999-04-12Mirar (Pontus Hagland) 
bf57c82000-09-10Per Hedbor  ADD_FUNCTION("bits",image_color_bits,tFunc(tInt tInt tInt tInt tInt tInt,tInt),0);
07228a1999-06-19Fredrik Hübinette (Hubbe)  ADD_FUNCTION("rgb",image_color_rgb,tFunc(tNone,tArr(tInt)),0); ADD_FUNCTION("rgbf",image_color_rgbf,tFunc(tNone,tArr(tFlt)),0); ADD_FUNCTION("hsv",image_color_hsv,tFunc(tNone,tArr(tInt)),0); ADD_FUNCTION("hsvf",image_color_hsvf,tFunc(tNone,tArr(tFlt)),0); ADD_FUNCTION("cmyk",image_color_cmyk,tFunc(tNone,tArr(tFlt)),0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("greylevel",image_color_greylevel,tOr(tFunc(tNone,tInt), tFunc(tInt tInt tInt,tInt)),0);
5e94231999-01-23Mirar (Pontus Hagland)  /* color conversion methods */
2d87fb1999-04-12Mirar (Pontus Hagland)  ADD_FUNCTION("grey",image_color_grey,
d520932013-12-15Henrik Grubbström (Grubba)  tOr(tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR), tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR)),0);
2d87fb1999-04-12Mirar (Pontus Hagland) 
d520932013-12-15Henrik Grubbström (Grubba)  ADD_FUNCTION("light",image_color_light,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR),0); ADD_FUNCTION("dark",image_color_dark,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR),0); ADD_FUNCTION("neon",image_color_neon,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR),0); ADD_FUNCTION("bright",image_color_bright,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR),0); ADD_FUNCTION("dull",image_color_dull,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR),0);
2d87fb1999-04-12Mirar (Pontus Hagland) 
d520932013-12-15Henrik Grubbström (Grubba)  ADD_FUNCTION("`*",image_color_mult,tFunc(tFlt,tObjIs_IMAGE_COLOR_COLOR),0); ADD_FUNCTION("`+",image_color_add,tFunc(tObjImpl_IMAGE_COLOR_COLOR, tObjIs_IMAGE_COLOR_COLOR),0);
e405f01999-01-24Mirar (Pontus Hagland) 
415c0f1999-01-22Mirar (Pontus Hagland)  image_color_program=end_program();
13670c2015-05-25Martin Nilsson  image_color_program->flags |=
f3c7152001-04-14Fredrik Hübinette (Hubbe)  PROGRAM_CONSTANT | PROGRAM_NO_EXPLICIT_DESTRUCT ;
8db2c31999-05-23Mirar (Pontus Hagland) 
aedbd72005-11-12Martin Nilsson  PIKE_MODULE_EXPORT(Image, image_color_program);
8db2c31999-05-23Mirar (Pontus Hagland)  /* this is the Image.Color stuff */
13670c2015-05-25Martin Nilsson 
d520932013-12-15Henrik Grubbström (Grubba)  ADD_FUNCTION("`[]",image_colors_index,tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR),0);
53371b1999-05-24Mirar (Pontus Hagland)  ADD_FUNCTION("`()",image_make_color,
d520932013-12-15Henrik Grubbström (Grubba)  tOr3(tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR), tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR), tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR)),0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("rgb",image_make_rgb_color,
d520932013-12-15Henrik Grubbström (Grubba)  tOr(tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR), tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR)),0);
2d87fb1999-04-12Mirar (Pontus Hagland)  ADD_FUNCTION("hsv",image_make_hsv_color,
d520932013-12-15Henrik Grubbström (Grubba)  tOr(tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR), tFunc(tFlt tFlt tFlt,tObjIs_IMAGE_COLOR_COLOR)),0);
13670c2015-05-25Martin Nilsson  ADD_FUNCTION("cmyk",image_make_cmyk_color,tFunc(tOr(tInt,tFlt) tOr(tInt,tFlt) tOr(tInt,tFlt)
4373ca2003-01-31Martin Stjernholm  tOr(tInt,tFlt),
d520932013-12-15Henrik Grubbström (Grubba)  tObjIs_IMAGE_COLOR_COLOR), 0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("html",image_make_html_color,
d520932013-12-15Henrik Grubbström (Grubba)  tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR),0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("guess",image_guess_color,
d520932013-12-15Henrik Grubbström (Grubba)  tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR),0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("greylevel",image_make_greylevel_color,
d520932013-12-15Henrik Grubbström (Grubba)  tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR),0);
4373ca2003-01-31Martin Stjernholm  ADD_FUNCTION("_indices",image_colors_indices, tFunc(tNone,tArr(tStr)),0); ADD_FUNCTION("_values",image_colors_values,
d520932013-12-15Henrik Grubbström (Grubba)  tFunc(tNone,tArr(tObjIs_IMAGE_COLOR_COLOR)),0);
5e94231999-01-23Mirar (Pontus Hagland) 
e9ce612001-03-29Per Hedbor  image_color_program->id = PROG_IMAGE_COLOR_COLOR_ID;
13670c2015-05-25Martin Nilsson 
448c201999-04-13Mirar (Pontus Hagland)  add_program_constant("Color",image_color_program,0);
415c0f1999-01-22Mirar (Pontus Hagland) } void exit_image_colors(void) {
8db2c31999-05-23Mirar (Pontus Hagland)  free_program(image_color_program);
415c0f1999-01-22Mirar (Pontus Hagland)  if (colors) {
4d21f91999-01-24Mirar (Pontus Hagland)  int i;
415c0f1999-01-22Mirar (Pontus Hagland)  free_mapping(colors); free_object(colortable); free_array(colornames); colors=NULL; colortable=NULL; colornames=NULL;
4d21f91999-01-24Mirar (Pontus Hagland)  for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++) free_string(html_color[i].pname);
415c0f1999-01-22Mirar (Pontus Hagland)  } free_string(str_r); free_string(str_g); free_string(str_b); free_string(str_h); free_string(str_s); free_string(str_v);
4d21f91999-01-24Mirar (Pontus Hagland) 
7a49a11999-04-10Mirar (Pontus Hagland)  free_string(no_name);
415c0f1999-01-22Mirar (Pontus Hagland) }