Browse Source

image: implement AutoContrast().

undefined
Sam Hocevar 10 years ago
parent
commit
6c323663ab
9 changed files with 62 additions and 378 deletions
  1. +0
    -4
      TODO
  2. +1
    -0
      src/Makefile.am
  3. +0
    -65
      src/image/accessors.cpp
  4. +53
    -89
      src/image/filter/autocontrast.cpp
  5. +0
    -97
      src/image/pipi-stubs.h
  6. +0
    -100
      src/image/pipi-types.h
  7. +6
    -20
      src/image/render/noise.cpp
  8. +1
    -1
      src/image/stock.cpp
  9. +1
    -2
      src/lol/image/image.h

+ 0
- 4
TODO View File

@@ -13,7 +13,6 @@ Image:
- Fix the Floyd-Steinberg ode in pixels.cpp
- Add gamma handling in pixels.cpp
- port libpipi files:
· accessors.cpp
· analysis/histogram.cpp
· analysis/measure.cpp
· codec/coreimage.cpp
@@ -36,7 +35,6 @@ Image:
· dither/ordered.cpp
· dither/ostromoukhov.cpp
· dither/random.cpp
· filter/autocontrast.cpp
· filter/blur.cpp
· filter/color.cpp
· filter/convolution.cpp
@@ -54,9 +52,7 @@ Image:
· paint/tile.cpp
· pipi.h
· pipi-internals.h
· pipi-stubs.h
· pipi-template.h
· pipi-types.h
· quantize/reduce.cpp
· resample/bicubic.cpp
· resample/bresenham.cpp


+ 1
- 0
src/Makefile.am View File

@@ -116,6 +116,7 @@ liblolcore_sources = \
image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \
image/codec/dummy-image.cpp \
image/color/cie1931.cpp image/color/color.cpp \
image/filter/autocontrast.cpp \
image/render/noise.cpp image/render/screen.cpp \
\
loldebug.h \


+ 0
- 65
src/image/accessors.cpp View File

@@ -1,65 +0,0 @@
/*
* libpipi Pathetic image processing interface 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.
*/

/*
* accessors.c: accessors for various informations about images
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <math.h>

#include "pipi.h"
#include "pipi-internals.h"

int pipi_get_image_width(pipi_image_t *img)
{
return img->w;
}
int pipi_get_image_height(pipi_image_t *img)
{
return img->h;
}
int pipi_get_image_pitch(pipi_image_t *img)
{
return img->pitch;
}
int pipi_get_image_last_modified(pipi_image_t *img)
{
return img->last_modified;
}



char formats[][100] =
{
"Unknow",
"RGBA_C",
"BGR_C",
"RGBA_F",
"Y_F",
"MASK_C",
"LOL",
};

const char* pipi_get_format_name(int format)
{
if(format>PIPI_PIXELS_MAX) return "Invalid";
else return formats[format];
}

+ 53
- 89
src/image/filter/autocontrast.cpp View File

@@ -1,111 +1,75 @@
/*
* libpipi Pathetic image processing interface library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.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.
*/
//
// Lol Engine
//
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net>
// This program is free software; 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://www.wtfpl.net/ for more details.
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include "core.h"

/*
* autocontrast.c: autocontrast functions
* Autocontrast functions
* TODO: the current approach is naive; we should use the histogram in order
* to decide how to change the contrast.
*/

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "pipi.h"
#include "pipi-internals.h"

pipi_image_t *pipi_autocontrast(pipi_image_t *src)
namespace lol
{
pipi_image_t *dst;
pipi_pixels_t *srcp, *dstp;
float *srcdata, *dstdata;
float min = 1.0, max = 0.0, t;
int x, y, w, h, gray;

w = src->w;
h = src->h;

gray = (src->last_modified == PIPI_PIXELS_Y_F32);
Image Image::AutoContrast() const
{
Image ret = *this;

srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
: pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
srcdata = (float *)srcp->pixels;
float min_val = 1.f, max_val = 0.f;
int count = GetSize().x * GetSize().y;

for(y = 0; y < h; y++)
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32)
{
for(x = 0; x < w; x++)
float *pixels = ret.Lock<PixelFormat::Y_F32>();
for (int n = 0; n < count; ++n)
{
if(gray)
{
if(srcdata[y * w + x] < min)
min = srcdata[y * w + x];
if(srcdata[y * w + x] > max)
max = srcdata[y * w + x];
}
else
{
if(srcdata[4 * (y * w + x)] < min)
min = srcdata[4 * (y * w + x)];
if(srcdata[4 * (y * w + x)] > max)
max = srcdata[4 * (y * w + x)];
if(srcdata[4 * (y * w + x) + 1] < min)
min = srcdata[4 * (y * w + x) + 1];
if(srcdata[4 * (y * w + x) + 1] > max)
max = srcdata[4 * (y * w + x) + 1];
if(srcdata[4 * (y * w + x) + 2] < min)
min = srcdata[4 * (y * w + x) + 2];
if(srcdata[4 * (y * w + x) + 2] > max)
max = srcdata[4 * (y * w + x) + 2];
}
min_val = lol::min(min_val, pixels[n]);
max_val = lol::max(max_val, pixels[n]);
}
}

if(min >= max)
return pipi_copy(src);

t = 1. / (max - min);

dst = pipi_new(w, h);
dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
: pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
dstdata = (float *)dstp->pixels;
float t = max_val > min_val ? 1.f / (max_val - min_val) : 1.f;
for (int n = 0; n < count; ++n)
pixels[n] = (pixels[n] - min_val) * t;

for(y = 0; y < h; y++)
ret.Unlock(pixels);
}
else
{
for(x = 0; x < w; x++)
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>();
for (int n = 0; n < count; ++n)
{
if(gray)
{
dstdata[y * w + x] = (srcdata[y * w + x] - min) * t;
}
else
{
dstdata[4 * (y * w + x)]
= (srcdata[4 * (y * w + x)] - min) * t;
dstdata[4 * (y * w + x) + 1]
= (srcdata[4 * (y * w + x) + 1] - min) * t;
dstdata[4 * (y * w + x) + 2]
= (srcdata[4 * (y * w + x) + 2] - min) * t;
dstdata[4 * (y * w + x) + 3]
= srcdata[4 * (y * w + x) + 3];
}
min_val = lol::min(min_val, pixels[n].r);
min_val = lol::min(min_val, pixels[n].g);
min_val = lol::min(min_val, pixels[n].b);
max_val = lol::max(max_val, pixels[n].r);
max_val = lol::max(max_val, pixels[n].g);
max_val = lol::max(max_val, pixels[n].b);
}

float t = max_val > min_val ? 1.f / (max_val - min_val) : 1.f;
for (int n = 0; n < count; ++n)
pixels[n] = vec4((pixels[n].r - min_val) * t,
(pixels[n].g - min_val) * t,
(pixels[n].b - min_val) * t,
pixels[n].a);;

ret.Unlock(pixels);
}

return dst;
return ret;
}

} /* namespace lol */


+ 0
- 97
src/image/pipi-stubs.h View File

@@ -1,97 +0,0 @@
/*
* libpipi Pathetic image processing interface library
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software; 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.
*/

/*
* This file contains replacements for commonly found object types and
* function prototypes that are sometimes missing.
*/

#ifndef __PIPI_STUBS_H__
#define __PIPI_STUBS_H__

/* errno handling */
#if defined HAVE_ERRNO_H && !defined __KERNEL__
# include <errno.h>
static inline void seterrno(int e) { errno = e; }
static inline int geterrno(void) { return errno; }
#else
# define seterrno(x) do { (void)(x); } while(0)
# define geterrno(x) 0
#endif

/* debug messages */
#if defined DEBUG && !defined __KERNEL__
# include <stdio.h>
# include <stdarg.h>
static inline void debug(const char *format, ...)
{
int saved_errno = geterrno();
va_list args;
va_start(args, format);
fprintf(stderr, "** libpipi debug ** ");
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
va_end(args);
seterrno(saved_errno);
}
#else
# define debug(format, ...) do {} while(0)
#endif

/* hton16() and hton32() */
#if defined HAVE_HTONS && !defined __KERNEL__
# if defined HAVE_ARPA_INET_H
# include <arpa/inet.h>
# elif defined HAVE_NETINET_IN_H
# include <netinet/in.h>
# endif
# define hton16 htons
# define hton32 htonl
#else
# if defined __KERNEL__
/* Nothing to do */
# elif defined HAVE_ENDIAN_H
# include <endian.h>
# endif
static inline uint16_t hton16(uint16_t x)
{
/* This is compile-time optimised with at least -O1 or -Os */
#if defined HAVE_ENDIAN_H
if(__BYTE_ORDER == __BIG_ENDIAN)
#else
uint32_t const dummy = 0x12345678;
if(*(uint8_t const *)&dummy == 0x12)
#endif
return x;
else
return (x >> 8) | (x << 8);
}

static inline uint32_t hton32(uint32_t x)
{
/* This is compile-time optimised with at least -O1 or -Os */
#if defined HAVE_ENDIAN_H
if(__BYTE_ORDER == __BIG_ENDIAN)
#else
uint32_t const dummy = 0x12345678;
if(*(uint8_t const *)&dummy == 0x12)
#endif
return x;
else
return (x >> 24) | ((x >> 8) & 0x0000ff00)
| ((x << 8) & 0x00ff0000) | (x << 24);
}
#endif

#endif /* __PIPI_STUBS_H__ */


+ 0
- 100
src/image/pipi-types.h View File

@@ -1,100 +0,0 @@
/*
* libpipi Pathetic image processing interface library
* Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software; 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.
*/

/*
* This file contains definitions for the C99 integer types.
*/

#ifndef __PIPI_TYPES_H__
#define __PIPI_TYPES_H__

#ifndef PIPI_TYPES
# define PIPI_TYPES 1
#endif

/* mode 1: standard <stdint.h> header is present, just include it */
#if PIPI_TYPES == 1
# include <stdint.h>
# include <unistd.h>

/* mode 2: standard <inttypes.h> header is present, just include it */
#elif PIPI_TYPES == 2
# include <inttypes.h>
# include <unistd.h>

/* mode 3: <windows.h> indicates Win32, only (u)intptr_t is present
* FIXME: Win64 probably doesn't work that way */
#elif PIPI_TYPES == 3
#include <windows.h>

typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int int64_t;

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;

typedef int ssize_t;
typedef unsigned int size_t;

/* fallback: nothing is known, we assume the platform is 32-bit and
* sizeof(long) == sizeof(void *). We don't typedef directly because we
* have no idea what other typedefs have already been made. */
#else
typedef signed char _pipi_int8_t;
typedef signed short _pipi_int16_t;
typedef signed long int _pipi_int32_t;
typedef signed long long int _pipi_int64_t;
# undef int8_t
# define int8_t _pipi_int8_t
# undef int16_t
# define int16_t _pipi_int16_t
# undef int32_t
# define int32_t _pipi_int32_t
# undef int64_t
# define int64_t _pipi_int64_t

typedef unsigned char _pipi_uint8_t;
typedef unsigned short _pipi_uint16_t;
typedef unsigned long int _pipi_uint32_t;
typedef unsigned long long int _pipi_uint64_t;
# undef uint8_t
# define uint8_t _pipi_uint8_t
# undef uint16_t
# define uint16_t _pipi_uint16_t
# undef uint32_t
# define uint32_t _pipi_uint32_t
# undef uint64_t
# define uint64_t _pipi_uint64_t

typedef long int _pipi_intptr_t;
typedef unsigned long int _pipi_uintptr_t;
# undef intptr_t
# define intptr_t _pipi_intptr_t
# undef uintptr_t
# define uintptr_t _pipi_uintptr_t

typedef int _pipi_ssize_t;
typedef unsigned int _pipi_size_t;
# undef ssize_t
# define ssize_t _pipi_ssize_t
# undef size_t
# define size_t _pipi_size_t

#endif

#endif /* __PIPI_TYPES_H__ */


+ 6
- 20
src/image/render/noise.cpp View File

@@ -23,28 +23,14 @@ namespace lol

bool Image::RenderRandom(ivec2 size)
{
unsigned int ctx = 1;

SetSize(size);
vec4 *pixels = Lock<PixelFormat::RGBA_F32>();
int count = size.x * size.y;

for (int n = 0; n < count; ++n)
{
for (int t : { 0, 1, 2 })
{
long hi, lo;

hi = ctx / 12773L;
lo = ctx % 12773L;
ctx = 16807L * lo - 2836L * hi;
if(ctx <= 0)
ctx += 0x7fffffffL;

pixels[n][t] = (float)((ctx % 65536) / 65535.);
}
pixels[n][3] = 1.0f;
}

for (int n = 0; n < size.x * size.y; ++n)
pixels[n] = vec4(lol::rand(1.f),
lol::rand(1.f),
lol::rand(1.f),
1.f);

Unlock(pixels);



+ 1
- 1
src/image/stock.cpp View File

@@ -54,7 +54,7 @@ bool Image::Stock(char const *name)
/* Generate an error diffusion matrix. */
if (!strncmp(name, "ediff:", 6))
{
float const *ker;
float const *ker = nullptr;
ivec2 size(0);

if (!strcmp(name + 6, "fs"))


+ 1
- 2
src/lol/image/image.h View File

@@ -66,8 +66,7 @@ public:
bool RenderRandom(ivec2 size);

/* Image processing */


Image AutoContrast() const;

private:
class ImageData *m_data;


Loading…
Cancel
Save