@@ -46,7 +46,5 @@ Image: | |||||
· pipi-internals.h | · pipi-internals.h | ||||
· pipi-template.h | · pipi-template.h | ||||
· quantize/reduce.cpp | · quantize/reduce.cpp | ||||
· resample/bicubic.cpp | |||||
· resample/bresenham.cpp | |||||
· sequence.cpp | · sequence.cpp | ||||
@@ -111,7 +111,7 @@ liblolcore_sources = \ | |||||
sys/thread.cpp sys/threadbase.h \ | sys/thread.cpp sys/threadbase.h \ | ||||
\ | \ | ||||
image/image.cpp image/image-private.h image/kernel.cpp image/pixels.cpp \ | image/image.cpp image/image-private.h image/kernel.cpp image/pixels.cpp \ | ||||
image/crop.cpp \ | |||||
image/crop.cpp image/resample.cpp image/noise.cpp \ | |||||
image/codec/gdiplus-image.cpp image/codec/imlib2-image.cpp \ | image/codec/gdiplus-image.cpp image/codec/imlib2-image.cpp \ | ||||
image/codec/sdl-image.cpp image/codec/ios-image.cpp \ | image/codec/sdl-image.cpp image/codec/ios-image.cpp \ | ||||
image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \ | image/codec/zed-image.cpp image/codec/zed-palette-image.cpp \ | ||||
@@ -121,7 +121,6 @@ liblolcore_sources = \ | |||||
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 \ | ||||
image/render/noise.cpp \ | |||||
\ | \ | ||||
loldebug.h \ | loldebug.h \ | ||||
debug/fps.cpp debug/fps.h debug/lines.cpp \ | debug/fps.cpp debug/fps.h debug/lines.cpp \ | ||||
@@ -0,0 +1,212 @@ | |||||
// | |||||
// 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" | |||||
/* | |||||
* Image resizing functions | |||||
*/ | |||||
namespace lol | |||||
{ | |||||
static Image ResizeBicubic(Image &image, ivec2 size); | |||||
static Image ResizeBresenham(Image &image, ivec2 size); | |||||
Image Image::Resize(ivec2 size, ResampleAlgorithm algorithm) | |||||
{ | |||||
switch (algorithm) | |||||
{ | |||||
case ResampleAlgorithm::Bicubic: | |||||
return ResizeBicubic(*this, size); | |||||
case ResampleAlgorithm::Bresenham: | |||||
default: | |||||
return ResizeBresenham(*this, size); | |||||
} | |||||
} | |||||
static Image ResizeBicubic(Image &image, ivec2 size) | |||||
{ | |||||
Image dst(size); | |||||
ivec2 const oldsize = image.GetSize(); | |||||
vec4 const *srcp = image.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||||
float scalex = size.x > 1 ? (oldsize.x - 1.f) / (size.x - 1) : 1.f; | |||||
float scaley = size.y > 1 ? (oldsize.y - 1.f) / (size.y - 1) : 1.f; | |||||
for (int y = 0; y < size.y; ++y) | |||||
{ | |||||
float yfloat = scaley * y; | |||||
int yint = (int)yfloat; | |||||
float y1 = yfloat - yint; | |||||
vec4 const *p0 = srcp + oldsize.x * lol::min(lol::max(0, yint - 1), oldsize.y - 1); | |||||
vec4 const *p1 = srcp + oldsize.x * lol::min(lol::max(0, yint ), oldsize.y - 1); | |||||
vec4 const *p2 = srcp + oldsize.x * lol::min(lol::max(0, yint + 1), oldsize.y - 1); | |||||
vec4 const *p3 = srcp + oldsize.x * lol::min(lol::max(0, yint + 2), oldsize.y - 1); | |||||
for (int x = 0; x < size.x; ++x) | |||||
{ | |||||
float xfloat = scalex * x; | |||||
int xint = (int)xfloat; | |||||
float x1 = xfloat - xint; | |||||
int const i0 = lol::min(lol::max(0, xint - 1), oldsize.x - 1); | |||||
int const i1 = lol::min(lol::max(0, xint ), oldsize.x - 1); | |||||
int const i2 = lol::min(lol::max(0, xint + 1), oldsize.x - 1); | |||||
int const i3 = lol::min(lol::max(0, xint + 2), oldsize.x - 1); | |||||
vec4 a00 = p1[i1]; | |||||
vec4 a01 = .5f * (p2[i1] - p0[i1]); | |||||
vec4 a02 = p0[i1] - 2.5f * p1[i1] | |||||
+ 2.f * p2[i1] - .5f * p3[i1]; | |||||
vec4 a03 = .5f * (p3[i1] - p0[i1]) + 1.5f * (p1[i1] - p2[i1]); | |||||
vec4 a10 = .5f * (p1[i2] - p1[i0]); | |||||
vec4 a11 = .25f * (p0[i0] - p2[i0] - p0[i2] + p2[i2]); | |||||
vec4 a12 = .5f * (p0[i2] - p0[i0]) + 1.25f * (p1[i0] - p1[i2]) | |||||
+ .25f * (p3[i0] - p3[i2]) + p2[i2] - p2[i0]; | |||||
vec4 a13 = .25f * (p0[i0] - p3[i0] - p0[i2] + p3[i2]) | |||||
+ .75f * (p2[i0] - p1[i0] + p1[i2] - p2[i2]); | |||||
vec4 a20 = p1[i0] - 2.5f * p1[i1] | |||||
+ 2.f * p1[i2] - .5f * p1[i3]; | |||||
vec4 a21 = .5f * (p2[i0] - p0[i0]) + 1.25f * (p0[i1] - p2[i1]) | |||||
+ .25f * (p0[i3] - p2[i3]) - p0[i2] + p2[i2]; | |||||
vec4 a22 = p0[i0] - p3[i2] - 2.5f * (p1[i0] + p0[i1]) | |||||
+ 2.f * (p2[i0] + p0[i2]) - .5f * (p3[i0] + p0[i3]) | |||||
+ 6.25f * p1[i1] - 5.f * (p2[i1] + p1[i2]) | |||||
+ 1.25f * (p3[i1] + p1[i3]) | |||||
+ 4.f * p2[i2] - p2[i3] + .25f * p3[i3]; | |||||
vec4 a23 = 1.5f * (p1[i0] - p2[i0]) + .5f * (p3[i0] - p0[i0]) | |||||
+ 1.25f * (p0[i1] - p3[i1]) | |||||
+ 3.75f * (p2[i1] - p1[i1]) + p3[i2] - p0[i2] | |||||
+ 3.f * (p1[i2] - p2[i2]) + .25f * (p0[i3] - p3[i3]) | |||||
+ .75f * (p2[i3] - p1[i3]); | |||||
vec4 a30 = .5f * (p1[i3] - p1[i0]) + 1.5f * (p1[i1] - p1[i2]); | |||||
vec4 a31 = .25f * (p0[i0] - p2[i0]) + .25f * (p2[i3] - p0[i3]) | |||||
+ .75f * (p2[i1] - p0[i1] + p0[i2] - p2[i2]); | |||||
vec4 a32 = -.5f * p0[i0] + 1.25f * p1[i0] - p2[i0] | |||||
+ .25f * p3[i0] + 1.5f * p0[i1] - 3.75f * p1[i1] | |||||
+ 3.f * p2[i1] - .75f * p3[i1] - 1.5f * p0[i2] | |||||
+ 3.75f * p1[i2] - 3.f * p2[i2] + .75f * p3[i2] | |||||
+ .5f * p0[i3] - 1.25f * p1[i3] + p2[i3] | |||||
- .25f * p3[i3]; | |||||
vec4 a33 = .25f * p0[i0] - .75f * p1[i0] + .75f * p2[i0] | |||||
- .25f * p3[i0] - .75f * p0[i1] + 2.25f * p1[i1] | |||||
- 2.25f * p2[i1] + .75f * p3[i1] + .75f * p0[i2] | |||||
- 2.25f * p1[i2] + 2.25f * p2[i2] - .75f * p3[i2] | |||||
- .25f * p0[i3] + .75f * p1[i3] - .75f * p2[i3] | |||||
+ .25f * p3[i3]; | |||||
float y2 = y1 * y1; float y3 = y2 * y1; | |||||
float x2 = x1 * x1; float x3 = x2 * x1; | |||||
vec4 p = a00 + a01 * y1 + a02 * y2 + a03 * y3 | |||||
+ a10 * x1 + a11 * x1 * y1 + a12 * x1 * y2 + a13 * x1 * y3 | |||||
+ a20 * x2 + a21 * x2 * y1 + a22 * x2 * y2 + a23 * x2 * y3 | |||||
+ a30 * x3 + a31 * x3 * y1 + a32 * x3 * y2 + a33 * x3 * y3; | |||||
dstp[y * size.x + x] = lol::clamp(p, 0.f, 1.f); | |||||
} | |||||
} | |||||
dst.Unlock(dstp); | |||||
image.Unlock(srcp); | |||||
return dst; | |||||
} | |||||
/* This is Bresenham resizing. I “rediscovered” it independently but | |||||
* it was actually first described in 1995 by Tim Kientzle in “Scaling | |||||
* Bitmaps with Bresenham”. */ | |||||
/* FIXME: the algorithm does not handle alpha components properly. Resulting | |||||
* alpha should be the mean alpha value of the neightbouring pixels, but | |||||
* the colour components should be weighted with the alpha value. */ | |||||
static Image ResizeBresenham(Image &image, ivec2 size) | |||||
{ | |||||
Image dst(size); | |||||
ivec2 const oldsize = image.GetSize(); | |||||
float const invswsh = 1.0f / (oldsize.x * oldsize.y); | |||||
vec4 const *srcp = image.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||||
Array<vec4> aline, line; | |||||
aline.Resize(size.x); | |||||
line.Resize(size.x); | |||||
memset(line.Data(), 0, line.Bytes()); | |||||
int remy = 0; | |||||
for (int y = 0, y0 = 0; y < size.y; y++) | |||||
{ | |||||
memset(aline.Data(), 0, aline.Bytes()); | |||||
for (int toty = 0; toty < oldsize.y; ) | |||||
{ | |||||
if (remy == 0) | |||||
{ | |||||
vec4 color(0.f); | |||||
int remx = 0; | |||||
for (int x = 0, x0 = 0; x < size.x; x++) | |||||
{ | |||||
vec4 acolor(0.f); | |||||
for (int totx = 0; totx < oldsize.x; ) | |||||
{ | |||||
if (remx == 0) | |||||
{ | |||||
color = srcp[y0 * oldsize.x + x0]; | |||||
x0++; | |||||
remx = size.x; | |||||
} | |||||
int nx = lol::min(remx, oldsize.x - totx); | |||||
acolor += (float)nx * color; | |||||
totx += nx; | |||||
remx -= nx; | |||||
} | |||||
line[x] = acolor; | |||||
} | |||||
y0++; | |||||
remy = size.y; | |||||
} | |||||
int ny = lol::min(remy, oldsize.y - toty); | |||||
for (int x = 0; x < size.x; x++) | |||||
aline[x] += (float)ny * line[x]; | |||||
toty += ny; | |||||
remy -= ny; | |||||
} | |||||
for (int x = 0; x < size.x; x++) | |||||
dstp[y * size.x + x] = aline[x] * invswsh; | |||||
} | |||||
dst.Unlock(dstp); | |||||
image.Unlock(srcp); | |||||
return dst; | |||||
} | |||||
} /* namespace lol */ | |||||
@@ -1,136 +0,0 @@ | |||||
/* | |||||
* libpipi Pathetic image processing interface library | |||||
* Copyright (c) 2004-2010 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. | |||||
*/ | |||||
/* | |||||
* bicubic.c: Bicubic image resizing functions | |||||
*/ | |||||
#include "config.h" | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include "pipi.h" | |||||
#include "pipi-internals.h" | |||||
static inline int min_int(int a, int b) { return a < b ? a : b; } | |||||
static inline int max_int(int a, int b) { return a > b ? a : b; } | |||||
pipi_image_t *pipi_resize_bicubic(pipi_image_t *src, int w, int h) | |||||
{ | |||||
float *srcdata, *dstdata, *p0, *p1, *p2, *p3; | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
int x, y, i, sw, dw, sh, dh, i0, i1, i2, i3; | |||||
float scalex, scaley; | |||||
srcp = pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32); | |||||
srcdata = (float *)srcp->pixels; | |||||
dst = pipi_new(w, h); | |||||
dstp = pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32); | |||||
dstdata = (float *)dstp->pixels; | |||||
sw = src->w; sh = src->h; | |||||
dw = dst->w; dh = dst->h; | |||||
scalex = dw > 1 ? (float)(sw - 1) / (dw - 1) : 1.0f; | |||||
scaley = dh > 1 ? (float)(sh - 1) / (dh - 1) : 1.0f; | |||||
for(y = 0; y < dh; y++) | |||||
{ | |||||
float yfloat = scaley * y; | |||||
int yint = (int)yfloat; | |||||
float y1 = yfloat - yint; | |||||
p0 = srcdata + 4 * sw * min_int(max_int(0, yint - 1), sh - 1); | |||||
p1 = srcdata + 4 * sw * min_int(max_int(0, yint ), sh - 1); | |||||
p2 = srcdata + 4 * sw * min_int(max_int(0, yint + 1), sh - 1); | |||||
p3 = srcdata + 4 * sw * min_int(max_int(0, yint + 2), sh - 1); | |||||
for (x = 0; x < dw; x++) | |||||
{ | |||||
float xfloat = scalex * x; | |||||
int xint = (int)xfloat; | |||||
float x1 = xfloat - xint; | |||||
i0 = 4 * min_int(max_int(0, xint - 1), sw - 1); | |||||
i1 = 4 * min_int(max_int(0, xint ), sw - 1); | |||||
i2 = 4 * min_int(max_int(0, xint + 1), sw - 1); | |||||
i3 = 4 * min_int(max_int(0, xint + 2), sw - 1); | |||||
for (i = 0; i < 4; i++, i0++, i1++, i2++, i3++) | |||||
{ | |||||
float a00 = p1[i1]; | |||||
float a01 = .5f * (p2[i1] - p0[i1]); | |||||
float a02 = p0[i1] - 2.5f * p1[i1] | |||||
+ 2.f * p2[i1] - .5f * p3[i1]; | |||||
float a03 = .5f * (p3[i1] - p0[i1]) + 1.5f * (p1[i1] - p2[i1]); | |||||
float a10 = .5f * (p1[i2] - p1[i0]); | |||||
float a11 = .25f * (p0[i0] - p2[i0] - p0[i2] + p2[i2]); | |||||
float a12 = .5f * (p0[i2] - p0[i0]) + 1.25f * (p1[i0] - p1[i2]) | |||||
+ .25f * (p3[i0] - p3[i2]) + p2[i2] - p2[i0]; | |||||
float a13 = .25f * (p0[i0] - p3[i0] - p0[i2] + p3[i2]) | |||||
+ .75f * (p2[i0] - p1[i0] + p1[i2] - p2[i2]); | |||||
float a20 = p1[i0] - 2.5f * p1[i1] | |||||
+ 2.f * p1[i2] - .5f * p1[i3]; | |||||
float a21 = .5f * (p2[i0] - p0[i0]) + 1.25f * (p0[i1] - p2[i1]) | |||||
+ .25f * (p0[i3] - p2[i3]) - p0[i2] + p2[i2]; | |||||
float a22 = p0[i0] - p3[i2] - 2.5f * (p1[i0] + p0[i1]) | |||||
+ 2.f * (p2[i0] + p0[i2]) - .5f * (p3[i0] + p0[i3]) | |||||
+ 6.25f * p1[i1] - 5.f * (p2[i1] + p1[i2]) | |||||
+ 1.25f * (p3[i1] + p1[i3]) | |||||
+ 4.f * p2[i2] - p2[i3] + .25f * p3[i3]; | |||||
float a23 = 1.5f * (p1[i0] - p2[i0]) + .5f * (p3[i0] - p0[i0]) | |||||
+ 1.25f * (p0[i1] - p3[i1]) | |||||
+ 3.75f * (p2[i1] - p1[i1]) + p3[i2] - p0[i2] | |||||
+ 3.f * (p1[i2] - p2[i2]) + .25f * (p0[i3] - p3[i3]) | |||||
+ .75f * (p2[i3] - p1[i3]); | |||||
float a30 = .5f * (p1[i3] - p1[i0]) + 1.5f * (p1[i1] - p1[i2]); | |||||
float a31 = .25f * (p0[i0] - p2[i0]) + .25f * (p2[i3] - p0[i3]) | |||||
+ .75f * (p2[i1] - p0[i1] + p0[i2] - p2[i2]); | |||||
float a32 = -.5f * p0[i0] + 1.25f * p1[i0] - p2[i0] | |||||
+ .25f * p3[i0] + 1.5f * p0[i1] - 3.75f * p1[i1] | |||||
+ 3.f * p2[i1] - .75f * p3[i1] - 1.5f * p0[i2] | |||||
+ 3.75f * p1[i2] - 3.f * p2[i2] + .75f * p3[i2] | |||||
+ .5f * p0[i3] - 1.25f * p1[i3] + p2[i3] | |||||
- .25f * p3[i3]; | |||||
float a33 = .25f * p0[i0] - .75f * p1[i0] + .75f * p2[i0] | |||||
- .25f * p3[i0] - .75f * p0[i1] + 2.25f * p1[i1] | |||||
- 2.25f * p2[i1] + .75f * p3[i1] + .75f * p0[i2] | |||||
- 2.25f * p1[i2] + 2.25f * p2[i2] - .75f * p3[i2] | |||||
- .25f * p0[i3] + .75f * p1[i3] - .75f * p2[i3] | |||||
+ .25f * p3[i3]; | |||||
float y2 = y1 * y1; float y3 = y2 * y1; | |||||
float x2 = x1 * x1; float x3 = x2 * x1; | |||||
float p = a00 + a01 * y1 + a02 * y2 + a03 * y3 + | |||||
+ a10 * x1 + a11 * x1 * y1 + a12 * x1 * y2 + a13 * x1 * y3 | |||||
+ a20 * x2 + a21 * x2 * y1 + a22 * x2 * y2 + a23 * x2 * y3 | |||||
+ a30 * x3 + a31 * x3 * y1 + a32 * x3 * y2 + a33 * x3 * y3; | |||||
if (p < 0.0f) p = 0.0f; | |||||
if (p > 1.0f) p = 1.0f; | |||||
dstdata[(y * dw + x) * 4 + i] = p; | |||||
} | |||||
} | |||||
} | |||||
return dst; | |||||
} | |||||
@@ -1,131 +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. | |||||
*/ | |||||
/* | |||||
* bresenham.c: Bresenham image resizing functions | |||||
*/ | |||||
#include "config.h" | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include "pipi.h" | |||||
#include "pipi-internals.h" | |||||
/* This is Bresenham resizing. I rediscovered it independently but it was | |||||
* actually first described in 1995 by Tim Kientzle in "Scaling Bitmaps | |||||
* with Bresenham". */ | |||||
/* FIXME: the algorithm does not handle alpha components properly. Resulting | |||||
* alpha should be the mean alpha value of the neightbouring pixels, but | |||||
* the colour components should be weighted with the alpha value. */ | |||||
pipi_image_t *pipi_resize_bresenham(pipi_image_t *src, int w, int h) | |||||
{ | |||||
float *srcdata, *dstdata, *aline, *line; | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
int x, y, x0, y0, sw, dw, sh, dh, remy; | |||||
float invswsh; | |||||
srcp = pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32); | |||||
srcdata = (float *)srcp->pixels; | |||||
dst = pipi_new(w, h); | |||||
dstp = pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32); | |||||
dstdata = (float *)dstp->pixels; | |||||
sw = src->w; sh = src->h; | |||||
dw = dst->w; dh = dst->h; | |||||
invswsh = 1.0f / (sw * sh); | |||||
aline = malloc(4 * dw * sizeof(float)); | |||||
line = malloc(4 * dw * sizeof(float)); | |||||
memset(line, 0, 4 * dw * sizeof(float)); | |||||
remy = 0; | |||||
for(y = 0, y0 = 0; y < dh; y++) | |||||
{ | |||||
int toty = 0, ny; | |||||
memset(aline, 0, 4 * dw * sizeof(float)); | |||||
while(toty < sh) | |||||
{ | |||||
if(remy == 0) | |||||
{ | |||||
float r = 0, g = 0, b = 0, a = 0; | |||||
int remx = 0; | |||||
for(x = 0, x0 = 0; x < dw; x++) | |||||
{ | |||||
float ar = 0, ag = 0, ab = 0, aa = 0; | |||||
int totx = 0, nx; | |||||
while(totx < sw) | |||||
{ | |||||
if(remx == 0) | |||||
{ | |||||
r = srcdata[(y0 * sw + x0) * 4]; | |||||
g = srcdata[(y0 * sw + x0) * 4 + 1]; | |||||
b = srcdata[(y0 * sw + x0) * 4 + 2]; | |||||
a = srcdata[(y0 * sw + x0) * 4 + 3]; | |||||
x0++; | |||||
remx = dw; | |||||
} | |||||
nx = (totx + remx <= sw) ? remx : sw - totx; | |||||
ar += nx * r; ag += nx * g; ab += nx * b; aa += nx * a; | |||||
totx += nx; | |||||
remx -= nx; | |||||
} | |||||
line[4 * x] = ar; | |||||
line[4 * x + 1] = ag; | |||||
line[4 * x + 2] = ab; | |||||
line[4 * x + 3] = aa; | |||||
} | |||||
y0++; | |||||
remy = dh; | |||||
} | |||||
ny = (toty + remy <= sh) ? remy : sh - toty; | |||||
for(x = 0; x < dw; x++) | |||||
{ | |||||
aline[4 * x] += ny * line[4 * x]; | |||||
aline[4 * x + 1] += ny * line[4 * x + 1]; | |||||
aline[4 * x + 2] += ny * line[4 * x + 2]; | |||||
aline[4 * x + 3] += ny * line[4 * x + 3]; | |||||
} | |||||
toty += ny; | |||||
remy -= ny; | |||||
} | |||||
for(x = 0; x < dw; x++) | |||||
{ | |||||
dstdata[(y * dw + x) * 4] = aline[4 * x] * invswsh; | |||||
dstdata[(y * dw + x) * 4 + 1] = aline[4 * x + 1] * invswsh; | |||||
dstdata[(y * dw + x) * 4 + 2] = aline[4 * x + 2] * invswsh; | |||||
dstdata[(y * dw + x) * 4 + 3] = aline[4 * x + 3] * invswsh; | |||||
} | |||||
} | |||||
free(aline); | |||||
free(line); | |||||
return dst; | |||||
} | |||||
@@ -41,6 +41,12 @@ enum class ScanMode : uint8_t | |||||
Serpentine, | Serpentine, | ||||
}; | }; | ||||
enum class ResampleAlgorithm : uint8_t | |||||
{ | |||||
Bicubic, | |||||
Bresenham, | |||||
}; | |||||
enum class EdiffAlgorithm : uint8_t | enum class EdiffAlgorithm : uint8_t | ||||
{ | { | ||||
FloydSteinberg, | FloydSteinberg, | ||||
@@ -102,12 +108,15 @@ public: | |||||
/* Rendering */ | /* Rendering */ | ||||
bool RenderRandom(ivec2 size); | bool RenderRandom(ivec2 size); | ||||
/* Resize and crop */ | |||||
Image Resize(ivec2 size, ResampleAlgorithm algorithm); | |||||
Image Crop(ibox2 box) const; | |||||
/* Image processing */ | /* Image processing */ | ||||
Image AutoContrast() const; | Image AutoContrast() const; | ||||
Image Brightness(float val) const; | Image Brightness(float val) const; | ||||
Image Contrast(float val) const; | Image Contrast(float val) const; | ||||
Image Convolution(Array2D<float> const &kernel); | Image Convolution(Array2D<float> const &kernel); | ||||
Image Crop(ibox2 box) const; | |||||
Image Dilate(); | Image Dilate(); | ||||
Image Erode(); | Image Erode(); | ||||
Image Invert() const; | Image Invert() const; | ||||
@@ -161,8 +161,9 @@ | |||||
<ClCompile Include="image\crop.cpp" /> | <ClCompile Include="image\crop.cpp" /> | ||||
<ClCompile Include="image\image.cpp" /> | <ClCompile Include="image\image.cpp" /> | ||||
<ClCompile Include="image\kernel.cpp" /> | <ClCompile Include="image\kernel.cpp" /> | ||||
<ClCompile Include="image\noise.cpp" /> | |||||
<ClCompile Include="image\pixels.cpp" /> | <ClCompile Include="image\pixels.cpp" /> | ||||
<ClCompile Include="image\render\noise.cpp" /> | |||||
<ClCompile Include="image\resample.cpp" /> | |||||
<ClCompile Include="input\controller.cpp" /> | <ClCompile Include="input\controller.cpp" /> | ||||
<ClCompile Include="input\input.cpp" /> | <ClCompile Include="input\input.cpp" /> | ||||
<ClCompile Include="light.cpp" /> | <ClCompile Include="light.cpp" /> | ||||
@@ -91,9 +91,6 @@ | |||||
<Filter Include="image\filter"> | <Filter Include="image\filter"> | ||||
<UniqueIdentifier>{3f420a7d-0538-463a-925b-3f8968bf628e}</UniqueIdentifier> | <UniqueIdentifier>{3f420a7d-0538-463a-925b-3f8968bf628e}</UniqueIdentifier> | ||||
</Filter> | </Filter> | ||||
<Filter Include="image\render"> | |||||
<UniqueIdentifier>{23655fca-56e5-48ec-8cf0-a71322f4cc89}</UniqueIdentifier> | |||||
</Filter> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ClCompile Include="image\crop.cpp"> | <ClCompile Include="image\crop.cpp"> | ||||
@@ -391,8 +388,11 @@ | |||||
<ClCompile Include="image\dither\random.cpp"> | <ClCompile Include="image\dither\random.cpp"> | ||||
<Filter>image\dither</Filter> | <Filter>image\dither</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="image\render\noise.cpp"> | |||||
<Filter>image\render</Filter> | |||||
<ClCompile Include="image\noise.cpp"> | |||||
<Filter>image</Filter> | |||||
</ClCompile> | |||||
<ClCompile Include="image\resample.cpp"> | |||||
<Filter>image</Filter> | |||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="image\pixels.cpp"> | <ClCompile Include="image\pixels.cpp"> | ||||
<Filter>image</Filter> | <Filter>image</Filter> | ||||