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