diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-15 12:10:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-15 12:10:02 +0400 |
commit | 9263fdb30e1dc2e6fdca95a553f116d350622910 (patch) | |
tree | 6353c461b2e204b88611bc637b8a616a4dc8f071 /source/blender/imbuf/intern/png.c | |
parent | baad27ec80c8c77f4fb139189339c454caa93763 (diff) |
fix [#33781] Confusing units in displacement modifier parameters
16bit PNG images were not doing any conversions when saving linear float buffers, but would always load them as SRGB.
apply the same method used for 16bit images from floats as used in jpeg2000.
Diffstat (limited to 'source/blender/imbuf/intern/png.c')
-rw-r--r-- | source/blender/imbuf/intern/png.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index ce5f797b2d8..02aea4b9965 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -107,6 +107,17 @@ static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length) longjmp(png_jmpbuf(png_ptr), 1); } +static float channel_colormanage_noop(float value) +{ + return value; +} + +/* wrap to avoid macro calling functions multiple times */ +BLI_INLINE unsigned short ftoshort(float val) +{ + return FTOUSHORT(val); +} + int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) { png_structp png_ptr; @@ -123,11 +134,22 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) bool is_16bit = (ibuf->ftype & PNG_16BIT); bool has_float = (ibuf->rect_float != NULL); + float (*chanel_colormanage_cb)(float); + /* use the jpeg quality setting for compression */ int compression; compression = (int)(((float)(ibuf->ftype & 0xff) / 11.1111f)); compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression); + if (ibuf->float_colorspace) { + /* float buffer was managed already, no need in color space conversion */ + chanel_colormanage_cb = channel_colormanage_noop; + } + else { + /* standard linear-to-srgb conversion if float buffer wasn't managed */ + chanel_colormanage_cb = linearrgb_to_srgb; + } + /* for prints */ if (flags & IB_mem) name = "<memory>"; @@ -183,10 +205,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) if (has_float) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); - to16[0] = FTOUSHORT(from_straight[0]); - to16[1] = FTOUSHORT(from_straight[1]); - to16[2] = FTOUSHORT(from_straight[2]); - to16[3] = FTOUSHORT(from_straight[3]); + to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); + to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); + to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); + to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3])); to16 += 4; from_float += 4; } } @@ -216,9 +238,9 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) if (has_float) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); - to16[0] = FTOUSHORT(from_straight[0]); - to16[1] = FTOUSHORT(from_straight[1]); - to16[2] = FTOUSHORT(from_straight[2]); + to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); + to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); + to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); to16 += 3; from_float += 4; } } @@ -246,7 +268,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) if (has_float) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); - to16[0] = FTOUSHORT(from_straight[0]); + to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); to16++; from_float += 4; } } |