| @@ -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> | ||||