diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-01-05 00:34:06 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-01-05 00:34:06 +0400 |
commit | 52a81c8364c1da5d7607b6964d5e64d1cd00703a (patch) | |
tree | 4456291c2cf4d6766fd898a67d527ce2dda03e82 /source/blender/imbuf | |
parent | 0e676bf50bd961c86b48af2c0baf10136cdb60a9 (diff) |
There was a typo in previous commit
Additional changes:
- Made mipmapping operate with unsigned short instead of char
which allowed to eliminate extra division by 255, so prevision
should be a bit better now.
- Actually, this is not real unsigned short range, but it's a
range of 255*255 which is more convenient for mipmapping, so
made conversion functions private for scaling.c
Not sure it worth making this functions operate in 65535
range, for now current behavior seems to be just fine.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r-- | source/blender/imbuf/intern/scaling.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 8d3cd648fc1..1050d3f8715 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -292,6 +292,37 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) return (ibuf2); } +/* pretty much specific functions which converts uchar <-> ushort but assumes + * ushort range of 255*255 which is more convenient here + */ +MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4], const unsigned char color[4]) +{ + unsigned short alpha = color[3]; + + result[0] = color[0] * alpha; + result[1] = color[1] * alpha; + result[2] = color[2] * alpha; + result[3] = alpha * 255; +} + +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; + } + else { + unsigned short alpha = color[3] / 255; + + result[0] = color[0] / alpha; + result[1] = color[1] / alpha; + result[2] = color[2] / alpha; + result[3] = alpha; + } +} + /* result in ibuf2, scaling should be done correctly */ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) { @@ -311,19 +342,19 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) for (y = ibuf2->y; y > 0; y--) { cp2 = cp1 + (ibuf1->x << 2); for (x = ibuf2->x; x > 0; x--) { - int p1i[8], p2i[8], desti[4]; + unsigned short p1i[8], p2i[8], desti[4]; - straight_uchar_to_premul_int(p1i, cp1); - straight_uchar_to_premul_int(p2i, cp2); - straight_uchar_to_premul_int(p1i + 4, cp1 + 4); - straight_uchar_to_premul_int(p2i + 4, cp2 + 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] = (p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2; - desti[1] = (p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2; - desti[2] = (p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2; - desti[3] = (p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2; + 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_int_to_straight_uchar(dest, desti); + premul_ushort_to_straight_uchar(dest, desti); cp1 += 8; cp2 += 8; |