Browse Source

* Preliminary image histogram routines and example

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2809 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
jylam 16 years ago
parent
commit
756cc89890
6 changed files with 257 additions and 1 deletions
  1. +4
    -1
      examples/Makefile.am
  2. +49
    -0
      examples/histogram.c
  3. +4
    -0
      pipi/Makefile.am
  4. +171
    -0
      pipi/histogram/histogram.c
  5. +18
    -0
      pipi/pipi.h
  6. +11
    -0
      pipi/pipi_internals.h

+ 4
- 1
examples/Makefile.am View File

@@ -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

+ 49
- 0
examples/histogram.c View File

@@ -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;
}


+ 4
- 0
pipi/Makefile.am View File

@@ -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


+ 171
- 0
pipi/histogram/histogram.c View File

@@ -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;
}

+ 18
- 0
pipi/pipi.h View File

@@ -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
} }


+ 11
- 0
pipi/pipi_internals.h View File

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


Loading…
Cancel
Save