Fix #33747: do better backwards compatibility for image transparency changes.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 8 Feb 2013 15:56:14 +0000 (15:56 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 8 Feb 2013 15:56:14 +0000 (15:56 +0000)
The use alpha option moved from the texture datablock to the image, and now it
will duplicate the image datablock in case you have one texture using alpha and
the other not.

source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/library.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_image_types.h

index f098def..d12b048 100644 (file)
@@ -205,7 +205,7 @@ void BKE_image_memorypack(struct Image *ima);
 void BKE_image_print_memlist(void);
 
 /* empty image block, of similar type and filename */
-struct Image *BKE_image_copy(struct Image *ima);
+struct Image *BKE_image_copy(struct Main *bmain, struct Image *ima);
 
 /* merge source into dest, and free source */
 void BKE_image_merge(struct Image *dest, struct Image *source);
index 39d76eb..018cd25 100644 (file)
@@ -323,9 +323,9 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
 }
 
 /* empty image block, of similar type and filename */
-Image *BKE_image_copy(Image *ima)
+Image *BKE_image_copy(Main *bmain, Image *ima)
 {
-       Image *nima = image_alloc(G.main, ima->id.name + 2, ima->source, ima->type);
+       Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
 
        BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
 
@@ -343,6 +343,9 @@ Image *BKE_image_copy(Image *ima)
 
        BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings);
 
+       if (ima->packedfile)
+               nima->packedfile = dupPackedFile(ima->packedfile);
+
        return nima;
 }
 
@@ -433,7 +436,7 @@ void BKE_image_make_local(struct Image *ima)
                extern_local_image(ima);
        }
        else if (is_local && is_lib) {
-               Image *ima_new = BKE_image_copy(ima);
+               Image *ima_new = BKE_image_copy(bmain, ima);
 
                ima_new->id.us = 0;
 
index cd40f75..0c5e2b8 100644 (file)
@@ -312,7 +312,7 @@ int id_copy(ID *id, ID **newid, int test)
                        if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id);
                        return 1;
                case ID_IM:
-                       if (!test) *newid = (ID *)BKE_image_copy((Image *)id);
+                       if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id);
                        return 1;
                case ID_LT:
                        if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id);
index 8a695ab..1d76bef 100644 (file)
@@ -8644,8 +8644,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
                Scene *scene;
-               Image *image;
-               Tex *tex;
+               Image *image, *nimage;
+               Tex *tex, *otex;
 
                for (scene = main->scene.first; scene; scene = scene->id.next) {
                        Sequence *seq;
@@ -8664,16 +8664,63 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                for (image = main->image.first; image; image = image->id.next) {
                        if (image->flag & IMA_DO_PREMUL)
                                image->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+                       image->flag &= ~IMA_DONE_TAG;
                }
 
+               /* use alpha flag moved from texture to image datablock */
                for (tex = main->tex.first; tex; tex = tex->id.next) {
                        if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
                                image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
 
-                               if (image)
+                               /* skip if no image or already tested */
+                               if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
+                                       continue;
+
+                               image->flag |= IMA_DONE_TAG;
+
+                               /* we might have some textures using alpha and others not, so we check if
+                                * they exist and duplicate the image datablock if necessary */
+                               for (otex = main->tex.first; otex; otex = otex->id.next)
+                                       if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
+                                               if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
+                                                       break;
+
+                               if (otex) {
+                                       /* copy image datablock */
+                                       nimage = BKE_image_copy(main, image);
+                                       nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
+                                       nimage->id.us--;
+
+                                       /* we need to do some trickery to make file loading think
+                                        * this new datablock is part of file we're loading */
+                                       blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
+                                       nimage->id.lib = image->id.lib;
+                                       nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
+
+                                       /* assign new image, and update the users counts accordingly */
+                                       for (otex = main->tex.first; otex; otex = otex->id.next) {
+                                               if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
+                                                       if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
+                                                               if (!(otex->id.flag & LIB_NEED_LINK)) {
+                                                                       image->id.us--;
+                                                                       nimage->id.us++;
+                                                               }
+                                                               otex->ima = nimage;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               else {
+                                       /* no other textures using alpha, just set the flag */
                                        image->flag |= IMA_IGNORE_ALPHA;
+                               }
                        }
                }
+
+               for (image = main->image.first; image; image = image->id.next)
+                       image->flag &= ~IMA_DONE_TAG;
        }
 
        if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
index 0f47ee2..682f544 100644 (file)
@@ -125,7 +125,7 @@ typedef struct Image {
 #define IMA_DO_PREMUL          4    /* deprecated, should not be used */
 #define IMA_REFLECT                    16
 #define IMA_NOCOLLECT          32
-#define IMA_DEPRECATED         64
+#define IMA_DONE_TAG           64
 #define IMA_OLD_PREMUL         128
 /*#define IMA_CM_PREDIVIDE     256*/  /* deprecated, should not be used */
 #define IMA_USED_FOR_RENDER    512