浏览代码

image: port the DBS dithering method and remove a few dead files.

undefined
Sam Hocevar 10 年前
父节点
当前提交
c5a3d4873b
共有 11 个文件被更改,包括 119 次插入660 次删除
  1. +1
    -0
      .gitignore
  2. +2
    -6
      TODO
  3. +1
    -1
      src/Makefile.am
  4. +110
    -126
      src/image/dither/dbs.cpp
  5. +0
    -56
      src/image/paint/tile.cpp
  6. +0
    -138
      src/image/pipi-internals.h
  7. +0
    -80
      src/image/pipi-template.h
  8. +0
    -253
      src/image/pipi.h
  9. +1
    -0
      src/lol/image/image.h
  10. +1
    -0
      src/lolcore.vcxproj
  11. +3
    -0
      src/lolcore.vcxproj.filters

+ 1
- 0
.gitignore 查看文件

@@ -97,6 +97,7 @@ demos/tutorial/03_noise
demos/tutorial/04_texture
demos/tutorial/05_easymesh
demos/tutorial/06_sprite
demos/tutorial/07_input
demos/tutorial/08_fbo
demos/tutorial/11_fractal
demos/tutorial/12_voronoi


+ 2
- 6
TODO 查看文件

@@ -14,8 +14,9 @@ Scene:

Image:
- Handle pitch in SDL codec (and all others, actually)
- Fix the Floyd-Steinberg ode in pixels.cpp
- Fix the Floyd-Steinberg code in pixels.cpp
- Add gamma handling in pixels.cpp
- Make some Image::Lock2D method that returns an Array2D
- port libpipi files:
· analysis/histogram.cpp
· analysis/measure.cpp
@@ -31,7 +32,6 @@ Image:
· combine/rgb.cpp
· combine/subadd.cpp
· context.cpp
· dither/dbs.cpp
· filter/blur.cpp
· filter/rotate.cpp
· filter/transform.cpp
@@ -40,10 +40,6 @@ Image:
· paint/floodfill.cpp
· paint/line.cpp
· paint/rectangle.cpp
· paint/tile.cpp
· pipi.h
· pipi-internals.h
· pipi-template.h
· quantize/reduce.cpp
· sequence.cpp


+ 1
- 1
src/Makefile.am 查看文件

@@ -117,7 +117,7 @@ liblolcore_sources = \
image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \
image/codec/oric-image.cpp image/codec/dummy-image.cpp \
image/color/cie1931.cpp image/color/color.cpp \
image/dither/random.cpp image/dither/ediff.cpp \
image/dither/random.cpp image/dither/ediff.cpp image/dither/dbs.cpp \
image/dither/ostromoukhov.cpp image/dither/ordered.cpp \
image/filter/convolution.cpp image/filter/color.cpp \
image/filter/dilate.cpp image/filter/median.cpp image/filter/yuv.cpp \


+ 110
- 126
src/image/dither/dbs.cpp 查看文件

@@ -1,173 +1,154 @@
/*
* 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"

/*
* dbs.c: Direct Binary Search dithering functions
* Direct Binary Search dithering
*/

#include "config.h"

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

#include <math.h>

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

#define CELL 16

#define N 7
#define NN ((N * 2 + 1))

namespace lol
{

/* FIXME: though the algorithm is supposed to stop, we do not have a real,
* guaranteed stop condition here. */

pipi_image_t *pipi_dither_dbs(pipi_image_t *img)
Image Image::DitherDbs() const
{
double kernel[NN * NN];
double t = 0.;
pipi_image_t *src, *dst, *tmp1, *tmp2;
pipi_pixels_t *dstp, *tmp1p, *tmp2p;
int *changelist;
float *dstdata, *tmp1data, *tmp2data;
int i, j, x, y, w, h, cw, ch;
ivec2 size = GetSize();

/* Build our human visual system kernel. */
for(j = 0; j < NN; j++)
for(i = 0; i < NN; i++)
Array2D<float> kernel;
kernel.SetSize(ivec2(NN, NN));
float t = 0.f;
for (int j = 0; j < NN; j++)
for (int i = 0; i < NN; i++)
{
double a = (double)(i - N);
double b = (double)(j - N);
kernel[j * NN + i] =
exp(-(a * a + b * b) / (2. * 1.6 * 1.6))
+ exp(-(a * a + b * b) / (2. * 0.6 * 0.6));
t += kernel[j * NN + i];
vec2 v = vec2(i - N, j - N);
kernel[i][j] = exp(-sqlength(v / 1.6f) / 2.f)
+ exp(-sqlength(v / 0.6f) / 2.f);
t += kernel[i][j];
}

for(j = 0; j < NN; j++)
for(i = 0; i < NN; i++)
kernel[j * NN + i] /= t;
for (int j = 0; j < NN; j++)
for (int i = 0; i < NN; i++)
kernel[i][j] /= t;

w = img->w;
h = img->h;
/* A list of cells in our picture. If no change is done to a cell
* for two iterations, we stop considering changes to it. */
ivec2 csize = (size + ivec2(CELL - 1)) / CELL;
Array2D<int> changelist;
changelist.SetSize(csize);
memset(changelist.Data(), 0, changelist.Bytes());

cw = (w + CELL - 1) / CELL;
ch = (h + CELL - 1) / CELL;
changelist = malloc(cw * ch * sizeof(int));
memset(changelist, 0, cw * ch * sizeof(int));
Image dst = *this;
dst.SetFormat(PixelFormat::Y_F32);

src = pipi_copy(img);
pipi_get_pixels(src, PIPI_PIXELS_Y_F32);
Image tmp1 = dst.Convolution(kernel);
float *tmp1data = tmp1.Lock<PixelFormat::Y_F32>();

tmp1 = pipi_convolution(src, NN, NN, kernel);
tmp1p = pipi_get_pixels(tmp1, PIPI_PIXELS_Y_F32);
tmp1data = (float *)tmp1p->pixels;
dst = dst.DitherRandom();
float *dstdata = dst.Lock<PixelFormat::Y_F32>();

dst = pipi_dither_random(src);
dstp = pipi_get_pixels(dst, PIPI_PIXELS_Y_F32);
dstdata = (float *)dstp->pixels;
Image tmp2 = dst.Convolution(kernel);
float *tmp2data = tmp2.Lock<PixelFormat::Y_F32>();

pipi_free(src);

tmp2 = pipi_convolution(dst, NN, NN, kernel);
tmp2p = pipi_get_pixels(tmp2, PIPI_PIXELS_Y_F32);
tmp2data = (float *)tmp2p->pixels;

for(;;)
for (;;)
{
int cx, cy, n;
int allchanges = 0;

for(cy = 0; cy < ch; cy++)
for(cx = 0; cx < cw; cx++)
for (int cy = 0; cy < csize.y; ++cy)
for (int cx = 0; cx < csize.x; ++cx)
{
int changes = 0;

if(changelist[cy * cw + cx] >= 2)
if (changelist[cx][cy] >= 2)
continue;

for(y = cy * CELL; y < (cy + 1) * CELL; y++)
for(x = cx * CELL; x < (cx + 1) * CELL; x++)
for (int y = cy * CELL; y < (cy + 1) * CELL; ++y)
for (int x = cx * CELL; x < (cx + 1) * CELL; ++x)
{
double d, d2, e, best = 0.;
int opx = -1, opy = -1;

d = dstdata[y * w + x];
float d = dstdata[y * size.x + x];
float d2;

/* Compute the effect of a toggle */
e = 0.;
for(j = -N; j < N + 1; j++)
float e = 0.f, best = 0.f;
for (int j = -N; j < N + 1; j++)
{
if(y + j < 0 || y + j >= h)
if (y + j < 0 || y + j >= size.y)
continue;

for(i = -N; i < N + 1; i++)
for (int i = -N; i < N + 1; i++)
{
double m, p, q1, q2;

if(x + i < 0 || x + i >= w)
if (x + i < 0 || x + i >= size.x)
continue;

m = kernel[(j + N) * NN + i + N];
p = tmp1data[(y + j) * w + x + i];
q1 = tmp2data[(y + j) * w + x + i];
q2 = q1 - m * d + m * (1. - d);
float m = kernel[i + N][j + N];
float p = tmp1data[(y + j) * size.x + x + i];
float q1 = tmp2data[(y + j) * size.x + x + i];
float q2 = q1 - m * d + m * (1. - d);
e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p);
}
}
if(e > best)

if (e > best)
{
best = e;
opx = opy = 0;
}

/* Compute the effect of swaps */
for(n = 0; n < 8; n++)
for (int n = 0; n < 8; n++)
{
static int const step[] =
{ 0, 1, 0, -1, -1, 0, 1, 0, -1, -1, -1, 1, 1, -1, 1, 1 };
int idx = step[n * 2], idy = step[n * 2 + 1];
if(y + idy < 0 || y + idy >= h
|| x + idx < 0 || x + idx >= w)
if (y + idy < 0 || y + idy >= size.y
|| x + idx < 0 || x + idx >= size.x)
continue;
d2 = dstdata[(y + idy) * w + x + idx];
if(d2 == d)
d2 = dstdata[(y + idy) * size.x + x + idx];
if (d2 == d)
continue;
e = 0.;
for(j = -N; j < N + 1; j++)
for (int j = -N; j < N + 1; j++)
{
if(y + j < 0 || y + j >= h)
if (y + j < 0 || y + j >= size.y)
continue;
if(j - idy + N < 0 || j - idy + N >= NN)
if (j - idy + N < 0 || j - idy + N >= NN)
continue;
for(i = -N; i < N + 1; i++)
for (int i = -N; i < N + 1; i++)
{
double ma, mb, p, q1, q2;
if(x + i < 0 || x + i >= w)
if (x + i < 0 || x + i >= size.x)
continue;
if(i - idx + N < 0 || i - idx + N >= NN)
if (i - idx + N < 0 || i - idx + N >= NN)
continue;
ma = kernel[(j + N) * NN + i + N];
mb = kernel[(j - idy + N) * NN + i - idx + N];
p = tmp1data[(y + j) * w + x + i];
q1 = tmp2data[(y + j) * w + x + i];
q2 = q1 - ma * d + ma * d2 - mb * d2 + mb * d;
float ma = kernel[i + N][j + N];
float mb = kernel[i - idx + N][j - idy + N];
float p = tmp1data[(y + j) * size.x + x + i];
float q1 = tmp2data[(y + j) * size.x + x + i];
float q2 = q1 - ma * d + ma * d2 - mb * d2 + mb * d;
e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p);
}
}
if(e > best)

if (e > best)
{
best = e;
opx = idx;
@@ -176,31 +157,33 @@ pipi_image_t *pipi_dither_dbs(pipi_image_t *img)
}

/* Apply the change if interesting */
if(best <= 0.)
if (best <= 0.f)
continue;
if(opx || opy)

if (opx || opy)
{
d2 = dstdata[(y + opy) * w + x + opx];
dstdata[(y + opy) * w + x + opx] = d;
d2 = dstdata[(y + opy) * size.x + x + opx];
dstdata[(y + opy) * size.x + x + opx] = d;
}
else
d2 = 1. - d;
dstdata[y * w + x] = d2;
for(j = -N; j < N + 1; j++)
for(i = -N; i < N + 1; i++)
dstdata[y * size.x + x] = d2;

for (int j = -N; j < N + 1; j++)
for (int i = -N; i < N + 1; i++)
{
double m = kernel[(j + N) * NN + i + N];
if(y + j >= 0 && y + j < h
&& x + i >= 0 && x + i < w)
float m = kernel[i + N][j + N];
if (y + j >= 0 && y + j < size.y
&& x + i >= 0 && x + i < size.x)
{
t = tmp2data[(y + j) * w + x + i];
tmp2data[(y + j) * w + x + i] = t + m * (d2 - d);
t = tmp2data[(y + j) * size.x + x + i];
tmp2data[(y + j) * size.x + x + i] = t + m * (d2 - d);
}
if((opx || opy) && y + opy + j >= 0 && y + opy + j < h
&& x + opx + i >= 0 && x + opx + i < w)
if ((opx || opy) && y + opy + j >= 0 && y + opy + j < size.y
&& x + opx + i >= 0 && x + opx + i < size.x)
{
t = tmp2data[(y + opy + j) * w + x + opx + i];
tmp2data[(y + opy + j) * w + x + opx + i]
t = tmp2data[(y + opy + j) * size.x + x + opx + i];
tmp2data[(y + opy + j) * size.x + x + opx + i]
= t + m * (d - d2);
}
}
@@ -208,21 +191,22 @@ pipi_image_t *pipi_dither_dbs(pipi_image_t *img)
changes++;
}

if(changes == 0)
changelist[cy * cw + cx]++;
if (changes == 0)
++changelist[cx][cy];

allchanges += changes;
}

if(allchanges == 0)
if (allchanges == 0)
break;
}

free(changelist);

pipi_free(tmp1);
pipi_free(tmp2);
tmp1.Unlock(tmp1data);
tmp2.Unlock(tmp2data);
dst.Unlock(dstdata);

return dst;
}

} /* namespace lol */


+ 0
- 56
src/image/paint/tile.cpp 查看文件

@@ -1,56 +0,0 @@
/*
* 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.
*/

/*
* tile.c: Tiling function
*/

#include "config.h"

#include <string.h>

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

pipi_image_t *pipi_tile(pipi_image_t *tile, int w, int h)
{
pipi_image_t *dst;
pipi_pixels_t *tilep, *dstp;
float *tiledata, *dstdata;
int x, y, tw, th, todo;

tw = tile->w;
th = tile->h;

dst = pipi_new(w, h);
dstp = pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
dstdata = (float *)dstp->pixels;

tilep = pipi_get_pixels(tile, PIPI_PIXELS_RGBA_F32);
tiledata = (float *)tilep->pixels;

for(y = 0; y < h; y++)
{
for(x = 0; x < w; x += todo)
{
todo = (x + tw > w) ? w - x : tw;
memcpy(dstdata + 4 * (y * w + x),
tiledata + 4 * (y % th) * tw,
4 * todo * sizeof(float));
}
}

return dst;
}


+ 0
- 138
src/image/pipi-internals.h 查看文件

@@ -1,138 +0,0 @@
/*
* libpipi Pathetic image processing interface library
* Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net>
* 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.
*/

/*
* pipi-internals.h: internal types
*/

#ifndef __PIPI_INTERNALS_H__
#define __PIPI_INTERNALS_H__

#include "pipi-stubs.h"

#define SET_FLAG_GRAY 0x00000001
#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];
};

#ifdef USE_TILES
#define TILE_SIZE 128

struct pipi_tile
{
int x, y;
int zoom;

int refcount;

pipi_format_t fmt;
int plane;
union { uint8_t *u8; float *f; double *d; } data;
union { uint8_t u8[1]; float f[1]; double d[1]; } align;
};
#endif /* USE_TILES */

/* 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. */
struct pipi_image
{
int w, h, pitch;

#ifdef USE_TILES
pipi_tile_t **tiles;
int ntiles;
#endif /* USE_TILES */

/* A list of internal image flags.
* wrap: should filters wrap around at edges?
* u8: are the image samples still 8-bit per channel? */
int wrap, u8;

/* Translation vectors for wrap around and tiling. */
int wrapx1, wrapy1, wrapx2, wrapy2;

/* List of all possible pixel formats and the last active one. */
pipi_pixels_t p[PIPI_PIXELS_MAX];
pipi_format_t last_modified;

/* Private data used by the codec */
pipi_format_t codec_format;
void *codec_priv;
int (*codec_free)(pipi_image_t *);
};

struct pipi_sequence
{
int w, h, fps;
uint8_t *convert_buf;

void *codec_priv;
};

struct pipi_context
{
int nimages;
pipi_image_t *images[1024]; /* FIXME: do dynamic allocation */
};

#ifdef USE_IMLIB2
pipi_image_t *pipi_load_imlib2(const char *name);
int pipi_save_imlib2(pipi_image_t *img, const char *name);
#endif

#ifdef USE_OPENCV
pipi_image_t *pipi_load_opencv(const char *name);
int pipi_save_opencv(pipi_image_t *img, const char *name);
#endif

#ifdef USE_SDL
pipi_image_t *pipi_load_sdl(const char *name);
int pipi_save_sdl(pipi_image_t *img, const char *name);
#endif

#ifdef USE_GDIPLUS
pipi_image_t *pipi_load_gdiplus(const char *name);
int pipi_save_gdiplus(pipi_image_t *img, const char *name);
#endif

#ifdef USE_GDI
pipi_image_t *pipi_load_gdi(const char *name);
int pipi_save_gdi(pipi_image_t *img, const char *name);
#endif

#ifdef USE_COCOA
pipi_image_t *pipi_load_coreimage(const char *name);
int pipi_save_coreimage(pipi_image_t *img, const char *name);
#endif

#ifdef USE_JPEG
pipi_image_t *pipi_load_jpeg(const char *name);
int pipi_save_jpeg(pipi_image_t *img, const char *name);
#endif

pipi_image_t *pipi_load_oric(const char *name);
int pipi_save_oric(pipi_image_t *img, const char *name);

#endif /* __PIPI_INTERNALS_H__ */


+ 0
- 80
src/image/pipi-template.h 查看文件

@@ -1,80 +0,0 @@
/*
* 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.
*/

/* pipi-template.h: the magic template preprocessing file
*
* Define the following macros before including this file:
* * TEMPLATE_FLAGS is set to a list of toggle flags, a binary OR of:
* - SET_FLAG_GRAY
* - SET_FLAG_WRAP
* - SET_FLAG_8BIT
* * TEMPLATE_FILE is set to the template file. The following macros
* will be defined when including it. Their value depend on the flags
* specified above:
* - FLAG_GRAY is set to 0 or 1
* - FLAG_WRAP is set to 0 or 1
* - FLAG_8BIT is set to 0 or 1
* - T(x) expands x by adding relevant information, eg. x##_gray_wrap
*/

#if !defined FLAG_GRAY
# if (TEMPLATE_FLAGS) & SET_FLAG_GRAY
# define FLAG_GRAY 1
# define T_GRAY(x) CAT(x, _gray)
# include __FILE__
# undef FLAG_GRAY
# undef T_GRAY
# endif
# define FLAG_GRAY 0
# define T_GRAY(x) x
# include __FILE__
# undef FLAG_GRAY
# undef T_GRAY

#elif !defined FLAG_WRAP
# if (TEMPLATE_FLAGS) & SET_FLAG_WRAP
# define FLAG_WRAP 1
# define T_WRAP(x) CAT(x, _wrap)
# include __FILE__
# undef FLAG_WRAP
# undef T_WRAP
# endif
# define FLAG_WRAP 0
# define T_WRAP(x) x
# include __FILE__
# undef FLAG_WRAP
# undef T_WRAP

#elif !defined FLAG_8BIT
# if (TEMPLATE_FLAGS) & SET_FLAG_8BIT
# define FLAG_8BIT 1
# define T_8BIT(x) CAT(x, _8bit)
# include __FILE__
# undef FLAG_8BIT
# undef T_8BIT
# endif
# define FLAG_8BIT 0
# define T_8BIT(x) x
# include __FILE__
# undef FLAG_8BIT
# undef T_8BIT

#else
# define CAT(x, y) x ## y
# define T(x) T_8BIT(T_WRAP(T_GRAY(x)))
# include TEMPLATE_FILE
# undef CAT
# undef S
#endif


+ 0
- 253
src/image/pipi.h 查看文件

@@ -1,253 +0,0 @@
/*
* libpipi Pathetic image processing interface library
* Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net>
* 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.
*/

/*
* pipi.h: the full libpipi public API
*/

#ifndef __PIPI_H__
#define __PIPI_H__

#include <pipi-types.h>

#undef __extern
#if defined(_DOXYGEN_SKIP_ME)
#elif defined(_WIN32) && defined(__LIBPIPI__)
# define __extern extern __declspec(dllexport)
#else
# define __extern extern
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/* pipi_scan_t: this enum is a list of all possible scanning methods when
* parsing an image’s pixels. Not all functions support all scanning paths. */
typedef enum
{
PIPI_SCAN_RASTER = 0,
PIPI_SCAN_SERPENTINE = 1
}
pipi_scan_t;

/* pipi_format_t: this enum is a list of all possible pixel formats for
* our internal images. RGBA_U8 is the most usual format when an image has
* just been loaded, but RGBA_F32 is a lot better for complex operations. */
typedef enum
{
PIPI_PIXELS_UNINITIALISED = -1,

PIPI_PIXELS_RGBA_U8 = 0,
PIPI_PIXELS_BGR_U8 = 1,
PIPI_PIXELS_RGBA_F32 = 2,
PIPI_PIXELS_Y_F32 = 3,

PIPI_PIXELS_MASK_U8 = 4,

PIPI_PIXELS_MAX = 5
}
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;
};
struct pixel_float
{
float r, g, b, a;
};

typedef struct
{
union
{
struct pixel_float pixel_float;
struct pixel_u32 pixel_u32;
};
}
pipi_pixel_t;

/* pipi_pixels_t: this structure stores a pixel view of an image. */
typedef struct
{
void *pixels;
int w, h, pitch, bpp;
size_t bytes;
}
pipi_pixels_t;

/* pipi_tile_t: the internal tile type */
typedef struct pipi_tile pipi_tile_t;

/* pipi_image_t: the main image type */
typedef struct pipi_image pipi_image_t;

/* pipi_sequence_t: the image sequence type */
typedef struct pipi_sequence pipi_sequence_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;

/* pipi_command_t: the command type */
typedef struct
{
char const *name;
int argc;
}
pipi_command_t;

__extern pipi_pixel_t *pipi_get_color_from_string(const char* s);

__extern char const * pipi_get_version(void);

__extern pipi_context_t *pipi_create_context(void);
__extern void pipi_destroy_context(pipi_context_t *);
__extern pipi_command_t const *pipi_get_command_list(void);
__extern int pipi_command(pipi_context_t *, char const *, ...);

__extern pipi_tile_t *pipi_get_tile(pipi_image_t *, int, int, int,
pipi_format_t, int);
__extern void pipi_release_tile(pipi_image_t *, pipi_tile_t *);
__extern pipi_tile_t *pipi_create_tile(pipi_format_t, int);

__extern pipi_image_t *pipi_load(char const *);
__extern pipi_image_t *pipi_load_stock(char const *);
__extern pipi_image_t *pipi_new(int, int);
__extern pipi_image_t *pipi_copy(pipi_image_t *);
__extern void pipi_free(pipi_image_t *);
__extern int pipi_save(pipi_image_t *, const char *);

__extern void pipi_set_gamma(double);
__extern pipi_pixels_t *pipi_get_pixels(pipi_image_t *, pipi_format_t);
__extern void pipi_release_pixels(pipi_image_t *, pipi_pixels_t *);
__extern void pipi_set_colorspace(pipi_image_t *, pipi_format_t);
__extern int pipi_get_image_width(pipi_image_t *img);
__extern int pipi_get_image_height(pipi_image_t *img);
__extern int pipi_get_image_pitch(pipi_image_t *img);
__extern int pipi_get_image_last_modified(pipi_image_t *img);
__extern const char* pipi_get_format_name(int format);


__extern double pipi_measure_msd(pipi_image_t *, pipi_image_t *);
__extern double pipi_measure_rmsd(pipi_image_t *, pipi_image_t *);

__extern pipi_image_t *pipi_resize_bresenham(pipi_image_t *, int, int);
__extern pipi_image_t *pipi_resize_bicubic(pipi_image_t *, int, int);
__extern pipi_image_t *pipi_crop(pipi_image_t *, int, int, int, int);

__extern pipi_image_t *pipi_render_random(int, int);
__extern pipi_image_t *pipi_render_bayer(int, int);
__extern pipi_image_t *pipi_render_halftone(int, int);

__extern pipi_image_t *pipi_rgb(pipi_image_t *, pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_red(pipi_image_t *);
__extern pipi_image_t *pipi_green(pipi_image_t *);
__extern pipi_image_t *pipi_blue(pipi_image_t *);
__extern pipi_image_t *pipi_blit(pipi_image_t *, pipi_image_t *, int, int);
__extern pipi_image_t *pipi_merge(pipi_image_t *, pipi_image_t *, double);
__extern pipi_image_t *pipi_mean(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_min(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_max(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_add(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_sub(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_difference(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_multiply(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_divide(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_screen(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_overlay(pipi_image_t *, pipi_image_t *);

__extern pipi_image_t *pipi_convolution(pipi_image_t *, int, int, double[]);
__extern pipi_image_t *pipi_gaussian_blur(pipi_image_t *, float);
__extern pipi_image_t *pipi_gaussian_blur_ext(pipi_image_t *,
float, float, float, float, float);
__extern pipi_image_t *pipi_box_blur(pipi_image_t *, int);
__extern pipi_image_t *pipi_box_blur_ext(pipi_image_t *, int, int);
__extern pipi_image_t *pipi_brightness(pipi_image_t *, double);
__extern pipi_image_t *pipi_contrast(pipi_image_t *, double);
__extern pipi_image_t *pipi_autocontrast(pipi_image_t *);
__extern pipi_image_t *pipi_invert(pipi_image_t *);
__extern pipi_image_t *pipi_threshold(pipi_image_t *, double);
__extern pipi_image_t *pipi_hflip(pipi_image_t *);
__extern pipi_image_t *pipi_vflip(pipi_image_t *);
__extern pipi_image_t *pipi_rotate(pipi_image_t *, double);
__extern pipi_image_t *pipi_rotate90(pipi_image_t *);
__extern pipi_image_t *pipi_rotate180(pipi_image_t *);
__extern pipi_image_t *pipi_rotate270(pipi_image_t *);
__extern pipi_image_t *pipi_median(pipi_image_t *, int);
__extern pipi_image_t *pipi_median_ext(pipi_image_t *, int, int);
__extern pipi_image_t *pipi_dilate(pipi_image_t *);
__extern pipi_image_t *pipi_erode(pipi_image_t *);
__extern pipi_image_t *pipi_sine(pipi_image_t *, double, double,
double, double);
__extern pipi_image_t *pipi_wave(pipi_image_t *, double, double,
double, double);
__extern pipi_image_t *pipi_rgb2yuv(pipi_image_t *);
__extern pipi_image_t *pipi_yuv2rgb(pipi_image_t *);

__extern pipi_image_t *pipi_order(pipi_image_t *);

__extern pipi_image_t *pipi_tile(pipi_image_t *, int, int);
__extern int pipi_flood_fill(pipi_image_t *,
int, int, float, float, float, float);
__extern int pipi_draw_line(pipi_image_t *, int, int, int, int, uint32_t, int);
__extern int pipi_draw_rectangle(pipi_image_t *, int, int, int, int, uint32_t, int);
__extern int pipi_draw_polyline(pipi_image_t *, int const[], int const[],
int , uint32_t, int);
__extern int pipi_draw_bezier4(pipi_image_t *,int, int, int, int, int, int, int, int, uint32_t, int, int);
__extern pipi_image_t *pipi_reduce(pipi_image_t *, int, double const *);

__extern pipi_image_t *pipi_dither_ediff(pipi_image_t *, pipi_image_t *,
pipi_scan_t);
__extern pipi_image_t *pipi_dither_ordered(pipi_image_t *, pipi_image_t *);
__extern pipi_image_t *pipi_dither_ordered_ext(pipi_image_t *, pipi_image_t *,
double, double);
__extern pipi_image_t *pipi_dither_halftone(pipi_image_t *, double, double);
__extern pipi_image_t *pipi_dither_random(pipi_image_t *);
__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);

__extern pipi_sequence_t *pipi_open_sequence(char const *, int, int, int,
int, int, int, int);
__extern int pipi_feed_sequence(pipi_sequence_t *, uint8_t const *, int, int);
__extern int pipi_close_sequence(pipi_sequence_t *);

#ifdef __cplusplus
}
#endif

#endif /* __PIPI_H__ */


+ 1
- 0
src/lol/image/image.h 查看文件

@@ -135,6 +135,7 @@ public:
Image DitherOstromoukhov(ScanMode scan = ScanMode::Raster) const;
Image DitherOrdered(Array2D<float> const &kernel) const;
Image DitherHalftone(float radius, float angle) const;
Image DitherDbs() const;

private:
class ImageData *m_data;


+ 1
- 0
src/lolcore.vcxproj 查看文件

@@ -155,6 +155,7 @@
<ClCompile Include="image\filter\dilate.cpp" />
<ClCompile Include="image\filter\median.cpp" />
<ClCompile Include="image\filter\yuv.cpp" />
<ClCompile Include="image\dither\dbs.cpp" />
<ClCompile Include="image\dither\ediff.cpp" />
<ClCompile Include="image\dither\ordered.cpp" />
<ClCompile Include="image\dither\ostromoukhov.cpp" />


+ 3
- 0
src/lolcore.vcxproj.filters 查看文件

@@ -379,6 +379,9 @@
<ClCompile Include="image\filter\yuv.cpp">
<Filter>image\filter</Filter>
</ClCompile>
<ClCompile Include="image\dither\dbs.cpp">
<Filter>image\dither</Filter>
</ClCompile>
<ClCompile Include="image\dither\ediff.cpp">
<Filter>image\dither</Filter>
</ClCompile>


正在加载...
取消
保存