pike.git/
src/
modules/
Image/
colors.c
Branch:
Tag:
Non-build tags
All tags
No tags
1999-01-26
1999-01-26 02:02:33 by Mirar (Pontus Hagland) <pike@sort.mirar.org>
cded6a6d3e3b73e8c388e1feef2d807ed2f7c027 (
346
lines) (+
233
/-
113
)
[
Show
|
Annotate
]
Branch:
7.9
better precision
Rev: src/modules/Image/colors.c:1.7
Rev: src/modules/Image/image.h:1.23
1:
/* **! module Image **! note
-
**! $Id: colors.c,v 1.
6
1999/01/
24
21
:
38
:
01
mirar Exp $
+
**! $Id: colors.c,v 1.
7
1999/01/
26
02
:
02
:
31
mirar Exp $
**! submodule color **! **! This module keeps names and easy handling
97:
#include "global.h" #include <config.h>
-
RCSID("$Id: colors.c,v 1.
6
1999/01/
24
21
:
38
:
01
mirar Exp $");
+
RCSID("$Id: colors.c,v 1.
7
1999/01/
26
02
:
02
:
31
mirar Exp $");
#include "config.h"
140:
struct color_struct { rgb_group rgb;
+
rgbl_group rgbl;
struct pike_string *name; }; /* forward */ static void image_make_rgb_color(INT32 args); static void _image_make_rgb_color(INT32 r,INT32 g,INT32 b);
-
+
static void _image_make_rgbl_color(INT32 r,INT32 g,INT32 b);
+
static void _image_make_rgbf_color(float r,float g,float b);
static void image_make_hsv_color(INT32 args); static void image_make_cmyk_color(INT32 args); static void image_make_color(INT32 args);
163:
{128,0,0,"maroon",NULL}, {0,0,128,"navy",NULL}, {255,0,0,"red",NULL}, {0,0,255,"blue",NULL}, {128,0,128,"purple",NULL}, {0,128,128,"teal",NULL},
-
{255,
255,
0,"fuchsia",NULL}, {0,255,255,"aqua",NULL}};
+
{255,
0,
255,"fuchsia",NULL}, {0,255,255,"aqua",NULL}};
static void make_colors(void) {
196:
cs->rgb.r=(COLORTYPE)c[i].r; cs->rgb.g=(COLORTYPE)c[i].g; cs->rgb.b=(COLORTYPE)c[i].b;
+
RGB_TO_RGBL(cs->rgbl,cs->rgb);
copy_shared_string(cs->name,c[i].pname); } f_aggregate_mapping(n*2);
261:
this->name=NULL; }
+
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))
+
return;
+
image_colortable_map_image((struct neo_colortable*)colortable->storage, &(this->rgb),&d,1,1);
340:
#define MAX3(X,Y,Z) MAXIMUM(MAXIMUM(X,Y),Z)
-
static void image_color_
hsv
(INT32 args)
+
static void image_color_
hsvf
(INT32 args)
{ float max, min; float r,g,b, delta;
350:
if((THIS->rgb.r==THIS->rgb.g) && (THIS->rgb.g==THIS->rgb.b)) {
-
push_
int
(0);
-
push_
int
(0);
-
push_
int
(THIS->
rgb
.r);
+
push_
float
(0);
+
push_
float
(0);
+
push_
float
(
COLORL_TO_FLOAT(
THIS->
rgbl
.r)
)
;
f_aggregate(3); return; }
-
r = (
float)(
THIS->
rgb
.r)
/((float)COLORMAX)
;
-
g = (
float)(
THIS->
rgb
.g)
/((float)COLORMAX)
;
-
b = (
float)(
THIS->
rgb
.b)
/((float)COLORMAX)
;
+
r =
COLORL_TO_FLOAT
(THIS->
rgbl
.r);
+
g =
COLORL_TO_FLOAT
(THIS->
rgbl
.g);
+
b =
COLORL_TO_FLOAT
(THIS->
rgbl
.b);
max = MAX3(r,g,b); min = -(MAX3(-r,-g,-b));
378:
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
)
)
;
+
push_
float
(h);
+
push_
float
(s);
+
push_
float
(v);
f_aggregate(3); }
-
+
static void image_color_hsv(INT32 args)
+
{
+
float 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;
+
+
pop_stack();
+
push_int(FLOAT_TO_COLOR(h/360.0));
+
push_int(FLOAT_TO_COLOR(s));
+
push_int(FLOAT_TO_COLOR(v));
+
f_aggregate(3);
+
}
+
static void image_color_cmyk(INT32 args) { float c,m,y,k;
-
+
float r,g,b;
pop_n_elems(args);
-
k
=
255.0-MAX3
(THIS->
rgb
.r
,
THIS->
rgb
.g
,
THIS->
rgb
.b);
+
r
=
COLORL_TO_FLOAT
(THIS->
rgbl
.r
);
+
g=COLORL_TO_FLOAT(
THIS->
rgbl
.g
);
+
b=COLORL_TO_FLOAT(
THIS->
rgbl
.b);
-
c=255.0-THIS->rgb.r-
k
;
-
m
=
255
.0-
THIS->rgb.
g
-k;
-
y=255.0-THIS->rgb.
b
-k
;
+
k
=
1
.0-
MAX3(
r
,
g
,
b
)
;
-
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);
+
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);
f_aggregate(4); }
468:
i,THIS->rgb.g>>sh,i,THIS->rgb.b>>sh); else {
-
unsigned INT32 r=THIS->
rgb
.r;
-
unsigned INT32 g=THIS->
rgb
.g;
-
unsigned INT32 b=THIS->
rgb
.b;
-
const int q
=
-
(
(sizeof(COLORTYPE
)
==1)?0x01010101:
-
(
sizeof
(
COLORTYPE
)
==2
)
?0x00010001:1)
;
-
sh
=
32
-
i*4
;
-
sprintf
(
buf,"#%0*x%0*x%0*x",i,(r*q)>>
sh
,i,(g*q
)
>>sh,i,
(b
*q)
>>
sh
);
+
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);
}
-
+
}
else
-
switch (sizeof(COLORTYPE))
+
switch (sizeof(COLORTYPE))
/* constant */
{ case 1: sprintf(buf,"#%02x%02x%02x",THIS->rgb.r,THIS->rgb.g,THIS->rgb.b);
647:
other=(struct color_struct*) get_storage(sp[-1].u.object,image_color_program); if (other&&
-
other->
rgb
.r==THIS->
rgb
.r &&
-
other->
rgb
.g==THIS->
rgb
.g &&
-
other->
rgb
.b==THIS->
rgb
.b)
+
other->
rgbl
.r==THIS->
rgbl
.r &&
+
other->
rgbl
.g==THIS->
rgbl
.g &&
+
other->
rgbl
.b==THIS->
rgbl
.b)
{ pop_stack(); push_int(1);
751:
static void image_color_light(INT32 args) { pop_n_elems(args);
-
image_color_
hsv
(0);
+
image_color_
hsvf
(0);
sp--; push_array_items(sp->u.array); /* frees */
-
sp[-1].u.
integer+
=
50
;
+
sp[-1].u.
float_number+
=
+0.2
;
image_make_hsv_color(3); } static void image_color_dark(INT32 args) { pop_n_elems(args);
-
image_color_
hsv
(0);
+
image_color_
hsvf
(0);
sp--; push_array_items(sp->u.array); /* frees */
-
sp[-1].u.
integer
-=
50
;
+
sp[-1].u.
float_number
-=
0.2
;
image_make_hsv_color(3); } static void image_color_neon(INT32 args) { pop_n_elems(args);
-
image_color_
hsv
(0);
+
image_color_
hsvf
(0);
sp--; push_array_items(sp->u.array); /* frees */
-
sp[-1].u.
integer
=
255
;
-
sp[-2].u.
integer
=
255
;
+
+
if (
sp[-1].u.
float_number
=
=0.0 ||
+
sp[-2].u.float_number==0.0)
+
{
+
if (sp[-2].u.float_number<0.5)
+
sp[-2].u.float_number=0.0
;
+
else
+
sp[-2].u.
float_number
=
1.0
;
+
}
+
else
+
{
+
sp[-1].u.float_number=1.0;
+
sp[-2].u.float_number=1.0;
+
}
image_make_hsv_color(3); } static void image_color_dull(INT32 args) { pop_n_elems(args);
-
image_color_
hsv
(0);
+
+
image_color_
hsvf
(0);
sp--; push_array_items(sp->u.array); /* frees */
-
sp[-
2
].u.
integer-
=
50
;
-
sp[-
1
].u.
integer
-=
50
;
+
+
if (
sp[-
1
].u.
float_number
=
=0.0)
+
{
+
pop_n_elems(3)
;
+
ref_push_object(THISOBJ);
+
return;
+
}
+
+
sp[-
2
].u.
float_number
-=
0.2
;
image_make_hsv_color(3); } static void image_color_bright(INT32 args) { pop_n_elems(args);
-
image_color_
hsv
(0);
+
image_color_
hsvf
(0);
sp--; push_array_items(sp->u.array); /* frees */
-
sp[-
2
].u.
integer+
=
50
;
-
sp[-
1
].u.
integer+
=
50
;
+
+
if (
sp[-
1
].u.
float_number
=
=0.0)
+
{
+
pop_n_elems(3)
;
+
ref_push_object(THISOBJ);
+
return;
+
}
+
+
sp[-
2
].u.
float_number+
=
0.2
;
image_make_hsv_color(3); }
856:
} pop_stack(); }
-
return
NULL
;
+
return
0
;
} static void image_color_add(INT32 args)
908:
if (sp[-1].u.string->len>=4 && sp[-1].u.string->str[0]=='#') {
-
/* #rgb, #rrggbb, #rrrgggbbb
or
#rrrrggggbbbb
*/
+
/* #rgb, #rrggbb, #rrrgggbbb
,
etc
*/
unsigned long i=sp[-1].u.string->len-1,j,k,rgb[3]; unsigned char *src=sp[-1].u.string->str+1;
931:
} switch (i) {
-
case 1: z=(z
<<12
)
+
(
z<<8
)
+(z<<4)+(z<<0)
; break;
-
case 2: z=(z
<<8
)
+
(
z<<0
); break;
-
case 3: z=(z
<<4)+
(z>>8); break;
+
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
5
:
z=(z>>4);
break;
-
case 6:
z=(z>>8); break;
-
case 7: z=(z>>
12
);
break;
-
case
8:
z=
(
z>>
16
); break;
+
case
4:
+
case
5:
+
case 6:
+
case 7:
+
case 8:
+
if (i*4<COLORLBITS)
+
z=(z
<<(COLORLBITS-i*4))+(z
>>
(i*8-COLORLBITS
)
)
;
+
else
+
z=z>>
(i*4-COLORLBITS
);
+
break;
}
-
switch (sizeof(COLORTYPE))
-
{
-
case 1: z>>=8; break;
-
case 4: z<<=16; break;
-
}
+
rgb[j]=z; } pop_n_elems(args);
-
push
_
int
((INT32)rgb[0]
);
-
push_int
(
(
INT32)rgb[1]
);
-
push_int((INT32)rgb[2]);
-
image_make_rgb_color
(
3
);
-
+
_
image_make_rgbl_color
((INT32)rgb[0]
,
+
(INT32)rgb[1]
,
+
(
INT32
)
rgb[2])
;
return; } }
1014:
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("grey%f\n");
+
f_sscanf(2);
+
if (sp[-1].type==T_ARRAY &&
+
sp[-1].u.array->size==1)
+
{
+
float f;
+
f=sp[-1].u.array->item[0].u.float_number;
+
pop_stack();
+
sp--;
+
+
return;
}
-
+
pop_stack();
+
}
+
}
/* try other stuff here */
1097:
**! returns the created object. */
+
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));
+
+
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);
+
+
try_find_name(cs);
+
}
+
+
static void _image_make_rgbf_color(float r,float g,float 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
+
}
+
static void _image_make_rgb_color(INT32 r,INT32 g,INT32 b) { struct color_struct *cs;
1113:
cs->rgb.r=(COLORTYPE)r; cs->rgb.g=(COLORTYPE)g; cs->rgb.b=(COLORTYPE)b;
+
RGB_TO_RGBL(cs->rgbl,cs->rgb);
try_find_name(cs); }
1129:
static 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 */
-
+
if (args && sp[-args].type==T_INT)
+
{
+
INT32 hi,si,vi;
get_all_args("Image.color.hsv()",args,"%i%i%i", &hi,&si,&vi); pop_n_elems(args);
1144:
h = (hi/((float)COLORMAX))*(360.0/60.0); s = si/((float)COLORMAX); v = vi/((float)COLORMAX);
+
}
+
else
+
{
+
get_all_args("Image.color.hsv()",args,"%f%f%f",
+
&h,&s,&v);
+
pop_n_elems(args);
+
if (h<0) h=360+h-(((int)h/360)*360);
+
if (h>360.0) h-=(((int)h/360)*360);
+
h/=60;
+
}
-
if(s==0.0
|| si==0
)
+
if(s==0.0)
{ r = g = b = v; } else {
1163:
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: error("internal error\n");
} } #undef i
1170:
#undef p #undef q #undef t
-
#define FOO(X) ((int)((X)<0.0?0:(X)>1.0?COLORMAX:(int)((X)*((float)COLORMAX)+0.5)))
+
-
_image_make_
rgb
_color(
FOO(
r
)
,
FOO(
g
)
,
FOO(
b)
)
;
-
-
#undef FOO
+
_image_make_
rgbf
_color(r,g,b);
} static void image_make_cmyk_color(INT32 args)
1187:
g=100-(m+k); b=100-(y+k);
-
_image_make_
rgb
_color(
(int)(
r*
255.4/100.
0
)
,
-
(int)(
g*
255.4/100.
0
)
,
-
(int)(
b*
255.4/100.
0)
)
;
+
_image_make_
rgbf
_color(r*
0
.
01
,g*
0
.
01
,b*
0
.
01
);
} static void image_make_greylevel_color(INT32 args)
1283:
/* color info methods */ add_function("cast",image_color_cast,
-
"function(string:array|string)",
OPT_TRY_OPTIMIZE
);
+
"function(string:array|string)",
/* opt */0
);
add_function("`[]",image_color_index,
-
"function(string|int:int|function)",
OPT_TRY_OPTIMIZE
);
+
"function(string|int:int|function)",
/* opt */0
);
add_function("`->",image_color_index,
-
"function(string|int:int|function)",
OPT_TRY_OPTIMIZE
);
+
"function(string|int:int|function)",
/* opt */0
);
add_function("`==",image_color_equal,
-
"function(object|int:int)",
OPT_TRY_OPTIMIZE
);
+
"function(object|int:int)",
/* opt */0
);
add_function("name",image_color_name,
-
"function(:string)",
OPT_TRY_OPTIMIZE
);
+
"function(:string)",
/* opt */0
);
add_function("hex",image_color_hex,
-
"function(:string)",
OPT_TRY_OPTIMIZE
);
+
"function(:string)",
/* opt */0
);
add_function("html",image_color_html,
-
"function(:string)",
OPT_TRY_OPTIMIZE
);
+
"function(:string)",
/* opt */0
);
add_function("rgb",image_color_rgb,
-
"function(:array)",
OPT_TRY_OPTIMIZE
);
+
"function(:array
(int
)
)
",
/* opt */0
);
add_function("hsv",image_color_hsv,
-
"function(:array)",
OPT
_
TRY
_
OPTIMIZE
);
+
"function(:array
(int
)
)
",
/* opt */0);
+
add
_
function("hsvf",image
_
color_hsvf,
+
"function(:array(float
)
)",/* opt */0)
;
add_function("cmyk",image_color_cmyk,
-
"function(:array)",
OPT_TRY_OPTIMIZE
);
+
"function(:array
(float
)
)
",
/* opt */0
);
add_function("greylevel",image_color_greylevel,
-
"function(:int)|function(int,int,int:int)",
OPT_TRY_OPTIMIZE
);
+
"function(:int)|function(int,int,int:int)",
/* opt */0
);
/* color conversion methods */ add_function("grey",image_color_grey, "function(:object)|function(int,int,int:object)",
-
OPT_TRY_OPTIMIZE
);
+
/* opt */0
);
add_function("light",image_color_light,
-
"function(:object)",
OPT_TRY_OPTIMIZE
);
+
"function(:object)",
/* opt */0
);
add_function("dark",image_color_dark,
-
"function(:object)",
OPT_TRY_OPTIMIZE
);
+
"function(:object)",
/* opt */0
);
add_function("neon",image_color_neon,
-
"function(:object)",
OPT_TRY_OPTIMIZE
);
+
"function(:object)",
/* opt */0
);
add_function("bright",image_color_bright,
-
"function(:object)",
OPT_TRY_OPTIMIZE
);
+
"function(:object)",
/* opt */0
);
add_function("dull",image_color_dull,
-
"function(:object)",
OPT_TRY_OPTIMIZE
);
+
"function(:object)",
/* opt */0
);
add_function("`*",image_color_mult,
-
"function(float:object)",
OPT_TRY_OPTIMIZE
);
+
"function(float:object)",
/* opt */0
);
add_function("`+",image_color_add,
-
"function(object:object)",
OPT_TRY_OPTIMIZE
);
+
"function(object:object)",
/* opt */0
);
image_color_program=end_program(); start_new_program(); add_function("`[]",image_get_color,
-
"function(string:object)",
OPT_TRY_OPTIMIZE
);
+
"function(string:object)",
/* opt */0
);
add_function("`()",image_make_color,
-
"function(string|int...:object)",
OPT_TRY_OPTIMIZE
);
+
"function(string|int...:object)",
/* opt */0
);
add_function("rgb",image_make_rgb_color,
-
"function(int,int,int:object)",
OPT_TRY_OPTIMIZE
);
+
"function(int,int,int:object)",
/* opt */0
);
add_function("hsv",image_make_hsv_color,
-
"function(int,int,int:object)",
OPT_TRY_OPTIMIZE
);
+
"function(int,int,int:object)
|
"
+
"function(float
,
float,float:object
)
",/* opt */0)
;
add_function("cmyk",image_make_cmyk_color, "function(int|float,int|float,int|float,int|float:object)",
-
OPT_TRY_OPTIMIZE
);
+
/* opt */0
);
add_function("html",image_make_html_color,
-
"function(string:object)",
OPT_TRY_OPTIMIZE
);
+
"function(string:object)",
/* opt */0
);
add_function("guess",image_guess_color,
-
"function(string:object)",
OPT_TRY_OPTIMIZE
);
+
"function(string:object)",
/* opt */0
);
add_function("greylevel",image_make_greylevel_color,
-
"function(int:object)",
OPT_TRY_OPTIMIZE
);
+
"function(int:object)",
/* opt */0
);
add_function("_indices",image_colors_indices,
-
"function(:array(string))",
OPT_TRY_OPTIMIZE
);
+
"function(:array(string))",
/* opt */0
);
add_function("_values",image_colors_values,
-
"function(:array(object))",
OPT_TRY_OPTIMIZE
);
+
"function(:array(object))",
/* opt */0
);
add_program_constant("color",image_color_program,0);