Fix T52920: Saving Tiff Files type Blender crashes
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 2 Oct 2017 08:44:13 +0000 (13:44 +0500)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 2 Oct 2017 08:44:13 +0000 (13:44 +0500)
Was only happening for 3 and 1 channel sources.

source/blender/imbuf/intern/tiff.c

index 8e5cf80e013635d8ec5c43613df8cb8506cc94c0..98aa7c5353b88ea0fcbec66bc3ad87fdd6b00af6 100644 (file)
@@ -813,26 +813,51 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
        }
 
        /* copy pixel data.  While copying, we flip the image vertically. */
+       const int channels_in_float = ibuf->channels ? ibuf->channels : 4;
        for (x = 0; x < ibuf->x; x++) {
                for (y = 0; y < ibuf->y; y++) {
-                       from_i = 4 * (y * ibuf->x + x);
+                       from_i = ((size_t)channels_in_float) * (y * ibuf->x + x);
                        to_i   = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x);
 
                        if (pixels16) {
                                /* convert from float source */
                                float rgb[4];
-                               
-                               if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
-                                       /* float buffer was managed already, no need in color space conversion */
-                                       copy_v3_v3(rgb, &fromf[from_i]);
+
+                               if (channels_in_float == 3 || channels_in_float == 4) {
+                                       if (ibuf->float_colorspace ||
+                                           (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
+                                       {
+                                               /* Float buffer was managed already, no need in color
+                                                * space conversion.
+                                                */
+                                               copy_v3_v3(rgb, &fromf[from_i]);
+                                       }
+                                       else {
+                                               /* Standard linear-to-srgb conversion if float buffer
+                                                * wasn't managed.
+                                                */
+                                               linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
+                                       }
+                                       if (channels_in_float == 4) {
+                                               rgb[3] = fromf[from_i + 3];
+                                       }
+                                       else {
+                                               rgb[3] = 1.0f;
+                                       }
                                }
                                else {
-                                       /* standard linear-to-srgb conversion if float buffer wasn't managed */
-                                       linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
+                                       if (ibuf->float_colorspace ||
+                                           (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
+                                       {
+                                               rgb[0] = fromf[from_i];
+                                       }
+                                       else {
+                                               rgb[0] = linearrgb_to_srgb(fromf[from_i]);
+                                       }
+                                       rgb[1] = rgb[2] = rgb[0];
+                                       rgb[3] = 1.0f;
                                }
 
-                               rgb[3] = fromf[from_i + 3];
-
                                for (i = 0; i < samplesperpixel; i++, to_i++)
                                        to16[to_i] = FTOUSHORT(rgb[i]);
                        }