@@ -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 | |||
@@ -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 | |||
@@ -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 \ | |||
@@ -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 */ | |||
@@ -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; | |||
} | |||
@@ -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__ */ | |||
@@ -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 | |||
@@ -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__ */ | |||
@@ -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; | |||
@@ -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" /> | |||
@@ -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> | |||