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 | 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_SOURCES = edd.c | ||||
edd_LDADD = ../pipi/libpipi.la | edd_LDADD = ../pipi/libpipi.la | ||||
@@ -21,3 +21,6 @@ line_LDADD = ../pipi/libpipi.la | |||||
bezier_SOURCES = bezier.c | bezier_SOURCES = bezier.c | ||||
bezier_LDADD = ../pipi/libpipi.la | 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) \ | $(filter_sources) \ | ||||
$(quantize_sources) \ | $(quantize_sources) \ | ||||
$(dither_sources) \ | $(dither_sources) \ | ||||
$(histogram_sources) \ | |||||
$(NULL) | $(NULL) | ||||
libpipi_la_CFLAGS = $(codec_cflags) | libpipi_la_CFLAGS = $(codec_cflags) | ||||
libpipi_la_LDFLAGS = $(codec_libs) \ | libpipi_la_LDFLAGS = $(codec_libs) \ | ||||
@@ -79,6 +80,9 @@ dither_sources = \ | |||||
dither/dbs.c \ | dither/dbs.c \ | ||||
dither/random.c | dither/random.c | ||||
histogram_sources = \ | |||||
histogram/histogram.c | |||||
if USE_SDL | if USE_SDL | ||||
codec_cflags += `sdl-config --cflags` | codec_cflags += `sdl-config --cflags` | ||||
codec_libs += `sdl-config --libs` -lSDL_image | 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; | 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 | struct pixel_u32 | ||||
{ | { | ||||
uint8_t r, g, b, a; | uint8_t r, g, b, a; | ||||
@@ -88,6 +99,8 @@ typedef struct pipi_image pipi_image_t; | |||||
/* pipi_context_t: the processing stack */ | /* pipi_context_t: the processing stack */ | ||||
typedef struct pipi_context pipi_context_t; | 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 pipi_context_t *pipi_create_context(void); | ||||
extern void pipi_destroy_context(pipi_context_t *); | 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 pipi_image_t *pipi_dither_dbs(pipi_image_t *); | ||||
extern void pipi_dither_24to16(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 | #ifdef __cplusplus | ||||
} | } | ||||
@@ -23,6 +23,17 @@ | |||||
#define SET_FLAG_WRAP 0x00000002 | #define SET_FLAG_WRAP 0x00000002 | ||||
#define SET_FLAG_8BIT 0x00000004 | #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 | /* 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 | * complex structure in the library, but right now it only has fairly normal | ||||
* stuff, like width and height and pointers to pixel areas. */ | * stuff, like width and height and pointers to pixel areas. */ | ||||