/* palettes.c ---------- for more informations about color maps, you can seek the web from this starting point: http://www.fractint.org/ */ #include #include /* for rand() */ #include #include #include "../tthimage.h" /*::------------------------------------------------------------------::*/ /* * Les colors maps sont censees etre compatible avec celles * de FRACTINT, mais il faudrait verifier. */ int Image_save_color_Map(char *file, char *name, RGB_map *map) { int foo; FILE *fp; if ( (fp=fopen(file, "w")) == NULL ) { fprintf(stderr, "Save Color Map: err fopen\n"); return FILE_CREATE_ERR; } if ( map->nbre == 0 ) { fprintf(stderr, "Save Color Map: empty map\n"); } for (foo=0; foonbre; foo++) { fprintf(fp, "%3d %3d %3d", map->red[foo], map->green[foo], map->blue[foo]); switch (foo) { case 0: if (name != NULL) fprintf(fp, " Name: %s", name); else fprintf(fp, " Anne Onim Colormap"); break; case 1: fprintf(fp, " Lib version: %s", IMAGE_VERSION_STRING); break; case 2: fprintf(fp, " Number of colors %d", map->nbre); break; case 3: fprintf(fp, " Bugs -> call Tonton Th"); break; case 42: fprintf(fp, " Yes, 42 is _the_ answer"); break; } fprintf(fp, "\n"); } fclose(fp); return OLL_KORRECT; } /*::------------------------------------------------------------------::*/ /* * Colors map file are (maybe?) compatibles with colors maps * of FRACTINT. More check must be done. * * Les colors maps sont censees etre compatible avec celles * de FRACTINT, mais il faudrait verifier. * * What is the 'right thing' to do when we get more than * 256 lines of data ? return an error ? */ int Image_load_color_Map(char *file, char *name, RGB_map *where) { FILE *fp; int nbre, r, g, b, foo, errcode; char buffer[256]; if ( name != NULL ) { if (strlen(name)>IMG_OBJNAME_LEN) return STRING_TOO_LONG; strcpy(where->name, name); } else strcpy(where->name, "no name"); /* * patch du 11 Décembre 2001: on utilise une fonction qui recherche le * fichier dans differents endroits. Cf 'musopen.c' pour + de détails. */ if ((fp=Image_must_fopen(file, "r", 0)) == NULL) { /* safety poke */ where->nbre = 0; fprintf(stderr, "Load color MAP: %s not found\n", file); return FILE_NOT_FOUND; } nbre = 0; errcode = 0; where->nbre = 0; /* kill bad value */ while ( fgets(buffer, 250, fp) != NULL ) { foo = sscanf(buffer, "%d %d %d", &r, &g, &b); if (foo != 3) { fprintf(stderr, "line %d: [%s]\n", nbre, buffer); errcode = BAD_COLOR_NUMBER; break; } where->red[nbre] = r; where->green[nbre] = g; where->blue[nbre] = b; nbre++; if (nbre > 256) { fprintf(stderr, "load color map: nbre = %d\n", nbre); errcode = MAP_TOO_BIG; break; } } where->nbre = nbre; fclose(fp); return errcode; } /*::------------------------------------------------------------------::*/ /* * attach color map a finir... * * XXX voir aussi indexcol.x XXX */ int Image_attach_Map(Image_Desc *im, char *nom_map, int flags) { RGB_map map; int foo; fprintf(stderr, "Image attach Map: cette fonction n'est pas finie\n"); foo = Image_load_color_Map(nom_map, "", &map); if (foo == 0) { fprintf(stderr, "Attach Map: foo is zero ?\n"); } return FUNC_NOT_FINISH; } /*::------------------------------------------------------------------::*/ /* new 31 Juillet 2000 */ int Image_make_random_Map(char *nom, RGB_map *map, int nbre) { int foo; fprintf(stderr, "making a random map named '%s'\n", nom); if (nbre < 0 || nbre > 255) { fprintf(stderr, "make random map: nbre = %d\n", map->nbre); return BAD_COLOR_NUMBER; } map->nbre = nbre; for (foo=0; foored[foo] = rand() & 0xff; map->green[foo] = rand() & 0xff; map->blue[foo] = rand() & 0xff; } return OLL_KORRECT; } /*::------------------------------------------------------------------::*/ /* 21 Sept 2000 Make a 2x2x2 color palette. */ int Image_make_222_Map(char *nom, RGB_map *map, int noise) { int foo, r, g, b; #if DEBUG_LEVEL fprintf(stderr, "Make 222 map: parameter 'noise' (%d) not used\n", noise); #endif strcpy(map->name, "* FMBL roulaize *"); map->nbre = 64; for (foo=0; foo<64; foo++) { r = ((foo >> 0) & 0x03) * 85; g = ((foo >> 2) & 0x03) * 85; b = ((foo >> 4) & 0x03) * 85; #if DEBUG_LEVEL fprintf(stderr, "make 222 map: %3d: %3d %3d %3d\n", foo, r, g, b); #endif map->red[foo] = r; map->green[foo] = g; map->blue[foo] = b; } return OLL_KORRECT; } /*::------------------------------------------------------------------::*/ /* 15 Mai 2001 * A big classic: the three-sinus color map. * paramètres: * 0,1,2 R,G,B period * 3,4,5 R,G,B phase * 6,7 reserved */ int Image_palette_3sinus(char *nom, RGB_map *ou, double pars[8]) { int foo; double dfoo, dra, dga, dba; fprintf(stderr, "Palette 3 Sinus: may be bogus ?\n"); #if DEBUG_LEVEL for (foo=0; foo<8; foo++) fprintf(stderr, " %3d %g\n", foo, pars[foo]); #endif for (foo=0; foo<256; foo++) { dfoo = (double)foo / 255.0 * M_PI * 2; dra = sin((pars[0] * dfoo) + pars[3]); dga = sin((pars[1] * dfoo) + pars[4]); dba = sin((pars[2] * dfoo) + pars[5]); ou->red[foo] = (int)(dra * 127.0 + 127.0); ou->green[foo] = (int)(dga * 127.0 + 127.0); ou->blue[foo] = (int)(dba * 127.0 + 127.0); } ou->nbre = 256; return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ /* new 18 Dec 2001 */ int Image_mix_palettes(RGB_map *p1, RGB_map *p2, RGB_map *d, char *txt, int k) { int idx, k2; int r1, g1, b1, r2, g2, b2; #if DEBUG_LEVEL fprintf(stderr, "Image mix palette: work in progress...\n"); #endif k2 = 10000 - k; for (idx=0; idx<256; idx++) { if (idx < p1->nbre) { r1 = p1->red[idx]; g1 = p1->green[idx]; b1 = p1->blue[idx]; } else { r1 = g1 = b1 = 0; } if (idx < p2->nbre) { r2 = p2->red[idx]; g2 = p2->green[idx]; b2 = p2->blue[idx]; } else { r2 = g2 = b2 = 0; } d->red[idx] = (r1*k + r2*k2) / 10000; d->green[idx] = (g1*k + g2*k2) / 10000; d->blue[idx] = (b1*k + b2*k2) / 10000; } d->nbre = 256; if (strlen(txt)name, txt); else strcpy(d->name, "mix palettes: TXT is too long"); return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ /* new 01 aout 2008 */ /* XXX HACK XXX */ double round(double); /* XXX HACK XXX */ int Image_scale_palette(RGB_map *p, double v, int clip_it) { int foo; #if DEBUG_LEVEL int maxval = -99999; #endif if (p->nbre < 1 || p->nbre > 256) { fprintf(stderr, "%s: RGB_map %p has %d entries ?\n", __func__, p, p->nbre); } for (foo=0; foonbre; foo++) { p->red[foo] = round((double)p->red[foo] * v); p->green[foo] = round((double)p->green[foo] * v); p->blue[foo] = round((double)p->blue[foo] * v); if (clip_it) { if (p->red[foo] < 0) p->red[foo] = 0; if (p->red[foo] > 255) p->red[foo] = 255; if (p->green[foo] < 0) p->green[foo] = 0; if (p->green[foo] > 255) p->green[foo] = 255; if (p->blue[foo] < 0) p->blue[foo] = 0; if (p->blue[foo] > 255) p->blue[foo] = 255; } #if DEBUG_LEVEL if (p->red[foo] > maxval) maxval = p->red[foo]; if (p->green[foo] > maxval) maxval = p->green[foo]; if (p->blue[foo] > maxval) maxval = p->blue[foo]; #endif } #if DEBUG_LEVEL fprintf(stderr, "%s: maxval is %d\n", __func__, maxval); #endif return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ /* nouveau 10 aout 2008 - avenue St Exupery - */ int Image_scale3_palette(RGB_map *p, double rk, double gk, double bk, int clip_it) { int foo; if (p->nbre < 1 || p->nbre > 256) { fprintf(stderr, "%s: RGB_map %p has %d entries ?\n", __func__, p, p->nbre); } for (foo=0; foonbre; foo++) { p->red[foo] = round((double)p->red[foo] * rk); p->green[foo] = round((double)p->green[foo] * gk); p->blue[foo] = round((double)p->blue[foo] * bk); if (clip_it) { if (p->red[foo] < 0) p->red[foo] = 0; if (p->red[foo] > 255) p->red[foo] = 255; if (p->green[foo] < 0) p->green[foo] = 0; if (p->green[foo] > 255) p->green[foo] = 255; if (p->blue[foo] < 0) p->blue[foo] = 0; if (p->blue[foo] > 255) p->blue[foo] = 255; } } return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ /* * nouveau 7 juillet 2010 - enregistrement d'une palette dans un fichier * au format PPM - man ppmquant pour plus de details. * premiere mise en oeuvre : les vignettes de l'exPOVsition. */ int Image_map2ppm(RGB_map *p, char *fname, char *comment) { FILE *fp; int foo; #if DEBUG_LEVEL fprintf(stderr, "%s (( %p '%s' '%s' ))\n", __func__, p, fname, comment); #endif if (NULL==p) { fprintf(stderr, "in %s, can't gruik au nill map\n", __func__); abort(); } #if DEBUG_LEVEL fprintf(stderr, "we have %d colors in palette at %p\n", p->nbre, p); #endif if ( (fp=fopen(fname, "w")) == NULL ) { fprintf(stderr, "%s: err fopen %s\n", __func__, fname); return FILE_CREATE_ERR; } fprintf(fp, "P3\n%d 1\n255\n", p->nbre); if (NULL != comment) { fprintf(fp, "# %s\n", comment); } for (foo=0; foonbre; foo++) { fprintf(fp, "%3d %3d %3d\n", p->red[foo], p->green[foo], p->blue[foo]); } fclose(fp); return FULL_NUCKED; } /*::------------------------------------------------------------------::*/