libtthimage/Lib/plotteur.c

521 lines
12 KiB
C

/*
plotteur.c
----------
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef NEED_ALLOCA_H
#include <alloca.h>
#endif
#include "../tthimage.h"
#define SOMBRE 26 /* pourquoi ces valeurs sont codees en */
#define CLAIR 242 /* dur ? et ~/.tth/libimagerc alors ? */
/*::------------------------------------------------------------------::*/
static void vline(Image_Desc *i, int x, int y1, int y2, char c, int v)
{
int haut, bas, foo;
if (y1 > y2) { bas = y2; haut = y1; }
else { bas = y1; haut = y2; }
for (foo=bas; foo<=haut; foo++)
Image_plot_channel(i, c, x, foo, v);
}
/*::------------------------------------------------------------------::*/
/* new 20 mars 2002
*/
int Image_plot_luts(char *nomtga, int *lr, int *lg, int *lb, char *texte)
{
Image_Desc *img;
int foo;
RGBA paper, ink;
int vr, vg, vb, ovr, ovg, ovb;
if ( (img = Image_alloc(400, 300, 3)) == NULL ) {
#if DEBUG_LEVEL
fprintf(stderr, "%s: alloc of img failed, file=%s\n", __func__, nomtga);
#endif
return IMAGE_NO_MEM;
}
Image_clear(img, SOMBRE, SOMBRE, SOMBRE);
ovr = ovg = ovb = 0; /* warning suppressor */
for (foo=0; foo<256; foo++)
{
vr = lr[foo];
vg = lg[foo];
vb = lb[foo];
if (foo)
{
vline(img, foo+60, 290-vr, 290-ovr, 'r', CLAIR);
vline(img, foo+60, 290-vg, 290-ovg, 'g', CLAIR);
vline(img, foo+60, 290-vb, 290-ovb, 'b', CLAIR);
}
ovr = vr; ovg = vg; ovb = vb;
}
if (texte != NULL)
{
paper.r = paper.b = paper.g = SOMBRE; paper.a = 0;
ink.r = ink.b = ink.g = CLAIR; ink.a = 255;
Image_trace_chaine_1(img, texte, 5, 5, "libimage.fonte", &paper, &ink);
}
Image_cadre_A(img);
foo=Image_TGA_save(nomtga, img, 0);
Image_DeAllocate(img); free(img);
return foo;
}
/*::------------------------------------------------------------------::*/
/*
* fevrier 2009 : je constate avec amertume que cette fonction ne
* remplit plus vraiment son role face aux exigences
* de buzzwording du monde moderne. un revamping me
* semble vraiment necessaire.
*/
int
Image_plot_histo(char *nomtga, long *hr, long *hg, long *hb, char *txt)
{
Image_Desc *img;
int foo, vr, vg, vb, ovr, ovg, ovb;
long maxhisto;
RGBA paper, ink;
char chaine[120];
if ( (img = Image_alloc(400, 300, 3)) == NULL )
{
#if DEBUG_LEVEL
fprintf(stderr, "Plot Histo: alloc of img failed, file=%s\n", nomtga);
#endif
return IMAGE_NO_MEM;
}
maxhisto = 0;
for (foo=0; foo<256; foo++)
{
if (hr[foo] > maxhisto) maxhisto = hr[foo];
if (hg[foo] > maxhisto) maxhisto = hg[foo];
if (hb[foo] > maxhisto) maxhisto = hb[foo];
}
#if DEBUG_LEVEL > 1
fprintf(stderr, "plot histo: max rgb = %ld\n", maxhisto);
#endif
Image_clear(img, SOMBRE, SOMBRE, SOMBRE); /* ou est SOMBRE ? */
ovr = ovg = ovb = 0; /* warning suppressor */
for (foo=0; foo<256; foo++)
{
vr = (hr[foo]*256)/maxhisto;
vg = (hg[foo]*256)/maxhisto;
vb = (hb[foo]*256)/maxhisto;
if (foo)
{
vline(img, foo+60, 290-vr, 290-ovr, 'r', CLAIR);
vline(img, foo+60, 290-vg, 290-ovg, 'g', CLAIR);
vline(img, foo+60, 290-vb, 290-ovb, 'b', CLAIR);
}
ovr = vr; ovg = vg; ovb = vb;
}
paper.r = paper.b = paper.g = SOMBRE; paper.a = 0;
ink.r = ink.b = ink.g = CLAIR; ink.a = 255;
#if DEBUG_LEVEL > 1
fprintf(stderr, "taille txt %d\n", strlen(txt));
#endif
Image_trace_chaine_1(img, txt, 5, 5, "libimage.fonte", &paper, &ink);
#if DEBUG_LEVEL > 1
fprintf(stderr, "[%s] drawed...\n", txt);
#endif
sprintf(chaine, "max rgb = %ld", maxhisto);
Image_trace_chaine_1(img, chaine, 5, 15, NULL, &paper, &ink);
#if DEBUG_LEVEL > 1
fprintf(stderr, "[%s] drawed...\n", chaine);
#endif
Image_cadre_A(img);
foo=Image_TGA_save(nomtga, img, 0);
Image_DeAllocate(img); free(img);
return foo;
}
/*::------------------------------------------------------------------::*/
/* mmmmm, pas tres sexy, ce truc-la...
*/
int
Image_calc_plot_histo(Image_Desc *img, char *tganame)
{
long hr[256], hg[256], hb[256];
int foo;
#if DEBUG_LEVEL
fprintf(stderr, "%s : %p --> '%s'\n", __func__, img, tganame);
#endif
foo = Image_histo_RGB(img, hr, hg, hb);
Image_print_error("calc plot histo: calc", foo);
foo = Image_plot_histo(tganame, hr, hg, hb, tganame);
Image_print_error("calc plot histo: plot", foo);
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* fabrique dans une image une petite bande a partir d'une palette
* cette bande est horizontale.
*/
int Image_plot_h_Map(Image_Desc *img, RGB_map *map, int xpos, int ypos, int h)
{
int x, y, v;
for (x=0; x<256; x++)
{
for (y=0; y<h; y++)
{
if ( ((y>>2)+(x>>2)) & 1) v = SOMBRE;
else v = CLAIR;
Image_plotRGB(img, x+xpos, y+ypos, v, v, v);
}
}
#if DEBUG_LEVEL
fprintf(stderr, "Image plot h Map: %d colors\n", map->nbre);
#endif
for (x=0; x<map->nbre; x++)
{
for (y=0; y<h; y++)
{
Image_plotRGB(img, x+xpos, y+ypos,
map->red[x], map->green[x], map->blue[x]);
}
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* fabrique dans une image une petite bande a partir d'une palette
* cette bande est verticale.
*/
int Image_plot_v_Map(Image_Desc *img, RGB_map *map, int xpos, int ypos, int l)
{
int x, y, v;
for (y=0; y<256; y++) {
for (x=0; x<l; x++) {
if ( ((y>>2)+(x>>2)) & 1) v = SOMBRE;
else v = CLAIR;
Image_plotRGB(img, x+xpos, y+ypos, v, v, v);
}
}
#if DEBUG_LEVEL
fprintf(stderr, "Image plot v Map: %d colors\n", map->nbre);
#endif
for (y=0; y<map->nbre; y++)
{
for (x=0; x<l; x++)
{
Image_plotRGB(img, x+xpos, y+ypos,
map->red[y], map->green[y], map->blue[y]);
}
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* fabrique une petite TGA horizontale avec une palette dedans
*/
#define LITTLE_DIM 42
int Image_plot_little_h_Map(char *nom, RGB_map *map, char *texte)
{
Image_Desc *img;
int foo;
if ( (img=Image_alloc(260, LITTLE_DIM+4, 3)) == NULL)
{
return IMAGE_NO_MEM;
}
foo = Image_plot_h_Map(img, map, 2, 2, LITTLE_DIM);
#if DEBUG_LEVEL
fprintf(stderr, "Plot little H map: ret plot = %d, %s\n",
foo, Image_err2str(foo));
#endif
(void)Image_cadre_A(img);
if (texte != NULL) Image_set_comment(img, texte);
foo = Image_TGA_save(nom, img, 0);
fprintf(stderr, "plot little H map: save %s: %d\n", nom, foo);
Image_DeAllocate(img); free(img);
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* 20 Fevrier 2002.
* fabrique une petite TGA verticale avec une palette dedans
*/
int Image_plot_little_v_Map(char *nom, RGB_map *map, char *texte)
{
Image_Desc *img;
int foo;
if ( (img=Image_alloc(LITTLE_DIM+4, 260, 3)) == NULL)
{
return IMAGE_NO_MEM;
}
foo = Image_plot_v_Map(img, map, 2, 2, LITTLE_DIM);
(void)Image_cadre_A(img);
if (texte != NULL) Image_set_comment(img, texte);
foo = Image_TGA_save(nom, img, 0);
fprintf(stderr, "plot little V map: save '%s': %d\n", nom, foo);
Image_DeAllocate(img); free(img);
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/* new 2 decembre 2009 - ave St Exupery
*/
int Image_plot_square_Map(char *fname, RGB_map *map, char *texte, int k)
{
int x, y, foo;
int r, g, b;
Image_Desc *img;
Image_Rect rect;
#if DEBUG_LEVEL
fprintf(stderr, "%s ( '%s' %p '%s' %d )\n", __func__,
fname, map, texte, k);
#endif
if ( (img = Image_alloc(512, 512, 3)) == NULL ) {
#if DEBUG_LEVEL
fprintf(stderr, "%s: alloc of img failed, file=%s\n", __func__, fname);
#endif
return IMAGE_NO_MEM;
}
Image_clear(img, 0, 0, 0);
rect.h = rect.w = 31;
for (foo=0; foo<256; foo++) {
x = ( foo & 0x0f ) * 32;
y = ( foo & 0xf0 ) * 2;
#if DEBUG_LEVEL > 1
printf("%4d : %3d %3d ", foo, x, y);
#endif
rect.x = x;
rect.y = y;
if (foo < map->nbre) {
r = map->red[foo];
g = map->green[foo];
b = map->blue[foo];
#if DEBUG_LEVEL > 1
printf(" %3d %3d %3d\n", r, g, b);
#endif
Image_paint_rect(img, &rect, r, g, b);
}
else { /* on est au dela de la fin de la palette */
/* Image_gadrct_Hsweep_0(img, &rect, 0); */
Image_gadrct_cross(img, &rect, 0);
}
}
foo=Image_TGA_save(fname, img, 0);
Image_DeAllocate(img); free(img);
return FULL_NUCKED;
}
/*::------------------------------------------------------------------::*/
/*
* plotte une palette 'a la fractint'
*/
int
Image_plot_Map(char *nomtga, RGB_map *map , char *txt)
{
Image_Desc *img;
int foo, x;
RGBA paper, ink;
Image_Rect rect;
if ( (img = Image_alloc(400, 300, 3)) == NULL )
{
#if DEBUG_LEVEL
fprintf(stderr, "%s: alloc of img failed, file=%s\n", __func__, nomtga);
#endif
return IMAGE_NO_MEM;
}
Image_clear(img, SOMBRE, SOMBRE, SOMBRE);
for (foo=0; foo<map->nbre; foo++) {
Image_plotRGB(img, foo+90, 120, 255, 255, 255);
Image_plotRGB(img, foo+90, 200, 255, 255, 255);
Image_plotRGB(img, foo+90, 280, 255, 255, 255);
Image_plotRGB(img, foo+90, 120-(map->red[foo]/5), 255, 0, 0);
Image_plotRGB(img, foo+90, 200-(map->green[foo]/5), 0, 255, 0);
Image_plotRGB(img, foo+90, 280-(map->blue[foo]/5), 0, 0, 255);
}
rect.x = 20; rect.y = 30;
rect.h = 258; rect.w = 31;
Image_draw_rect(img, &rect, CLAIR/2, CLAIR/2, CLAIR/2);
#if DEBUG_LEVEL > 1
fprintf(stderr, "Plot MAP: the text is '%s'\n", txt);
#endif
for (foo=0; foo<map->nbre; foo++) {
for (x=21; x<50; x++) {
Image_plotRGB(img, x, foo+31,
map->red[foo], map->green[foo], map->blue[foo]);
}
}
paper.r = paper.b = paper.g = SOMBRE; paper.a = 0;
ink.r = ink.b = ink.g = CLAIR; ink.a = 255;
foo = Image_trace_chaine_1(img, txt, 15, 7, "8x8thin", &paper, &ink);
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s: retour trace chaine = %d\n", __func__, foo);
#endif
Image_cadre_A(img);
if ( (foo=Image_TGA_save(nomtga, img, 0)) )
{
Image_DeAllocate(img); free(img);
return foo;
}
Image_DeAllocate(img); free(img);
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* new 23 oct 2001
* parameters 'p1' and 'p2' are not used, and must be 0 !
*/
int Image_plot_histo_hf15(Image_Desc *img, char *nom, char *txt, int p1, int p2)
{
Image_Desc *plot;
long *histo, maximum;
double diviseur;
int x, y, foo, h, h2, epic_fail;
RGBA paper, ink;
char chaine[200];
#if DEBUG_LEVEL
fprintf(stderr, "%s: img %p ! work in progress !\n", __func__, img);
#endif
if ( (histo=alloca(sizeof(long)*32768)) == NULL) {
fprintf(stderr, "%s: no mem for buffer\n", __func__);
#if FORCE_ABORT
abort();
#endif
return BUFFER_NO_MEM;
}
if ( (plot = Image_alloc(800, 600, 3)) == NULL ) {
#if DEBUG_LEVEL
fprintf(stderr, "Plot histo hf15: alloc img failed\n");
#endif
free(histo);
return IMAGE_NO_MEM;
}
Image_clear(plot, SOMBRE, SOMBRE, SOMBRE);
for (foo=0; foo<32768; foo++) histo[foo] = 0L;
epic_fail = 0;
for (y=0; y<img->height; y++) {
for (x=0; x<img->width; x++) {
h = Image_hf15_height(img, x, y);
if (h<0 || h>32767) epic_fail++;
else histo[h]++;
}
}
if (epic_fail) {
fprintf(stderr, "%s: %d epic fail(s) is epic\n", __func__, epic_fail);
#if FORCE_ABORT
abort();
#endif
free(histo);
}
/* recherche du maximum de l'histogramme, pour faire la mise a l'echelle */
maximum = 0L;
for (foo=0; foo<32768; foo++)
if (histo[foo] > maximum)
maximum = histo[foo];
diviseur = (double)maximum/400.0;
if (diviseur==0) diviseur=1.0; /* XXX workaround */
fprintf(stderr, "%s: maximum = %ld, diviseur = %g\n", __func__,
maximum, diviseur);
h2 = 0;
for (foo=0; foo<32768; foo+=4) {
h = (int)((double)histo[foo] / diviseur);
x = (foo/64)+60;
if (foo) { /* pourquoi ? */
vline(plot, x, 590-h, 290-h2, 'g', CLAIR);
h2 = h;
}
Image_plotRGB(plot, x, 590-h, CLAIR, SOMBRE, SOMBRE);
Image_plotRGB(plot, x, 590, SOMBRE, CLAIR, SOMBRE);
}
paper.r = paper.b = paper.g = SOMBRE; paper.a = 0;
ink.r = ink.b = ink.g = CLAIR; ink.a = 255;
/* Image_trace_chaine_0(plot, txt, 5, 5, &paper, &ink, 0); */
Image_trace_chaine_1(plot, chaine, 5, 5, NULL, &paper, &ink);
sprintf(chaine, "max %ld", maximum);
/* Image_trace_chaine_0(plot, chaine, 5, 15, &paper, &ink, 0); */
Image_trace_chaine_1(plot, chaine, 5, 15, NULL, &paper, &ink);
sprintf(chaine, "div %g", diviseur);
/* Image_trace_chaine_0(plot, chaine, 5, 25, &paper, &ink, 0); */
Image_trace_chaine_1(plot, chaine, 5, 25, NULL, &paper, &ink);
Image_cadre_A(plot);
foo=Image_TGA_save(nom, plot, 0);
Image_DeAllocate(plot); free(plot);
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/