Fix for double-freeing image buffers when rendering opengl animation into movie file.
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Dec 2012 09:07:44 +0000 (09:07 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Dec 2012 09:07:44 +0000 (09:07 +0000)
source/blender/editors/render/render_opengl.c

index effb984c0839e3d3164338da874d348fd22aee91..73f8abdf15f27029ede703bfdbb3a4df2786dd1c 100644 (file)
@@ -481,7 +481,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
        Main *bmain = CTX_data_main(C);
        OGLRender *oglrender = op->customdata;
        Scene *scene = oglrender->scene;
-       ImBuf *ibuf;
+       ImBuf *ibuf, *ibuf_save = NULL;
        void *lock;
        char name[FILE_MAX];
        int ok = 0;
@@ -549,47 +549,46 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
        if (ibuf) {
                int needs_free = FALSE;
 
-               if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
-                       ImBuf *colormanage_ibuf;
+               ibuf_save = ibuf;
 
-                       colormanage_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings,
-                                                                              &scene->display_settings, &scene->r.im_format);
+               if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
+                       ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings,
+                                                                       &scene->display_settings, &scene->r.im_format);
 
-                       // IMB_freeImBuf(ibuf); /* owned by the image */
-                       ibuf = colormanage_ibuf;
                        needs_free = TRUE;
                }
 
                /* color -> grayscale */
                /* editing directly would alter the render view */
                if (scene->r.im_format.planes == R_IMF_PLANES_BW) {
-                        ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
+                       ImBuf *ibuf_bw = IMB_dupImBuf(ibuf_save);
                        IMB_color_to_bw(ibuf_bw);
 
                        if (needs_free)
-                               IMB_freeImBuf(ibuf);
+                               IMB_freeImBuf(ibuf_save);
 
-                       ibuf = ibuf_bw;
+                       ibuf_save = ibuf_bw;
                }
                else {
                        /* this is lightweight & doesnt re-alloc the buffers, only do this
                         * to save the correct bit depth since the image is always RGBA */
-                       ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf->x, ibuf->y, scene->r.im_format.planes, 0);
-                       ibuf_cpy->rect = ibuf->rect;
-                       ibuf_cpy->rect_float = ibuf->rect_float;
-                       ibuf_cpy->zbuf_float = ibuf->zbuf_float;
+                       ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf_save->x, ibuf_save->y, scene->r.im_format.planes, 0);
+
+                       ibuf_cpy->rect = ibuf_save->rect;
+                       ibuf_cpy->rect_float = ibuf_save->rect_float;
+                       ibuf_cpy->zbuf_float = ibuf_save->zbuf_float;
 
                        if (needs_free) {
-                               ibuf_cpy->mall = ibuf->mall;
-                               ibuf->mall = 0;
-                               IMB_freeImBuf(ibuf);
+                               ibuf_cpy->mall = ibuf_save->mall;
+                               ibuf_save->mall = 0;
+                               IMB_freeImBuf(ibuf_save);
                        }
 
-                       ibuf = ibuf_cpy;
+                       ibuf_save = ibuf_cpy;
                }
 
                if (is_movie) {
-                       ok = oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int *)ibuf->rect,
+                       ok = oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int *)ibuf_save->rect,
                                                         oglrender->sizex, oglrender->sizey, oglrender->reports);
                        if (ok) {
                                printf("Append frame %d", scene->r.cfra);
@@ -597,7 +596,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
                        }
                }
                else {
-                       ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format);
+                       ok = BKE_imbuf_write_stamp(scene, camera, ibuf_save, name, &scene->r.im_format);
 
                        if (ok == 0) {
                                printf("Write error: cannot save %s\n", name);
@@ -609,8 +608,8 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
                        }
                }
 
-               /* imbuf knows which rects are not part of ibuf */
-               IMB_freeImBuf(ibuf);
+               if (needs_free)
+                       IMB_freeImBuf(ibuf_save);
        }
 
        BKE_image_release_ibuf(oglrender->ima, ibuf, lock);