Code cleanup: use r_ prefix for return args
[blender.git] / source / blender / blenkernel / intern / image.c
index 1e55b5ee962fa6ee315c96c6cdbcd0583c56f730..aaeead431b947560bb6b8f80a7c0a23f666bd579 100644 (file)
@@ -68,6 +68,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
+#include "BLI_timecode.h"  /* for stamp timecode format */
 #include "BLI_utildefines.h"
 
 #include "BKE_bmfont.h"
@@ -108,7 +109,9 @@ static SpinLock image_spin;
 /* quick lookup: supports 1 million frames, thousand passes */
 #define IMA_MAKE_INDEX(frame, index)    ((frame) << 10) + index
 #define IMA_INDEX_FRAME(index)          (index >> 10)
+/*
 #define IMA_INDEX_PASS(index)           (index & ~1023)
+*/
 
 /* ******** IMAGE CACHE ************* */
 
@@ -135,6 +138,9 @@ static void imagecache_put(Image *image, int index, ImBuf *ibuf)
        ImageCacheKey key;
 
        if (image->cache == NULL) {
+               // char cache_name[64];
+               // BLI_snprintf(cache_name, sizeof(cache_name), "Image Datablock %s", image->id.name);
+
                image->cache = IMB_moviecache_create("Image Datablock Cache", sizeof(ImageCacheKey),
                                                     imagecache_hashhash, imagecache_hashcmp);
        }
@@ -144,7 +150,7 @@ static void imagecache_put(Image *image, int index, ImBuf *ibuf)
        IMB_moviecache_put(image->cache, &key, ibuf);
 }
 
-static struct ImBufimagecache_get(Image *image, int index)
+static struct ImBuf *imagecache_get(Image *image, int index)
 {
        if (image->cache) {
                ImageCacheKey key;
@@ -290,7 +296,7 @@ static Image *image_alloc(Main *bmain, const char *name, short source, short typ
 {
        Image *ima;
 
-       ima = BKE_libblock_alloc(&bmain->image, ID_IM, name);
+       ima = BKE_libblock_alloc(bmain, ID_IM, name);
        if (ima) {
                ima->ok = IMA_OK;
 
@@ -550,12 +556,12 @@ void BKE_image_merge(Image *dest, Image *source)
                }
                BLI_spin_unlock(&image_spin);
 
-               BKE_libblock_free(&G.main->image, source);
+               BKE_libblock_free(G.main, source);
        }
 }
 
 /* note, we could be clever and scale all imbuf's but since some are mipmaps its not so simple */
-int BKE_image_scale(Image *image, int width, int height)
+bool BKE_image_scale(Image *image, int width, int height)
 {
        ImBuf *ibuf;
        void *lock;
@@ -592,20 +598,21 @@ static void image_init_color_management(Image *ima)
        }
 }
 
-void BKE_image_alpha_mode_from_extension(Image *image)
+char BKE_image_alpha_mode_from_extension_ex(const char *filepath)
 {
-       if (BLI_testextensie(image->name, ".exr") ||
-           BLI_testextensie(image->name, ".cin") ||
-           BLI_testextensie(image->name, ".dpx") ||
-           BLI_testextensie(image->name, ".hdr"))
-       {
-               image->alpha_mode = IMA_ALPHA_PREMUL;
+       if (BLI_testextensie_n(filepath, ".exr", ".cin", ".dpx", ".hdr", NULL)) {
+               return IMA_ALPHA_PREMUL;
        }
        else {
-               image->alpha_mode = IMA_ALPHA_STRAIGHT;
+               return IMA_ALPHA_STRAIGHT;
        }
 }
 
+void BKE_image_alpha_mode_from_extension(Image *image)
+{
+       image->alpha_mode = BKE_image_alpha_mode_from_extension_ex(image->name);
+}
+
 Image *BKE_image_load(Main *bmain, const char *filepath)
 {
        Image *ima;
@@ -682,7 +689,6 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
 
        if (floatbuf) {
                ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat);
-               rect_float = ibuf->rect_float;
 
                if (colorspace_settings->name[0] == '\0') {
                        const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT);
@@ -690,11 +696,13 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
                        BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name));
                }
 
-               IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name);
+               if (ibuf != NULL) {
+                       rect_float = ibuf->rect_float;
+                       IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name);
+               }
        }
        else {
                ibuf = IMB_allocImBuf(width, height, depth, IB_rect);
-               rect = (unsigned char *)ibuf->rect;
 
                if (colorspace_settings->name[0] == '\0') {
                        const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
@@ -702,7 +710,14 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
                        BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name));
                }
 
-               IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name);
+               if (ibuf != NULL) {
+                       rect = (unsigned char *)ibuf->rect;
+                       IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name);
+               }
+       }
+
+       if (!ibuf) {
+               return NULL;
        }
 
        BLI_strncpy(ibuf->name, name, sizeof(ibuf->name));
@@ -985,7 +1000,11 @@ static bool imagecache_check_free_anim(ImBuf *ibuf, void *UNUSED(userkey), void
 /* except_frame is weak, only works for seqs without offset... */
 void BKE_image_free_anim_ibufs(Image *ima, int except_frame)
 {
-       IMB_moviecache_cleanup(ima->cache, imagecache_check_free_anim, &except_frame);
+       BLI_spin_lock(&image_spin);
+       if (ima->cache != NULL) {
+               IMB_moviecache_cleanup(ima->cache, imagecache_check_free_anim, &except_frame);
+       }
+       BLI_spin_unlock(&image_spin);
 }
 
 void BKE_image_all_free_anim_ibufs(int cfra)
@@ -993,7 +1012,7 @@ void BKE_image_all_free_anim_ibufs(int cfra)
        Image *ima;
 
        for (ima = G.main->image.first; ima; ima = ima->id.next)
-               if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE))
+               if (BKE_image_is_animated(ima))
                        BKE_image_free_anim_ibufs(ima, cfra);
 }
 
@@ -1245,101 +1264,96 @@ char BKE_imtype_from_arg(const char *imtype_arg)
        else return R_IMF_IMTYPE_INVALID;
 }
 
-static int do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
+static bool do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
 {
        const char *extension = NULL;
+       const char *extension_test;
        (void)im_format;  /* may be unused, depends on build options */
 
        if (imtype == R_IMF_IMTYPE_IRIS) {
-               if (!BLI_testextensie(string, ".rgb"))
-                       extension = ".rgb";
+               if (!BLI_testextensie(string, extension_test = ".rgb"))
+                       extension = extension_test;
        }
        else if (imtype == R_IMF_IMTYPE_IRIZ) {
-               if (!BLI_testextensie(string, ".rgb"))
-                       extension = ".rgb";
+               if (!BLI_testextensie(string, extension_test = ".rgb"))
+                       extension = extension_test;
        }
 #ifdef WITH_HDR
        else if (imtype == R_IMF_IMTYPE_RADHDR) {
-               if (!BLI_testextensie(string, ".hdr"))
-                       extension = ".hdr";
+               if (!BLI_testextensie(string, extension_test = ".hdr"))
+                       extension = extension_test;
        }
 #endif
        else if (ELEM5(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, R_IMF_IMTYPE_H264, R_IMF_IMTYPE_THEORA, R_IMF_IMTYPE_XVID)) {
-               if (!BLI_testextensie(string, ".png"))
-                       extension = ".png";
+               if (!BLI_testextensie(string, extension_test = ".png"))
+                       extension = extension_test;
        }
 #ifdef WITH_DDS
        else if (imtype == R_IMF_IMTYPE_DDS) {
-               if (!BLI_testextensie(string, ".dds"))
-                       extension = ".dds";
+               if (!BLI_testextensie(string, extension_test = ".dds"))
+                       extension = extension_test;
        }
 #endif
-       else if (imtype == R_IMF_IMTYPE_RAWTGA) {
-               if (!BLI_testextensie(string, ".tga"))
-                       extension = ".tga";
+       else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
+               if (!BLI_testextensie(string, extension_test = ".tga"))
+                       extension = extension_test;
        }
        else if (imtype == R_IMF_IMTYPE_BMP) {
-               if (!BLI_testextensie(string, ".bmp"))
-                       extension = ".bmp";
+               if (!BLI_testextensie(string, extension_test = ".bmp"))
+                       extension = extension_test;
        }
 #ifdef WITH_TIFF
        else if (imtype == R_IMF_IMTYPE_TIFF) {
-               if (!BLI_testextensie(string, ".tif") &&
-                   !BLI_testextensie(string, ".tiff"))
-               {
-                       extension = ".tif";
+               if (!BLI_testextensie_n(string, extension_test = ".tif", ".tiff", NULL)) {
+                       extension = extension_test;
                }
        }
 #endif
 #ifdef WITH_OPENIMAGEIO
        else if (imtype == R_IMF_IMTYPE_PSD) {
-               if (!BLI_testextensie(string, ".psd"))
-                       extension = ".psd";
+               if (!BLI_testextensie(string, extension_test = ".psd"))
+                       extension = extension_test;
        }
 #endif
 #ifdef WITH_OPENEXR
        else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
-               if (!BLI_testextensie(string, ".exr"))
-                       extension = ".exr";
+               if (!BLI_testextensie(string, extension_test = ".exr"))
+                       extension = extension_test;
        }
 #endif
 #ifdef WITH_CINEON
        else if (imtype == R_IMF_IMTYPE_CINEON) {
-               if (!BLI_testextensie(string, ".cin"))
-                       extension = ".cin";
+               if (!BLI_testextensie(string, extension_test = ".cin"))
+                       extension = extension_test;
        }
        else if (imtype == R_IMF_IMTYPE_DPX) {
-               if (!BLI_testextensie(string, ".dpx"))
-                       extension = ".dpx";
+               if (!BLI_testextensie(string, extension_test = ".dpx"))
+                       extension = extension_test;
        }
 #endif
-       else if (imtype == R_IMF_IMTYPE_TARGA) {
-               if (!BLI_testextensie(string, ".tga"))
-                       extension = ".tga";
-       }
 #ifdef WITH_OPENJPEG
        else if (imtype == R_IMF_IMTYPE_JP2) {
                if (im_format) {
                        if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
-                               if (!BLI_testextensie(string, ".jp2"))
-                                       extension = ".jp2";
+                               if (!BLI_testextensie(string, extension_test = ".jp2"))
+                                       extension = extension_test;
                        }
                        else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
-                               if (!BLI_testextensie(string, ".j2c"))
-                                       extension = ".j2c";
+                               if (!BLI_testextensie(string, extension_test = ".j2c"))
+                                       extension = extension_test;
                        }
                        else
                                BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
                }
                else {
-                       if (!BLI_testextensie(string, ".jp2"))
-                               extension = ".jp2";
+                       if (!BLI_testextensie(string, extension_test = ".jp2"))
+                               extension = extension_test;
                }
        }
 #endif
        else { //   R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc
-               if (!(BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
-                       extension = ".jpg";
+               if (!(BLI_testextensie_n(string, extension_test = ".jpg", ".jpeg", NULL)))
+                       extension = extension_test;
        }
 
        if (extension) {
@@ -1483,6 +1497,12 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
        }
 
        /* planes */
+       /* TODO(sergey): Channels doesn't correspond actual planes used for image buffer
+        *               For example byte buffer will have 4 channels but it might easily
+        *               be BW or RGB image.
+        *
+        *               Need to use im_format->planes = imbuf->planes instead?
+        */
        switch (imbuf->channels) {
                case 0:
                case 4: im_format->planes = R_IMF_PLANES_RGBA;
@@ -1497,30 +1517,6 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
 
 }
 
-static void timecode_simple_string(char *text, size_t text_size, const int cfra, int const frs_sec)
-{
-       int f = (int)(cfra % frs_sec);
-       int s = (int)(cfra / frs_sec);
-       int h = 0;
-       int m = 0;
-
-       if (s) {
-               m = (int)(s / 60);
-               s %= 60;
-
-               if (m) {
-                       h = (int)(m / 60);
-                       m %= 60;
-               }
-       }
-
-       if (frs_sec < 100) {
-               BLI_snprintf(text, text_size, "%02d:%02d:%02d.%02d", h, m, s, f);
-       }
-       else {
-               BLI_snprintf(text, text_size, "%02d:%02d:%02d.%03d", h, m, s, f);
-       }
-}
 
 #define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16)
 /* could allow access externally - 512 is for long names,
@@ -1584,8 +1580,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
        }
 
        if (scene->r.stamp & R_STAMP_TIME) {
-               timecode_simple_string(text, sizeof(text), scene->r.cfra, scene->r.frs_sec);
-               BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Time %s" : "%s", text);
+               const short timecode_style = USER_TIMECODE_SMPTE_FULL;
+               BLI_timecode_string_from_time(text, sizeof(text), 0, FRA2TIME(scene->r.cfra), FPS, timecode_style);
+               BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Timecode %s" : "%s", text);
        }
        else {
                stamp_data->time[0] = '\0';
@@ -1889,7 +1886,7 @@ void BKE_imbuf_stamp_info(Scene *scene, Object *camera, struct ImBuf *ibuf)
        if (stamp_data.rendertime[0]) IMB_metadata_change_field(ibuf, "RenderTime", stamp_data.rendertime);
 }
 
-int BKE_imbuf_alpha_test(ImBuf *ibuf)
+bool BKE_imbuf_alpha_test(ImBuf *ibuf)
 {
        int tot;
        if (ibuf->rect_float) {
@@ -2231,7 +2228,7 @@ static void image_tag_frame_recalc(Image *ima, ImageUser *iuser, void *customdat
 {
        Image *changed_image = customdata;
 
-       if (ima == changed_image && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+       if (ima == changed_image && BKE_image_is_animated(ima)) {
                iuser->flag |= IMA_NEED_FRAME_RECALC;
        }
 }
@@ -2263,6 +2260,15 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
                                                IMB_freeImBuf(ibuf);
                                        }
                                }
+
+                               /* Changing source type to generated will likely change file format
+                                * used by generated image buffer. Saving different file format to
+                                * the old name might confuse other applications.
+                                *
+                                * Here we ensure original image path wouldn't be used when saving
+                                * generated image.
+                                */
+                               ima->name[0] = '\0';
                        }
 
 #if 0
@@ -2744,6 +2750,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        int channels, layer, pass;
        ImBuf *ibuf;
        int from_render = (ima->render_slot == ima->last_render_slot);
+       bool byte_buffer_in_display_space = false;
 
        if (!(iuser && iuser->scene))
                return NULL;
@@ -2806,6 +2813,13 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                        /* there's no combined pass, is in renderlayer itself */
                        if (pass == 0) {
                                rectf = rl->rectf;
+                               if (rectf == NULL) {
+                                       /* Happens when Save Buffers is enabled.
+                                        * Use display buffer stored in the render layer.
+                                        */
+                                       rect = (unsigned int *) rl->display_buffer;
+                                       byte_buffer_in_display_space = true;
+                               }
                        }
                        else {
                                rpass = BLI_findlink(&rl->passes, pass - 1);
@@ -2830,6 +2844,27 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
        }
 
+       /* Set color space settings for a byte buffer.
+        *
+        * This is mainly to make it so color management treats byte buffer
+        * from render result with Save Buffers enabled as final display buffer
+        * and doesnt' apply any color management on it.
+        *
+        * For other cases we need to be sure it stays to default byte buffer space.
+        */
+       if (ibuf->rect != rect) {
+               if (byte_buffer_in_display_space) {
+                       const char *colorspace =
+                               IMB_colormanagement_get_display_colorspace_name(&iuser->scene->view_settings,
+                                                                           &iuser->scene->display_settings);
+                       IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace);
+               }
+               else {
+                       const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
+                       IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace);
+               }
+       }
+
        /* invalidate color managed buffers if render result changed */
        BLI_lock_thread(LOCK_COLORMANAGE);
        if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) {
@@ -2839,13 +2874,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        ibuf->x = rres.rectx;
        ibuf->y = rres.recty;
 
-       /* free rect buffer if float buffer changes, so it can be recreated with
-        * the updated result, and also in case we got byte buffer from sequencer,
-        * so we don't keep reference to freed buffer */
-       if (ibuf->rect_float != rectf || rect)
-               imb_freerectImBuf(ibuf);
-
        if (rect) {
+               imb_freerectImBuf(ibuf);
                ibuf->rect = rect;
        }
        else {
@@ -2886,7 +2916,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        return ibuf;
 }
 
-static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
+static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *r_frame, int *r_index)
 {
        int frame = 0, index = 0;
 
@@ -2904,8 +2934,8 @@ static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r
                }
        }
 
-       *frame_r = frame;
-       *index_r = index;
+       *r_frame = frame;
+       *r_index = index;
 }
 
 /* Get the ibuf from an image cache for a given image user.
@@ -2914,7 +2944,7 @@ static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r
  * call IMB_freeImBuf to de-reference the image buffer after
  * it's done handling it.
  */
-static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
+static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *r_frame, int *r_index)
 {
        ImBuf *ibuf = NULL;
        int frame = 0, index = 0;
@@ -2960,16 +2990,16 @@ static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *frame_r,
                 * a big bottleneck */
        }
 
-       if (frame_r)
-               *frame_r = frame;
+       if (r_frame)
+               *r_frame = frame;
 
-       if (index_r)
-               *index_r = index;
+       if (r_index)
+               *r_index = index;
 
        return ibuf;
 }
 
-BLI_INLINE int image_quick_test(Image *ima, ImageUser *iuser)
+BLI_INLINE bool image_quick_test(Image *ima, ImageUser *iuser)
 {
        if (ima == NULL)
                return FALSE;
@@ -3046,6 +3076,9 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
                                /* always verify entirely, and potentially
                                 * returns pointer to release later */
                                ibuf = image_get_render_result(ima, iuser, lock_r);
+                               if (ibuf) {
+                                       ibuf->userflags |= IB_PERSISTENT;
+                               }
                        }
                        else if (ima->type == IMA_TYPE_COMPOSITE) {
                                /* requires lock/unlock, otherwise don't return image */
@@ -3064,6 +3097,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
                                                ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
                                                image_assign_ibuf(ima, ibuf, 0, frame);
                                        }
+                                       ibuf->userflags |= IB_PERSISTENT;
                                }
                        }
                }
@@ -3115,7 +3149,7 @@ void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
 }
 
 /* checks whether there's an image buffer for given image and user */
-int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
+bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
 {
        ImBuf *ibuf;
 
@@ -3250,7 +3284,7 @@ void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
        }
 }
 
-int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range)
+int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool *r_is_in_range)
 {
        const int len = (iuser->fie_ima * iuser->frames) / 2;
 
@@ -3312,7 +3346,7 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, shor
 void BKE_image_user_frame_calc(ImageUser *iuser, int cfra, int fieldnr)
 {
        if (iuser) {
-               short is_in_range;
+               bool is_in_range;
                const int framenr = BKE_image_user_frame_get(iuser, cfra, fieldnr, &is_in_range);
 
                if (is_in_range) {
@@ -3370,7 +3404,7 @@ void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath)
        BLI_path_abs(filepath, ID_BLEND_PATH(G.main, &ima->id));
 }
 
-int BKE_image_has_alpha(struct Image *image)
+bool BKE_image_has_alpha(struct Image *image)
 {
        ImBuf *ibuf;
        void *lock;
@@ -3492,6 +3526,16 @@ int BKE_image_sequence_guess_offset(Image *image)
        return atoi(num);
 }
 
+/**
+ * Checks the image buffer changes (not keyframed values)
+ *
+ * to see if we need to call #BKE_image_user_check_frame_calc
+ */
+bool BKE_image_is_animated(Image *image)
+{
+       return ELEM(image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE);
+}
+
 bool BKE_image_is_dirty(Image *image)
 {
        bool is_dirty = false;
@@ -3558,7 +3602,9 @@ bool BKE_image_has_loaded_ibuf(Image *image)
        return has_loaded_ibuf;
 }
 
-/* References the result, IMB_freeImBuf is to be called to de-reference. */
+/* References the result, BKE_image_release_ibuf is to be called to de-reference.
+ * Use lock=NULL when calling BKE_image_release_ibuf().
+ */
 ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
 {
        ImBuf *ibuf = NULL;
@@ -3574,6 +3620,7 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
                                IMB_refImBuf(ibuf);
                                break;
                        }
+                       IMB_moviecacheIter_step(iter);
                }
                IMB_moviecacheIter_free(iter);
        }
@@ -3582,7 +3629,8 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
        return ibuf;
 }
 
-/* References the result, IMB_freeImBuf is to be called to de-reference.
+/* References the result, BKE_image_release_ibuf is to be called to de-reference.
+ * Use lock=NULL when calling BKE_image_release_ibuf().
  *
  * TODO(sergey): This is actually "get first entry from the cache", which is
  *               not so much predictable. But using first loaded image buffer