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

version» Context lines:

pike.git/src/modules/Image/colors.c:1:   /*   **! module Image   **! note - **! $Id: colors.c,v 1.4 1999/01/24 01:14:19 mirar Exp $ + **! $Id: colors.c,v 1.5 1999/01/24 17:31:02 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.   **! <ref>Image.color()</ref> takes the following arguments:   **! <pre> - **! Image.color(string name) - **! Image.color(string hex_name) - **! Image.color(string prefix_string) + **! 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"   **! Image.color(int red, int green, int blue)   **! </pre>   **!   **! The color names available can be listed by using indices   **! on Image.color. The colors are available by name directly   **! as <tt>Image.color.name</tt>, too:   **! <pre>   **! ...Image.color.red...   **! ...Image.color.green...   **! or, maybe   **! import Image.color;   **! ...red...   **! ...green...   **! ...lightgreen...   **! </pre>   **!   **! Giving red, green and blue values is equal to calling   **! <ref>Image.color.rgb</ref>().   **! - **! 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 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   **! "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> + **!   **! see also: Image.color.color->name, Image.color.color->rgb   **!   **! 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:79:   **! 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"   #include <config.h>    - RCSID("$Id: colors.c,v 1.4 1999/01/24 01:14:19 mirar Exp $"); + RCSID("$Id: colors.c,v 1.5 1999/01/24 17:31:02 mirar Exp $");      #include "config.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 "image.h"   #include "colortable.h"      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;
pike.git/src/modules/Image/colors.c:125:   static struct pike_string *str_s;   static struct pike_string *str_v;      struct color_struct   {    rgb_group rgb;    struct pike_string *name;   };      void image_make_hsv_color(INT32 args); /* forward */ + void image_make_cmyk_color(INT32 args); /* forward */      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},    {0,255,0,"lime",NULL}, {128,128,128,"gray",NULL},
pike.git/src/modules/Image/colors.c:307:    try_find_name();    }    else error("Image.color.color->create(): Illegal argument(s)\n");       push_int(0);   }      /*   **! method array(int) rgb()   **! method array(int) hsv() + **! method array(int) 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, - **! hue, saturation and value (hsv) values, - **! or the greylevel value. + **! 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).   **!   **! The greylevel is calculated by weighting red, green   **! and blue. Default weights are 87, 127 and 41, respective,   **! and could be given by argument.   **!   **! returns array(int) respective int   **! see also: Image.color.color, grey   */      void image_color_rgb(INT32 args)
pike.git/src/modules/Image/colors.c:397:    else /*if(b==max)*/ h = 4+(r-g)/delta;    h *= 60; // now in degrees.    if(h<0) h+=360;       push_int((int)((h/360.0)*COLORMAX+0.5));    push_int((int)(s*COLORMAX+0.5));    push_int((int)(v*COLORMAX+0.5));    f_aggregate(3);   }    + void image_color_cmyk(INT32 args) + { +  float c,m,y,k; +  pop_n_elems(args); +  +  k=255.0-MAX3(THIS->rgb.r,THIS->rgb.g,THIS->rgb.b); +  +  c=255.0-THIS->rgb.r-k; +  m=255.0-THIS->rgb.g-k; +  y=255.0-THIS->rgb.b-k; +  +  push_float(c*100.0/255.0); +  push_float(m*100.0/255.0); +  push_float(y/255.0*100.0); +  push_float(k/255.0*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   */      void image_color_grey(INT32 args)
pike.git/src/modules/Image/colors.c:878:    }    pop_n_elems(args);    push_int((INT32)rgb[0]);    push_int((INT32)rgb[1]);    push_int((INT32)rgb[2]);    push_object(clone_object(image_color_program,3));       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 && +  sp[-1].u.array->size==3) +  { +  float h,s,v; +  stack_swap(); +  pop_stack(); +  sp--; +  push_array_items(sp->u.array); +  get_all_args("Image.color()",3,"%f%f%f",&h,&s,&v); +  pop_n_elems(3); +  push_int((INT32)(h/360.0*256.0)); +  push_int((INT32)(s/100.0*255.4)); +  push_int((INT32)(v/100.0*255.4)); +  image_make_hsv_color(3); +  return; +  } +  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 && +  sp[-1].u.array->size==4) +  { +  stack_swap(); +  pop_stack(); +  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>(INT32)strlen(callables[n]) &&    memcmp(sp[-1].u.string->str,callables[n],strlen(callables[n]))==0)    {    push_int(strlen(callables[n]));    push_int(1000000);    f_index(3);    image_get_color(1);    if (sp[-1].type!=T_OBJECT) return; /* no way */    safe_apply(sp[-1].u.object,callables[n],0);
pike.git/src/modules/Image/colors.c:963:   **! <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)   **! method object hsv(int hue, int saturation, int value) + **! method object cmyk(float c,float m,float y,float k)   **! method object greylevel(int level)   **! method object html(string html_color)   **! Creates a new color object from given red, green and blue, - **! hue, saturation and value, or greylevel. + **! hue, saturation and value, or greylevel, in color value range. + **! It could also be created from <i>cmyk</i> values in percent.   **!   **! The <ref>html</ref>() method only understands the HTML color names,   **! or the <tt>#rrggbb</tt> form. It is case insensitive.   **!   **! returns the created object.   */      void image_make_rgb_color(INT32 args)   {    if (args!=3)
pike.git/src/modules/Image/colors.c:993:   }      void image_make_hsv_color(INT32 args)   {    float h,s,v;    INT32 hi,si,vi;    float r=0,g=0,b=0; /* to avoid warning */       get_all_args("Image.color.hsv()",args,"%i%i%i",    &hi,&si,&vi); +  pop_n_elems(args);    -  if (hi<0) hi=0; else if (hi>COLORMAX) hi=COLORMAX; +  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;       h = (hi/((float)COLORMAX))*(360.0/60.0);    s = si/((float)COLORMAX);    v = vi/((float)COLORMAX);       if(s==0.0 || si==0)    {    r = g = b = v;
pike.git/src/modules/Image/colors.c:1032:   #undef i   #undef f   #undef p   #undef q   #undef t   #define FOO(X) ((int)((X)<0.0?0:(X)>1.0?COLORMAX:(int)((X)*((float)COLORMAX)+0.5)))    push_int(FOO(r));    push_int(FOO(g));    push_int(FOO(b));    -  push_object(clone_object(image_color_program,args)); +  push_object(clone_object(image_color_program,3));   }    -  + void image_make_cmyk_color(INT32 args) + { +  float c,m,y,k,r,g,b; +  get_all_args("Image.color.cmyk()",args,"%F%F%F%F",&c,&m,&y,&k); +  pop_n_elems(args); +  +  r=100-(c+k); +  g=100-(m+k); +  b=100-(y+k); +  +  push_int((int)(r*255.4/100.0)); +  push_int((int)(g*255.4/100.0)); +  push_int((int)(b*255.4/100.0)); +  +  push_object(clone_object(image_color_program,3)); + } +    void image_make_greylevel_color(INT32 args)   {    INT32 i;       get_all_args("Image.color.greylevel()",args,"%i",&i); -  +  pop_n_elems(args);       push_int(i);    push_int(i);    push_int(i);       push_object(clone_object(image_color_program,3));   }      void image_make_html_color(INT32 args)   {
pike.git/src/modules/Image/colors.c:1152:    "function(:string)",OPT_TRY_OPTIMIZE);    add_function("hex",image_color_hex,    "function(:string)",OPT_TRY_OPTIMIZE);    add_function("html",image_color_html,    "function(:string)",OPT_TRY_OPTIMIZE);       add_function("rgb",image_color_rgb,    "function(:array)",OPT_TRY_OPTIMIZE);    add_function("hsv",image_color_hsv,    "function(:array)",OPT_TRY_OPTIMIZE); +  add_function("cmyk",image_color_cmyk, +  "function(:array)",OPT_TRY_OPTIMIZE);    add_function("greylevel",image_color_greylevel,    "function(:int)|function(int,int,int:int)",OPT_TRY_OPTIMIZE);       /* color conversion methods */       add_function("grey",image_color_grey,    "function(:object)|function(int,int,int:object)",    OPT_TRY_OPTIMIZE);       add_function("light",image_color_light,
pike.git/src/modules/Image/colors.c:1183:       start_new_program();    add_function("`[]",image_get_color,    "function(string:object)",OPT_TRY_OPTIMIZE);    add_function("`()",image_make_color,    "function(string|int...:object)",OPT_TRY_OPTIMIZE);    add_function("rgb",image_make_rgb_color,    "function(int,int,int:object)",OPT_TRY_OPTIMIZE);    add_function("hsv",image_make_hsv_color,    "function(int,int,int:object)",OPT_TRY_OPTIMIZE); +  add_function("cmyk",image_make_cmyk_color, +  "function(int|float,int|float,int|float,int|float:object)", +  OPT_TRY_OPTIMIZE);    add_function("html",image_make_html_color,    "function(string:object)",OPT_TRY_OPTIMIZE);    add_function("guess",image_guess_color,    "function(string:object)",OPT_TRY_OPTIMIZE);    add_function("greylevel",image_make_greylevel_color,    "function(int:object)",OPT_TRY_OPTIMIZE);    add_function("_indices",image_colors_indices,    "function(:array(string))",OPT_TRY_OPTIMIZE);    add_function("_values",image_colors_values,    "function(:array(object))",OPT_TRY_OPTIMIZE);