pike.git / src / modules / Image / colors.c

version» Context lines:

pike.git/src/modules/Image/colors.c:1:   /* + || 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. + */ +  + /*   **! module Image - **! note - **! $Id: colors.c,v 1.44 2001/01/04 16:18:26 mirar Exp $ +    **! submodule Color   **!   **! This module keeps names and easy handling   **! for easy color support. It gives you an easy   **! way to get colors from names.   **!   **! A color is here an object, containing color   **! information and methods for conversion, see below.   **!   **! <ref>Image.Color</ref> can be called to make a color object.
pike.git/src/modules/Image/colors.c:33:   **! ...red...   **! ...green...   **! ...lightgreen...   **! </pre>   **!   **! Giving red, green and blue values is equal to calling   **! <ref>Image.Color.rgb</ref>().   **!   **! The prefix_string method is a form for getting modified   **! colors, it understands all modifiers - **! (<link to=Image.Color.Color.light>light</link>, - **! <link to=Image.Color.Color.dark>dark</link>, - **! <link to=Image.Color.Color.bright>bright</link>, - **! <link to=Image.Color.Color.dull>dull</link> and - **! <link to=Image.Color.Color.neon>neon</link>). Simply use + **! (<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   **! "method"+"color"; (as in <tt>lightgreen</tt>,   **! <tt>dullmagenta</tt>, <tt>lightdullorange</tt>).   **!   **! The <tt>hex_name</tt> form is a simple   **! <tt>#rrggbb</tt> form, as in HTML or X-program argument.   **! A shorter form (<tt>#rgb</tt>) is also accepted. This   **! is the inverse to the <ref>Image.Color.Color->hex</ref>()   **! 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>   **! -  + **! 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().   **! - **! <add_appendix name="colors" title="Image.Color colors"><execute> + **! <execute>   **!   **! import Image;   **!   **! array modifiers=({"neon","light","dark","bright","dull"});   **!   **! object F=Font();   **!   **! mixed color_info(array(object) ac)   **! {   **!
pike.git/src/modules/Image/colors.c:109:   **! }   **! 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);   **! i->paste_alpha_color(F->write(c->name()), Color.white,   **! txPOS(c->name()),y+1);   **! y+=YZz;   **! }   **!   **! write(illustration(i,(["alpha":a]))); - **! write(mktag("br")); + **! write(mktag("br")+"\n");   **! }   **!   **! void main()   **! {   **! array cs=values(Color);   **!   **! array orig=({Color.black,Color.red,Color.green,Color.yellow,   **! Color.blue,Color.violet,Color.cyan,Color.white});   **! cs-=orig; -  + **! cs-=({Color.pikegreen,Color.avantgardepikegreen,Color.roxenorange, + **! Color.pikeblue}); // Lame sort of easter egg.   **!   **! array grey=Array.filter(cs,lambda(object c) { return c->s==0; });   **! array colored=cs-grey;   **! -  + **! sort(grey->name(), grey);   **! sort(grey->v,grey); -  + **! sort(colored->name(), colored);   **! sort(Array.map(colored,lambda(object c)   **! {   **! return (c->h*50-c->s)*10+c->v;   **! }),colored);   **!   **! Array.map(({orig}),color_info); - **! write("\240"); + **! // write("\240");   **! Array.map(({grey}),color_info); - **! write("\240"); + **! // write("\240");   **! Array.map(colored/8.0,color_info);   **! }   **!   **! </execute> - **! </add_appendix> +    **! -  + **!   **! see also: Image.Color.Color->name, Image.Color.Color->rgb, colors   **!   **! added:   **! pike 0.7   **!   **! note:   **! <tt>Image.Color["something"]</tt> will never(!) generate an error,   **! but a zero_type 0, if the color is unknown. This is enough   **! to give the error "not present in module", if used   **! as <tt>Image.Color.something</tt>, though.
pike.git/src/modules/Image/colors.c:172:   **! class Color   **! This is the color object. It has six readable variables,   **! <tt>r</tt>, <tt>g</tt>, <tt>b</tt>, for the <i>red</i>,   **! <i>green</i> and <i>blue</i> values,   **! and <tt>h</tt>, <tt>s</tt>, <tt>v</tt>, for   **! the <i>hue</i>, <i>saturation</i> anv <i>value</i> values.   */      #include "global.h"    - RCSID("$Id: colors.c,v 1.44 2001/01/04 16:18:26 mirar Exp $"); -  +    #include "image_machine.h"      #include <math.h>      #include "stralloc.h"   #include "pike_macros.h"   #include "object.h" - #include "constants.h" +    #include "interpret.h"   #include "svalue.h"   #include "array.h"   #include "mapping.h" - #include "threads.h" +    #include "builtin_functions.h"   #include "dmalloc.h"   #include "operators.h"   #include "module_support.h" - #include "opcodes.h" + #include "sscanf.h" + #include "program_id.h"      #include "image.h"   #include "colortable.h"    - /* This must be included last! */ - #include "module_magic.h" +     -  + #define sp Pike_sp +    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_array;   static struct pike_string *str_string; -  + static struct pike_string *str_int;   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;      static struct pike_string *no_name;      /* forward */
pike.git/src/modules/Image/colors.c:289:    for (i=0;i<n;i++)    {    push_int(c[i].r);    push_int(c[i].g);    push_int(c[i].b);    f_aggregate(3);    }    f_aggregate(n);    colortable=clone_object(image_colortable_program,1);    if (!colortable) -  fatal("couldn't create colortable\n"); +  Pike_fatal("couldn't create colortable\n");       push_int(12);    push_int(12);    push_int(12);    push_int(1);    safe_apply(colortable,"cubicles",4);    pop_stack();       for (i=0;i<n;i++)    push_string(c[i].pname);
pike.git/src/modules/Image/colors.c:313:    sp--;    dmalloc_touch_svalue(sp);   }      #ifdef THIS   #undef THIS /* Needed for NT */   #endif   #define THIS ((struct color_struct*)(Pike_fp->current_storage))   #define THISOBJ (Pike_fp->current_object)    - static void init_color_struct(struct object *dummy) + static void init_color_struct(struct object *UNUSED(dummy))   {    THIS->rgb.r=THIS->rgb.g=THIS->rgb.b=0;    THIS->name=NULL;   }    - static void exit_color_struct(struct object *dummy) + static void exit_color_struct(struct object *UNUSED(dummy))   {    if (THIS->name)    {    free_string(THIS->name);    THIS->name=NULL;    }   }      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);      static void try_find_name(struct color_struct *this)   {    rgb_group d; -  static struct nct_dither dith = { NCTD_NONE,NULL,NULL,NULL,NULL,-1 }; +  static struct nct_dither dith = { +  NCTD_NONE,NULL,NULL,NULL,NULL,-1, + #ifdef HAVE_UNION_INIT +  {{NULL,NULL,0.0,0.0,0.0,0.0,0,0}}, /* Only to avoid warnings. */ + #endif +  };       if (!colors)    make_colors();       if (this->name) -  fatal("try_find_name called twice\n"); +  Pike_fatal("try_find_name called twice\n");       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))    {    copy_shared_string(this->name,no_name);    return;    }       _img_nct_map_to_flat_cubicles(&(this->rgb),&d,1,
pike.git/src/modules/Image/colors.c:386:      /*   **! method void create(int r,int g,int b)   **! This is the main <ref>Image.Color.Color</ref> creation   **! method, mostly for internal use.   **----- internal note: it takes a fourth argument, name of color ---   **!   */   /*   **! method array(int) rgb() + **! method array(float) rgbf()   **! method array(int) hsv() - **! method array(int) cmyk() + **! method array(float) hsvf() + **! method array(float) cmyk()   **! method int greylevel()   **! method int greylevel(int r, int g, int b)   **! This is methods of getting information from an   **! <ref>Image.Color.Color</ref> object.   **!   **! They give an array of   **! 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>   **! or the greylevel value (range as color value).
pike.git/src/modules/Image/colors.c:485:    Pike_error("internal error, max==0.0\n");       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;    h *= 60; /* now in degrees. */    if(h<0) h+=360;    -  push_float(h); -  push_float(s); -  push_float(v); +  push_float(DO_NOT_WARN((FLOAT_TYPE)h)); +  push_float(DO_NOT_WARN((FLOAT_TYPE)s)); +  push_float(DO_NOT_WARN((FLOAT_TYPE)v));    f_aggregate(3);   }      static void image_color_hsv(INT32 args)   {    double h,s,v;    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;
pike.git/src/modules/Image/colors.c:522:    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);       c=1.0-r-k;    m=1.0-g-k;    y=1.0-b-k;    -  push_float(c*100.0); -  push_float(m*100.0); -  push_float(y*100.0); -  push_float(k*100.0); +  push_float(DO_NOT_WARN((FLOAT_TYPE)(c*100.0))); +  push_float(DO_NOT_WARN((FLOAT_TYPE)(m*100.0))); +  push_float(DO_NOT_WARN((FLOAT_TYPE)(y*100.0))); +  push_float(DO_NOT_WARN((FLOAT_TYPE)(k*100.0)));    f_aggregate(4);   }      /*   **! 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.   **! returns a new <ref>Image.Color.Color</ref> object   **! see also: greylevel
pike.git/src/modules/Image/colors.c:548:   static void image_color_grey(INT32 args)   {    image_color_greylevel(args);    stack_dup();    stack_dup();    image_make_rgb_color(3);   }      /*   **! method int bits( int rbits, int gbits, int bbits, int rshift, int gshift, int bshift ) - **! Returns the color as an integer + **! 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.   */   static void image_color_bits( INT32 args )   {    INT_TYPE rb, gb, bb, rs, gs, bs; -  get_all_args( "bits", args, "%d%d%d%d%d%d", &rb,&gb,&bb, &rs, &gs, &bs ); +  get_all_args( "bits", args, "%i%i%i%i%i%i", &rb,&gb,&bb, &rs, &gs, &bs );    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,    * but...    */      #define push_int_bits( i, b, s ) \    if( b <= 31 ) \
pike.git/src/modules/Image/colors.c:636:   {    char buf[80];    INT_TYPE i=sizeof(COLORTYPE)*2;       if (args)    get_all_args("Image.Color.Color->hex()",args,"%i",&i);       pop_n_elems(args);    if (i<1)    { -  push_text("#"); /* stupid */ +  push_constant_text("#"); /* stupid */    return;    }    else if (i!=sizeof(COLORTYPE)*2)    {    ptrdiff_t sh;    if (i>8) i=8;       sh=4*(sizeof(COLORTYPE)*2-i);    if (sh>0) -  sprintf(buf,"#%0*x%0*x%0*x",i,THIS->rgb.r>>sh, -  i,THIS->rgb.g>>sh,i,THIS->rgb.b>>sh); +  sprintf(buf,"#%0*x%0*x%0*x", +  (int)i,(unsigned)(THIS->rgb.r>>sh), +  (int)i,(unsigned)(THIS->rgb.g>>sh), +  (int)i,(unsigned)(THIS->rgb.b>>sh));    else    {    unsigned INT32 r=THIS->rgbl.r;    unsigned INT32 g=THIS->rgbl.g;    unsigned INT32 b=THIS->rgbl.b;    sh=COLORLBITS-i*4;    if (sh<0)    {    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", -  i,r>>sh,i,g>>sh,i,b>>sh); +  (int)i,(unsigned)(r>>sh), +  (int)i,(unsigned)(g>>sh), +  (int)i,(unsigned)(b>>sh));    }    }    else    switch (sizeof(COLORTYPE)) /* constant */    {    case 1:    sprintf(buf,"#%02x%02x%02x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);    break;    case 2:    sprintf(buf,"#%04x%04x%04x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);
pike.git/src/modules/Image/colors.c:727:   **! 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   */      static void image_color_cast(INT32 args)   {    if (args!=1 || -  sp[-1].type!=T_STRING) +  TYPEOF(sp[-1]) != T_STRING)    bad_arg_error("Image.Color.Color->cast",sp-args,args,0,"",sp-args,    "Bad arguments to Image.Color.Color->cast()\n");       if (sp[-1].u.string==str_array)    {    image_color_rgb(args);    return;    }    if (sp[-1].u.string==str_string)    {    image_color_name(args);    return;    } -  +  if (sp[-1].u.string==str_int) +  { +  pop_stack(); +  push_int( (THIS->rgb.r << 8 | THIS->rgb.g) << 8 | THIS->rgb.b ); +  return; +  }    Pike_error("Image.Color.Color->cast(): Can't cast to that\n");   }    - /* - **! method _sprintf(string s, mapping flags) - **! - */ -  +    static void image_color__sprintf(INT32 args)   { -  int prec,n,x; +  int prec,x;       if (args<2)    SIMPLE_TOO_FEW_ARGS_ERROR("_sprintf",2);    -  if (sp[-args].type!=T_INT) +  if (TYPEOF(sp[-args]) != T_INT)    SIMPLE_BAD_ARG_ERROR("_sprintf",0,"integer"); -  if (sp[1-args].type!=T_MAPPING) +  if (TYPEOF(sp[1-args]) != T_MAPPING)    SIMPLE_BAD_ARG_ERROR("_sprintf",1,"mapping");       pop_n_elems(args-2);       push_text("precision");    f_index(2); -  if (sp[-1].type!=T_INT) +  if (TYPEOF(sp[-1]) != T_INT)    SIMPLE_BAD_ARG_ERROR("_sprintf",1,"mapping(\"precision\":int)");    prec=sp[-1].u.integer;    x=sp[-2].u.integer;    pop_n_elems(2);       switch (x)    {   /* case 'c': */   /* case 'd': */    case 't':
pike.git/src/modules/Image/colors.c:837:      }      static void image_color_index(INT32 args)   {    struct svalue s;       if (args!=1)    Pike_error("Image.Color[]: illegal number of arguments\n");    -  object_index_no_free2(&s,THISOBJ,sp-1); -  if (s.type==T_INT && sp[-1].type==T_STRING) +  object_index_no_free2(&s, THISOBJ, 0, sp-1); +  if (TYPEOF(s) == T_INT && TYPEOF(sp[-1]) == T_STRING)    {    if (sp[-1].u.string==str_r)    {    pop_stack();    push_int(THIS->rgb.r);    return;    }    if (sp[-1].u.string==str_g)    {    pop_stack();
pike.git/src/modules/Image/colors.c:915:   **!   **! returns 1 or 0   **! see also: rgb, grey, name   **! note:   **! The other datatype (not color object) must be to the right!   */      static void image_color_equal(INT32 args)   {    if (args!=1) -  Pike_error("Image.Color.Color->`==: illegal number of arguments"); +  Pike_error("Image.Color.Color->`==: illegal number of arguments\n");    -  if (sp[-1].type==T_OBJECT) +  if (TYPEOF(sp[-1]) == T_OBJECT)    {    struct color_struct *other;    other=(struct color_struct*)    get_storage(sp[-1].u.object,image_color_program);    if (other&&    other->rgbl.r==THIS->rgbl.r &&    other->rgbl.g==THIS->rgbl.g &&    other->rgbl.b==THIS->rgbl.b)    {    pop_stack();    push_int(1);    return;    }    } -  else if (sp[-1].type==T_ARRAY) +  else if (TYPEOF(sp[-1]) == T_ARRAY)    {    if (sp[-1].u.array->size==3 && -  sp[-1].u.array->item[0].type==T_INT && -  sp[-1].u.array->item[1].type==T_INT && -  sp[-1].u.array->item[2].type==T_INT && +  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 &&    sp[-1].u.array->item[0].u.integer == THIS->rgb.r &&    sp[-1].u.array->item[1].u.integer == THIS->rgb.g &&    sp[-1].u.array->item[2].u.integer == THIS->rgb.b)    {    pop_stack();    push_int(1);    return;    }    } -  else if (sp[-1].type==T_INT) + /* else if (TYPEOF(sp[-1]) == T_INT) */ + /* { */ + /* 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; */ + /* } */ + /* } */ +  else if (TYPEOF(sp[-1]) == T_STRING)    { -  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; -  } -  } -  else if (sp[-1].type==T_STRING) -  { +     if (!THIS->name)    try_find_name(THIS);    if (sp[-1].u.string==THIS->name && THIS->name!=no_name)    {    pop_stack();    push_int(1);    return;    }    }    pop_stack();
pike.git/src/modules/Image/colors.c:993:   **! 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>   **! <tr><td>light </td><td>raise light level</td><td>±0</td><td> ±0</td><td>+50</td> - **! <td><illustration>return Image(20,20,@(array)Color["#693e3e"])</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->light())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->light()->light())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->light()->light()->light())</illustration></td></tr> + **! <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>   **!   **! <tr><td>dark </td><td>lower light level</td><td>±0</td><td> ±0</td><td>-50</td> - **! <td><illustration>return Image(20,20,@(array)Color["#693e3e"])</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->dark())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->dark()->dark())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->dark()->dark()->dark())</illustration></td></tr> + **! <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>   **!   **! <tr><td>bright</td><td>brighter color </td><td>±0</td><td>+50</td><td>+50</td> - **! <td><illustration>return Image(20,20,@(array)Color["#693e3e"])</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->bright())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->bright()->bright())</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->bright()->bright()->bright())</illustration></td></tr> + **! <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>   **!   **! <tr><td>dull </td><td>greyer color </td><td>±0</td><td>-50</td><td>-50</td> - **! <td><illustration>return Image(20,20,@(array)Color.red)</illustration> - **! <illustration>return Image(20,20,@(array)Color.red->dull())</illustration> - **! <illustration>return Image(20,20,@(array)Color.red->dull()->dull())</illustration> - **! <illustration>return Image(20,20,@(array)Color.red->dull()->dull()->dull())</illustration></td></tr> + **! <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>   **!   **! <tr><td>neon </td><td>set to extreme </td><td>±0</td><td>max</td><td>max</td> - **! <td><illustration>return Image(20,20,@(array)Color["#693e3e"])</illustration> - **! <illustration>return Image(20,20,@(array)Color["#693e3e"]->neon())</illustration></td></tr> + **! <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>   **!   **! </table>   **!   **! <ref>light</ref> and <ref>dark</ref> lower/highers saturation   **! when value is min-/maximised respective.   **!   **! returns the new color object   **! note:   **! The opposites may not always take each other out.   **! The color is maximised at white and black levels,
pike.git/src/modules/Image/colors.c:1044:   */         static void image_color_light(INT32 args)   {    pop_n_elems(args);    image_color_hsvf(0);    sp--;    dmalloc_touch_svalue(sp);    push_array_items(sp->u.array); /* frees */ -  sp[-1].u.float_number+=+0.2; -  if (sp[-1].u.float_number>=1.0) -  sp[-2].u.float_number-=sp[-1].u.float_number-1.0; +  sp[-1].u.float_number += DO_NOT_WARN((FLOAT_TYPE)0.2); +  if (((double)sp[-1].u.float_number) >= 1.0) +  sp[-2].u.float_number -= DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number - +  1.0));       image_make_hsv_color(3);   }      static void image_color_dark(INT32 args)   {    pop_n_elems(args);    image_color_hsvf(0);    sp--;    dmalloc_touch_svalue(sp);
pike.git/src/modules/Image/colors.c:1099:   {    pop_n_elems(args);       image_color_hsvf(0);    sp--;    dmalloc_touch_svalue(sp);    push_array_items(sp->u.array); /* frees */       if (sp[-2].u.float_number==0.0)    { -  sp[-1].u.float_number-=0.2; +  sp[-1].u.float_number -= DO_NOT_WARN((FLOAT_TYPE)0.2);    }    else    { -  sp[-2].u.float_number-=0.2; -  sp[-1].u.float_number-=0.2; +  sp[-2].u.float_number -= DO_NOT_WARN((FLOAT_TYPE)0.2); +  sp[-1].u.float_number -= DO_NOT_WARN((FLOAT_TYPE)0.2);    }    image_make_hsv_color(3);   }      static void image_color_bright(INT32 args)   {    pop_n_elems(args);    image_color_hsvf(0);    sp--;    dmalloc_touch_svalue(sp);
pike.git/src/modules/Image/colors.c:1142:    FLOAT_TYPE x=0.0;    get_all_args("Image.Color.Color->`*",args,"%f",&x);    pop_n_elems(args);    _image_make_rgb_color(DOUBLE_TO_INT(THIS->rgb.r*x),    DOUBLE_TO_INT(THIS->rgb.g*x),    DOUBLE_TO_INT(THIS->rgb.b*x));   }      int image_color_svalue(struct svalue *v,rgb_group *rgb)   { -  if (v->type==T_OBJECT) +  if (TYPEOF(*v) == T_OBJECT)    {    struct color_struct *cs=(struct color_struct*)    get_storage(v->u.object,image_color_program);       if (cs)    {    *rgb=cs->rgb;    return 1;    }    } -  else if (v->type==T_ARRAY) +  else if (TYPEOF(*v) == T_ARRAY)    {    if (v->u.array->size==3 && -  v->u.array->item[0].type==T_INT && -  v->u.array->item[1].type==T_INT && -  v->u.array->item[2].type==T_INT) +  TYPEOF(v->u.array->item[0]) == T_INT && +  TYPEOF(v->u.array->item[1]) == T_INT && +  TYPEOF(v->u.array->item[2]) == T_INT)    {    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);    return 1;    }    } -  else if (v->type==T_STRING) +  else if (TYPEOF(*v) == T_STRING)    {    push_svalue(v);    image_make_color(1); -  if (sp[-1].type==T_OBJECT) +  if (TYPEOF(sp[-1]) == T_OBJECT)    {    struct color_struct *cs=(struct color_struct*)    get_storage(sp[-1].u.object,image_color_program);    *rgb=cs->rgb;    pop_stack();    return 1;    }    pop_stack();    }    return 0;
pike.git/src/modules/Image/colors.c:1214:      #define HEXTONUM(C) \    (((C)>='0' && (C)<='9')?(C)-'0': \    ((C)>='a' && (C)<='f')?(C)-'a'+10: \    ((C)>='A' && (C)<='F')?(C)-'A'+10:-1)      static void image_get_color(INT32 args)   {    struct svalue s;    int n; -  static char *callables[]={"light","dark","neon","dull","bright"}; +  static const char *callables[]={"light","dark","neon","dull","bright"};       if (args!=1) -  Pike_error("Image.Color[]: illegal number of args"); +  Pike_error("Image.Color[]: illegal number of args.\n");       if (!colors)    make_colors();    -  if (sp[-1].type==T_STRING) +  if (TYPEOF(sp[-1]) == T_STRING)    {    mapping_index_no_free(&s,colors,sp-1); -  if (s.type==T_OBJECT) +  if (TYPEOF(s) == T_OBJECT)    {    pop_stack();    *(sp++)=s;    return;    }    else    free_svalue(&s);    }    -  if (sp[-1].type==T_STRING && +  if (TYPEOF(sp[-1]) == T_STRING &&    sp[-1].u.string->size_shift==0)    {    if (sp[-1].u.string->len>=4 &&    sp[-1].u.string->str[0]=='#')    {    /* #rgb, #rrggbb, #rrrgggbbb, etc */       size_t i = sp[-1].u.string->len-1, j, k;    unsigned INT32 rgb[3];    unsigned char *src=(unsigned char *)sp[-1].u.string->str+1;
pike.git/src/modules/Image/colors.c:1257:    {    i/=3;    for (j=0; j<3; j++)    {    unsigned INT32 z=0;    for (k=0; k<i; k++)    {    if (HEXTONUM(*src)==-1)    {    pop_stack(); -  push_int(0); -  sp[-1].subtype=NUMBER_UNDEFINED; +  push_undefined();    return;    }    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;   
pike.git/src/modules/Image/colors.c:1296:    return;    }    }    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();    push_text("@%f,%f,%f\n");    f_sscanf(2); -  if (sp[-1].type==T_ARRAY && +  if (TYPEOF(sp[-1]) == T_ARRAY &&    sp[-1].u.array->size==3)    {    FLOAT_TYPE h,s,v;    stack_swap();    pop_stack();    sp--;    dmalloc_touch_svalue(sp);    push_array_items(sp->u.array);    get_all_args("Image.Color()",3,"%f%f%f",&h,&s,&v);    pop_n_elems(3);
pike.git/src/modules/Image/colors.c:1322:    }    pop_stack();    }    if (sp[-1].u.string->len>=4 &&    sp[-1].u.string->str[0]=='%')    {    /* @c,m,y,k; 0..100 */    stack_dup();    push_text("%%%f,%f,%f,%f\n");    f_sscanf(2); -  if (sp[-1].type==T_ARRAY && +  if (TYPEOF(sp[-1]) == T_ARRAY &&    sp[-1].u.array->size==4)    {    stack_swap();    pop_stack();    sp--;    dmalloc_touch_svalue(sp);    push_array_items(sp->u.array);    image_make_cmyk_color(4);    return;    }    pop_stack();    }    for (n=0; (size_t)n<sizeof(callables)/sizeof(callables[0]); n++)    if (sp[-1].u.string->len>(ptrdiff_t)strlen(callables[n]) &&    memcmp(sp[-1].u.string->str,callables[n],strlen(callables[n]))==0)    { -  push_int(DO_NOT_WARN(strlen(callables[n]))); +  push_int(DO_NOT_WARN((INT32)strlen(callables[n])));    push_int(1000000);    f_index(3);    image_get_color(1); -  if (sp[-1].type!=T_OBJECT) return; /* no way */ +  if (TYPEOF(sp[-1]) != T_OBJECT) return; /* no way */    safe_apply(sp[-1].u.object,callables[n],0);    stack_swap();    pop_stack();    return;    }    if (sp[-1].u.string->len>=4 &&    sp[-1].u.string->str[0]=='g')    {    /* greyx; x=0..99 */    stack_dup();    push_text("gr%*[ea]y%f\n");    f_sscanf(2); -  if (sp[-1].type==T_ARRAY && +  if (TYPEOF(sp[-1]) == T_ARRAY &&    sp[-1].u.array->size==1)    {    double f;    f = sp[-1].u.array->item[0].u.float_number;    pop_stack();    pop_stack(); -  push_int( (int)(255*f/100) ); +  push_int( DO_NOT_WARN((int)(255*f/100)) );    /* grey100 is white, grey0 is black */    stack_dup();    stack_dup();    image_make_rgb_color(3);       return;    }    pop_stack();    }    }       /* try other stuff here */       pop_stack(); -  push_int(0); -  sp[-1].subtype=NUMBER_UNDEFINED; +  push_undefined();    return;   }      static void image_guess_color(INT32 args)   { -  struct svalue s; -  -  if (args!=1 && sp[-args].type!=T_STRING) +  if (args!=1 && TYPEOF(sp[-args]) != T_STRING)    bad_arg_error("Image.Color->guess",sp-args,args,0,"",sp-args,    "Bad arguments to Image.Color->guess()\n");       f_lower_case(1); -  push_text(" "); +  push_constant_text(" ");    o_subtract();       stack_dup();    image_get_color(1); -  if (sp[-1].type==T_OBJECT) +  if (TYPEOF(sp[-1]) == T_OBJECT)    {    stack_swap();    pop_stack();    return;    }    pop_stack(); -  push_text("#"); +  push_constant_text("#");    stack_swap();    f_add(2);       image_get_color(1);   }      static void image_colors_index(INT32 args)   {    struct svalue s; -  object_index_no_free2(&s,THISOBJ,sp-1); -  if (s.type!=T_INT) +  object_index_no_free2(&s, THISOBJ, 0, sp-1); +  if (TYPEOF(s) != T_INT)    {    pop_stack();    *(sp++)=s;    return;    }    image_get_color(args);   }      static void image_make_color(INT32 args)   { -  struct svalue s; -  -  if (args==1 && sp[-args].type==T_STRING) +  if (args==1 && TYPEOF(sp[-args]) == T_STRING)    {    image_get_color(args);    return;    }    image_make_rgb_color(args);   }         /*   **! module Image   **! submodule Color   **! - **! method object guess(string) + **! method object guess(string color)   **! This is equivalent to   **! <tt><ref>Image.Color</ref>(lower_case(str)-" ")</tt>,   **! and tries the color with a prepending '#' if no   **! corresponding color is found.   **!   **! returns a color object or zero_type   */      /*   **! method object rgb(int red, int green, int blue)
pike.git/src/modules/Image/colors.c:1485:       cs=(struct color_struct*)    get_storage(sp[-1].u.object,image_color_program);       cs->rgbl.r=(INT32)r;    cs->rgbl.g=(INT32)g;    cs->rgbl.b=(INT32)b;    RGBL_TO_RGB(cs->rgb,cs->rgbl);   }    + static void image_color__encode( INT32 UNUSED(args) ) + { +  push_int( THIS->rgbl.r ); +  push_int( THIS->rgbl.g ); +  push_int( THIS->rgbl.b ); +  f_aggregate( 3 ); + } +  + static void image_color__decode( INT32 UNUSED(args) ) + { +  struct svalue *a; +  if( TYPEOF(Pike_sp[-1]) != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3 ) +  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(); + } +    static void _image_make_rgbf_color(double r, double g, double b)   {   #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   }      void _image_make_rgb_color(INT32 r,INT32 g,INT32 b)   {    struct color_struct *cs;
pike.git/src/modules/Image/colors.c:1515:    cs->rgb.r=(COLORTYPE)r;    cs->rgb.g=(COLORTYPE)g;    cs->rgb.b=(COLORTYPE)b;    RGB_TO_RGBL(cs->rgbl,cs->rgb);   }      static void image_make_rgb_color(INT32 args)   {    INT_TYPE r=0,g=0,b=0;    +  if( args==1 && TYPEOF(sp[-1]) == T_INT ) +  { +  r = sp[-1].u.integer; +  b = r & 0xff; +  r >>= 8; +  g = r & 0xff; +  r >>= 8; +  r &= 0xff; +  } +  else    get_all_args("Image.Color.rgb()",args,"%i%i%i",&r,&g,&b);       _image_make_rgb_color(r,g,b);   }      static void image_make_hsv_color(INT32 args)   {    FLOAT_TYPE h,s,v;    FLOAT_TYPE r=0,g=0,b=0; /* to avoid warning */    -  if (args && sp[-args].type==T_INT) +  if (args && TYPEOF(sp[-args]) == T_INT)    {    INT_TYPE hi,si,vi;    get_all_args("Image.Color.hsv()",args,"%i%i%i",    &hi,&si,&vi);    pop_n_elems(args);       if (hi<0) hi=(hi%COLORMAX)+COLORMAX;    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;
pike.git/src/modules/Image/colors.c:1557:    if (h>360.0) h -= ((DOUBLE_TO_INT(h)/360)*360);    h/=60;    }       if(s==0.0)    {    r = g = b = v;    } else {   #define i floor(h)   #define f (h-i) - #define p (v * (1 - s)) - #define q (v * (1 - (s * f))) - #define t (v * (1 - (s * (1 -f)))) + #define p ((FLOAT_TYPE)(v * (1 - s))) + #define q ((FLOAT_TYPE)(v * (1 - (s * f)))) + #define t ((FLOAT_TYPE)(v * (1 - (s * (1 -f)))))    switch(DOUBLE_TO_INT(i))    {    case 6: /* 360 degrees. Same as 0.. */    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; -  default: Pike_error("internal error (hue=%d <= hsv[%f,%f,%f])\n", +  default: Pike_error("internal error (hue=%d <= hsv[%"PRINTPIKEFLOAT"f," +  "%"PRINTPIKEFLOAT"f,%"PRINTPIKEFLOAT"f])\n",    DOUBLE_TO_INT(i), h, s, v);    }    }   #undef i   #undef f   #undef p   #undef q   #undef t       _image_make_rgbf_color(r,g,b);
pike.git/src/modules/Image/colors.c:1610:    pop_n_elems(args);       _image_make_rgb_color(i,i,i);   }      static void image_make_html_color(INT32 args)   {    int i;       if (args!=1 || -  sp[-1].type!=T_STRING) +  TYPEOF(sp[-1]) != T_STRING)    {    bad_arg_error("Image.Color.html",sp-args,args,0,"",sp-args,    "Bad arguments to Image.Color.html()\n");    return;    }       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)    {
pike.git/src/modules/Image/colors.c:1632:    html_color[i].g,    html_color[i].b);    return;    }       if (sp[-1].u.string->len>0 &&    sp[-1].u.string->str[0]=='#')    image_get_color(1);    else    { -  push_text("#"); +  push_constant_text("#");    stack_swap();    f_add(2);    image_get_color(1);    }   }      /*   **! method array(string) _indices()   **! method array(object) _values()   **! (ie as <tt>indices(Image.Color)</tt> or <tt>values(Image.Color)</tt>)
pike.git/src/modules/Image/colors.c:1666:   static void image_colors_values(INT32 args)   {    pop_n_elems(args);    if (!colors) make_colors();    ref_push_mapping(colors);    f_values(1);   }      void init_image_colors(void)   { -  struct program *prg; -  struct pike_string *str; -  +     str_array=make_shared_string("array");    str_string=make_shared_string("string"); -  +  str_int=make_shared_string("int");    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");       no_name=make_shared_string("");       /* make color object program */
pike.git/src/modules/Image/colors.c:1695:    set_init_callback(init_color_struct);    set_exit_callback(exit_color_struct);       /* color info methods */       ADD_FUNCTION("cast",image_color_cast,tFunc(tStr,tOr(tArray,tStr)),0);    ADD_FUNCTION("_sprintf",image_color__sprintf,    tFunc(tInt tMap(tStr,tMix),tStr),0);    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); -  ADD_FUNCTION("`==",image_color_equal,tFunc(tOr(tObj,tInt),tInt),0); +  ADD_FUNCTION("`==",image_color_equal,tFunc(tOr(tObjImpl_IMAGE_COLOR_COLOR_ID,tInt), +  tInt),0);    ADD_FUNCTION("__hash",image_color___hash,tFunc(tNone,tInt),0);    -  +  ADD_FUNCTION("_encode", image_color__encode,tFunc(tNone,tArr(tInt)),0); +  ADD_FUNCTION("_decode", image_color__decode,tFunc(tInt,tVoid),0); +     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);       ADD_FUNCTION("bits",image_color_bits,tFunc(tInt tInt tInt tInt tInt tInt,tInt),0);    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); -  ADD_FUNCTION("greylevel",image_color_greylevel,tOr(tFunc(tNone,tInt),tFunc(tInt tInt tInt,tInt)),0); +  ADD_FUNCTION("greylevel",image_color_greylevel,tOr(tFunc(tNone,tInt), +  tFunc(tInt tInt tInt,tInt)),0);       /* color conversion methods */       ADD_FUNCTION("grey",image_color_grey, -  tOr(tFunc(tNone,tObj),tFunc(tInt tInt tInt,tObj)),0); +  tOr(tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID), +  tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR_ID)),0);    -  ADD_FUNCTION("light",image_color_light,tFunc(tNone,tObj),0); -  ADD_FUNCTION("dark",image_color_dark,tFunc(tNone,tObj),0); -  ADD_FUNCTION("neon",image_color_neon,tFunc(tNone,tObj),0); -  ADD_FUNCTION("bright",image_color_bright,tFunc(tNone,tObj),0); -  ADD_FUNCTION("dull",image_color_dull,tFunc(tNone,tObj),0); +  ADD_FUNCTION("light",image_color_light,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("dark",image_color_dark,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("neon",image_color_neon,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("bright",image_color_bright,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("dull",image_color_dull,tFunc(tNone,tObjIs_IMAGE_COLOR_COLOR_ID),0);    -  ADD_FUNCTION("`*",image_color_mult,tFunc(tFlt,tObj),0); -  ADD_FUNCTION("`+",image_color_add,tFunc(tObj,tObj),0); +  ADD_FUNCTION("`*",image_color_mult,tFunc(tFlt,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("`+",image_color_add,tFunc(tObjImpl_IMAGE_COLOR_COLOR_ID, +  tObjIs_IMAGE_COLOR_COLOR_ID),0);       image_color_program=end_program(); -  +  image_color_program->flags |= +  PROGRAM_CONSTANT | +  PROGRAM_NO_EXPLICIT_DESTRUCT ;    -  +  PIKE_MODULE_EXPORT(Image, image_color_program); +     /* this is the Image.Color stuff */    -  ADD_FUNCTION("`[]",image_colors_index,tFunc(tStr,tObj),0); +  ADD_FUNCTION("`[]",image_colors_index,tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR_ID),0);    ADD_FUNCTION("`()",image_make_color, -  tOr(tFunc(tStr,tObj), -  tFunc(tInt tInt tInt,tObj)),0); -  ADD_FUNCTION("rgb",image_make_rgb_color,tFunc(tInt tInt tInt,tObj),0); +  tOr3(tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR_ID), +  tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR_ID), +  tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR_ID)),0); +  ADD_FUNCTION("rgb",image_make_rgb_color, +  tOr(tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR_ID), +  tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR_ID)),0);    ADD_FUNCTION("hsv",image_make_hsv_color, -  tOr(tFunc(tInt tInt tInt,tObj), -  tFunc(tFlt tFlt tFlt,tObj)) ,0); +  tOr(tFunc(tInt tInt tInt,tObjIs_IMAGE_COLOR_COLOR_ID), +  tFunc(tFlt tFlt tFlt,tObjIs_IMAGE_COLOR_COLOR_ID)) ,0);    ADD_FUNCTION("cmyk",image_make_cmyk_color,tFunc(tOr(tInt,tFlt)    tOr(tInt,tFlt)    tOr(tInt,tFlt) -  tOr(tInt,tFlt),tObj), 0); -  ADD_FUNCTION("html",image_make_html_color,tFunc(tStr,tObj),0); -  ADD_FUNCTION("guess",image_guess_color,tFunc(tStr,tObj),0); -  ADD_FUNCTION("greylevel",image_make_greylevel_color,tFunc(tInt,tObj),0); -  ADD_FUNCTION("_indices",image_colors_indices,tFunc(tNone,tArr(tStr)),0); -  ADD_FUNCTION("_values",image_colors_values,tFunc(tNone,tArr(tObj)),0); +  tOr(tInt,tFlt), +  tObjIs_IMAGE_COLOR_COLOR_ID), 0); +  ADD_FUNCTION("html",image_make_html_color, +  tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("guess",image_guess_color, +  tFunc(tStr,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("greylevel",image_make_greylevel_color, +  tFunc(tInt,tObjIs_IMAGE_COLOR_COLOR_ID),0); +  ADD_FUNCTION("_indices",image_colors_indices, +  tFunc(tNone,tArr(tStr)),0); +  ADD_FUNCTION("_values",image_colors_values, +  tFunc(tNone,tArr(tObjIs_IMAGE_COLOR_COLOR_ID)),0);    -  +  image_color_program->id = PROG_IMAGE_COLOR_COLOR_ID; +     add_program_constant("Color",image_color_program,0);   }      void exit_image_colors(void)   {    free_program(image_color_program);    if (colors)    {    int i;   
pike.git/src/modules/Image/colors.c:1769:       colors=NULL;    colortable=NULL;    colornames=NULL;       for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++)    free_string(html_color[i].pname);    }    free_string(str_array);    free_string(str_string); +  free_string(str_int);    free_string(str_r);    free_string(str_g);    free_string(str_b);    free_string(str_h);    free_string(str_s);    free_string(str_v);       free_string(no_name);   } -  +