solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 01ca48f4f6411ad2fd26916927707e46297c92cb
parent 1ef0c178832b421e0d0ee96841192a24a54e1c70
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon,  3 Apr 2017 15:11:20 +0200

Add the ssol_image_sample function

Diffstat:
Msrc/ssol.h | 19+++++++++++++++++++
Msrc/ssol_image.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -92,6 +92,16 @@ enum ssol_pixel_format { SSOL_PIXEL_FORMATS_COUNT__ }; +enum ssol_filter_mode { + SSOL_FILTER_LINEAR, + SSOL_FILTER_NEAREST +}; + +enum ssol_address_mode { + SSOL_ADDRESS_CLAMP, + SSOL_ADDRESS_REPEAT +}; + enum ssol_quadric_type { SSOL_QUADRIC_PLANE, SSOL_QUADRIC_PARABOL, @@ -517,6 +527,15 @@ SSOL_API res_T ssol_image_unmap (const struct ssol_image* image); +SSOL_API res_T +ssol_image_sample + (const struct ssol_image* image, + const enum ssol_filter_mode filter, + const enum ssol_address_mode address_u, + const enum ssol_address_mode address_v, + const double uv[2], + void* val); + /* Helper function that matches the `ssol_write_pixels_T' functor type */ SSOL_API res_T ssol_image_write diff --git a/src/ssol_image.c b/src/ssol_image.c @@ -26,6 +26,26 @@ /******************************************************************************* * Helper functions ******************************************************************************/ +static INLINE double +map_address(const double address, const enum ssol_address_mode mode) +{ + double dbl; + double i; + switch(mode) { + case SSOL_ADDRESS_CLAMP: dbl = CLAMP(address, 0, 1); break; + case SSOL_ADDRESS_REPEAT: dbl = modf(address, &i); break; + default: FATAL("Unreachable code.\n"); break; + } + return dbl; +} + +static INLINE const char* +get_pixel(const struct ssol_image* img, const size_t x, const size_t y) +{ + ASSERT(img && x < img->size[0] && y < img->size[1]); + return img->mem + y*img->pitch + x*ssol_sizeof_pixel_format(img->format); +} + static void image_release(ref_T* ref) { @@ -151,6 +171,57 @@ res_T ssol_image_unmap(const struct ssol_image* img) } res_T +ssol_image_sample + (const struct ssol_image* img, + const enum ssol_filter_mode filter, + const enum ssol_address_mode address_u, + const enum ssol_address_mode address_v, + const double uv[2], + void* val) +{ + double* z00, *z01, *z10, *z11; + double x0, y0, x1, y1; + double texsz[2]; + double s, t; + double* pix = val; + double integer; + + if(!img || !uv || !val) return RES_BAD_ARG; + + /* Only double3 pixel format is currently supported */ + if(img->format != SSOL_PIXEL_DOUBLE3) return RES_BAD_ARG; + + x0 = map_address(uv[0], address_u) * (double)img->size[0]; + y0 = map_address(uv[1], address_v) * (double)img->size[1]; + + switch(filter) { + case SSOL_FILTER_NEAREST: + z00 = (double*)get_pixel(img, (size_t)x0, (size_t)y0); + pix[0] = z00[0]; + pix[1] = z00[1]; + pix[2] = z00[2]; + break; + case SSOL_FILTER_LINEAR: + texsz[0] = 1.0/(double)img->size[0]; + texsz[1] = 1.0/(double)img->size[1]; + x1 = map_address(uv[0] + texsz[0], address_u) * (double)img->size[0]; + y1 = map_address(uv[1] + texsz[1], address_v) * (double)img->size[1]; + z00 = (double*)get_pixel(img, (size_t)x0, (size_t)y0); + z01 = (double*)get_pixel(img, (size_t)x0, (size_t)y1); + z10 = (double*)get_pixel(img, (size_t)x1, (size_t)y0); + z11 = (double*)get_pixel(img, (size_t)x1, (size_t)y1); + s = modf(x0, &integer); + t = modf(y0, &integer); + pix[0] = (1-s)*((1-t)*z00[0] + t*z01[0]) + s*((1-t)*z10[0] + t*z11[0]); + pix[1] = (1-s)*((1-t)*z00[1] + t*z01[1]) + s*((1-t)*z10[1] + t*z11[1]); + pix[2] = (1-s)*((1-t)*z00[2] + t*z01[2]) + s*((1-t)*z10[2] + t*z11[2]); + break; + default: FATAL("Unreachable code.\n"); break; + } + return RES_OK; +} + +res_T ssol_image_write (void* image, const size_t origin[2],