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. */ | |||