libtthimage/Lib/col4bits.c

154 lines
3.3 KiB
C

/*
col4bits.c
this module is dedicated to functions who works on
4096 colors images. You got four bits by components.
*/
#include <stdio.h>
#include <stdlib.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
int Image_col4bits_and(Image_Desc *src, Image_Desc *dst)
{
int foo;
if ((foo=Image_compare_desc(src, dst))) {
fprintf(stderr, "%s : images not compatibles\n", __func__);
return foo;
}
foo = Image_copy(src, dst);
if (foo) {
fprintf(stderr, "In %s: copy: err #%d %s\n", __func__,
foo, Image_err2str(foo));
return foo;
}
foo = Image_and_pix(dst, 0xf0, 0xf0, 0xf0);
if (foo) {
fprintf(stderr, "In %s: and pix: err #%d %s\n", __func__,
foo, Image_err2str(foo));
return foo;
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
struct elem
{
long compte;
int rgb;
};
static int compare_compteur(struct elem *p1, struct elem *p2)
{
/* printf("%8d %8d\n", p1->compte, p2->compte); */
return (p2->compte - p1->compte);
}
static int compare_teinte(struct elem *p1, struct elem *p2)
{
int r1, g1, b1, r2, b2, g2;
r1 = (( (p1->rgb) >>8)&0xf)<<4;
g1 = (( (p1->rgb) >>4)&0xf)<<4;
b1 = ( (p1->rgb) &0xf)<<4;
r2 = (( (p2->rgb) >>8)&0xf)<<4;
g2 = (( (p2->rgb) >>4)&0xf)<<4;
b2 = ( (p2->rgb) &0xf)<<4;
/* printf("%8d %8d\n", p1->compte, p2->compte);
return (p1->rgb - p2->rgb); */
return ( (r1+g1+b1) - (r2+g2+b2) );
}
/*::------------------------------------------------------------------::*/
#define TAILLE (1<<12)
int Image_calc_Map_4bits(Image_Desc *img, RGB_map *map, int nbre)
{
long surface, maxi;
int x, y, r, g, b, idx;
struct elem elems[TAILLE];
#if DEBUG_LEVEL
fprintf(stderr, " Calc map 4 bits: nbre = %d\n", nbre);
#endif
if ( (nbre<1) || (nbre>255) ) {
fprintf(stderr, "Calc map 4 bits: nbre %d out of range\n", nbre);
return BAD_COLOR_NUMBER;
}
surface = img->width * img->height;
#if DEBUG_LEVEL
fprintf(stderr, " calc Map 4 bits: surface de l'image = %ld pixels\n", surface);
#endif
for (x=0; x<TAILLE; x++) {
elems[x].compte = 0L;
elems[x].rgb = x;
}
maxi = 0L;
for (x=0; x<img->width; x++) {
for (y=0; y<img->height; y++) {
r = (img->Rpix[y])[x] >> 4;
g = (img->Gpix[y])[x] >> 4;
b = (img->Bpix[y])[x] >> 4;
idx = (r<<8) | (g<<4) | b;
if (idx >= TAILLE) {
fprintf(stderr, "FATAL ERROR in %s\n", __func__);
exit(5);
}
elems[idx].compte++;
if (elems[idx].compte > maxi)
maxi = elems[idx].compte;
}
}
#if DEBUG_LEVEL
fprintf(stderr, " Map4bits: compte maximum = %ld\n", maxi);
#endif
/*
* trier la table pour avoir les couleurs les plus
* frequentes en haut.
*/
qsort(elems, TAILLE, sizeof(struct elem), compare_compteur);
/*
* trier la palette, certe, mais dans quel ordre ?
* 28 Jan 2002: why ?
*/
qsort(elems, nbre, sizeof(struct elem), compare_teinte);
/*
* recopier les 'nbre' entrees hautes dans la palette
*/
for(x=0; x<nbre; x++) {
y = elems[x].rgb;
r = ((y>>8)&0xf)<<4;
g = ((y>>4)&0xf)<<4;
b = (y&0xf)<<4;
/* printf("%06x %02x %02x %02x\n", x, r, g, b); */
map->red[x] = r;
map->green[x] = g;
map->blue[x] = b;
}
map->nbre = nbre;
#if DEBUG_LEVEL
fprintf(stderr, "Image_calc_Map_4bits: fini!\n");
#endif
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/