/* calculs.c --------- voir aussi: distances.c */ #include #include #include #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; xw; x++) { for (y=0; yh; 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; xwidth; x++) { for (y=0; yheight; 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; xwidth; x++) { for (y=0; yheight; 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; yheight; y++) { for (x=0; xwidth; 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; yheight; y++) { for (x=0; xwidth; 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; yheight; y++) { for (x=0; xwidth; 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 ? */