| @@ -97,6 +97,7 @@ demos/tutorial/03_noise | |||||
| demos/tutorial/04_texture | demos/tutorial/04_texture | ||||
| demos/tutorial/05_easymesh | demos/tutorial/05_easymesh | ||||
| demos/tutorial/06_sprite | demos/tutorial/06_sprite | ||||
| demos/tutorial/07_input | |||||
| demos/tutorial/08_fbo | demos/tutorial/08_fbo | ||||
| demos/tutorial/11_fractal | demos/tutorial/11_fractal | ||||
| demos/tutorial/12_voronoi | demos/tutorial/12_voronoi | ||||
| @@ -14,8 +14,9 @@ Scene: | |||||
| Image: | Image: | ||||
| - Handle pitch in SDL codec (and all others, actually) | - 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 | - Add gamma handling in pixels.cpp | ||||
| - Make some Image::Lock2D method that returns an Array2D | |||||
| - port libpipi files: | - port libpipi files: | ||||
| · analysis/histogram.cpp | · analysis/histogram.cpp | ||||
| · analysis/measure.cpp | · analysis/measure.cpp | ||||
| @@ -31,7 +32,6 @@ Image: | |||||
| · combine/rgb.cpp | · combine/rgb.cpp | ||||
| · combine/subadd.cpp | · combine/subadd.cpp | ||||
| · context.cpp | · context.cpp | ||||
| · dither/dbs.cpp | |||||
| · filter/blur.cpp | · filter/blur.cpp | ||||
| · filter/rotate.cpp | · filter/rotate.cpp | ||||
| · filter/transform.cpp | · filter/transform.cpp | ||||
| @@ -40,10 +40,6 @@ Image: | |||||
| · paint/floodfill.cpp | · paint/floodfill.cpp | ||||
| · paint/line.cpp | · paint/line.cpp | ||||
| · paint/rectangle.cpp | · paint/rectangle.cpp | ||||
| · paint/tile.cpp | |||||
| · pipi.h | |||||
| · pipi-internals.h | |||||
| · pipi-template.h | |||||
| · quantize/reduce.cpp | · quantize/reduce.cpp | ||||
| · sequence.cpp | · sequence.cpp | ||||
| @@ -117,7 +117,7 @@ liblolcore_sources = \ | |||||
| image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \ | image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \ | ||||
| image/codec/oric-image.cpp image/codec/dummy-image.cpp \ | image/codec/oric-image.cpp image/codec/dummy-image.cpp \ | ||||
| image/color/cie1931.cpp image/color/color.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/dither/ostromoukhov.cpp image/dither/ordered.cpp \ | ||||
| image/filter/convolution.cpp image/filter/color.cpp \ | image/filter/convolution.cpp image/filter/color.cpp \ | ||||
| image/filter/dilate.cpp image/filter/median.cpp image/filter/yuv.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 CELL 16 | ||||
| #define N 7 | #define N 7 | ||||
| #define NN ((N * 2 + 1)) | #define NN ((N * 2 + 1)) | ||||
| namespace lol | |||||
| { | |||||
| /* FIXME: though the algorithm is supposed to stop, we do not have a real, | /* FIXME: though the algorithm is supposed to stop, we do not have a real, | ||||
| * guaranteed stop condition here. */ | * 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. */ | /* 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; | 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; | int changes = 0; | ||||
| if(changelist[cy * cw + cx] >= 2) | |||||
| if (changelist[cx][cy] >= 2) | |||||
| continue; | 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; | 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 */ | /* 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; | 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; | 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); | e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p); | ||||
| } | } | ||||
| } | } | ||||
| if(e > best) | |||||
| if (e > best) | |||||
| { | { | ||||
| best = e; | best = e; | ||||
| opx = opy = 0; | opx = opy = 0; | ||||
| } | } | ||||
| /* Compute the effect of swaps */ | /* Compute the effect of swaps */ | ||||
| for(n = 0; n < 8; n++) | |||||
| for (int n = 0; n < 8; n++) | |||||
| { | { | ||||
| static int const step[] = | static int const step[] = | ||||
| { 0, 1, 0, -1, -1, 0, 1, 0, -1, -1, -1, 1, 1, -1, 1, 1 }; | { 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]; | 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; | continue; | ||||
| d2 = dstdata[(y + idy) * w + x + idx]; | |||||
| if(d2 == d) | |||||
| d2 = dstdata[(y + idy) * size.x + x + idx]; | |||||
| if (d2 == d) | |||||
| continue; | continue; | ||||
| e = 0.; | 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; | continue; | ||||
| if(j - idy + N < 0 || j - idy + N >= NN) | |||||
| if (j - idy + N < 0 || j - idy + N >= NN) | |||||
| continue; | 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; | continue; | ||||
| if(i - idx + N < 0 || i - idx + N >= NN) | |||||
| if (i - idx + N < 0 || i - idx + N >= NN) | |||||
| continue; | 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); | e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p); | ||||
| } | } | ||||
| } | } | ||||
| if(e > best) | |||||
| if (e > best) | |||||
| { | { | ||||
| best = e; | best = e; | ||||
| opx = idx; | opx = idx; | ||||
| @@ -176,31 +157,33 @@ pipi_image_t *pipi_dither_dbs(pipi_image_t *img) | |||||
| } | } | ||||
| /* Apply the change if interesting */ | /* Apply the change if interesting */ | ||||
| if(best <= 0.) | |||||
| if (best <= 0.f) | |||||
| continue; | 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 | else | ||||
| d2 = 1. - d; | 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); | = t + m * (d - d2); | ||||
| } | } | ||||
| } | } | ||||
| @@ -208,21 +191,22 @@ pipi_image_t *pipi_dither_dbs(pipi_image_t *img) | |||||
| changes++; | changes++; | ||||
| } | } | ||||
| if(changes == 0) | |||||
| changelist[cy * cw + cx]++; | |||||
| if (changes == 0) | |||||
| ++changelist[cx][cy]; | |||||
| allchanges += changes; | allchanges += changes; | ||||
| } | } | ||||
| if(allchanges == 0) | |||||
| if (allchanges == 0) | |||||
| break; | break; | ||||
| } | } | ||||
| free(changelist); | |||||
| pipi_free(tmp1); | |||||
| pipi_free(tmp2); | |||||
| tmp1.Unlock(tmp1data); | |||||
| tmp2.Unlock(tmp2data); | |||||
| dst.Unlock(dstdata); | |||||
| return dst; | 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 DitherOstromoukhov(ScanMode scan = ScanMode::Raster) const; | ||||
| Image DitherOrdered(Array2D<float> const &kernel) const; | Image DitherOrdered(Array2D<float> const &kernel) const; | ||||
| Image DitherHalftone(float radius, float angle) const; | Image DitherHalftone(float radius, float angle) const; | ||||
| Image DitherDbs() const; | |||||
| private: | private: | ||||
| class ImageData *m_data; | class ImageData *m_data; | ||||
| @@ -155,6 +155,7 @@ | |||||
| <ClCompile Include="image\filter\dilate.cpp" /> | <ClCompile Include="image\filter\dilate.cpp" /> | ||||
| <ClCompile Include="image\filter\median.cpp" /> | <ClCompile Include="image\filter\median.cpp" /> | ||||
| <ClCompile Include="image\filter\yuv.cpp" /> | <ClCompile Include="image\filter\yuv.cpp" /> | ||||
| <ClCompile Include="image\dither\dbs.cpp" /> | |||||
| <ClCompile Include="image\dither\ediff.cpp" /> | <ClCompile Include="image\dither\ediff.cpp" /> | ||||
| <ClCompile Include="image\dither\ordered.cpp" /> | <ClCompile Include="image\dither\ordered.cpp" /> | ||||
| <ClCompile Include="image\dither\ostromoukhov.cpp" /> | <ClCompile Include="image\dither\ostromoukhov.cpp" /> | ||||
| @@ -379,6 +379,9 @@ | |||||
| <ClCompile Include="image\filter\yuv.cpp"> | <ClCompile Include="image\filter\yuv.cpp"> | ||||
| <Filter>image\filter</Filter> | <Filter>image\filter</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| <ClCompile Include="image\dither\dbs.cpp"> | |||||
| <Filter>image\dither</Filter> | |||||
| </ClCompile> | |||||
| <ClCompile Include="image\dither\ediff.cpp"> | <ClCompile Include="image\dither\ediff.cpp"> | ||||
| <Filter>image\dither</Filter> | <Filter>image\dither</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||