git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2809 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
@@ -2,7 +2,7 @@ | |||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/pipi | |||
bin_PROGRAMS = edd img2rubik sharpen floodfill line bezier | |||
bin_PROGRAMS = edd img2rubik sharpen floodfill line bezier histogram | |||
edd_SOURCES = edd.c | |||
edd_LDADD = ../pipi/libpipi.la | |||
@@ -21,3 +21,6 @@ line_LDADD = ../pipi/libpipi.la | |||
bezier_SOURCES = bezier.c | |||
bezier_LDADD = ../pipi/libpipi.la | |||
histogram_SOURCES = histogram.c | |||
histogram_LDADD = ../pipi/libpipi.la |
@@ -0,0 +1,49 @@ | |||
#include "config.h" | |||
#include "common.h" | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <pipi.h> | |||
int main(int argc, char *argv[]) | |||
{ | |||
char *srcname = NULL, *dstname = NULL; | |||
pipi_image_t *img, *newimg, *tmp; | |||
pipi_histogram_t* histogram; | |||
int ret = 0; | |||
if(argc < 2) | |||
{ | |||
fprintf(stderr, "%s: too few arguments\n", argv[0]); | |||
fprintf(stderr, "Usage: %s <src> <dest>\n", argv[0]); | |||
return EXIT_FAILURE; | |||
} | |||
srcname = argv[1]; | |||
dstname = argv[2]; | |||
img = pipi_load(srcname); | |||
if(!img) { | |||
fprintf(stderr, "Can't open %s for reading\n", srcname); | |||
} | |||
newimg = pipi_copy(img); | |||
pipi_free(img); | |||
tmp = pipi_copy(newimg); | |||
histogram = pipi_new_histogram(); | |||
pipi_get_image_histogram(tmp, histogram, PIPI_COLOR_R|PIPI_COLOR_G|PIPI_COLOR_B); | |||
pipi_render_histogram(tmp, histogram, PIPI_COLOR_R|PIPI_COLOR_G|PIPI_COLOR_B); | |||
pipi_save(tmp, dstname); | |||
pipi_free(newimg); | |||
return ret; | |||
} | |||
@@ -31,6 +31,7 @@ libpipi_la_SOURCES = \ | |||
$(filter_sources) \ | |||
$(quantize_sources) \ | |||
$(dither_sources) \ | |||
$(histogram_sources) \ | |||
$(NULL) | |||
libpipi_la_CFLAGS = $(codec_cflags) | |||
libpipi_la_LDFLAGS = $(codec_libs) \ | |||
@@ -79,6 +80,9 @@ dither_sources = \ | |||
dither/dbs.c \ | |||
dither/random.c | |||
histogram_sources = \ | |||
histogram/histogram.c | |||
if USE_SDL | |||
codec_cflags += `sdl-config --cflags` | |||
codec_libs += `sdl-config --libs` -lSDL_image | |||
@@ -0,0 +1,171 @@ | |||
/* | |||
* libpipi Proper image processing implementation library | |||
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> | |||
* 2008 Jean-Yves Lamoureux <jylam@lnxscene.org | |||
* All Rights Reserved | |||
* | |||
* $Id$ | |||
* | |||
* This library is free software. It comes without any warranty, to | |||
* the extent permitted by applicable law. You can redistribute it | |||
* and/or modify it under the terms of the Do What The Fuck You Want | |||
* To Public License, Version 2, as published by Sam Hocevar. See | |||
* http://sam.zoy.org/wtfpl/COPYING for more details. | |||
*/ | |||
/* | |||
* histogram.c: histogram functions | |||
*/ | |||
#include "config.h" | |||
#include "common.h" | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include "pipi.h" | |||
#include "pipi_internals.h" | |||
pipi_histogram_t* pipi_new_histogram(void) | |||
{ | |||
return malloc(sizeof(pipi_histogram_t)); | |||
} | |||
int pipi_get_image_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags) | |||
{ | |||
int i; | |||
if(!h) return -1; | |||
uint8_t *data = (uint8_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; | |||
for(i=0; i< img->w*img->h*4; i+=4) | |||
{ | |||
if(flags&PIPI_COLOR_A) | |||
h->a[data[i+3]]++; | |||
if(flags&PIPI_COLOR_R) | |||
h->r[data[i+2]]++; | |||
if(flags&PIPI_COLOR_G) | |||
h->g[data[i+1]]++; | |||
if(flags&PIPI_COLOR_B) | |||
h->b[data[i]]++; | |||
if(flags&PIPI_COLOR_Y) | |||
{ | |||
uint32_t p = 0.; | |||
p += 0.299 * data[i]; | |||
p += 0.587 * data[i+1]; | |||
p += 0.114 * data[i+2]; | |||
h->y[p>255?255:p]++; | |||
} | |||
} | |||
/* Normalize dataset */ | |||
unsigned int max; | |||
float n; | |||
if(flags&PIPI_COLOR_R) | |||
{ | |||
max = 0; | |||
for(i=0; i<256; i++) | |||
if(h->r[i] > max) max = h->r[i]; | |||
n = 255.0f / max; | |||
for(i=0; i<256; i++) | |||
h->r[i]*=n; | |||
} | |||
if(flags&PIPI_COLOR_G) | |||
{ | |||
max = 0; | |||
for(i=0; i<256; i++) | |||
if(h->g[i] > max) max = h->g[i]; | |||
n = 255.0f / max; | |||
for(i=0; i<256; i++) | |||
h->g[i]*=n; | |||
} | |||
if(flags&PIPI_COLOR_B) | |||
{ | |||
max = 0; | |||
for(i=0; i<256; i++) | |||
if(h->b[i] > max) max = h->b[i]; | |||
n = 255.0f / max; | |||
for(i=0; i<256; i++) | |||
h->b[i]*=n; | |||
} | |||
if(flags&PIPI_COLOR_A) | |||
{ | |||
max = 0; | |||
for(i=0; i<256; i++) | |||
if(h->a[i] > max) max = h->a[i]; | |||
n = 255.0f / max; | |||
for(i=0; i<256; i++) | |||
h->a[i]*=n; | |||
} | |||
if(flags&PIPI_COLOR_Y) | |||
{ | |||
max = 0; | |||
for(i=0; i<256; i++) | |||
if(h->y[i] > max) max = h->y[i]; | |||
n = 255.0f / max; | |||
for(i=0; i<256; i++) | |||
h->y[i]*=n; | |||
} | |||
return 0; | |||
} | |||
int pipi_render_histogram(pipi_image_t *img, pipi_histogram_t*h, int flags) | |||
{ | |||
if(!img || !h) return -1; | |||
int x; | |||
for(x=0; x<256; x++) | |||
{ | |||
if(flags&PIPI_COLOR_R) | |||
pipi_draw_line(img, | |||
x, 255, | |||
x, 255 - h->r[x], | |||
0x00FF0000, | |||
0); | |||
if(flags&PIPI_COLOR_G) | |||
pipi_draw_line(img, | |||
x, 255, | |||
x, 255 - h->g[x], | |||
0x0000FF00, | |||
0); | |||
if(flags&PIPI_COLOR_B) | |||
pipi_draw_line(img, | |||
x, 255, | |||
x, 255 - h->b[x], | |||
0x000000FF, | |||
0); | |||
if(flags&PIPI_COLOR_A) | |||
pipi_draw_line(img, | |||
x, 255, | |||
x, 255 - h->a[x], | |||
0x00000FFF, | |||
0); | |||
if(flags&PIPI_COLOR_Y) | |||
pipi_draw_line(img, | |||
x, 255, | |||
x, 255 - h->y[x], | |||
0x00FFFFFF, | |||
0); | |||
} | |||
return 0; | |||
} | |||
int pipi_free_histogram(pipi_histogram_t* h) | |||
{ | |||
if(h) free(h); | |||
else return -1; | |||
return 0; | |||
} |
@@ -54,6 +54,17 @@ typedef enum | |||
} | |||
pipi_format_t; | |||
typedef enum | |||
{ | |||
PIPI_COLOR_R = 1, | |||
PIPI_COLOR_G = 2, | |||
PIPI_COLOR_B = 4, | |||
PIPI_COLOR_A = 8, | |||
PIPI_COLOR_Y = 16 | |||
} | |||
pipi_color_flag_t; | |||
struct pixel_u32 | |||
{ | |||
uint8_t r, g, b, a; | |||
@@ -88,6 +99,8 @@ typedef struct pipi_image pipi_image_t; | |||
/* pipi_context_t: the processing stack */ | |||
typedef struct pipi_context pipi_context_t; | |||
/* pipi_histogram_t: the histogram type */ | |||
typedef struct pipi_histogram pipi_histogram_t; | |||
extern pipi_context_t *pipi_create_context(void); | |||
extern void pipi_destroy_context(pipi_context_t *); | |||
@@ -170,6 +183,11 @@ extern pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *, pipi_scan_t); | |||
extern pipi_image_t *pipi_dither_dbs(pipi_image_t *); | |||
extern void pipi_dither_24to16(pipi_image_t *); | |||
extern pipi_histogram_t* pipi_new_histogram(void); | |||
extern int pipi_get_image_histogram(pipi_image_t *, pipi_histogram_t *, int); | |||
extern int pipi_free_histogram(pipi_histogram_t*); | |||
extern int pipi_render_histogram(pipi_image_t *, pipi_histogram_t*, int); | |||
#ifdef __cplusplus | |||
} | |||
@@ -23,6 +23,17 @@ | |||
#define SET_FLAG_WRAP 0x00000002 | |||
#define SET_FLAG_8BIT 0x00000004 | |||
struct pipi_histogram | |||
{ | |||
int r_present, g_present, b_present, y_present; | |||
unsigned int a[256]; | |||
unsigned int r[256]; | |||
unsigned int g[256]; | |||
unsigned int b[256]; | |||
unsigned int y[256]; | |||
}; | |||
/* pipi_image_t: the image structure. This is probably going to be the most | |||
* complex structure in the library, but right now it only has fairly normal | |||
* stuff, like width and height and pointers to pixel areas. */ | |||