2022-06-26 11:06:35 +02:00
|
|
|
/*
|
|
|
|
colors.c
|
|
|
|
--------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h> /* for rand() */
|
|
|
|
#include <time.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#ifdef NEED_ALLOCA_H
|
|
|
|
#include <alloca.h>
|
|
|
|
#endif
|
|
|
|
|
2022-06-27 02:19:31 +02:00
|
|
|
#include "../tthimage.h"
|
2022-06-26 11:06:35 +02:00
|
|
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
echange de deux composantes d'une image RGB
|
|
|
|
what about swapping with the alpha channel ?
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_swap_colors(Image_Desc *im, char *cols)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
uint8_t *buffer;
|
|
|
|
int y, code;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "Echange de couleurs: [%s] %p\n", cols, im);
|
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (strlen(cols) != 2) {
|
|
|
|
fprintf(stderr, "%s: bad control string: '%s'\n", __func__, cols);
|
2022-06-26 11:06:35 +02:00
|
|
|
return INVALID_PARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
code = 0;
|
2022-09-15 17:47:16 +02:00
|
|
|
switch (cols[0]) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 'r': case 'R': code |= 0x10; break;
|
|
|
|
case 'g': case 'G': code |= 0x20; break;
|
|
|
|
case 'b': case 'B': code |= 0x30; break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "SwapColors: bad first color '%c'\n", cols[0]);
|
|
|
|
return INVALID_PARAM;
|
|
|
|
}
|
2022-09-15 17:47:16 +02:00
|
|
|
switch (cols[1]) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 'r': case 'R': code |= 0x1; break;
|
|
|
|
case 'g': case 'G': code |= 0x2; break;
|
|
|
|
case 'b': case 'B': code |= 0x3; break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "SwapColors: bad second color '%c'\n", cols[0]);
|
|
|
|
return INVALID_PARAM;
|
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( (buffer=(uint8_t *)alloca(im->width)) == NULL ) {
|
|
|
|
fprintf(stderr, "%s: no mem for buffer\n", __func__);
|
2022-06-26 11:06:35 +02:00
|
|
|
return BUFFER_NO_MEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, "%s: code is %02x, buffer at %p\n", __func__, code, buffer);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<im->height; y++) {
|
|
|
|
switch (code) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 0x12: case 0x21:
|
|
|
|
memcpy(buffer, im->Rpix[y], im->width);
|
|
|
|
memcpy(im->Rpix[y], im->Gpix[y], im->width);
|
|
|
|
memcpy(im->Gpix[y], buffer, im->width);
|
|
|
|
break;
|
|
|
|
case 0x13: case 0x31:
|
|
|
|
memcpy(buffer, im->Rpix[y], im->width);
|
|
|
|
memcpy(im->Rpix[y], im->Bpix[y], im->width);
|
|
|
|
memcpy(im->Bpix[y], buffer, im->width);
|
|
|
|
break;
|
|
|
|
case 0x23: case 0x32:
|
|
|
|
memcpy(buffer, im->Bpix[y], im->width);
|
|
|
|
memcpy(im->Bpix[y], im->Gpix[y], im->width);
|
|
|
|
memcpy(im->Gpix[y], buffer, im->width);
|
|
|
|
break;
|
|
|
|
default:
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, "%s: code=%02x, Aie.\n", __func__, code);
|
2022-06-26 11:06:35 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
im->modified = 1;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
cette func est cense donner une couleur RVB en
|
|
|
|
fonction de deux parametre [0..1], mais c,a marche
|
|
|
|
pas terrible, alors je vais faire encore des essais
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_color_x(double v1, double v2, int *pr, int *pg, int *pb)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
double s, c;
|
|
|
|
|
|
|
|
s = sin(v1*M_PI) + 1.0; c = cos(v1*M_PI) + 1.0;
|
|
|
|
|
|
|
|
*pr = (int) (s * 127.0);
|
|
|
|
*pg = (int) (c * 127.0);
|
|
|
|
*pb = (int) (v2 * 255.0);
|
|
|
|
|
|
|
|
/* printf("%8f %8f %3d %3d %3d\n", v1, v2, *pr, *pg, *pb); */
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* Calcul de la couleur moyenne sur l'ensemble d'une image
|
|
|
|
* Il doit exister quelque part la meme fonction pour ce
|
|
|
|
* calcul sur une zone rectangulaire d'une image.
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_couleur_moyenne(Image_Desc *im, int *pr, int *pg, int *pb)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
long sr, sg, sb, surface;
|
|
|
|
|
|
|
|
sr = sg = sb = 0L;
|
|
|
|
|
|
|
|
for (y=0; y<im->height; y++) {
|
|
|
|
for (x=0; x<im->width; x++) {
|
|
|
|
sr += im->Rpix[y][x];
|
|
|
|
sg += im->Gpix[y][x];
|
|
|
|
sb += im->Bpix[y][x];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
surface = (long)im->width * (long)im->height;
|
|
|
|
sr /= surface; sg /= surface; sb /= surface;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "couleurs moyennes : r=%ld g=%ld b=%ld\n", sr, sg, sb);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*pr = (int)sr; *pg = (int)sg; *pb = (int)sb;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* nouveau 28 juillet 2008 - avenue St Exupery
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_saturate(Image_Desc *src, Image_Desc *dst, int sr, int sg, int sb)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int foo;
|
|
|
|
int minmax[6];
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p %d %d %d )", __func__, src, dst,
|
|
|
|
sr, sg, sb);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
|
|
|
foo = Image_minmax_RGB(src, minmax); /* pourquoi faire ce truc ici ? */
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, " calcul minmax -> %d\n", foo);
|
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
for (x=0; x<src->width; x++)
|
|
|
|
{
|
|
|
|
/* et il faut faire quoi, exactement ? */
|
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Rpix[y][x];
|
|
|
|
b = src->Rpix[y][x];
|
|
|
|
/* je n'en ai pas la moindre ideee LOL */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* nouveau 12 mars 2009 - avenue St Exupery, avec du "Gros plant nantais"
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_desaturate(Image_Desc *src, Image_Desc *dst, int sr, int sg, int sb)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p %d %d %d )", __func__, src, dst,
|
|
|
|
sr, sg, sb);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
|
|
|
for (x=0; x<src->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
|
|
|
|
if (r < sr) r = sr;
|
|
|
|
if (g < sg) g = sg;
|
|
|
|
if (b < sb) b = sb;
|
|
|
|
|
|
|
|
if (r > 256-sr) r = (256-sr);
|
|
|
|
if (g > 256-sg) g = (256-sg);
|
|
|
|
if (b > 256-sb) b = (256-sb);
|
|
|
|
|
|
|
|
src->Rpix[y][x] = r;
|
|
|
|
src->Gpix[y][x] = g;
|
|
|
|
src->Bpix[y][x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
Je ne sais plus d'ou sort cette formule, ni a quoi
|
|
|
|
elle sert, ni comment faire le calcul inverse.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
Image_RGB_2_HLS(int r, int g, int b, int *ph, int *pl, int *ps)
|
|
|
|
{
|
|
|
|
double C1, C2, S, L, H;
|
|
|
|
|
|
|
|
C1 = sqrt(1.5) * (double)(r-g);
|
|
|
|
C2 = b - 0.5 * (double)(r+g);
|
|
|
|
S = sqrt((C1*C1) + (C2*C2));
|
|
|
|
L = (r+g+b) / 3.0;
|
|
|
|
H = acos(C1/S);
|
|
|
|
if (C2 < 0.0) H = (2*M_PI) - H;
|
|
|
|
|
|
|
|
*ph = H; *ps = S; *pl = L;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* nouveau 12Jun2001
|
|
|
|
* 16 Dec 2001: not fully tested, may be bogus :-(
|
|
|
|
*/
|
|
|
|
int Image_color_shift_rgb(Image_Desc *s, Image_Desc *d, int rs, int gs, int bs)
|
|
|
|
{
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int foo;
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( (foo=Image_compare_desc(s, d)) ) {
|
|
|
|
fprintf(stderr, "%s: src & dst are differents (%d)\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "Shift RGB: %d %d %d\n", rs, gs, bs);
|
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<s->height; y++) {
|
|
|
|
for (x=0; x<s->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = (s->Rpix[y][x] + rs) % 256;
|
|
|
|
g = (s->Gpix[y][x] + gs) % 256;
|
|
|
|
b = (s->Bpix[y][x] + bs) % 256;
|
|
|
|
|
|
|
|
d->Rpix[y][x] = r;
|
|
|
|
d->Gpix[y][x] = g;
|
|
|
|
d->Bpix[y][x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d->modified = 1;
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
dans cette fonction, plein de trucs sont calcules en
|
|
|
|
'double float' mais est-ce bien necessaire ?
|
|
|
|
|
|
|
|
* 16 Dec 2001: not fully tested, may be bogus :-(
|
|
|
|
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_colors_recenter_0(Image_Desc *s, Image_Desc *d)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int or, og, ob;
|
|
|
|
double cr, cg, cb, surface;
|
|
|
|
|
|
|
|
fprintf(stderr, "Image_colors_recenter_0 is a work in progress... ymmv.\n");
|
|
|
|
|
|
|
|
cr = cg = cb = 0.0;
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<s->height; y++) {
|
|
|
|
for (x=0; x<s->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
Image_getRGB(s, x, y, &r, &g, &b);
|
|
|
|
cr += (double)r;
|
|
|
|
cg += (double)g;
|
|
|
|
cb += (double)b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf(stderr, "colors recenter 0: %g %g %g\n", cr, cg, cb);
|
|
|
|
surface = (double)(s->width*s->height);
|
|
|
|
fprintf(stderr, "colors recenter 0: surface image %g\n", surface);
|
|
|
|
|
|
|
|
or = (int)(cr / surface);
|
|
|
|
og = (int)(cg / surface);
|
|
|
|
ob = (int)(cb / surface);
|
|
|
|
or -= 127;
|
|
|
|
og -= 127;
|
|
|
|
ob -= 127;
|
|
|
|
fprintf(stderr, "colors recenter 0: %d %d %d\n", or, og, ob);
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<s->height; y++) {
|
|
|
|
for (x=0; x<s->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
Image_getRGB(s, x, y, &r, &g, &b);
|
|
|
|
r = Image_clamp_pixel(r + or);
|
|
|
|
g = Image_clamp_pixel(g + og);
|
|
|
|
b = Image_clamp_pixel(b + ob);
|
|
|
|
(d->Rpix[y])[x] = r;
|
|
|
|
(d->Gpix[y])[x] = g;
|
|
|
|
(d->Bpix[y])[x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
#define CUB(x) ((x)*(x))
|
|
|
|
/*
|
|
|
|
* XXX manque des explications sur l'usage du parametre 'mode'
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
Image_colors_2_Map(Image_Desc *s, Image_Desc *d, RGB_map * map, int mode)
|
|
|
|
{
|
|
|
|
int foo, x, y, m;
|
|
|
|
int sr, sg, sb, dr, dg, db;
|
|
|
|
long mindist, pos, dist;
|
|
|
|
|
|
|
|
if ( (foo=Image_compare_desc(s, d)) ) return foo;
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( map->nbre == 0 ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, "%s: empty map at %p\n", __func__, map);
|
|
|
|
/*
|
|
|
|
* WTF ? we have an empty map ?!? *
|
|
|
|
*/
|
|
|
|
return EMPTY_COL_MAP;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "Colors 2 Map: %d couleurs dans la map\n", map->nbre);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
pos = 0; /* XXX verifier a quoi c,a sert ?! */
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<s->height; y++) {
|
|
|
|
for (x=0; x<s->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
mindist = 99999999;
|
|
|
|
sr = s->Rpix[y][x];
|
|
|
|
sg = s->Gpix[y][x];
|
|
|
|
sb = s->Bpix[y][x];
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (m=0; m<map->nbre; m++) {
|
|
|
|
switch (mode) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 0:
|
|
|
|
dist = CUB(sr-map->red[m]) +
|
|
|
|
CUB(sg-map->green[m]) +
|
|
|
|
CUB(sb-map->blue[m]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* There was probably a bug in this case...
|
|
|
|
*/
|
|
|
|
case 1:
|
|
|
|
dr = abs(sr - map->red[m]);
|
|
|
|
dg = abs(sg - map->green[m]);
|
|
|
|
db = abs(sb - map->blue[m]);
|
|
|
|
dist = dr;
|
|
|
|
if (dg < dist) dist = dg;
|
|
|
|
if (db < dist) dist = db;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
dr = abs(sr-map->red[m]);
|
|
|
|
dg = abs(sg-map->green[m]);
|
|
|
|
db = abs(sb-map->blue[m]);
|
|
|
|
dist = dr + dg + db;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
dist = CUB(sr-map->red[m]);
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
dist = CUB(sg-map->green[m]);
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
dist = CUB(sb-map->blue[m]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "Colors To Map: invalid mode %d\n", mode);
|
|
|
|
return INVALID_PARAM;
|
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (dist < mindist) {
|
2022-06-26 11:06:35 +02:00
|
|
|
pos = m; mindist = dist;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(d->Rpix[y])[x] = map->red[pos];
|
|
|
|
(d->Gpix[y])[x] = map->green[pos];
|
|
|
|
(d->Bpix[y])[x] = map->blue[pos];
|
|
|
|
}
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
if ( ! (y % 42) )
|
|
|
|
fprintf(stderr, "remapping line %4d / %d\r", y, s->height);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
d->modified = 1;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* ces coeffs viennent de Povray (a verifier) */
|
|
|
|
|
|
|
|
#define R_COEF 297
|
|
|
|
#define G_COEF 589
|
|
|
|
#define B_COEF 114
|
|
|
|
#define RGB_DIV (R_COEF+G_COEF+B_COEF)
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_to_gray_k(Image_Desc *s, Image_Desc *d, int kr, int kg, int kb, int flag)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b, v, foo;
|
|
|
|
int grey, diviseur;
|
|
|
|
int vmax;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "converting image %p to gray in %p, flag %d\n", s, d, flag);
|
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if ( (foo=Image_compare_desc(s, d)) ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, "To Gray: src & dst are differents (%d)\n", foo);
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
|
|
|
diviseur = kr + kg + kb;
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "to Gray K: %d %d %d %d\n", kr, kg, kb, diviseur);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
if (flag==1) {
|
|
|
|
fprintf(stderr, "%s: %d %d %d -> %d\n", __func__,
|
|
|
|
kr, kg, kb, diviseur);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (diviseur==0) {
|
|
|
|
fprintf(stderr, "%s: divisor is 0\n", __func__);
|
|
|
|
return DIVISOR_IS_ZERO;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmax = 0;
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<s->height; y++) {
|
|
|
|
for (x=0; x<s->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = s->Rpix[y][x];
|
|
|
|
g = s->Gpix[y][x];
|
|
|
|
b = s->Bpix[y][x];
|
|
|
|
grey = (r * kr) + (g * kg) + (b * kb);
|
|
|
|
v = grey / diviseur;
|
|
|
|
|
|
|
|
if (v > vmax) vmax=v;
|
|
|
|
|
|
|
|
d->Rpix[y][x] = v;
|
|
|
|
d->Gpix[y][x] = v;
|
|
|
|
d->Bpix[y][x] = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
if (flag==1) {
|
|
|
|
fprintf(stderr, "%s: max value is %d\n", __func__, vmax);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
d->modified = 1;
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-09-21 00:06:11 +02:00
|
|
|
/* what are the three magic constants *_COEF ?
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_to_gray(Image_Desc *s, Image_Desc *d, int flag)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, "Image to gray: flag is %d\n", flag);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
foo=Image_to_gray_k(s, d, 100, 100, 100, flag);
|
|
|
|
else
|
|
|
|
foo=Image_to_gray_k(s, d, R_COEF, G_COEF, B_COEF, flag);
|
|
|
|
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* 8 Jan 2001
|
|
|
|
*
|
|
|
|
* et on fait quoi si il y a pas assez de couleurs dans la MAP ?
|
|
|
|
* ben, on patche ?
|
|
|
|
*/
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_apply_Map(Image_Desc *src, Image_Desc *dst, RGB_map *map)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, src, dst, map);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (map->nbre == 0) {
|
|
|
|
fprintf(stderr, "%s: no colors in palette ?\n", __func__);
|
2022-06-26 11:06:35 +02:00
|
|
|
return EMPTY_COL_MAP;
|
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (map->nbre < 255) {
|
|
|
|
fprintf(stderr, "%s: only %d cols in palette\n", __func__, map->nbre);
|
2022-06-26 11:06:35 +02:00
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
|
|
|
for (x=0; x<src->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = (src->Rpix[y])[x];
|
|
|
|
g = (src->Gpix[y])[x];
|
|
|
|
b = (src->Bpix[y])[x];
|
|
|
|
|
|
|
|
r = map->red[r];
|
|
|
|
g = map->green[g];
|
|
|
|
b = map->blue[b];
|
|
|
|
|
|
|
|
(dst->Rpix[y])[x] = r;
|
|
|
|
(dst->Gpix[y])[x] = g;
|
|
|
|
(dst->Bpix[y])[x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dst->modified = 1;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* 8 May 2001
|
|
|
|
et on fait quoi si il y a pas assez de couleurs dans la MAP ? */
|
2022-09-15 17:47:16 +02:00
|
|
|
int Image_gray_Map(Image_Desc *src, Image_Desc *dst, RGB_map *map)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int x, y, r, g, b, gray;
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (map->nbre == 0) {
|
|
|
|
fprintf(stderr, "%s: no colors in palette ?\n", __func__);
|
2022-06-26 11:06:35 +02:00
|
|
|
return VERY_STRANGE;
|
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
if (map->nbre < 255) {
|
|
|
|
fprintf(stderr, "%s: only %d cols in palette\n", __func__, map->nbre);
|
2022-06-26 11:06:35 +02:00
|
|
|
}
|
|
|
|
|
2022-09-15 17:47:16 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
|
|
|
for (x=0; x<src->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = (src->Rpix[y])[x];
|
|
|
|
g = (src->Gpix[y])[x];
|
|
|
|
b = (src->Bpix[y])[x];
|
|
|
|
gray = ((r * R_COEF) + (g * G_COEF) + (b * B_COEF)) / RGB_DIV;
|
2022-09-15 17:47:16 +02:00
|
|
|
if (gray<0 || gray>255) {
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, "%s: GRAY---- %d\n", __func__, gray);
|
|
|
|
exit(5);
|
|
|
|
}
|
|
|
|
r = map->red[gray];
|
|
|
|
g = map->green[gray];
|
|
|
|
b = map->blue[gray];
|
|
|
|
|
|
|
|
(dst->Rpix[y])[x] = r;
|
|
|
|
(dst->Gpix[y])[x] = g;
|
|
|
|
(dst->Bpix[y])[x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dst->modified = 1;
|
|
|
|
|
|
|
|
return OLL_KORRECT;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* new 10 janvier 2009 - avenue St Exupery */
|
|
|
|
static int parse_3_ints(char *str, int ints[])
|
|
|
|
{
|
|
|
|
char *cptr, sep[] = " \t,";
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, str, ints);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
cptr = strtok(str, sep);
|
|
|
|
while (NULL != cptr) {
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "%3d %p -> %s\n", idx, cptr, cptr);
|
|
|
|
#endif
|
|
|
|
ints[idx] = atoi(cptr);
|
|
|
|
cptr = strtok(NULL, sep);
|
|
|
|
if (3 == idx) break;
|
|
|
|
idx ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Image_default_RGBA(RGBA *ptr, char *texte, int flags)
|
|
|
|
{
|
|
|
|
char *envptr;
|
|
|
|
int foo;
|
|
|
|
int values[4];
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-15 17:47:16 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p '%s' 0x%x )\n", __func__, ptr, texte, flags);
|
2022-06-26 11:06:35 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( NULL != (envptr=getenv(ENV_DEFAULT_RGBA)) ) {
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "default rgb = '%s'\n", envptr);
|
|
|
|
#endif
|
|
|
|
/* got the env var, parse it now */
|
|
|
|
foo = parse_3_ints(envptr, values);
|
|
|
|
ptr->r = values[0];
|
|
|
|
ptr->g = values[1];
|
|
|
|
ptr->b = values[2];
|
2022-09-15 17:47:16 +02:00
|
|
|
ptr->a = values[3]; /* wtf ? */
|
2022-06-26 11:06:35 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "no '%s' env var defined\n", ENV_DEFAULT_RGBA);
|
|
|
|
ptr->r = ptr->g = ptr->b = ptr->a = 142;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* quick and dirties default values */
|
|
|
|
ptr->reserved = 0x42516988;
|
|
|
|
ptr->reserved2 = time(NULL);
|
|
|
|
|
|
|
|
return FUNC_IS_BETA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|