libtthimage/Lib/calculs.c

275 lines
5.9 KiB
C

/*
calculs.c
---------
voir aussi: distances.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
/* pour les performances, cette fonction
pourrait devenir une #macro ?
*/
int
Image_clamp_pixel(int value)
{
if (value < 0) return 0;
if (value > 255) return 255;
return value;
}
/*::------------------------------------------------------------------::*/
/* new, 2001 June
*
* 23 Fev 2002: parfois (recurse ?) on passe plein de fois dans
* cette fonction. Est-il raisonnable d'optimiser en passant par
* les accès direct à la mémoire ? Oui, si on améliore les
* controles de XY ...
*/
int
Image_stats_zone_0(Image_Desc *img, Image_Rect *zone,
int *pmr, int *pmg, int *pmb,
int *pdr, int *pdg, int *pdb)
{
int x, y;
int r, g, b;
int r0, r1, g0, g1, b0, b1;
long pixels = 0;
if ( (zone->w < 2) || (zone->h < 2) )
{
Image_dump_rect(zone, "stat_zone_0: too small!", 0);
return RECT_TOO_SMALL;
}
*pmr = *pmg = *pmb = 0;
r0 = g0 = b0 = 300;
r1 = g1 = b1 = -10;
for (x=0; x<zone->w; x++)
{
for (y=0; y<zone->h; y++)
{
r = (img->Rpix[y+zone->y])[x+zone->x];
g = (img->Gpix[y+zone->y])[x+zone->x];
b = (img->Bpix[y+zone->y])[x+zone->x];
*pmr += r;
*pmg += g;
*pmb += b;
if (r > r1) r1 = r;
if (r < r0) r0 = r;
if (g > g1) g1 = g;
if (g < g0) g0 = g;
if (b > b1) b1 = b;
if (b < b0) b0 = b;
pixels ++;
}
}
#if DEBUG_LEVEL > 3
fprintf(stderr, "Calc zone 0: sommes %d %d %d\n", *pmr, *pmg, *pmb);
#endif
*pmr /= (zone->w*zone->h);
*pmg /= (zone->w*zone->h);
*pmb /= (zone->w*zone->h);
if (NULL != pdr) *pdr = r1 - r0;
if (NULL != pdr) *pdg = g1 - g0;
if (NULL != pdr) *pdb = b1 - b0;
/* XXX TO BE GARDED ABOUT NULL PTRS
if ( (*pdr<0) || (*pdg<0) || (*pdb<0) )
{
Image_dump_rect(zone, "negative in stat_zone_0", 0);
fprintf(stderr, "%ld / %d %d %d %d %d %d\n",
pixels, r0, r1, g0, g1, b0, b1);
}
XXX */
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* reserved for debugging the library. (never finished work :)
*/
int
Image_quelques_calculs(Image_Desc *image)
{
long surface, somme;
int x, y, r, g, b, idx;
int *compte4bits;
surface = image->width * image->height;
printf("surface de l'image = %ld pixels\n", surface);
if ( (compte4bits = (int *)calloc(1<<12, sizeof(int))) == NULL )
{
fprintf(stderr, "erreur calloc(surface)\n");
return 1;
}
for (x=0; x<image->width; x++)
{
for (y=0; y<image->height; y++)
{
r = (image->Rpix[y])[x] >> 4;
g = (image->Gpix[y])[x] >> 4;
b = (image->Bpix[y])[x] >> 4;
idx = (r<<8) | (g<<4) | b;
compte4bits[idx]++;
}
}
somme = 0;
for (idx=0; idx<(1<<12); idx++)
{
if (compte4bits[idx]) somme++;
}
printf("la somme '4bits' est %ld\n", somme);
return 0;
}
/*::------------------------------------------------------------------::*/
/*
* on pourrait rapprocher cette fonction de la fonction
* qui calcule la couleur moyenne d'une image.
* son nom est "Image_??????????????" et elle reside
* dans le module "colors.c".
*/
int
Image_minmax_RGB(Image_Desc *img, int *res)
{
int x, y, r, g, b, minr, ming, minb, maxr, maxg, maxb;
minr = ming = minb = 300;
maxr = maxg = maxb = -42;
for (x=0; x<img->width; x++)
{
for (y=0; y<img->height; y++)
{
r = Image_R_pixel(img, x, y);
if (r > maxr) maxr = r;
else if (r < minr) minr = r;
g = Image_G_pixel(img, x, y);
if (g > maxg) maxg = g;
else if (g < ming) ming = g;
b = Image_B_pixel(img, x, y);
if (b > maxb) maxb = b;
else if (b < minb) minb = b;
}
}
/*
* and now populate the return vector...
*/
res[0] = minr; res[1] = maxr;
res[2] = ming; res[3] = maxg;
res[4] = minb; res[5] = maxb;
/*
* et c,a serait cool de lui faire traiter le canal alpha...
*/
res[6] = res[7] = -1;
return 0;
}
/*::------------------------------------------------------------------::*/
/*
25 Aout 1999.
gaffe, les @ des buffers pour les histogrames
proviennent parfois de 'alloca'...
*/
int
Image_histo_RGB(Image_Desc *im, long *hr, long *hg, long *hb)
{
int foo, x, y;
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : %p --> %p %p %p\n", __func__, im, hr, hg, hb);
#endif
for (foo=0; foo<256; foo++) {
hr[foo] = 0L;
hg[foo] = 0L;
hb[foo] = 0L;
}
for (y=0; y<im->height; y++) {
for (x=0; x<im->width; x++) {
hr[(im->Rpix[y])[x]]++;
hg[(im->Gpix[y])[x]]++;
hb[(im->Bpix[y])[x]]++;
}
}
return 0;
}
/*::------------------------------------------------------------------::*/
/*
* 5 Fev 2001: optimization for spe3ed.
*/
int
Image_LUT_RGB(Image_Desc *src, Image_Desc *dst, int *lr, int *lg, int *lb)
{
int x, y, foo;
if ( (foo=Image_compare_desc(src, dst)) )
{
fprintf(stderr, "Image_LUT_RGB: images differentes %d\n", foo);
return foo;
}
for (y=0; y<src->height; y++)
{
for (x=0; x<src->width; x++)
{
dst->Rpix[y][x] = lr[src->Rpix[y][x]];
dst->Gpix[y][x] = lg[src->Gpix[y][x]];
dst->Bpix[y][x] = lb[src->Bpix[y][x]];
}
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
int Image_LUT_mono(Image_Desc *src, Image_Desc *dst, int *lut)
{
int x, y, foo;
if ( (foo=Image_compare_desc(src, dst)) )
{
fprintf(stderr, "%s: images differentes %d\n", __func__, foo);
return foo;
}
for (y=0; y<src->height; y++)
{
for (x=0; x<src->width; x++)
{
dst->Rpix[y][x] = lut[src->Rpix[y][x]];
dst->Gpix[y][x] = lut[src->Gpix[y][x]];
dst->Bpix[y][x] = lut[src->Bpix[y][x]];
}
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* et en parlant de LUTs, il n'y aurait pas un truc pour les LUTs
* avec les height-fields ? */