diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index f098defb907..d12b048bc96 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -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); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 39d76eb36f1..018cd25187a 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -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; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index cd40f752b03..0c5e2b89cf7 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -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); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8a695ab4edb..1d76bef8dc1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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)) { diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 0f47ee224ae..682f54481fc 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -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