Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/imbuf/intern/imageprocess.c120
1 files changed, 74 insertions, 46 deletions
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index c88a9b81ff2..4320f30884b 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -127,6 +127,22 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in
/** \name Bi-Linear Interpolation
* \{ */
+BLI_INLINE void bilinear_interpolation_color_fl(
+ struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v)
+{
+ BLI_assert(outF);
+ BLI_assert(in->rect_float);
+ BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
+}
+
+BLI_INLINE void bilinear_interpolation_color_char(
+ struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v)
+{
+ BLI_assert(outI);
+ BLI_assert(in->rect);
+ BLI_bilinear_interpolation_char((unsigned char *)in->rect, outI, in->x, in->y, 4, u, v);
+}
+
void bilinear_interpolation_color(
struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
@@ -238,60 +254,58 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
/** \name Nearest Interpolation
* \{ */
-/* function assumes out to be zero'ed, only does RGBA */
-void nearest_interpolation_color(
- struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+/* functions assumes out to be zero'ed, only does RGBA */
+BLI_INLINE void nearest_interpolation_color_char(
+ struct ImBuf *in, unsigned char outI[4], float UNUSED(outF[4]), float u, float v)
{
- const float *dataF;
- unsigned char *dataI;
- int y1, x1;
-
+ BLI_assert(outI);
+ BLI_assert(in->rect);
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+ int x1 = (int)(u);
+ int y1 = (int)(v);
- x1 = (int)(u);
- y1 = (int)(v);
+ /* sample area entirely outside image? */
+ if (x1 < 0 || x1 >= in->x || y1 < 0 || y1 >= in->y) {
+ outI[0] = outI[1] = outI[2] = outI[3] = 0;
+ return;
+ }
+
+ const size_t offset = (in->x * y1 + x1) * 4;
+ const unsigned char *dataI = (unsigned char *)in->rect + offset;
+ outI[0] = dataI[0];
+ outI[1] = dataI[1];
+ outI[2] = dataI[2];
+ outI[3] = dataI[3];
+}
+
+BLI_INLINE void nearest_interpolation_color_fl(
+ struct ImBuf *in, unsigned char UNUSED(outI[4]), float outF[4], float u, float v)
+{
+ BLI_assert(outF);
+ BLI_assert(in->rect_float);
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+ int x1 = (int)(u);
+ int y1 = (int)(v);
/* sample area entirely outside image? */
- if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) {
- if (outI) {
- outI[0] = outI[1] = outI[2] = outI[3] = 0;
- }
- if (outF) {
- outF[0] = outF[1] = outF[2] = outF[3] = 0.0f;
- }
+ if (x1 < 0 || x1 >= in->x || y1 < 0 || y1 >= in->y) {
+ zero_v4(outF);
return;
}
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) {
- if (outI) {
- outI[0] = 0;
- outI[1] = 0;
- outI[2] = 0;
- outI[3] = 0;
- }
- if (outF) {
- outF[0] = 0.0f;
- outF[1] = 0.0f;
- outF[2] = 0.0f;
- outF[3] = 0.0f;
- }
+ const size_t offset = (in->x * y1 + x1) * 4;
+ const float *dataF = in->rect_float + offset;
+ copy_v4_v4(outF, dataF);
+}
+
+void nearest_interpolation_color(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+{
+ if (outF) {
+ nearest_interpolation_color_fl(in, outI, outF, u, v);
}
else {
- dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
- if (outI) {
- outI[0] = dataI[0];
- outI[1] = dataI[1];
- outI[2] = dataI[2];
- outI[3] = dataI[3];
- }
- dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
- if (outF) {
- outF[0] = dataF[0];
- outF[1] = dataF[1];
- outF[2] = dataF[2];
- outF[3] = dataF[3];
- }
+ nearest_interpolation_color_char(in, outI, outF, u, v);
}
}
@@ -436,7 +450,14 @@ static void imb_transform_nearest_scanlines(void *custom_data,
int num_scanlines)
{
const TransformUserData *user_data = custom_data;
- imb_transform_scanlines(user_data, start_scanline, num_scanlines, nearest_interpolation_color);
+ InterpolationColorFunction interpolation = NULL;
+ if (user_data->dst->rect_float) {
+ interpolation = nearest_interpolation_color_fl;
+ }
+ else {
+ interpolation = nearest_interpolation_color_char;
+ }
+ imb_transform_scanlines(user_data, start_scanline, num_scanlines, interpolation);
}
static void imb_transform_bilinear_scanlines(void *custom_data,
@@ -444,7 +465,14 @@ static void imb_transform_bilinear_scanlines(void *custom_data,
int num_scanlines)
{
const TransformUserData *user_data = custom_data;
- imb_transform_scanlines(user_data, start_scanline, num_scanlines, bilinear_interpolation_color);
+ InterpolationColorFunction interpolation = NULL;
+ if (user_data->dst->rect_float) {
+ interpolation = bilinear_interpolation_color_fl;
+ }
+ else if (user_data->dst->rect) {
+ interpolation = bilinear_interpolation_color_char;
+ }
+ imb_transform_scanlines(user_data, start_scanline, num_scanlines, interpolation);
}
static ScanlineThreadFunc imb_transform_scanline_func(const eIMBInterpolationFilterMode filter)