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:
Diffstat (limited to 'source/blender/imbuf/intern/scaling.c')
-rw-r--r--source/blender/imbuf/intern/scaling.c99
1 files changed, 63 insertions, 36 deletions
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index c98b39c826b..e480f06da2b 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
+#include "BLI_math_base.h"
#include "BLI_math_color.h"
#include "BLI_math_interp.h"
#include "MEM_guardedalloc.h"
@@ -51,26 +52,17 @@
/************************************************************************/
-struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
+static void imb_half_x_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
uchar *p1, *_p1, *dest;
short a, r, g, b;
int x, y;
float af, rf, gf, bf, *p1f, *_p1f, *destf;
bool do_rect, do_float;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
-
do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL);
-
- if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1));
+ do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
- ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
-
_p1 = (uchar *) ibuf1->rect;
dest = (uchar *) ibuf2->rect;
@@ -113,9 +105,24 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
if (do_rect) _p1 += (ibuf1->x << 2);
if (do_float) _p1f += (ibuf1->x << 2);
}
- return (ibuf2);
}
+struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
+{
+ struct ImBuf *ibuf2;
+
+ if (ibuf1 == NULL) return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+
+ if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1));
+
+ ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL) return (NULL);
+
+ imb_half_x_no_alloc(ibuf2, ibuf1);
+
+ return (ibuf2);
+}
struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1)
{
@@ -170,9 +177,8 @@ struct ImBuf *IMB_double_x(struct ImBuf *ibuf1)
}
-struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
+static void imb_half_y_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
uchar *p1, *p2, *_p1, *dest;
short a, r, g, b;
int x, y;
@@ -181,15 +187,9 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
p1 = p2 = NULL;
p1f = p2f = NULL;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
- if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1));
do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL);
-
- ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
+ do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
_p1 = (uchar *) ibuf1->rect;
dest = (uchar *) ibuf2->rect;
@@ -238,6 +238,23 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
if (do_rect) _p1 += (ibuf1->x << 3);
if (do_float) _p1f += (ibuf1->x << 3);
}
+}
+
+
+struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
+{
+ struct ImBuf *ibuf2;
+
+ if (ibuf1 == NULL) return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+
+ if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1));
+
+ ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL) return (NULL);
+
+ imb_half_y_no_alloc(ibuf2, ibuf1);
+
return (ibuf2);
}
@@ -303,24 +320,24 @@ MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4], const uns
result[0] = color[0] * alpha;
result[1] = color[1] * alpha;
result[2] = color[2] * alpha;
- result[3] = alpha * 255;
+ result[3] = alpha * 256;
}
MINLINE void premul_ushort_to_straight_uchar(unsigned char *result, const unsigned short color[4])
{
if (color[3] <= 255) {
- result[0] = color[0] / 255;
- result[1] = color[1] / 255;
- result[2] = color[2] / 255;
- result[3] = color[3] / 255;
+ result[0] = USHORTTOUCHAR(color[0]);
+ result[1] = USHORTTOUCHAR(color[1]);
+ result[2] = USHORTTOUCHAR(color[2]);
+ result[3] = USHORTTOUCHAR(color[3]);
}
else {
- unsigned short alpha = color[3] / 255;
+ unsigned short alpha = color[3] / 256;
- result[0] = color[0] / alpha;
- result[1] = color[1] / alpha;
- result[2] = color[2] / alpha;
- result[3] = alpha;
+ result[0] = USHORTTOUCHAR(color[0] / alpha * 256);
+ result[1] = USHORTTOUCHAR(color[1] / alpha * 256);
+ result[2] = USHORTTOUCHAR(color[2] / alpha * 256);
+ result[3] = USHORTTOUCHAR(color[3]);
}
}
@@ -335,28 +352,38 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
imb_addrectImBuf(ibuf2);
}
+ if (ibuf1->x <= 1) {
+ imb_half_y_no_alloc(ibuf2, ibuf1);
+ return;
+ }
+ if (ibuf1->y <= 1) {
+ imb_half_x_no_alloc(ibuf2, ibuf1);
+ return;
+ }
+
if (do_rect) {
unsigned char *cp1, *cp2, *dest;
cp1 = (unsigned char *) ibuf1->rect;
dest = (unsigned char *) ibuf2->rect;
+
for (y = ibuf2->y; y > 0; y--) {
cp2 = cp1 + (ibuf1->x << 2);
for (x = ibuf2->x; x > 0; x--) {
unsigned short p1i[8], p2i[8], desti[4];
-
+
straight_uchar_to_premul_ushort(p1i, cp1);
straight_uchar_to_premul_ushort(p2i, cp2);
straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
-
+
desti[0] = ((unsigned int) p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
desti[1] = ((unsigned int) p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
desti[2] = ((unsigned int) p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
desti[3] = ((unsigned int) p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
-
+
premul_ushort_to_straight_uchar(dest, desti);
-
+
cp1 += 8;
cp2 += 8;
dest += 4;
@@ -1353,7 +1380,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
val_g += 0.5f;
val_r = rect[3];
- nval_r = rect[skipx + 4];
+ nval_r = rect[skipx + 3];
diff_r = nval_r - val_r;
val_r += 0.5f;