The Big Image refactor!
authorTon Roosendaal <ton@blender.org>
Wed, 20 Dec 2006 17:57:56 +0000 (17:57 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 20 Dec 2006 17:57:56 +0000 (17:57 +0000)
Please read:
http://www.blender3d.org/cms/Imaging.834.0.html

Or in short:

- adding MultiLayer Image support
- recoded entire Image API
- better integration of movie/sequence Images

Was a whole load of work... went down for a week to do this. So, will need
a lot of testing! Will be in irc all evening.

86 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/node_composite.c
source/blender/blenkernel/intern/packedFile.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/intern/gsqueue.c
source/blender/blenlib/intern/util.c
source/blender/blenloader/intern/readfile.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/divers.c
source/blender/imbuf/intern/filter.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/imbuf/intern/openexr/openexr_multi.h
source/blender/imbuf/intern/readimage.c
source/blender/imbuf/intern/rectop.c
source/blender/include/BIF_butspace.h
source/blender/include/BIF_drawimage.h
source/blender/include/BIF_editsima.h
source/blender/include/BIF_renderwin.h
source/blender/include/BIF_space.h
source/blender/include/BIF_writeimage.h
source/blender/include/BSE_filesel.h
source/blender/include/BSE_node.h
source/blender/include/blendef.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_image_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_packedFile_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/python/api2_2x/Draw.c
source/blender/python/api2_2x/Image.c
source/blender/python/api2_2x/Texture.c
source/blender/python/api2_2x/sceneRender.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/include/texture.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/texture.c
source/blender/src/butspace.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawimage.c
source/blender/src/drawmesh.c
source/blender/src/drawnode.c
source/blender/src/drawview.c
source/blender/src/editnode.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/editsima.c
source/blender/src/edittime.c
source/blender/src/filesel.c
source/blender/src/header_filesel.c
source/blender/src/header_image.c
source/blender/src/header_info.c
source/blender/src/header_node.c
source/blender/src/header_time.c
source/blender/src/headerbuttons.c
source/blender/src/imagepaint.c
source/blender/src/interface.c
source/blender/src/interface_icons.c
source/blender/src/meshtools.c
source/blender/src/previewrender.c
source/blender/src/renderwin.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/toolbox.c
source/blender/src/verse_object.c
source/blender/src/writeimage.c
source/blender/yafray/intern/yafray_Render.h

index 71ede8820dbcd007973507731b685dd3ac0aed5d..e7029a01c096eeb9c18a9c588b95306b5ee32143 100644 (file)
@@ -44,7 +44,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        242
-#define BLENDER_SUBVERSION             2
+#define BLENDER_SUBVERSION             3
 
 #define BLENDER_MINVERSION             240
 #define BLENDER_MINSUBVERSION  0
index 53097b915f0eb706b32c63671144904471a96f3f..e78882220a9264ee4e0578ed9d9b63a1cfd28ae3 100644 (file)
@@ -31,7 +31,7 @@
 
 struct CurveMapping;
 struct CurveMap;
-struct Image;
+struct ImBuf;
 struct rctf;
  
 struct CurveMapping    *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
@@ -53,7 +53,7 @@ float                         curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value
 void                           curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin);
 void                           curvemapping_evaluateRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin);
 void                           curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin);
-void                           curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima);
+void                           curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf);
 void                           curvemapping_premultiply(struct CurveMapping *cumap, int restore);
 int                                    curvemapping_RGBA_does_something(struct CurveMapping *cumap);
 void                           curvemapping_initialize(struct CurveMapping *cumap);
index 98a9361120440d1fc9a8362171943928e2fe165b..1acaf004fb91c32f1c6e457e722f33117f4ec966 100644 (file)
@@ -43,28 +43,108 @@ struct ImBuf;
 struct Tex;
 struct anim;
 
-void free_image(struct Image *me);
-void free_image_preview(struct Image *ima);
-void free_image_buffers(struct Image *ima);
-struct Image *add_image(char *name);
-void free_unused_animimages(void);
-struct Image *new_image(int width, int height, char *name, short uvtestgrid);
-
-int BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
-void BKE_makepicstring(char *string, char *base, int frame, int imtype);
-void BKE_add_image_extension(char *string, int imtype);
-int BKE_imtype_is_movie(int imtype);
+/* call from library */
+void   free_image(struct Image *me);
+
+int            BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
+void   BKE_makepicstring(char *string, char *base, int frame, int imtype);
+void   BKE_add_image_extension(char *string, int imtype);
+int            BKE_ftype_to_imtype(int ftype);
+int            BKE_imtype_to_ftype(int imtype);
+int            BKE_imtype_is_movie(int imtype);
 
 struct anim *openanim(char * name, int flags);
-void ima_ibuf_is_nul(struct Tex *tex, struct Image *ima);
-void load_image(struct Image * ima, int flags, char *relabase, int framenum);
-void converttopremul(struct ImBuf *ibuf);
-void image_de_interlace(struct Image *ima, int odd);
+
+void   converttopremul(struct ImBuf *ibuf);
+void   image_de_interlace(struct Image *ima, int odd);
        
-void tag_image_time(struct Image *ima);
-void free_old_images(void);
+void   tag_image_time(struct Image *ima);
+void   free_old_images(void);
+
+/* ********************************** NEW IMAGE API *********************** */
+
+/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
+/* should be used in conjunction with an ID * to Image. */
+struct ImageUser;
+struct RenderPass;
+struct RenderResult;
+
+/* ima->source; where image comes from */
+#define IMA_SRC_CHECK          0
+#define IMA_SRC_FILE           1
+#define IMA_SRC_SEQUENCE       2
+#define IMA_SRC_MOVIE          3
+#define IMA_SRC_GENERATED      4
+#define IMA_SRC_VIEWER         5
+
+/* ima->type, how to handle/generate it */
+#define IMA_TYPE_IMAGE         0
+#define IMA_TYPE_MULTILAYER    1
+               /* generated */
+#define IMA_TYPE_UV_TEST       2
+#define IMA_TYPE_VERSE         3
+               /* viewers */
+#define IMA_TYPE_R_RESULT   4
+#define IMA_TYPE_COMPOSITE     5
+
+/* ima->ok */
+#define IMA_OK                         1
+#define IMA_OK_LOADED          2
+
+/* signals */
+       /* reload only frees, doesn't read until image_get_ibuf() called */
+#define IMA_SIGNAL_RELOAD                      0
+#define IMA_SIGNAL_FREE                                1
+       /* pack signals are executed */
+#define IMA_SIGNAL_PACK                                2
+#define IMA_SIGNAL_REPACK                      3
+#define IMA_SIGNAL_UNPACK                      4
+       /* source changes, from image to sequence or movie, etc */
+#define IMA_SIGNAL_SRC_CHANGE          5
+       /* image-user gets a new image, check settings */
+#define IMA_SIGNAL_USER_NEW_IMAGE      6
+
+/* depending Image type, and (optional) ImageUser setting it returns ibuf */
+/* always call to make signals work */
+struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
+
+/* returns existing Image when filename/type is same */
+struct Image *BKE_add_image_file(const char *name);
+
+/* adds image, adds ibuf, generates color or pattern */
+struct Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid);
+
+/* for reload, refresh, pack */
+void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal);
+
+/* ensures an Image exists for viewing nodes or render */
+struct Image *BKE_image_verify_viewer(int type, const char *name);
+
+/* force an ImBuf to become part of Image */
+void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
+
+/* called on frame change or before render */
+void BKE_image_user_calc_imanr(struct ImageUser *iuser, int cfra, int fieldnr);
+
+/* fix things in ImageUser when new image gets assigned */
+void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
+
+/* sets index offset for multilayer files */
+struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser);
+
+/* for multilayer images as well as for render-viewer */
+struct RenderResult *BKE_image_get_renderresult(struct Image *ima);
+
+/* goes over all textures that use images */
+void   BKE_image_free_all_textures(void);
+
+/* does one image! */
+void   BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
+
+/* does all images with type MOVIE or SEQUENCE */
+void BKE_image_all_free_anim_ibufs(int except_frame);
 
-void free_all_imagetextures(void);
+void BKE_image_memorypack(struct Image *ima);
 
 #ifdef __cplusplus
 }
index c51ebe252268662e4e9087f28b797bc12b0fb16f..cc6d15f7bcbf964fdf974c8f9baeae31bc0b747b 100644 (file)
@@ -66,6 +66,7 @@ struct ID *find_id(char *type, char *name);
 void clear_id_newpoins(void);
 
 void IDnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb,struct ID* link, short *nr);
+void IMAnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb, struct ID *link, short *nr);
 void IPOnames_to_pupstring(char **str, char *title, char *extraops, struct ListBase *lb, struct ID* link, short *nr, int blocktype);
 
 #endif
index f5fe91920b7e6f42021d4ecef726360722bc53dd..232a2a2cd9ec308db209500f65292230929a739f 100644 (file)
 #define TRUE 1
 #endif
 
-/* also fill in structs itself, dna cannot handle defines, duplicate in blendef.h still */
+/* these values need to be hardcoded in structs, dna does not recognize defines */
+/* also defined in DNA_space_types.h */
 #ifndef FILE_MAXDIR
 #define FILE_MAXDIR                    160
 #define FILE_MAXFILE           80
+#define FILE_MAX                       240
 #endif
 
 #define ELEM(a, b, c)           ( (a)==(b) || (a)==(c) )
index 93238137f95ee80e6bb70f8872ae8c3570442041..6249bb2f21b5162bb940e29ab55834bccaba60fa 100644 (file)
@@ -43,6 +43,7 @@
 #include "BKE_curve.h"
 #include "BKE_global.h"
 #include "BKE_ipo.h"
+#include "BKE_image.h"
 #include "BKE_main.h"
 #include "BKE_utildefines.h"
 
@@ -623,30 +624,43 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const
 
 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
 
-void curvemapping_do_image(CurveMapping *cumap, Image *ima)
+void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
 {
        int pixel;
        
-       if(ima==NULL || ima->ibuf==NULL)
+       if(ibuf==NULL)
                return;
-       if(ima->ibuf->rect_float==NULL)
-               IMB_float_from_rect(ima->ibuf);
-       else if(ima->ibuf->rect==NULL)
-               imb_addrectImBuf(ima->ibuf);
+       if(ibuf->rect_float==NULL)
+               IMB_float_from_rect(ibuf);
+       else if(ibuf->rect==NULL)
+               imb_addrectImBuf(ibuf);
        
        curvemapping_premultiply(cumap, 0);
        
-       if(ima->ibuf->rect_float && ima->ibuf->rect) {
-               float *pixf= ima->ibuf->rect_float;
+       if(ibuf->rect_float && ibuf->rect) {
+               float *pixf= ibuf->rect_float;
                float col[3];
-               char *pixc= (char *)ima->ibuf->rect;
+               int stride= 4;
+               char *pixc= (char *)ibuf->rect;
                
-               for(pixel= ima->ibuf->x*ima->ibuf->y; pixel>0; pixel--, pixf+=4, pixc+=4) {
-                       curvemapping_evaluate_premulRGBF(cumap, col, pixf);
-                       pixc[0]= FTOCHAR(col[0]);
-                       pixc[1]= FTOCHAR(col[1]);
-                       pixc[2]= FTOCHAR(col[2]);
-                       pixc[3]= FTOCHAR(pixf[3]);
+               if(ibuf->channels)
+                       stride= ibuf->channels;
+               
+               for(pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pixf+=stride, pixc+=4) {
+                       if(stride<3) {
+                               col[0]= curvemap_evaluateF(cumap->cm, *pixf);
+                               pixc[1]= pixc[2]= pixc[3]= pixc[0]= FTOCHAR(col[0]);
+                       }
+                       else {
+                               curvemapping_evaluate_premulRGBF(cumap, col, pixf);
+                               pixc[0]= FTOCHAR(col[0]);
+                               pixc[1]= FTOCHAR(col[1]);
+                               pixc[2]= FTOCHAR(col[2]);
+                               if(stride>3)
+                                       pixc[3]= FTOCHAR(pixf[3]);
+                               else
+                                       pixc[3]= 255;
+                       }
                }
        }
        
index cf19d64ca036e56c720b9394fbde54b3b0e20484..b8a6ebf8928b4f7f808c88b2fbce21564402e22b 100644 (file)
@@ -2,15 +2,12 @@
  * 
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,9 +23,9 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Blender Foundation, 2006
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include <stdio.h>
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
+#include "intern/openexr/openexr_multi.h"
 
 #include "DNA_image_types.h"
-#include "DNA_texture_types.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
 #include "DNA_userdef_types.h"
 
-#include "BLI_blenlib.h"
 #include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
 
 #include "BKE_bmfont.h"
-#include "BKE_packedFile.h"
-#include "BKE_library.h"
 #include "BKE_global.h"
-#include "BKE_main.h"
 #include "BKE_icons.h"
 #include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_packedFile.h"
 #include "BKE_scene.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
 
 #include "PIL_time.h"
 
+#include "RE_pipeline.h"
+
 /* bad level; call to free_realtime_image */
 #include "BKE_bad_level_calls.h"       
 
-void free_image_buffers(Image *ima)
+/* max int, to indicate we don't store sequences in ibuf */
+#define IMA_NO_INDEX   0x7FEFEFEF
+
+/* quick lookup: supports 1 million frames, thousand passes */
+#define IMA_MAKE_INDEX(frame, index)   ((frame)<<10)+index
+#define IMA_INDEX_FRAME(index)                 (index>>10)
+
+/* ******** IMAGE PROCESSING ************* */
+
+/* used by sequencer */
+void converttopremul(struct ImBuf *ibuf)
 {
-       unsigned int a;
+       int x, y, val;
+       char *cp;
+       
+       if(ibuf==0) return;
+       if(ibuf->depth==24) {   /* put alpha at 255 */
+               
+               cp= (char *)(ibuf->rect);
+               for(y=0; y<ibuf->y; y++) {
+                       for(x=0; x<ibuf->x; x++, cp+=4) {
+                               cp[3]= 255;
+                       }
+               }
+               return;
+       }
 
-       if(ima->ibuf) {
-               if (ima->ibuf->userdata) {
-                       MEM_freeN(ima->ibuf->userdata);
-                       ima->ibuf->userdata = NULL;
+       cp= (char *)(ibuf->rect);
+       for(y=0; y<ibuf->y; y++) {
+               for(x=0; x<ibuf->x; x++, cp+=4) {
+                       if(cp[3]==0) {
+                               cp[0]= cp[1]= cp[2]= 0;
+                       }
+                       else if(cp[3]!=255) {
+                               val= cp[3];
+                               cp[0]= (cp[0]*val)>>8;
+                               cp[1]= (cp[1]*val)>>8;
+                               cp[2]= (cp[2]*val)>>8;
+                       }
                }
-               IMB_freeImBuf(ima->ibuf);
-               ima->ibuf= NULL;
        }
-       if(ima->anim) IMB_free_anim(ima->anim);
-       ima->anim= NULL;
+}
+
+static void de_interlace_ng(struct ImBuf *ibuf)        /* neogeo fields */
+{
+       struct ImBuf * tbuf1, * tbuf2;
        
-       for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
-               if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
-               ima->mipmap[a]= NULL;
+       if (ibuf == 0) return;
+       if (ibuf->flags & IB_fields) return;
+       ibuf->flags |= IB_fields;
+       
+       if (ibuf->rect) {
+               /* make copies */
+               tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+               tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+               
+               ibuf->x *= 2;
+               
+               IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
+               IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+               
+               ibuf->x /= 2;
+               IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
+               IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
+               
+               IMB_freeImBuf(tbuf1);
+               IMB_freeImBuf(tbuf2);
        }
+       ibuf->y /= 2;
+}
+
+static void de_interlace_st(struct ImBuf *ibuf)        /* standard fields */
+{
+       struct ImBuf * tbuf1, * tbuf2;
        
-       free_realtime_image(ima);
+       if (ibuf == 0) return;
+       if (ibuf->flags & IB_fields) return;
+       ibuf->flags |= IB_fields;
+       
+       if (ibuf->rect) {
+               /* make copies */
+               tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+               tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+               
+               ibuf->x *= 2;
+               
+               IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
+               IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+               
+               ibuf->x /= 2;
+               IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y);
+               IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y);
+               
+               IMB_freeImBuf(tbuf1);
+               IMB_freeImBuf(tbuf2);
+       }
+       ibuf->y /= 2;
+}
+
+void image_de_interlace(Image *ima, int odd)
+{
+       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       if(ibuf) {
+               if(odd)
+                       de_interlace_st(ibuf);
+               else
+                       de_interlace_ng(ibuf);
+       }
 }
 
-void free_image_preview(struct Image *ima)
+/* ***************** ALLOC & FREE, DATA MANAGING *************** */
+
+static void image_free_buffers(Image *ima)
 {
+       ImBuf *ibuf;
+       
+       while((ibuf = ima->ibufs.first)) {
+               BLI_remlink(&ima->ibufs, ibuf);
+               
+               if (ibuf->userdata) {
+                       MEM_freeN(ibuf->userdata);
+                       ibuf->userdata = NULL;
+               }
+               IMB_freeImBuf(ibuf);
+       }
+       
+       if(ima->anim) IMB_free_anim(ima->anim);
+       ima->anim= NULL;
+       
        if (ima->preview) {
                MEM_freeN(ima->preview->rect);
                MEM_freeN(ima->preview);
-               ima->preview = 0;
+               ima->preview = NULL;
        }
+       
+       if(ima->rr) {
+               RE_FreeRenderResult(ima->rr);
+               ima->rr= NULL;
+       }       
+       
+       free_realtime_image(ima);
+       
+       ima->ok= IMA_OK;
 }
 
+/* called by library too, do not free ima itself */
 void free_image(Image *ima)
 {
 
-       free_image_buffers(ima);
+       image_free_buffers(ima);
        if (ima->packedfile) {
                freePackedFile(ima->packedfile);
                ima->packedfile = NULL;
        }
-       free_image_preview(ima);
        BKE_icon_delete(&ima->id);
        ima->id.icon_id = 0;
 }
 
+/* only image block itself */
+static Image *image_alloc(const char *name, short source, short type)
+{
+       Image *ima;
+       
+       ima= alloc_libblock(&G.main->image, ID_IM, name);
+       if(ima) {
+               ima->ok= IMA_OK;
+               
+               ima->xrep= ima->yrep= 1;
+               ima->gen_x= 256; ima->gen_y= 256;
+               ima->gen_type= 1;       /* no defines yet? */
+               
+               ima->source= source;
+               ima->type= type;
+       }
+       return ima;
+}
+
+/* get the ibuf from an image cache, local use here only */
+static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
+{
+       if(index==IMA_NO_INDEX)
+               return ima->ibufs.first;
+       else {
+               ImBuf *ibuf;
+               
+               index= IMA_MAKE_INDEX(frame, index);
+               for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
+                       if(ibuf->index==index)
+                               return ibuf;
+               return NULL;
+       }
+}
+
+/* no ima->ibuf anymore, but listbase */
+static void image_remove_ibuf(Image *ima, ImBuf *ibuf)
+{
+       if(ibuf) {
+               BLI_remlink(&ima->ibufs, ibuf);
+               IMB_freeImBuf(ibuf);
+       }
+}
+
+
+/* no ima->ibuf anymore, but listbase */
+static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
+{
+       if(ibuf) {
+               ImBuf *link;
+               
+               if(index!=IMA_NO_INDEX)
+                       index= IMA_MAKE_INDEX(frame, index);
+               
+               /* insert based on index */
+               for(link= ima->ibufs.first; link; link= link->next)
+                       if(link->index>=index)
+                               break;
+               /* now we don't want copies? */
+               if(link && ibuf->index==link->index) {
+                       ImBuf *prev= ibuf->prev;
+                       image_remove_ibuf(ima, link);
+                       link= prev;
+               }
+               
+               /* this function accepts link==NULL */
+               BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
+               
+               ibuf->index= index;
+       }
+       
+}
 
-Image *add_image(char *name)
+/* checks if image was already loaded, then returns same image */
+/* otherwise creates new. */
+/* does not load ibuf itself */
+Image *BKE_add_image_file(const char *name)
 {
        Image *ima;
        int file, len;
-       char *libname, str[256], strtest[256];
+       const char *libname;
+       char str[FILE_MAX], strtest[FILE_MAX];
        
-       strcpy(str, name);
+       BLI_strncpy(str, name, sizeof(str));
        BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
        
        file= open(str, O_BINARY|O_RDONLY);
@@ -133,135 +323,188 @@ Image *add_image(char *name)
        close(file);
        
        /* first search an identical image */
-       ima= G.main->image.first;
-       while(ima) {
-               strcpy(strtest, ima->name);
-               BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
-               if( strcmp(strtest, str)==0 ) {
-                       if(ima->anim==0 || ima->id.us==0) {
-                               strcpy(ima->name, name);        /* for stringcode */
-                               ima->id.us++;                           /* officially should not, it doesn't link here! */
-                               ima->ok= 1;
-                               return ima;
+       for(ima= G.main->image.first; ima; ima= ima->id.next) {
+               if(ima->source!=IMA_SRC_VIEWER) {
+                       BLI_strncpy(strtest, ima->name, sizeof(ima->name));
+                       BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
+                       
+                       if( strcmp(strtest, str)==0 ) {
+                               if(ima->anim==NULL || ima->id.us==0) {
+                                       BLI_strncpy(ima->name, name, sizeof(ima->name));        /* for stringcode */
+                                       ima->id.us++;                                                                           /* officially should not, it doesn't link here! */
+                                       if(ima->ok==0)
+                                               ima->ok= IMA_OK;
+                       /* RETURN! */
+                                       return ima;
+                               }
                        }
                }
-               ima= ima->id.next;
        }
-
+       /* add new image */
+       
+       /* create a short library name */
        len= strlen(name);
        
        while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--;
        libname= name+len;
        
-       ima= alloc_libblock(&G.main->image, ID_IM, libname);
-       strcpy(ima->name, name);
-       ima->ok= 1;
+       ima= image_alloc(libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
+       BLI_strncpy(ima->name, name, sizeof(ima->name));
        
-       ima->xrep= ima->yrep= 1;
+       /* do a wild guess! */
+       if(BLI_testextensie(name, ".avi") || BLI_testextensie(name, ".mov")
+                       || BLI_testextensie(name, ".mpg")  || BLI_testextensie(name, ".mp4"))
+               ima->source= IMA_SRC_MOVIE;
        
        return ima;
 }
 
-Image *new_image(int width, int height, char *name, short uvtestgrid)
+static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid)
 {
-       Image *ima;
-                       
-       ima = alloc_libblock(&G.main->image, ID_IM, name);
+       ImBuf *ibuf;
+       float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
+       unsigned char *rect;
+       int x, y;
+       int checkerwidth=21, dark=1;
        
-       if (ima)
-       {
-               ImBuf *ibuf;
-               unsigned char *rect;
-               int x, y;
-               int checkerwidth=21, dark=1;
-               float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
-
-               strcpy(ima->name, "Untitled");
-
-               ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
-               strcpy(ibuf->name, "Untitled");
-               ima->ibuf= ibuf;
-               ibuf->userflags |= IB_BITMAPDIRTY;
-
-               rect= (unsigned char*)ibuf->rect;
+       ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
+       strcpy(ibuf->name, "Untitled");
+       ibuf->userflags |= IB_BITMAPDIRTY;
+       
+       rect= (unsigned char*)ibuf->rect;
+       
+       if (uvtestgrid) {
+               /* these two passes could be combined into one, but it's more readable and 
+               * easy to tweak like this, speed isn't really that much of an issue in this situation... */
                
-               if (uvtestgrid) {
-                       /* these two passes could be combined into one, but it's more readable and 
-                        * easy to tweak like this, speed isn't really that much of an issue in this situation... */
-
-                       /* checkers */
-                       for(y=0; y<ibuf->y; y++) {
-                               dark = pow(-1, floor(y / checkerwidth));
+               /* checkers */
+               for(y=0; y<ibuf->y; y++) {
+                       dark = pow(-1, floor(y / checkerwidth));
+                       
+                       for(x=0; x<ibuf->x; x++, rect+=4) {
+                               if (x % checkerwidth == 0) dark *= -1;
                                
-                               for(x=0; x<ibuf->x; x++, rect+=4) {
-                                       if (x % checkerwidth == 0) dark *= -1;
-                                       
-                                       if (dark > 0) {
-                                               rect[0] = rect[1] = rect[2] = 64;
-                                               rect[3] = 255;
-                                       } else {
-                                               rect[0] = rect[1] = rect[2] = 150;
-                                               rect[3] = 255;
-                                       }
+                               if (dark > 0) {
+                                       rect[0] = rect[1] = rect[2] = 64;
+                                       rect[3] = 255;
+                               } else {
+                                       rect[0] = rect[1] = rect[2] = 150;
+                                       rect[3] = 255;
                                }
                        }
-                                       
-                       /* 2nd pass, coloured + */
-                       rect= (unsigned char*)ibuf->rect;
+               }
+               
+               /* 2nd pass, coloured + */
+               rect= (unsigned char*)ibuf->rect;
+               
+               for(y=0; y<ibuf->y; y++) {
+                       hoffs = 0.125 * floor(y / checkerwidth);
                        
-                       for(y=0; y<ibuf->y; y++) {
-                               hoffs = 0.125 * floor(y / checkerwidth);
+                       for(x=0; x<ibuf->x; x++, rect+=4) {
+                               h = 0.125 * floor(x / checkerwidth);
                                
-                               for(x=0; x<ibuf->x; x++, rect+=4) {
-                                       h = 0.125 * floor(x / checkerwidth);
-                                                                       
-                                       if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
-                                               (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+                               if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
+                                       (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+                                       
+                                       if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
+                                               (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
                                                
-                                               if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
-                                                       (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
+                                               hue = fmod(fabs(h-hoffs), 1.0);
+                                               hsv_to_rgb(hue, s, v, &r, &g, &b);
                                                
-                                                       hue = fmod(fabs(h-hoffs), 1.0);
-                                                       hsv_to_rgb(hue, s, v, &r, &g, &b);
-                                                       
-                                                       rect[0]= (char)(r * 255.0);
-                                                       rect[1]= (char)(g * 255.0);
-                                                       rect[2]= (char)(b * 255.0);
-                                                       rect[3]= 255;
-                                               }
+                                               rect[0]= (char)(r * 255.0);
+                                               rect[1]= (char)(g * 255.0);
+                                               rect[2]= (char)(b * 255.0);
+                                               rect[3]= 255;
                                        }
-                                       
                                }
+                               
                        }
-               } else {        /* blank image */
-                       for(y=0; y<ibuf->y; y++) {
-                               for(x=0; x<ibuf->x; x++, rect+=4) {
-                                       rect[0]= rect[1]= rect[2]= 0;
-                                       rect[3]= 255;
-                               }
+               }
+       } else {        /* blank image */
+               for(y=0; y<ibuf->y; y++) {
+                       for(x=0; x<ibuf->x; x++, rect+=4) {
+                               rect[0]= rect[1]= rect[2]= 0;
+                               rect[3]= 255;
                        }
                }
+       }
+       return ibuf;
+}
 
-               ima->ok= 1;
-               ima->xrep= ima->yrep= 1;
+/* adds new image block, creates ImBuf and initializes color */
+Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid)
+{
+       Image *ima;
+       
+       /* on save, type is changed to FILE in editsima.c */
+       ima= image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
+       
+       if (ima) {
+               ImBuf *ibuf;
+               
+               BLI_strncpy(ima->name, name, FILE_MAX);
+               ima->gen_x= width;
+               ima->gen_y= height;
+               ima->gen_type= uvtestgrid;
+               
+               ibuf= add_ibuf_size(width, height, name, uvtestgrid);
+               image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+               
+               ima->ok= IMA_OK_LOADED;
        }
 
        return ima;
 }
 
+/* packs rect from memory as PNG */
+void BKE_image_memorypack(Image *ima)
+{
+       ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+       
+       if(ibuf==NULL)
+               return;
+       if (ima->packedfile) {
+               freePackedFile(ima->packedfile);
+               ima->packedfile = NULL;
+       }
+       
+       ibuf->ftype= PNG;
+       ibuf->depth= 32;
+       
+       IMB_saveiff(ibuf, ibuf->name, IB_rect | IB_mem);
+       if(ibuf->encodedbuffer==NULL) {
+               printf("memory save for pack error\n");
+       }
+       else {
+               PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
+               
+               pf->data = ibuf->encodedbuffer;
+               pf->size = ibuf->encodedsize;
+               ima->packedfile= pf;
+               ibuf->encodedbuffer= NULL;
+               ibuf->encodedsize= 0;
+               ibuf->userflags &= ~IB_BITMAPDIRTY;
+               
+               if(ima->source==IMA_SRC_GENERATED)
+                       ima->source= IMA_SRC_FILE;
+       }
+}
+
 void tag_image_time(Image *ima)
 {
        if (ima)
                ima->lastused = (int)PIL_check_seconds_timer();
 }
 
-void tag_all_images_time() {
+void tag_all_images_time() 
+{
        Image *ima;
        int ctime = (int)PIL_check_seconds_timer();
 
        ima= G.main->image.first;
        while(ima) {
-               if(ima->bindcode || ima->repbind || ima->ibuf) {
+               if(ima->bindcode || ima->repbind || ima->ibufs.first) {
                        ima->lastused = ctime;
                }
        }
@@ -294,29 +537,15 @@ void free_old_images()
                                ima->lastused = ctime;
                        }
                        /* Otherwise, just kill the buffers */
-                       else if (ima->ibuf) {
-                               free_image_buffers(ima);
+                       else if (ima->ibufs.first) {
+                               image_free_buffers(ima);
                        }
                }
                ima = ima->id.next;
        }
 }
 
-void free_unused_animimages()
-{
-       Image *ima, *nima;
-
-       ima= G.main->image.first;
-       while(ima) {
-               nima= ima->id.next;
-               if(ima->id.us==0) {
-                       if(ima->flag & IMA_FROMANIM) free_libblock(&G.main->image, ima);
-               }
-               ima= nima;
-       }
-}
-
-void free_all_imagetextures(void)
+void BKE_image_free_all_textures(void)
 {
        Tex *tex;
        Image *ima;
@@ -330,19 +559,116 @@ void free_all_imagetextures(void)
                        tex->ima->id.flag |= LIB_DOIT;
        
        for(ima= G.main->image.first; ima; ima= ima->id.next) {
-               if(ima->ibuf && (ima->id.flag & LIB_DOIT)) {
-                       if(ima->mipmap[0]) 
-                               totsize+= 1.33*ima->ibuf->x*ima->ibuf->y*4;
-                       else
-                               totsize+= ima->ibuf->x*ima->ibuf->y*4;
-                       free_image_buffers(ima);
+               if(ima->ibufs.first && (ima->id.flag & LIB_DOIT)) {
+                       ImBuf *ibuf;
+                       for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) {
+                               if(ibuf->mipmap[0]) 
+                                       totsize+= 1.33*ibuf->x*ibuf->y*4;
+                               else
+                                       totsize+= ibuf->x*ibuf->y*4;
+                       }
+                       image_free_buffers(ima);
                }
        }
-       printf("freed total %d MB\n", totsize/(1024*1024));
+       /* printf("freed total %d MB\n", totsize/(1024*1024)); */
 }
 
+/* except_frame is weak, only works for seqs without offset... */
+void BKE_image_free_anim_ibufs(Image *ima, int except_frame)
+{
+       ImBuf *ibuf, *nbuf;
+
+       for(ibuf= ima->ibufs.first; ibuf; ibuf= nbuf) {
+               nbuf= ibuf->next;
+               if(ibuf->userflags & IB_BITMAPDIRTY)
+                       continue;
+               if(ibuf->index==IMA_NO_INDEX)
+                       continue;
+               if(except_frame!=IMA_INDEX_FRAME(ibuf->index)) {
+                       BLI_remlink(&ima->ibufs, ibuf);
+                       
+                       if (ibuf->userdata) {
+                               MEM_freeN(ibuf->userdata);
+                               ibuf->userdata = NULL;
+                       }
+                       IMB_freeImBuf(ibuf);
+               }                                       
+       }
+}
+
+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))
+                       BKE_image_free_anim_ibufs(ima, cfra);
+}
+
+
 /* *********** READ AND WRITE ************** */
 
+int BKE_imtype_to_ftype(int imtype)
+{
+       if(imtype==0)
+               return TGA;
+       else if(imtype== R_IRIS) 
+               return IMAGIC;
+       else if (imtype==R_RADHDR)
+               return RADHDR;
+       else if (imtype==R_PNG)
+               return PNG;
+       else if (imtype==R_BMP)
+               return BMP;
+       else if (imtype==R_TIFF)
+               return TIF;
+       else if (imtype==R_OPENEXR || imtype==R_MULTILAYER)
+               return OPENEXR;
+       else if (imtype==R_CINEON)
+               return CINEON;
+       else if (imtype==R_DPX)
+               return DPX;
+       else if (imtype==R_TARGA)
+               return TGA;
+       else if(imtype==R_RAWTGA)
+               return RAWTGA;
+       else if(imtype==R_HAMX)
+               return AN_hamx;
+       else
+               return JPG|90;
+}
+
+int BKE_ftype_to_imtype(int ftype)
+{
+       if(ftype==0)
+               return TGA;
+       else if(ftype == IMAGIC) 
+               return R_IRIS;
+       else if (ftype & RADHDR)
+               return R_RADHDR;
+       else if (ftype & PNG)
+               return R_PNG;
+       else if (ftype & BMP)
+               return R_BMP;
+       else if (ftype & TIF)
+               return R_TIFF;
+       else if (ftype & OPENEXR)
+               return R_OPENEXR;
+       else if (ftype & CINEON)
+               return R_CINEON;
+       else if (ftype & DPX)
+               return R_DPX;
+       else if (ftype & TGA)
+               return R_TARGA;
+       else if(ftype & RAWTGA)
+               return R_RAWTGA;
+       else if(ftype == AN_hamx)
+               return R_HAMX;
+       else
+               return R_JPEG90;
+}
+
+
 int BKE_imtype_is_movie(int imtype)
 {
        switch(imtype) {
@@ -395,7 +721,7 @@ void BKE_add_image_extension(char *string, int imtype)
                        extension= ".tif";
        }
 #ifdef WITH_OPENEXR
-       else if(imtype==R_OPENEXR) {
+       else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
                if(!BLI_testextensie(string, ".exr"))
                        extension= ".exr";
        }
@@ -437,7 +763,7 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
                ibuf->ftype= TIF;
        }
 #ifdef WITH_OPENEXR
-       else if (imtype==R_OPENEXR) {
+       else if (imtype==R_OPENEXR || imtype==R_MULTILAYER) {
                ibuf->ftype= OPENEXR;
                if(subimtype & R_OPENEXR_HALF)
                        ibuf->ftype |= OPENEXR_HALF;
@@ -488,7 +814,7 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype)
 
        if (string==NULL) return;
 
-       BLI_strncpy(string, base, FILE_MAXDIR + FILE_MAXFILE - 10);     /* weak assumption */
+       BLI_strncpy(string, base, FILE_MAX - 10);       /* weak assumption */
        BLI_convertstringcode(string, G.sce, frame);
 
        len= strlen(string);
@@ -506,43 +832,7 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype)
                
 }
 
-/* ******** IMAGE WRAPPING INIT ************* */
-
-/* used by sequencer, texture */
-void converttopremul(struct ImBuf *ibuf)
-{
-       int x, y, val;
-       char *cp;
-       
-       if(ibuf==0) return;
-       if(ibuf->depth==24) {   /* put alpha at 255 */
-
-               cp= (char *)(ibuf->rect);
-               for(y=0; y<ibuf->y; y++) {
-                       for(x=0; x<ibuf->x; x++, cp+=4) {
-                               cp[3]= 255;
-                       }
-               }
-               return;
-       }
-       
-       cp= (char *)(ibuf->rect);
-       for(y=0; y<ibuf->y; y++) {
-               for(x=0; x<ibuf->x; x++, cp+=4) {
-                       if(cp[3]==0) {
-                               cp[0]= cp[1]= cp[2]= 0;
-                       }
-                       else if(cp[3]!=255) {
-                               val= cp[3];
-                               cp[0]= (cp[0]*val)>>8;
-                               cp[1]= (cp[1]*val)>>8;
-                               cp[2]= (cp[2]*val)>>8;
-                       }
-               }
-       }
-}
-
-/* used by sequencer, texture */
+/* used by sequencer too */
 struct anim *openanim(char *name, int flags)
 {
        struct anim *anim;
@@ -562,198 +852,656 @@ struct anim *openanim(char *name, int flags)
        return(anim);
 }
 
+/* ************************* New Image API *************** */
+
+
+/* Notes about Image storage 
+- packedfile
+  -> written in .blend
+- filename
+  -> written in .blend
+- movie
+  -> comes from packedfile or filename
+- renderresult
+  -> comes from packedfile or filename
+- listbase
+  -> ibufs from exrhandle
+- flipbook array
+  -> ibufs come from movie, temporary renderresult or sequence
+- ibuf
+  -> comes from packedfile or filename or generated
 
-/*
-load_image handles reading the image from disk or from the packedfile.
 */
 
-void load_image(Image * ima, int flags, char *relabase, int framenum)
-{
-       char name[FILE_MAXDIR + FILE_MAXFILE];
 
-       if(ima->id.lib) relabase= ima->id.lib->filename;
+/* forces existance of 1 Image for renderout or nodes, returns Image */
+/* name is only for default, when making new one */
+Image *BKE_image_verify_viewer(int type, const char *name)
+{
+       Image *ima;
        
-       if (ima->ibuf == NULL) {
-
-               // is there a PackedFile with this image ?;
-               if (ima->packedfile) {
-                       ima->ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, flags);
-               } else {
-                       strcpy(name, ima->name);
-                       BLI_convertstringcode(name, relabase, framenum);
+       for(ima=G.main->image.first; ima; ima= ima->id.next)
+               if(ima->source==IMA_SRC_VIEWER)
+                       if(ima->type==type)
+                               break;
+       
+       if(ima==NULL)
+               ima= image_alloc(name, IMA_SRC_VIEWER, type);
+       
+       /* happens on reload, imagewindow cannot be image user when hidden*/
+       if(ima->id.us==0)
+               id_us_plus(&ima->id);
 
-                       ima->ibuf = IMB_loadiffname(name , flags);
-               }
-               // check if the image is a font image...
-               // printf("Checking for font\n");
+       return ima;
+}
 
-               if (ima->ibuf) {
-                       detectBitmapFont(ima->ibuf);
-                       /* preview is NULL when it has never been used as an icon before */
-                       if(G.background==0 && ima->preview==NULL)
-                               BKE_icon_changed(BKE_icon_getid(&ima->id));
+void BKE_image_assign_ibuf(Image *ima, ImBuf *ibuf)
+{
+       image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+}
 
+void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
+{
+       if(ima==NULL)
+               return;
+       
+       switch(signal) {
+       case IMA_SIGNAL_FREE:
+               image_free_buffers(ima);
+               if(iuser)
+                       iuser->ok= 1;
+               break;
+       case IMA_SIGNAL_SRC_CHANGE:
+               if(ima->type==IMA_TYPE_MULTILAYER)
+                       image_free_buffers(ima);
+               else if(ima->source==IMA_SRC_GENERATED) {
+                       if(ima->gen_x==0 || ima->gen_y==0) {
+                               ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+                               if(ibuf) {
+                                       ima->gen_x= ibuf->x;
+                                       ima->gen_y= ibuf->y;
+                               }
+                       }
+               }
+               ima->ok= 1;
+               if(iuser)
+                       iuser->ok= 1;
+               break;
+                       
+       case IMA_SIGNAL_RELOAD:
+               /* try to repack file */
+               if(ima->packedfile) {
+                       PackedFile *pf;
+                       pf = newPackedFile(ima->name);
+                       if (pf) {
+                               freePackedFile(ima->packedfile);
+                               ima->packedfile = pf;
+                               image_free_buffers(ima);
+                       } else {
+                               printf("ERROR: Image not available. Keeping packed image\n");
+                       }
                }
+               else
+                       image_free_buffers(ima);
+               
+               if(iuser)
+                       iuser->ok= 1;
+               
+               break;
+       case IMA_SIGNAL_USER_NEW_IMAGE:
+               if(iuser) {
+                       iuser->ok= 1;
+                       if(ima->source==IMA_SRC_FILE || ima->source==IMA_SRC_SEQUENCE) {
+                               if(ima->type==IMA_TYPE_MULTILAYER) {
+                                       iuser->multi_index= 0;
+                                       iuser->layer= iuser->pass= 0;
+                               }
+                       }
+               }
+               break;
        }
 }
 
-
-static void de_interlace_ng(struct ImBuf *ibuf)        /* neogeo fields */
+/* if layer or pass changes, we need an index for the imbufs list */
+/* note it is called for rendered results, but it doesnt use the index! */
+/* and because rendered results use fake layer/passes, don't correct for wrong indices here */
+RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
 {
-       struct ImBuf * tbuf1, * tbuf2;
+       RenderLayer *rl;
+       RenderPass *rpass= NULL;
        
-       if (ibuf == 0) return;
-       if (ibuf->flags & IB_fields) return;
-       ibuf->flags |= IB_fields;
+       if(rr==NULL) 
+               return NULL;
        
-       if (ibuf->rect) {
-               /* make copies */
-               tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
-               tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
+       if(iuser) {
+               short index= 0, rl_index= 0, rp_index;
                
-               ibuf->x *= 2;
+               for(rl= rr->layers.first; rl; rl= rl->next, rl_index++) {
+                       rp_index= 0;
+                       for(rpass= rl->passes.first; rpass; rpass= rpass->next, index++, rp_index++)
+                               if(iuser->layer==rl_index && iuser->pass==rp_index)
+                                       break;
+                       if(rpass)
+                               break;
+               }
                
-               IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
-               IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+               if(rpass)
+                       iuser->multi_index= index;
+               else 
+                       iuser->multi_index= 0;
+       }
+       if(rpass==NULL) {
+               rl= rr->layers.first;
+               if(rl)
+                       rpass= rl->passes.first;
+       }
+       
+       return rpass;
+}
+
+RenderResult *BKE_image_get_renderresult(Image *ima)
+{
+       if(ima->rr)
+               return ima->rr;
+       if(ima->type==IMA_TYPE_R_RESULT)
+               return RE_GetResult(RE_GetRender(G.scene->id.name));
+       return NULL;
+}
+
+/* after imbuf load, openexr type can return with a exrhandle open */
+/* in that case we have to build a render-result */
+static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
+{
+       
+       ima->rr= RE_MultilayerConvert(ibuf->userdata, ibuf->x, ibuf->y);
+       IMB_exr_close(ibuf->userdata);
+       ibuf->userdata= NULL;
+       if(ima->rr)
+               ima->rr->framenr= framenr;
+}
+
+/* common stuff to do with images after loading */
+static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
+{
+       
+       
+       /* preview is NULL when it has never been used as an icon before */
+       if(G.background==0 && ima->preview==NULL)
+               BKE_icon_changed(BKE_icon_getid(&ima->id));
+       
+       /* stringcodes also in ibuf, ibuf->name is used to retrieve original (buttons) */
+       BLI_strncpy(ibuf->name, ima->name, FILE_MAX);
+       
+       /* fields */
+       if (ima->flag & IMA_FIELDS) {
+               if(ima->flag & IMA_STD_FIELD) de_interlace_st(ibuf);
+               else de_interlace_ng(ibuf);
+       }
+       /* timer */
+       ima->lastused = clock() / CLOCKS_PER_SEC;
+       
+       ima->ok= IMA_OK_LOADED;
+       
+}
+
+static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
+{
+       struct ImBuf *ibuf;
+       unsigned short numlen;
+       char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
+       
+       ima->lastframe= frame;
+
+       BLI_stringdec(ima->name, head, tail, &numlen);
+       BLI_stringenc(ima->name, head, tail, numlen, frame);
+       BLI_strncpy(name, ima->name, sizeof(name));
+       
+       if(ima->id.lib)
+               BLI_convertstringcode(name, ima->id.lib->filename, frame);
+       else
+               BLI_convertstringcode(name, G.sce, frame);
+       
+       /* read ibuf */
+       ibuf = IMB_loadiffname(name, IB_rect|IB_multilayer);
+       printf("loaded %s\n", name);
+       
+       if (ibuf) {
+               /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+               if (ibuf->ftype==OPENEXR && ibuf->userdata) {
+                       image_create_multilayer(ima, ibuf, frame);      
+                       ima->type= IMA_TYPE_MULTILAYER;
+                       IMB_freeImBuf(ibuf);
+                       ibuf= NULL;
+               }
+               else {
+                       image_assign_ibuf(ima, ibuf, 0, frame);
+                       image_initialize_after_load(ima, ibuf);
+               }
+       }
+       else
+               ima->ok= 0;
+       
+       if(iuser)
+               iuser->ok= ima->ok;
+       
+       return ibuf;
+}
+
+static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int frame)
+{
+       struct ImBuf *ibuf= NULL;
+       
+       /* either we load from RenderResult, or we have to load a new one */
+       
+       /* check for new RenderResult */
+       if(ima->rr==NULL || frame!=ima->rr->framenr) {
+               /* copy to survive not found multilayer image */
+               RenderResult *oldrr= ima->rr;
+       
+               ima->rr= NULL;
+               ibuf = image_load_sequence_file(ima, iuser, frame);
                
-               ibuf->x /= 2;
-               IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
-               IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
+               if(ibuf) { /* actually an error */
+                       ima->type= IMA_TYPE_IMAGE;
+                       printf("error, multi is normal image\n");
+               }
+               // printf("loaded new result %p\n", ima->rr);
+               /* free result if new one found */
+               if(ima->rr) {
+                       // if(oldrr) printf("freed previous result %p\n", oldrr);
+                       if(oldrr) RE_FreeRenderResult(oldrr);
+               }
+               else
+                       ima->rr= oldrr;
+
+       }
+       if(ima->rr) {
+               RenderPass *rpass= BKE_image_multilayer_index(ima->rr, iuser);
                
-               IMB_freeImBuf(tbuf1);
-               IMB_freeImBuf(tbuf2);
+               if(rpass) {
+                       // printf("load from pass %s\n", rpass->name);
+                       /* since we free  render results, we copy the rect */
+                       ibuf= IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0, 0);
+                       ibuf->rect_float= MEM_dupallocN(rpass->rect);
+                       ibuf->flags |= IB_rectfloat;
+                       ibuf->mall= IB_rectfloat;
+                       ibuf->channels= rpass->channels;
+                       
+                       image_assign_ibuf(ima, ibuf, iuser->multi_index, frame);
+                       image_initialize_after_load(ima, ibuf);
+                       
+               }
+               // else printf("pass not found\n");
        }
-       ibuf->y /= 2;
+       else
+               ima->ok= 0;
+       
+       if(iuser)
+               iuser->ok= ima->ok;
+       
+       return ibuf;
 }
 
-static void de_interlace_st(struct ImBuf *ibuf)        /* standard fields */
+
+static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
 {
-       struct ImBuf * tbuf1, * tbuf2;
+       struct ImBuf *ibuf= NULL;
        
-       if (ibuf == 0) return;
-       if (ibuf->flags & IB_fields) return;
-       ibuf->flags |= IB_fields;
+       ima->lastframe= frame;
        
-       if (ibuf->rect) {
-               /* make copies */
-               tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
-               tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
+       if(ima->anim==NULL) {
+               char str[FILE_MAX];
                
-               ibuf->x *= 2;
+               BLI_strncpy(str, ima->name, FILE_MAX);
+               if(ima->id.lib)
+                       BLI_convertstringcode(str, ima->id.lib->filename, 0);
+               else
+                       BLI_convertstringcode(str, G.sce, 0);
                
-               IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
-               IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
+               ima->anim = openanim(str, IB_cmap | IB_rect);
                
-               ibuf->x /= 2;
-               IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y);
-               IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y);
+               /* let's initialize this user */
+               if(ima->anim && iuser && iuser->frames==0)
+                       iuser->frames= IMB_anim_get_duration(ima->anim);
+       }
+       
+       if(ima->anim) {
+               int dur = IMB_anim_get_duration(ima->anim);
+               int fra= frame-1;
                
-               IMB_freeImBuf(tbuf1);
-               IMB_freeImBuf(tbuf2);
+               if(fra<0) fra = 0;
+               if(fra>(dur-1)) fra= dur-1;
+               ibuf = IMB_anim_absolute(ima->anim, fra);
+               
+               if(ibuf) {
+                       image_assign_ibuf(ima, ibuf, 0, frame);
+                       image_initialize_after_load(ima, ibuf);
+               }
+               else
+                       ima->ok= 0;
        }
-       ibuf->y /= 2;
+       else
+               ima->ok= 0;
+       
+       if(iuser)
+               iuser->ok= ima->ok;
+       
+       return ibuf;
 }
 
-void image_de_interlace(Image *ima, int odd)
+/* cfra used for # code, Image can only have this # for all its users */
+static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 {
-       if(odd)
-               de_interlace_st(ima->ibuf);
+       struct ImBuf *ibuf;
+       char str[FILE_MAX];
+       
+       /* always ensure clean ima */
+       image_free_buffers(ima);
+       
+       /* is there a PackedFile with this image ? */
+       if (ima->packedfile) {
+               ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, IB_rect|IB_multilayer);
+       } 
+       else {
+                       
+               /* get the right string */
+               BLI_strncpy(str, ima->name, sizeof(str));
+               if(ima->id.lib)
+                       BLI_convertstringcode(str, ima->id.lib->filename, cfra);
+               else
+                       BLI_convertstringcode(str, G.sce, cfra);
+               
+               /* read ibuf */
+               ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer);
+       }
+       
+       if (ibuf) {
+               /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+               if (ibuf->ftype==OPENEXR && ibuf->userdata) {
+                       image_create_multilayer(ima, ibuf, cfra);       
+                       ima->type= IMA_TYPE_MULTILAYER;
+                       IMB_freeImBuf(ibuf);
+                       ibuf= NULL;
+               }
+               else {
+                       image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+                       image_initialize_after_load(ima, ibuf);
+
+                       /* check if the image is a font image... */
+                       detectBitmapFont(ibuf);
+                       
+                       /* make packed file for autopack */
+                       if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
+                               ima->packedfile = newPackedFile(str);
+               }
+       }
        else
-               de_interlace_ng(ima->ibuf);
+               ima->ok= 0;
+       
+       if(iuser)
+               iuser->ok= ima->ok;
+       
+       return ibuf;
 }
 
-void ima_ibuf_is_nul(Tex *tex, Image *ima)
+static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
 {
-       void (*de_interlacefunc)(struct ImBuf *ibuf);
-       unsigned int a;
-       int     fra, dur;
-       char str[FILE_MAXDIR+FILE_MAXFILE], *cp;
+       ImBuf *ibuf= NULL;
        
-       if(ima==0) return;
+       if(ima->rr==NULL) {
+               ibuf = image_load_image_file(ima, iuser, 0);
+               if(ibuf) { /* actually an error */
+                       ima->type= IMA_TYPE_IMAGE;
+                       return ibuf;
+               }
+       }
+       if(ima->rr) {
+               RenderPass *rpass= BKE_image_multilayer_index(ima->rr, iuser);
+
+               if(rpass) {
+                       ibuf= IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0, 0);
+                       
+                       image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
+                       image_initialize_after_load(ima, ibuf);
+                       
+                       ibuf->rect_float= rpass->rect;
+                       ibuf->flags |= IB_rectfloat;
+                       ibuf->channels= rpass->channels;
+               }
+       }
        
-       strcpy(str, ima->name);
-       if(ima->id.lib)
-               BLI_convertstringcode(str, ima->id.lib->filename, G.scene->r.cfra);
-       else
-               BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       if(ibuf==NULL) 
+               ima->ok= 0;
+       if(iuser)
+               iuser->ok= ima->ok;
        
-       if(tex->imaflag & TEX_STD_FIELD) de_interlacefunc= de_interlace_st;
-       else de_interlacefunc= de_interlace_ng;
+       return ibuf;
+}
+
+
+/* showing RGBA result itself (from compo/sequence) or
+   like exr, using layers etc */
+static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
+{
+       RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name));
        
-       if(tex->imaflag & TEX_ANIM5) {
+       if(rr && iuser) {
+               RenderResult rres;
+               float *rectf;
+               unsigned int *rect;
+               int channels= 4, layer= iuser->layer;
                
-               if(ima->anim==NULL) ima->anim = openanim(str, IB_cmap | IB_rect);
-               if (ima->anim) {
-                       dur = IMB_anim_get_duration(ima->anim);
-                       
-                       fra= ima->lastframe-1;
-                       
-                       if(fra<0) fra = 0;
-                       if(fra>(dur-1)) fra= dur-1;
-                       ima->ibuf = IMB_anim_absolute(ima->anim, fra);
-                       
-                       /* patch for textbutton with name ima (B_NAMEIMA) */
-                       if(ima->ibuf) {
-                               strcpy(ima->ibuf->name, ima->name);
-                               if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
+               /* this gives active layer, composite or seqence result */
+               RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+               rect= rres.rect32;
+               rectf= rres.rectf;
+               
+               /* get compo/seq result by default */
+               if(rr->rectf && layer==0);
+               else if(rr->layers.first) {
+                       RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer-(rr->rectf?1:0));
+                       if(rl) {
+                               /* there's no combined pass, is in renderlayer itself */
+                               if(iuser->pass==0) {
+                                       rectf= rl->rectf;
+                               }
+                               else {
+                                       RenderPass *rpass= BLI_findlink(&rl->passes, iuser->pass-1);
+                                       if(rpass) {
+                                               channels= rpass->channels;
+                                               rectf= rpass->rect;
+                                       }
+                               }
                        }
                }
                
-       } else {
-               // create a packedfile for this image when autopack is on
-               // for performance (IMB_loadiffname uses mmap) we don't do this by default
-               if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK)) {
-                       ima->packedfile = newPackedFile(str);
+               if(rectf || rect) {
+                       ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+
+                       /* make ibuf if needed, and initialize it */
+                       if(ibuf==NULL) {
+                               ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, 0, 0);
+                               image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+                       }
+                       ibuf->x= rr->rectx;
+                       ibuf->y= rr->recty;
+                       
+                       if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */
+                               imb_freerectImBuf(ibuf);
+                       if(rect)
+                               ibuf->rect= rect;
+                       
+                       ibuf->rect_float= rectf;
+                       ibuf->flags |= IB_rectfloat;
+                       ibuf->channels= channels;
+                       
+                       ima->ok= IMA_OK_LOADED;
+                       return ibuf;
                }
-               
-               load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
-               
-               if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
        }
        
-       if(ima->ibuf) {
+       return NULL;
+}
+
+/* Checks optional ImageUser and verifies/creates ImBuf. */
+/* returns ibuf */
+ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+{
+       ImBuf *ibuf= NULL;
+
+       /* quick reject tests */
+       if(ima==NULL) 
+               return NULL;
+       if(iuser) {
+               if(iuser->ok==0)
+                       return NULL;
+       }
+       else if(ima->ok==0)
+               return NULL;
+       
+       BLI_lock_thread(LOCK_CUSTOM1);
+       
+       /* handle image source and types */
+       if(ima->source==IMA_SRC_MOVIE) {
+               /* source is from single file, use flipbook to store ibuf */
+               int frame= iuser?iuser->framenr:ima->lastframe;
                
-               /* stringcodes also in ibuf. ibuf->name is used as 'undo' (buttons.c) */
-               strcpy(ima->ibuf->name, ima->name);
+               ibuf= image_get_ibuf(ima, 0, frame);
+               if(ibuf==NULL)
+                       ibuf= image_load_movie_file(ima, iuser, frame);
+       }
+       else if(ima->source==IMA_SRC_SEQUENCE) {
                
-               if(ima->ibuf->cmap) {
+               if(ima->type==IMA_TYPE_IMAGE) {
+                       /* regular files, ibufs in flipbook, allows saving */
+                       int frame= iuser?iuser->framenr:ima->lastframe;
                        
-                       if(tex->imaflag & TEX_ANIM5) {
-                               
-                               if(tex->imaflag & TEX_MORKPATCH) {
-                                       /**** PATCH TO SET COLOR 2 RIGHT (neogeo..) */
-                                       if(ima->ibuf->maxcol > 4) {
-                                               cp= (char *)(ima->ibuf->cmap+2);
-                                               cp[0]= 0x80;
-                                       }
-                               }
-                               
-                               IMB_applycmap(ima->ibuf);
-                               IMB_convert_rgba_to_abgr(ima->ibuf);
-                               
-                       }
+                       ibuf= image_get_ibuf(ima, 0, frame);
+                       if(ibuf==NULL)
+                               ibuf= image_load_sequence_file(ima, iuser, frame);
+                       else
+                               BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
+               }
+               /* no else; on load the ima type can change */
+               if(ima->type==IMA_TYPE_MULTILAYER) {
+                       /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
+                       int frame= iuser?iuser->framenr:ima->lastframe;
+                       int index= iuser?iuser->multi_index:IMA_NO_INDEX;
                        
-                       converttopremul(ima->ibuf);
+                       ibuf= image_get_ibuf(ima, index, frame);
+                       if(G.rt) printf("seq multi fra %d id %d ibuf %p %s\n", frame, index, ibuf, ima->id.name);
+                       if(ibuf==NULL)
+                               ibuf= image_load_sequence_multilayer(ima, iuser, frame);
+                       else
+                               BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
+               }
+
+       }
+       else if(ima->source==IMA_SRC_FILE) {
+               
+               if(ima->type==IMA_TYPE_IMAGE) {
+                       ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+                       if(ibuf==NULL)
+                               ibuf= image_load_image_file(ima, iuser, G.scene->r.cfra);       /* cfra only for '#', this global is OK */
                }
+               /* no else; on load the ima type can change */
+               if(ima->type==IMA_TYPE_MULTILAYER) {
+                       /* keeps render result, stores ibufs in listbase, allows saving */
+                       ibuf= image_get_ibuf(ima, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
+                       if(ibuf==NULL)
+                               ibuf= image_get_ibuf_multilayer(ima, iuser);
+               }
+                       
+       }
+       else if(ima->source == IMA_SRC_GENERATED) {
+               /* generated is: ibuf is allocated dynamically */
+               ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
                
-               if(tex->imaflag & TEX_ANTISCALE) {
-                       IMB_clever_double(ima->ibuf);
-                       IMB_antialias(ima->ibuf);
+               if(ibuf==NULL) {
+                       if(ima->type==IMA_TYPE_VERSE) {
+                               /* todo */
+                       }
+                       else { /* always fall back to IMA_TYPE_UV_TEST */
+                               /* UV testgrid or black or solid etc */
+                               if(ima->gen_x==0) ima->gen_x= 256;
+                               if(ima->gen_y==0) ima->gen_y= 256;
+                               ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_type);
+                               image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+                       }
                }
-               else if(tex->imaflag & TEX_ANTIALI) IMB_antialias(ima->ibuf);
        }
-       
-       if(ima->ibuf)
-               ima->lastused = clock() / CLOCKS_PER_SEC;
-       else
-               ima->ok= 0;
-       
-       for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
-               if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
-               ima->mipmap[a]= 0;
+       else if(ima->source == IMA_SRC_VIEWER) {
+               if(ima->type==IMA_TYPE_R_RESULT) {
+                       /* always verify entirely */
+                       ibuf= image_get_render_result(ima, iuser);
+               }
+               else if(ima->type==IMA_TYPE_COMPOSITE) {
+                       int frame= iuser?iuser->framenr:0;
+                       
+                       /* Composite Viewer, all handled in compositor */
+                       ibuf= image_get_ibuf(ima, 0, frame);
+                       if(ibuf==NULL) {
+                               /* fake ibuf, will be filled in compositor */
+                               ibuf= IMB_allocImBuf(256, 256, 32, 0, 0);
+                               image_assign_ibuf(ima, ibuf, 0, frame);
+                       }
+               }
        }
 
+       if(G.rendering==0)
+               tag_image_time(ima);
+
+       BLI_unlock_thread(LOCK_CUSTOM1);
+
+       return ibuf;
 }
 
 
+void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
+{
+       int imanr, len;
+       
+       /* here (+fie_ima/2-1) makes sure that division happens correctly */
+       len= (iuser->fie_ima*iuser->frames)/2;
+       
+       if(len==0) {
+               iuser->framenr= 0;
+       }
+       else {
+               cfra= cfra - iuser->sfra+1;
+               
+               /* cyclic */
+               if(iuser->cycl) {
+                       cfra= ( (cfra) % len );
+                       if(cfra < 0) cfra+= len;
+                       if(cfra==0) cfra= len;
+               }
+               
+               if(cfra<1) cfra= 1;
+               else if(cfra>len) cfra= len;
+               
+               /* convert current frame to current field */
+               cfra= 2*(cfra);
+               if(fieldnr) cfra++;
+               
+               /* transform to images space */
+               imanr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
+               if(imanr>iuser->frames) imanr= iuser->frames;
+               imanr+= iuser->offset;
+               
+               if(iuser->cycl) {
+                       imanr= ( (imanr) % len );
+                       while(imanr < 0) imanr+= len;
+                       if(imanr==0) imanr= len;
+               }
+       
+               /* allows image users to handle redraws */
+               if(iuser->flag & IMA_ANIM_ALWAYS)
+                       if(imanr!=iuser->framenr)
+                               iuser->flag |= IMA_ANIM_REFRESHED;
+               
+               iuser->framenr= imanr;
+               if(iuser->ok==0) iuser->ok= 1;
+       }
+}
 
index b5680f989401176fc3c92572f36849248cb0ad0b..ba19ba5d8b2b0bea7f62a1807a93e4abb141b90d 100644 (file)
@@ -569,7 +569,9 @@ static void get_flags_for_id(ID *id, char *buf)
                sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
 }
 
-static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr)
+#define IDPUP_NO_VIEWER 1
+
+static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag)
 {
        int i, nids= BLI_countlist(lb);
                
@@ -588,6 +590,10 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor
 
                        if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.')
                                continue;
+                       if (hideflag & IDPUP_NO_VIEWER)
+                               if (GS(id->name)==ID_IM)
+                                       if ( ((Image *)id)->source==IMA_SRC_VIEWER )
+                                               continue;
                        
                        get_flags_for_id(id, buf);
                                
@@ -681,12 +687,35 @@ void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb,
                        BLI_dynstr_append(pupds, "|");
        }
 
-       IDnames_to_dyn_pupstring(pupds, lb, link, nr);
+       IDnames_to_dyn_pupstring(pupds, lb, link, nr, 0);
        
        *str= BLI_dynstr_get_cstring(pupds);
        BLI_dynstr_free(pupds);
 }
 
+/* skips viewer images */
+void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
+{
+       DynStr *pupds= BLI_dynstr_new();
+       
+       if (title) {
+               BLI_dynstr_append(pupds, title);
+               BLI_dynstr_append(pupds, "%t|");
+       }
+       
+       if (extraops) {
+               BLI_dynstr_append(pupds, extraops);
+               if (BLI_dynstr_get_len(pupds))
+                       BLI_dynstr_append(pupds, "|");
+       }
+       
+       IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER);
+       
+       *str= BLI_dynstr_get_cstring(pupds);
+       BLI_dynstr_free(pupds);
+}
+
+
 // only used by headerbuttons.c
 void IPOnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr, int blocktype)
 {
index bb6439d09fbe0125c40efd6c17dc2427756bfae5..d10ff6c6d33a78750286e60cd0b8b4e069407d6d 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 
 #include "DNA_ID.h"
+#include "DNA_image_types.h"
 #include "DNA_node_types.h"
 #include "DNA_material_types.h"
 #include "DNA_scene_types.h"
@@ -641,7 +642,7 @@ static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **n
 {
        bNode *node;
        bNodeSocket *tsock;
-       int index;
+       int index= 0;
        
        for(node= ntree->nodes.first; node; node= node->next) {
                for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
@@ -807,6 +808,13 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
                        nbd->samples= 32;
                        nbd->fac= 1.0f;
                }
+               else if(ELEM3(type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+                       ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
+                       node->storage= iuser;
+                       iuser->sfra= 1;
+                       iuser->fie_ima= 2;
+                       iuser->ok= 1;
+               }
                else if(type==CMP_NODE_HUE_SAT) {
                        NodeHueSat *nhs= MEM_callocN(sizeof(NodeHueSat), "node hue sat");
                        node->storage= nhs;
@@ -1488,10 +1496,10 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
                                free_compbuf(sock->ns.data);
                                sock->ns.data= NULL;
                                
-                               if(node->preview && node->preview->rect) {
-                                       MEM_freeN(node->preview->rect);
-                                       node->preview->rect= NULL;
-                               }
+                               //if(node->preview && node->preview->rect) {
+                               //      MEM_freeN(node->preview->rect);
+                               //      node->preview->rect= NULL;
+                               //}
                                        
                        }
                }
@@ -1967,6 +1975,14 @@ static void *exec_composite_node(void *node_v)
        return 0;
 }
 
+/* should become a type? these are nodes without input, only giving values */
+static int node_only_value(bNode *node)
+{
+       if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
+               return 1;
+       return 0;
+}
+
 /* return total of executable nodes, for timecursor */
 /* only compositor uses it */
 static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
@@ -1991,10 +2007,13 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                node_get_stack(node, thd->stack, nsin, nsout);
                
                /* test the outputs */
-               for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
-                       if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
-                               node->need_exec= 1;
-                               break;
+               /* skip value-only nodes (should be in type!) */
+               if(!node_only_value(node)) {
+                       for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+                               if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
+                                       node->need_exec= 1;
+                                       break;
+                               }
                        }
                }
                
@@ -2008,7 +2027,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                                bNodeLink *link= sock->link;
                                /* this is the test for a cyclic case */
                                if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
-                                       if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
+                                       if(sock->link->fromnode->need_exec) {
                                                node->need_exec= 1;
                                                break;
                                        }
@@ -2030,15 +2049,31 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                                }
                        }
                        totnode++;
-                       // printf("node needs exec %s\n", node->name);
+                       /* printf("node needs exec %s\n", node->name); */
                        
                        /* tag for getExecutableNode() */
                        node->exec= 0;
                }
-               else
+               else {
                        /* tag for getExecutableNode() */
                        node->exec= NODE_READY|NODE_FINISHED;
+                       
+               }
        }
+       
+       /* last step: set the stack values for only-value nodes */
+       /* just does all now, compared to a full buffer exec this is nothing */
+       if(totnode) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(node->need_exec==0 && node_only_value(node)) {
+                               if(node->typeinfo->execfunc) {
+                                       node_get_stack(node, thd->stack, nsin, nsout);
+                                       node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
+                               }
+                       }
+               }
+       }
+       
        return totnode;
 }
 
@@ -2187,8 +2222,6 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
        
        ntreeEndExecTree(ntree);
        
-       free_unused_animimages();
-       
 }
 
 
index b35bfba6b3e6720569c4fef0ce5c4fee06802224..9030b072b9d81dff2a1084e9490f8167e548c22f 100644 (file)
@@ -600,10 +600,27 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
        /* stack order input sockets: col, alpha, z */
        
        if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
+               RenderData *rd= data;
                Image *ima= (Image *)node->id;
+               ImBuf *ibuf;
                CompBuf *cbuf, *tbuf;
                int rectx, recty;
+               
+               BKE_image_user_calc_imanr(node->storage, rd->cfra, 0);
 
+               /* always returns for viewer image, but we check nevertheless */
+               ibuf= BKE_image_get_ibuf(ima, node->storage);
+               if(ibuf==NULL) {
+                       printf("node_composit_exec_viewer error\n");
+                       return;
+               }
+               
+               /* free all in ibuf */
+               imb_freerectImBuf(ibuf);
+               imb_freerectfloatImBuf(ibuf);
+               IMB_freezbuffloatImBuf(ibuf);
+               
+               /* get size */
                tbuf= in[0]->data?in[0]->data:(in[1]->data?in[1]->data:in[2]->data);
                if(tbuf==NULL) {
                        rectx= 320; recty= 256;
@@ -613,31 +630,16 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
                        recty= tbuf->y;
                }
                
-               if(ima->ibuf==NULL)
-                       ima->ibuf= IMB_allocImBuf(rectx, recty, 32, 0, 0);
-               
-               /* cleanup of composit image */
-               if(ima->ibuf->rect) {
-                       MEM_freeN(ima->ibuf->rect);
-                       ima->ibuf->rect= NULL;
-                       ima->ibuf->mall &= ~IB_rect;
-               }
-               if(ima->ibuf->zbuf_float) {
-                       MEM_freeN(ima->ibuf->zbuf_float);
-                       ima->ibuf->zbuf_float= NULL;
-                       ima->ibuf->mall &= ~IB_zbuffloat;
-               }
-               if(ima->ibuf->rect_float)
-                       MEM_freeN(ima->ibuf->rect_float);
-               
-               ima->ibuf->x= rectx;
-               ima->ibuf->y= recty;
-               ima->ibuf->mall |= IB_rectfloat;
-               ima->ibuf->rect_float= MEM_mallocN(4*rectx*recty*sizeof(float), "viewer rect");
+               /* make ibuf, and connect to ima */
+               ibuf->x= rectx;
+               ibuf->y= recty;
+               imb_addrectfloatImBuf(ibuf);
                
+               ima->ok= IMA_OK_LOADED;
+
                /* now we combine the input with ibuf */
                cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0);  /* no alloc*/
-               cbuf->rect= ima->ibuf->rect_float;
+               cbuf->rect= ibuf->rect_float;
                
                /* when no alpha, we can simply copy */
                if(in[1]->data==NULL) {
@@ -646,10 +648,11 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
                else
                        composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
                
+               /* zbuf option */
                if(in[2]->data) {
                        CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 1);
-                       ima->ibuf->zbuf_float= zbuf->rect;
-                       ima->ibuf->mall |= IB_zbuffloat;
+                       ibuf->zbuf_float= zbuf->rect;
+                       ibuf->mall |= IB_zbuffloat;
                        
                        composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL);
                        
@@ -674,7 +677,7 @@ static bNodeType cmp_node_viewer= {
        /* class+opts  */       NODE_CLASS_OUTPUT, NODE_PREVIEW,
        /* input sock  */       cmp_node_viewer_in,
        /* output sock */       NULL,
-       /* storage     */       "",
+       /* storage     */       "ImageUser",
        /* execfunc    */       node_composit_exec_viewer
        
 };
@@ -706,37 +709,38 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack *
        
        if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
                Image *ima= (Image *)node->id;
+               RenderData *rd= data;
+               ImBuf *ibuf;
                CompBuf *cbuf, *buf1, *buf2, *mask;
                int x, y;
                
                buf1= typecheck_compbuf(in[0]->data, CB_RGBA);
                buf2= typecheck_compbuf(in[1]->data, CB_RGBA);
                
-               if(ima->ibuf==NULL)
-                       ima->ibuf= IMB_allocImBuf(buf1->x, buf1->y, 32, 0, 0);
+               BKE_image_user_calc_imanr(node->storage, rd->cfra, 0);
                
-               /* cleanup of viewer image */
-               if(ima->ibuf->rect) {
-                       MEM_freeN(ima->ibuf->rect);
-                       ima->ibuf->rect= NULL;
-                       ima->ibuf->mall &= ~IB_rect;
-               }
-               if(ima->ibuf->zbuf_float) {
-                       MEM_freeN(ima->ibuf->zbuf_float);
-                       ima->ibuf->zbuf_float= NULL;
-                       ima->ibuf->mall &= ~IB_zbuffloat;
+               /* always returns for viewer image, but we check nevertheless */
+               ibuf= BKE_image_get_ibuf(ima, node->storage);
+               if(ibuf==NULL) {
+                       printf("node_composit_exec_viewer error\n");
+                       return;
                }
-               if(ima->ibuf->rect_float)
-                       MEM_freeN(ima->ibuf->rect_float);
                
-               ima->ibuf->x= buf1->x;
-               ima->ibuf->y= buf1->y;
-               ima->ibuf->mall |= IB_rectfloat;
-               ima->ibuf->rect_float= MEM_mallocN(4*buf1->x*buf1->y*sizeof(float), "viewer rect");
+               /* free all in ibuf */
+               imb_freerectImBuf(ibuf);
+               imb_freerectfloatImBuf(ibuf);
+               IMB_freezbuffloatImBuf(ibuf);
+               
+               /* make ibuf, and connect to ima */
+               ibuf->x= buf1->x;
+               ibuf->y= buf1->y;
+               imb_addrectfloatImBuf(ibuf);
                
+               ima->ok= IMA_OK_LOADED;
+
                /* output buf */
                cbuf= alloc_compbuf(buf1->x, buf1->y, CB_RGBA, 0);      /* no alloc*/
-               cbuf->rect= ima->ibuf->rect_float;
+               cbuf->rect= ibuf->rect_float;
                
                /* mask buf */
                mask= alloc_compbuf(buf1->x, buf1->y, CB_VAL, 1);
@@ -766,7 +770,7 @@ static bNodeType cmp_node_splitviewer= {
        /* class+opts  */       NODE_CLASS_OUTPUT, NODE_PREVIEW,
        /* input sock  */       cmp_node_splitviewer_in,
        /* output sock */       NULL,
-       /* storage     */       "",
+       /* storage     */       "ImageUser",
        /* execfunc    */       node_composit_exec_splitviewer
        
 };
@@ -818,6 +822,8 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
                                outbuf->malloc= 0;
                                free_compbuf(outbuf);
                                
+                               /* signal for imageviewer to refresh (it converts to byte rects...) */
+                               BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
                                return;
                        }
                }
@@ -900,140 +906,69 @@ static bNodeType cmp_node_output_file= {
        
 };
 
-/* **************** IMAGE ******************** */
-static bNodeSocketType cmp_node_image_out[]= {
+/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
+
+/* output socket defines */
+#define RRES_OUT_IMAGE 0
+#define RRES_OUT_ALPHA 1
+#define RRES_OUT_Z             2
+#define RRES_OUT_NORMAL        3
+#define RRES_OUT_UV            4
+#define RRES_OUT_VEC   5
+#define RRES_OUT_RGBA  6
+#define RRES_OUT_DIFF  7
+#define RRES_OUT_SPEC  8
+#define RRES_OUT_SHADOW        9
+#define RRES_OUT_AO            10
+#define RRES_OUT_REFLECT 11
+#define RRES_OUT_REFRACT 12
+#define RRES_OUT_RADIO  13
+#define RRES_OUT_INDEXOB 14
+
+static bNodeSocketType cmp_node_rlayers_out[]= {
        {       SOCK_RGBA, 0, "Image",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 0, "Alpha",         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 0, "Z",                     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, "Normal",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, "UV",           1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, "Speed",        1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Color",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Diffuse",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Specular",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Shadow",         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "AO",                     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Reflect",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Refract",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA, 0, "Radio",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VALUE, 0, "IndexOB",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       -1, 0, ""       }
 };
 
-static int calcimanr(int cfra, NodeImageAnim *nia)
-{
-       
-       if(nia->frames==0) return nia->nr;
-       
-       cfra= cfra - nia->sfra;
-       
-       /* cyclic */
-       if(nia->cyclic)
-               cfra= (cfra % nia->frames);
-       else if(cfra>=nia->frames)
-               cfra= nia->frames-1;
-       else if(cfra<0)
-               cfra= 0;
-       
-       cfra+= nia->nr;
-       
-       if(cfra<1) cfra= 1;
-       
-       return cfra;
-}
-
 
-static void animated_image(bNode *node, int cfra)
+/* note: this function is used for multilayer too, to ensure uniform 
+   handling with BKE_image_get_ibuf() */
+static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
 {
-       Image *ima;
-       NodeImageAnim *nia;
-       int imanr;
-       
-       ima= (Image *)node->id;
-       nia= node->storage;
-       
-       if(nia && nia->frames && ima && ima->name) {    /* frames anim or movie */
-               
-               imanr= calcimanr(cfra, nia);
-               
-               if(nia->movie) {
-                       char str[FILE_MAXDIR+FILE_MAXFILE];
-                       
-                       strcpy(str, ima->name);
-                       if(ima->id.lib)
-                               BLI_convertstringcode(str, ima->id.lib->filename, cfra);
-                       else
-                               BLI_convertstringcode(str, G.sce, cfra);
-                       
-                       if(ima->anim==NULL) 
-                               ima->anim = openanim(str, IB_cmap | IB_rect);
-                       
-                       if (ima->anim) {
-                               int dur = IMB_anim_get_duration(ima->anim);
-                               
-                               if(imanr < 0) imanr = 0;
-                               if(imanr > (dur-1)) imanr= dur-1;
-                               
-                               BLI_lock_thread(LOCK_CUSTOM1);
-                               if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
-                               ima->ibuf = IMB_anim_absolute(ima->anim, imanr);
-                               BLI_unlock_thread(LOCK_CUSTOM1);
-                               
-                               /* patch for textbutton with name ima (B_NAMEIMA) */
-                               if(ima->ibuf) {
-                                       strcpy(ima->ibuf->name, ima->name);
-                                       ima->ok= 1;
-                               }
-                       }
-               }
-               else {
-                       
-                       if(imanr!=ima->lastframe) {
-                               unsigned short numlen;
-                               char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE];
-                               
-                               strcpy(name, ima->name);
-                               
-                               ima->lastframe= imanr;
-                               
-                               BLI_stringdec(name, head, tail, &numlen);
-                               BLI_stringenc(name, head, tail, numlen, imanr);
-                               
-                               ima= add_image(name);
-                               
-                               if(ima) {
-                                       ima->flag |= IMA_FROMANIM;
-                                       if(node->id) node->id->us--;
-                                       node->id= (ID *)ima;
-                                       
-                                       ima->ok= 1;
-                               }
-                       }
-               }
-       }
-}
-
-static CompBuf *node_composit_get_image(bNode *node, RenderData *rd)
-{
-       Image *ima;
+       ImBuf *ibuf;
        CompBuf *stackbuf;
+       int type;
        
-       /* animated image? */
-       if(node->storage)
-               animated_image(node, rd->cfra);
+       ibuf= BKE_image_get_ibuf(ima, iuser);
+       if(ibuf==NULL)
+               return NULL;
        
-       ima= (Image *)node->id;
+       if(ibuf->rect_float==NULL)
+               IMB_float_from_rect(ibuf);
        
-       /* test if image is OK */
-       if(ima->ok==0) return NULL;
-       
-       if(ima->ibuf==NULL) {
-               BLI_lock_thread(LOCK_CUSTOM1);
-               load_image(ima, IB_rect, G.sce, rd->cfra);      /* G.sce is current .blend path */
-               BLI_unlock_thread(LOCK_CUSTOM1);
-               if(ima->ibuf==NULL) {
-                       ima->ok= 0;
-                       return NULL;
-               }
-       }
-       if(ima->ibuf->rect_float==NULL)
-               IMB_float_from_rect(ima->ibuf);
+       type= ibuf->channels;
        
        if(rd->scemode & R_COMP_CROP) {
-               stackbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->rect_float, ima->ibuf->x, ima->ibuf->y, CB_RGBA);
+               stackbuf= get_cropped_compbuf(&rd->disprect, ibuf->rect_float, ibuf->x, ibuf->y, type);
        }
        else {
                /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
-               stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0);
-               stackbuf->rect= ima->ibuf->rect_float;
+               stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, 0);
+               stackbuf->rect= ibuf->rect_float;
        }
        
        return stackbuf;
@@ -1041,39 +976,119 @@ static CompBuf *node_composit_get_image(bNode *node, RenderData *rd)
 
 static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
 {
-       Image *ima= (Image *)node->id;
+       ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
        CompBuf *zbuf= NULL;
        
-       if(ima->ibuf && ima->ibuf->zbuf_float) {
+       if(ibuf && ibuf->zbuf_float) {
                if(rd->scemode & R_COMP_CROP) {
-                       zbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->zbuf_float, ima->ibuf->x, ima->ibuf->y, CB_VAL);
+                       zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
                }
                else {
-                       zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0);
-                       zbuf->rect= ima->ibuf->zbuf_float;
+                       zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
+                       zbuf->rect= ibuf->zbuf_float;
                }
        }
        return zbuf;
 }
 
+/* check if layer is available, returns pass buffer */
+static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passtype)
+{
+       RenderPass *rpass;
+       short index;
+       
+       for(index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++)
+               if(rpass->passtype==passtype)
+                       break;
+       
+       if(rpass) {
+               CompBuf *cbuf;
+               
+               iuser->pass= index;
+               BKE_image_multilayer_index(ima->rr, iuser);
+               cbuf= node_composit_get_image(rd, ima, iuser);
+               
+               return cbuf;
+       }
+       return NULL;
+}
+
+void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser)
+{
+       if(out[RRES_OUT_Z]->hasoutput)
+               out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z);
+       if(out[RRES_OUT_VEC]->hasoutput)
+               out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR);
+       if(out[RRES_OUT_NORMAL]->hasoutput)
+               out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL);
+       if(out[RRES_OUT_UV]->hasoutput)
+               out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV);
+       
+       if(out[RRES_OUT_RGBA]->hasoutput)
+               out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA);
+       if(out[RRES_OUT_DIFF]->hasoutput)
+               out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE);
+       if(out[RRES_OUT_SPEC]->hasoutput)
+               out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC);
+       if(out[RRES_OUT_SHADOW]->hasoutput)
+               out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW);
+       if(out[RRES_OUT_AO]->hasoutput)
+               out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO);
+       if(out[RRES_OUT_REFLECT]->hasoutput)
+               out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT);
+       if(out[RRES_OUT_REFRACT]->hasoutput)
+               out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT);
+       if(out[RRES_OUT_RADIO]->hasoutput)
+               out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO);
+       if(out[RRES_OUT_INDEXOB]->hasoutput)
+               out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB);
+       
+}
+
+
 static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
        
        /* image assigned to output */
        /* stack order input sockets: col, alpha */
        if(node->id) {
-               CompBuf *stackbuf= node_composit_get_image(node, data);
+               RenderData *rd= data;
+               Image *ima= (Image *)node->id;
+               ImageUser *iuser= (ImageUser *)node->storage;
+               CompBuf *stackbuf= NULL;
                
-               /* put ibuf on stack */ 
-               out[0]->data= stackbuf;
+               /* first set the right frame number in iuser */
+               BKE_image_user_calc_imanr(iuser, rd->cfra, 0);
+               
+               /* force a load, we assume iuser index will be set OK anyway */
+               if(ima->type==IMA_TYPE_MULTILAYER)
+                       BKE_image_get_ibuf(ima, iuser);
                
+               if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
+                       RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+                       
+                       if(rl) {
+                               out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED);
+                               
+                               /* go over all layers */
+                               outputs_multilayer_get(rd, rl, out, ima, iuser);
+                       }
+               }
+               else {
+                       stackbuf= node_composit_get_image(rd, ima, iuser);
+
+                       /* put image on stack */        
+                       out[0]->data= stackbuf;
+                       
+                       if(out[2]->hasoutput)
+                               out[2]->data= node_composit_get_zimage(node, rd);
+               }
+               
+               /* alpha and preview for both types */
                if(stackbuf) {
                        if(out[1]->hasoutput)
                                out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-                       
-                       if(out[2]->hasoutput)
-                               out[2]->data= node_composit_get_zimage(node, data);
-                       
+
                        generate_preview(node, stackbuf);
                }
        }       
@@ -1087,51 +1102,14 @@ static bNodeType cmp_node_image= {
        /* width+range */       120, 80, 300,
        /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
        /* input sock  */       NULL,
-       /* output sock */       cmp_node_image_out,
-       /* storage     */       "NodeImageAnim",
+       /* output sock */       cmp_node_rlayers_out,
+       /* storage     */       "ImageUser",
        /* execfunc    */       node_composit_exec_image
        
 };
 
 /* **************** RENDER RESULT ******************** */
 
-/* output socket defines */
-#define RRES_OUT_IMAGE 0
-#define RRES_OUT_ALPHA 1
-#define RRES_OUT_Z             2
-#define RRES_OUT_NORMAL        3
-#define RRES_OUT_UV            4
-#define RRES_OUT_VEC   5
-#define RRES_OUT_RGBA  6
-#define RRES_OUT_DIFF  7
-#define RRES_OUT_SPEC  8
-#define RRES_OUT_SHADOW        9
-#define RRES_OUT_AO            10
-#define RRES_OUT_REFLECT 11
-#define RRES_OUT_REFRACT 12
-#define RRES_OUT_RADIO  13
-#define RRES_OUT_INDEXOB 14
-
-static bNodeSocketType cmp_node_rlayers_out[]= {
-       {       SOCK_RGBA, 0, "Image",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
-       {       SOCK_VALUE, 0, "Alpha",         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VALUE, 0, "Z",                     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, "Normal",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, "UV",           1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, "Speed",        1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Color",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Diffuse",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Specular",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Shadow",         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "AO",                     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Reflect",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Refract",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, "Radio",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VALUE, 0, "IndexOB",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       -1, 0, ""       }
-};
-
-
 static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode)
 {
        float *fp= RE_RenderLayerGetPass(rl, passcode);
@@ -1143,9 +1121,9 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
                        buftype= CB_VAL;
                else if(passcode==SCE_PASS_VECTOR)
                        buftype= CB_VEC4;
-               else if(passcode==SCE_PASS_RGBA)
+               else if(ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA))
                        buftype= CB_RGBA;
-
+               
                if(rd->scemode & R_COMP_CROP)
                        buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype);
                else {
@@ -1157,6 +1135,38 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
        return NULL;
 }
 
+void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out, int rectx, int recty)
+{
+       if(out[RRES_OUT_Z]->hasoutput)
+               out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_Z);
+       if(out[RRES_OUT_VEC]->hasoutput)
+               out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_VECTOR);
+       if(out[RRES_OUT_NORMAL]->hasoutput)
+               out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_NORMAL);
+       if(out[RRES_OUT_UV]->hasoutput)
+               out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_UV);
+       
+       if(out[RRES_OUT_RGBA]->hasoutput)
+               out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RGBA);
+       if(out[RRES_OUT_DIFF]->hasoutput)
+               out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE);
+       if(out[RRES_OUT_SPEC]->hasoutput)
+               out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SPEC);
+       if(out[RRES_OUT_SHADOW]->hasoutput)
+               out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SHADOW);
+       if(out[RRES_OUT_AO]->hasoutput)
+               out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_AO);
+       if(out[RRES_OUT_REFLECT]->hasoutput)
+               out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFLECT);
+       if(out[RRES_OUT_REFRACT]->hasoutput)
+               out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFRACT);
+       if(out[RRES_OUT_RADIO]->hasoutput)
+               out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO);
+       if(out[RRES_OUT_INDEXOB]->hasoutput)
+               out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+       
+}
+
 static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
        Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
@@ -1191,33 +1201,8 @@ static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in,
                                        
                                        if(out[RRES_OUT_ALPHA]->hasoutput)
                                                out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-                                       if(out[RRES_OUT_Z]->hasoutput)
-                                               out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z);
-                                       if(out[RRES_OUT_VEC]->hasoutput)
-                                               out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_VECTOR);
-                                       if(out[RRES_OUT_NORMAL]->hasoutput)
-                                               out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_NORMAL);
-                                       if(out[RRES_OUT_UV]->hasoutput)
-                                               out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_UV);
-
-                                       if(out[RRES_OUT_RGBA]->hasoutput)
-                                               out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RGBA);
-                                       if(out[RRES_OUT_DIFF]->hasoutput)
-                                               out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE);
-                                       if(out[RRES_OUT_SPEC]->hasoutput)
-                                               out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SPEC);
-                                       if(out[RRES_OUT_SHADOW]->hasoutput)
-                                               out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SHADOW);
-                                       if(out[RRES_OUT_AO]->hasoutput)
-                                               out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_AO);
-                                       if(out[RRES_OUT_REFLECT]->hasoutput)
-                                               out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_REFLECT);
-                                       if(out[RRES_OUT_REFRACT]->hasoutput)
-                                               out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_REFRACT);
-                                       if(out[RRES_OUT_RADIO]->hasoutput)
-                                               out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RADIO);
-                                       if(out[RRES_OUT_INDEXOB]->hasoutput)
-                                               out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_INDEXOB);
+                                       
+                                       node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);
 
                                        generate_preview(node, stackbuf);
                                }
@@ -3415,10 +3400,6 @@ static void node_composit_exec_dilateerode(void *data, bNode *node, bNodeStack *
                CompBuf *stackbuf= dupalloc_compbuf(cbuf);
                short i;
                
-               /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
-               stackbuf->xof= cbuf->xof;
-               stackbuf->yof= cbuf->yof;
-
                if (node->custom2 > 0) { // positive, dilate
                        for (i = 0; i < node->custom2; i++)
                                morpho_dilate(stackbuf);
@@ -3427,6 +3408,9 @@ static void node_composit_exec_dilateerode(void *data, bNode *node, bNodeStack *
                                morpho_erode(stackbuf);
                }
                
+               if(cbuf!=in[0]->data)
+                       free_compbuf(cbuf);
+               
                out[0]->data= stackbuf;
        }
 }
@@ -4673,6 +4657,43 @@ bNodeType *node_all_composit[]= {
 
 /* ******************* parse ************ */
 
+/* clumsy checking... should do dynamic outputs once */
+static void force_hidden_passes(bNode *node, int passflag)
+{
+       bNodeSocket *sock;
+       
+       for(sock= node->outputs.first; sock; sock= sock->next)
+               sock->flag &= ~SOCK_UNAVAIL;
+       
+       sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
+       if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
+       if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
+       if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
+       if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
+       if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
+       if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
+       if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
+       if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
+       if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
+       if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
+       if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
+       if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
+       sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
+       if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
+                               
+}
+
 /* based on rules, force sockets hidden always */
 void ntreeCompositForceHidden(bNodeTree *ntree)
 {
@@ -4684,38 +4705,26 @@ void ntreeCompositForceHidden(bNodeTree *ntree)
                if( node->type==CMP_NODE_R_LAYERS) {
                        Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
                        SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
-                       if(srl) {
-                               bNodeSocket *sock;
-                               for(sock= node->outputs.first; sock; sock= sock->next)
-                                       sock->flag &= ~SOCK_UNAVAIL;
-                               
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
-                               if(!(srl->passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
-                               if(!(srl->passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
-                               if(!(srl->passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
-                               if(!(srl->passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
-                               if(!(srl->passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
-                               if(!(srl->passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
-                               if(!(srl->passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
-                               if(!(srl->passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
-                               if(!(srl->passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
-                               if(!(srl->passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
-                               if(!(srl->passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
-                               if(!(srl->passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
-                               sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
-                               if(!(srl->passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
+                       if(srl)
+                               force_hidden_passes(node, srl->passflag);
+               }
+               else if( node->type==CMP_NODE_IMAGE) {
+                       Image *ima= (Image *)node->id;
+                       if(ima) {
+                               if(ima->rr) {
+                                       ImageUser *iuser= node->storage;
+                                       RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
+                                       if(rl)
+                                               force_hidden_passes(node, rl->passflag);
+                                       else
+                                               force_hidden_passes(node, 0);
+                               }
+                               else if(ima->type!=IMA_TYPE_MULTILAYER) {       /* if ->rr not yet read we keep inputs */
+                                       force_hidden_passes(node, 0);
+                               }
                        }
+                       else
+                               force_hidden_passes(node, 0);
                }
        }
        
@@ -4743,8 +4752,8 @@ void ntreeCompositTagAnimated(bNodeTree *ntree)
        
        for(node= ntree->nodes.first; node; node= node->next) {
                if(node->type==CMP_NODE_IMAGE) {
-                       /* no actual test yet... */
-                       if(node->storage)
+                       Image *ima= (Image *)node->id;
+                       if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
                                NodeTagChanged(ntree, node);
                }
                else if(node->type==CMP_NODE_TIME)
index 49ad8d2ac67e74c2ebe70967750ab51b1fb084a8..0cdfda3be5dc350b0b9e423ece928aef6c1e1f0b 100644 (file)
@@ -402,7 +402,7 @@ there was an error or when the user desides to cancel the operation.
 
 */
 
-char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
+char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 {
        char menu[6 * (FILE_MAXDIR + FILE_MAXFILE + 100)];
        char line[FILE_MAXDIR + FILE_MAXFILE + 100];
@@ -413,7 +413,7 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
        
        if (pf != NULL) {
                if (how == PF_ASK) {
-                       strcpy(menu, "UnPack file%t");
+                       sprintf(menu, "UnPack file%%t|Remove Pack %%x%d", PF_REMOVE);
                        
                        if (strcmp(abs_name, local_name)) {
                                switch (checkPackedFile(local_name, pf)) {
@@ -460,6 +460,9 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
                        case -1:
                        case PF_KEEP:
                                break;
+                       case PF_REMOVE:
+                               temp= abs_name;
+                               break;
                        case PF_USE_LOCAL:
                                // if file exists use it
                                if (BLI_exists(local_name)) {
@@ -596,10 +599,10 @@ int unpackImage(Image * ima, int how)
                if (newname != NULL) {
                        ret_value = RET_OK;
                        freePackedFile(ima->packedfile);
-                       ima->packedfile = 0;
+                       ima->packedfile = NULL;
                        strcpy(ima->name, newname);
                        MEM_freeN(newname);
-                       free_image_buffers(ima);
+                       BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
                }
        }
        
index c656f5cdeb669c5fe3edaf43bbd960e7e61a8f3f..40488cf8644ccfcdebb65b9a0263e32652d2af8e 100644 (file)
@@ -68,6 +68,7 @@
 #include "BKE_global.h"
 #include "BKE_group.h"
 #include "BKE_ipo.h"
+#include "BKE_image.h"
 #include "BKE_key.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
index 62ac911bea7fc70d8c4ac98cbcb4f309df9db7b5..341397cba1b8eef090e9f527546e82b37b2905b1 100644 (file)
@@ -455,13 +455,17 @@ void default_tex(Tex *tex)
 
        pit = tex->plugin;
        if (pit) {
-                       varstr= pit->varstr;
-                       if(varstr) {
-                                       for(a=0; a<pit->vars; a++, varstr++) {
-                                               pit->data[a] = varstr->def;
-                                       }
+               varstr= pit->varstr;
+               if(varstr) {
+                       for(a=0; a<pit->vars; a++, varstr++) {
+                               pit->data[a] = varstr->def;
                        }
+               }
        }
+       
+       tex->iuser.fie_ima= 2;
+       tex->iuser.ok= 1;
+       tex->iuser.frames= 100;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -776,7 +780,7 @@ EnvMap *BKE_copy_envmap(EnvMap *env)
        
        envn= MEM_dupallocN(env);
        envn->ok= 0;
-       for(a=0; a<6; a++) envn->cube[a]= 0;
+       for(a=0; a<6; a++) envn->cube[a]= NULL;
        if(envn->ima) id_us_plus((ID *)envn->ima);
        
        return envn;
@@ -786,20 +790,12 @@ EnvMap *BKE_copy_envmap(EnvMap *env)
 
 void BKE_free_envmapdata(EnvMap *env)
 {
-       Image *ima;
-       unsigned int a, part;
+       unsigned int part;
        
        for(part=0; part<6; part++) {
-               ima= env->cube[part];
-               if(ima) {
-                       if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
-                       
-                       for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
-                               if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
-                       }
-                       MEM_freeN(ima);
-                       env->cube[part]= 0;
-               }
+               if(env->cube[part])
+                       IMB_freeImBuf(env->cube[part]);
+               env->cube[part]= NULL;
        }
        env->ok= 0;
 }
index 1a35cad3a0312b9c3a933b1f934529c7226ff86f..58bd3fd6bf648fa0f87ae6c969e85f0c9041acb3 100644 (file)
@@ -96,7 +96,7 @@ void BLI_make_file_string(const char *relabase, char *string,  const char *dir,
 void BLI_make_exist(char *dir);
 void BLI_make_existing_file(char *name);
 void BLI_split_dirfile(const char *string, char *dir, char *file);
-int BLI_testextensie(char *str, char *ext);
+int BLI_testextensie(const char *str, const char *ext);
 void addlisttolist(ListBase *list1, ListBase *list2);
 void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
 void * BLI_findlink(struct ListBase *listbase, int number);
@@ -193,7 +193,7 @@ char* BLI_strdupn(char *str, int len);
         *   the size of dst)
         * @retval Returns dst
         */
-char* BLI_strncpy(char *dst, char *src, int maxncpy);
+char* BLI_strncpy(char *dst, const char *src, int maxncpy);
 
        /**
         * Compare two strings
index fbbc42115d5deba7a69c4ca11faaea4f1c68b0ba..e52c573eec729e3599b11a8477f72cb412c6c47e 100644 (file)
@@ -81,7 +81,14 @@ void BLI_gsqueue_pop(GSQueue *gq, void *item_r)
 }
 void BLI_gsqueue_push(GSQueue *gq, void *item)
 {
-       GSQueueElem *elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push");
+       GSQueueElem *elem;
+       
+       /* compare: prevent events added double in row */
+       if (!BLI_gsqueue_is_empty(gq)) {
+               if(0==memcmp(item, &gq->head[1], gq->elem_size))
+                       return;
+       }
+       elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push");
        memcpy(&elem[1], item, gq->elem_size);
        elem->next= NULL;
        
index 9fd5b40878e718009719cf0a93c986e513c60edf..29e15068f15cae6426d9683ea135a78e64ca867c 100644 (file)
@@ -638,7 +638,7 @@ char *BLI_strdup(char *str) {
        return BLI_strdupn(str, strlen(str));
 }
 
-char *BLI_strncpy(char *dst, char *src, int maxncpy) {
+char *BLI_strncpy(char *dst, const char *src, int maxncpy) {
        int srclen= strlen(src);
        int cpylen= (srclen>(maxncpy-1))?(maxncpy-1):srclen;
        
@@ -1117,7 +1117,7 @@ void BLI_make_file_string(const char *relabase, char *string,  const char *dir,
        BLI_clean(string);
 }
 
-int BLI_testextensie(char *str, char *ext)
+int BLI_testextensie(const char *str, const char *ext)
 {
        short a, b;
        int retval;
index 342f3232d22c5bb1816451855c749a0d0e7cda9e..48eb6ae8e55e59dea79cacccbce5420c75b540b8 100644 (file)
 #include "BKE_effect.h" // for give_parteff
 #include "BKE_global.h" // for G
 #include "BKE_group.h"
-#include "BKE_property.h" // for get_property
+#include "BKE_image.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h" // for wich_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_modifier.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
+#include "BKE_property.h" // for get_property
 #include "BKE_sca.h" // for init_actuator
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
@@ -1108,8 +1109,9 @@ void blo_make_image_pointer_map(FileData *fd)
        fd->imamap= oldnewmap_new();
        
        for(;ima; ima= ima->id.next) {
-               if(ima->ibuf)
-                       oldnewmap_insert(fd->imamap, ima->ibuf, ima->ibuf, 0);
+               Link *ibuf= ima->ibufs.first;
+               for(; ibuf; ibuf= ibuf->next) 
+                       oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1136,11 +1138,15 @@ void blo_end_image_pointer_map(FileData *fd)
        }
        
        for(;ima; ima= ima->id.next) {
-               if(ima->ibuf) {
-                       ima->ibuf= newimaadr(fd, ima->ibuf);
-                       /* this mirrors direct_link_image */
-                       if(ima->ibuf==NULL)
+               Link *ibuf, *next;
+               
+               /* this mirrors direct_link_image */
+               for(ibuf= ima->ibufs.first; ibuf; ibuf= next) {
+                       next= ibuf->next;
+                       if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
+                               BLI_remlink(&ima->ibufs, ibuf);
                                ima->bindcode= 0;
+                       }
                }
        }
        for(; sce; sce= sce->id.next) {
@@ -1213,11 +1219,11 @@ static void link_list(FileData *fd, ListBase *lb)               /* only direct data */
 {
        Link *ln, *prev;
 
-       if(lb->first==0) return;
+       if(lb->first==NULL) return;
 
        lb->first= newdataadr(fd, lb->first);
        ln= lb->first;
-       prev= 0;
+       prev= NULL;
        while(ln) {
                ln->next= newdataadr(fd, ln->next);
                ln->prev= prev;
@@ -1480,9 +1486,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                        /* could be handlerized at some point */
                        if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
                                direct_link_curvemapping(fd, node->storage);
-                       else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
-                               direct_link_curvemapping(fd, node->storage);
-                       
+                       else if(ntree->type==NTREE_COMPOSIT) {
+                               if( ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB))
+                                       direct_link_curvemapping(fd, node->storage);
+                               else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+                                       ((ImageUser *)node->storage)->ok= 1;
+                       }
                }
                link_list(fd, &node->inputs);
                link_list(fd, &node->outputs);
@@ -2167,16 +2176,38 @@ static void lib_link_image(FileData *fd, Main *main)
        }
 }
 
+static void link_ibuf_list(FileData *fd, ListBase *lb)
+{
+       Link *ln, *prev;
+       
+       if(lb->first==NULL) return;
+       
+       lb->first= newimaadr(fd, lb->first);
+       ln= lb->first;
+       prev= NULL;
+       while(ln) {
+               ln->next= newimaadr(fd, ln->next);
+               ln->prev= prev;
+               prev= ln;
+               ln= ln->next;
+       }
+       lb->last= prev;
+}
+
 static void direct_link_image(FileData *fd, Image *ima)
 {
        /* for undo system, pointers could be restored */
-       ima->ibuf= newimaadr(fd, ima->ibuf);
-       /* if restored, we keep the binded opengl index */
-       if(ima->ibuf==NULL)
+       if(fd->imamap)
+               link_ibuf_list(fd, &ima->ibufs);
+       else
+               ima->ibufs.first= ima->ibufs.last= NULL;
+       
+       /* if not restored, we keep the binded opengl index */
+       if(ima->ibufs.first==NULL)
                ima->bindcode= 0;
        
-       memset(ima->mipmap, 0, sizeof(ima->mipmap));
        ima->anim= NULL;
+       ima->rr= NULL;
        ima->repbind= NULL;
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
@@ -2319,10 +2350,11 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        tex->coba= newdataadr(fd, tex->coba);
        tex->env= newdataadr(fd, tex->env);
        if(tex->env) {
-               tex->env->ima= 0;
+               tex->env->ima= NULL;
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
+       tex->iuser.ok= 1;
 }
 
 
@@ -3304,10 +3336,8 @@ static void lib_link_screen_sequence_ipos(Main *main)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= main->screen.first;
-       while(sc) {
-               sa= sc->areabase.first;
-               while(sa) {
+       for(sc= main->screen.first; sc; sc= sc->id.next) {
+               for(sa= sc->areabase.first; sa; sa= sa->next) {
                        SpaceLink *sl;
                        for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                if(sl->spacetype == SPACE_IPO) {
@@ -3317,9 +3347,7 @@ static void lib_link_screen_sequence_ipos(Main *main)
                                        }
                                }
                        }
-                       sa= sa->next;
                }
-               sc= sc->id.next;
        }
 }
 
@@ -3332,8 +3360,7 @@ static void lib_link_screen(FileData *fd, Main *main)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= main->screen.first;
-       while(sc) {
+       for(sc= main->screen.first; sc; sc= sc->id.next) {
                if(sc->id.flag & LIB_NEEDLINK) {
                        sc->id.us= 1;
                        sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
@@ -3356,8 +3383,6 @@ static void lib_link_screen(FileData *fd, Main *main)
 
                                                if(v3d->bgpic) {
                                                        v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
-                                                       v3d->bgpic->tex= newlibadr_us(fd, sc->id.lib, v3d->bgpic->tex);
-                                                       v3d->bgpic->rect= NULL;
                                                }
                                                if(v3d->localvd) {
                                                        v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
@@ -3384,9 +3409,11 @@ static void lib_link_screen(FileData *fd, Main *main)
                                        else if(sl->spacetype==SPACE_FILE) {
                                                SpaceFile *sfile= (SpaceFile *)sl;
 
-                                               sfile->filelist= 0;
-                                               sfile->libfiledata= 0;
-                                               sfile->returnfunc= 0;
+                                               sfile->filelist= NULL;
+                                               sfile->libfiledata= NULL;
+                                               sfile->returnfunc= NULL;
+                                               sfile->menup= NULL;
+                                               sfile->pupmenu= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
                                                check_imasel_copy((SpaceImaSel *)sl);
@@ -3446,7 +3473,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                        }
                        sc->id.flag -= LIB_NEEDLINK;
                }
-               sc= sc->id.next;
        }
 }
 
@@ -3484,8 +3510,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
        bScreen *sc;
        ScrArea *sa;
 
-       sc= newmain->screen.first;
-       while(sc) {
+       for(sc= newmain->screen.first; sc; sc= sc->id.next) {
                
                sc->scene= curscene;
 
@@ -3514,9 +3539,6 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        
                                        if(v3d->bgpic) {
                                                v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
-                                               v3d->bgpic->tex= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->tex, 1);
-                                               if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect);
-                                               v3d->bgpic->rect= NULL;
                                        }
                                        if(v3d->localvd) {
                                                Base *base;
@@ -3624,10 +3646,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                        }
                        sa= sa->next;
                }
-
-               sc= sc->id.next;
        }
-
 }
 
 static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -3693,6 +3712,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                        if (sl->spacetype==SPACE_VIEW3D) {
                                View3D *v3d= (View3D*) sl;
                                v3d->bgpic= newdataadr(fd, v3d->bgpic);
+                               if(v3d->bgpic)
+                                       v3d->bgpic->iuser.ok= 1;
                                v3d->localvd= newdataadr(fd, v3d->localvd);
                                v3d->afterdraw.first= v3d->afterdraw.last= NULL;
                                v3d->clipbb= newdataadr(fd, v3d->clipbb);
@@ -3723,7 +3744,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                sima->cumap= newdataadr(fd, sima->cumap);
                                if(sima->cumap)
                                        direct_link_curvemapping(fd, sima->cumap);
-                               sima->info_str= NULL;
+                               sima->info_str= sima->info_spare= NULL;
+                               sima->spare= NULL;
+                               sima->iuser.ok= 1;
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
@@ -4049,10 +4072,6 @@ static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg)
        bfd->displaymode= fg->displaymode;
        bfd->globalf= fg->globalf;
        
-       bfd->main->subversionfile= fg->subversion;
-       bfd->main->minversionfile= fg->minversion;
-       bfd->main->minsubversionfile= fg->minsubversion;
-       
        bfd->curscreen= newlibadr(fd, 0, fg->curscreen);
        bfd->curscene= newlibadr(fd, 0, fg->curscene);
        // this happens in files older than 2.35
@@ -4240,6 +4259,40 @@ static void customdata_version_242(Mesh *me)
        mesh_update_customdata_pointers(me);
 }
 
+/* struct NodeImageAnim moved to ImageUser, and we make it default available */
+static void do_version_ntree_242_2(bNodeTree *ntree)
+{
+       bNode *node;
+       
+       if(ntree->type==NTREE_COMPOSIT) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+                               /* only image had storage */
+                               if(node->storage) {
+                                       NodeImageAnim *nia= node->storage;
+                                       ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "ima user node");
+
+                                       iuser->frames= nia->frames;
+                                       iuser->sfra= nia->sfra;
+                                       iuser->offset= nia->nr-1;
+                                       iuser->cycl= nia->cyclic;
+                                       iuser->fie_ima= 2;
+                                       iuser->ok= 1;
+                                       
+                                       node->storage= iuser;
+                                       MEM_freeN(nia);
+                               }
+                               else {
+                                       ImageUser *iuser= node->storage= MEM_callocN(sizeof(ImageUser), "node image user");
+                                       iuser->sfra= 1;
+                                       iuser->fie_ima= 2;
+                                       iuser->ok= 1;
+                               }
+                       }
+               }
+       }
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -4258,10 +4311,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        }
                                }
 
-                               if(tex->imaflag & TEX_ANIM5) {
-                                       tex->imaflag |= TEX_MORKPATCH;
-                                       tex->imaflag |= TEX_ANTIALI;
-                               }
                        }
                        tex= tex->id.next;
                }
@@ -6169,7 +6218,71 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                sort_shape_fix(main);
                
                /* now, subversion control! */
-               if(main->subversionfile < 1) {
+               if(main->subversionfile < 3) {
+                       bScreen *sc;
+                       Image *ima;
+                       Tex *tex;
+                       Scene *sce;
+                       bNodeTree *ntree;
+                       
+                       /* Image refactor initialize */
+                       for(ima= main->image.first; ima; ima= ima->id.next) {
+                               ima->source= IMA_SRC_FILE;
+                               ima->type= IMA_TYPE_IMAGE;
+                               
+                               ima->gen_x= 256; ima->gen_y= 256;
+                               ima->gen_type= 1;
+                               
+                               if(0==strncmp(ima->id.name+2, "Viewer Node", sizeof(ima->id.name+2))) {
+                                       ima->source= IMA_SRC_VIEWER;
+                                       ima->type= IMA_TYPE_COMPOSITE;
+                               }
+                               if(0==strncmp(ima->id.name+2, "Render Result", sizeof(ima->id.name+2))) {
+                                       ima->source= IMA_SRC_VIEWER;
+                                       ima->type= IMA_TYPE_R_RESULT;
+                               }
+                               
+                       }
+                       for(tex= main->tex.first; tex; tex= tex->id.next) {
+                               if(tex->type==TEX_IMAGE && tex->ima) {
+                                       ima= newlibadr(fd, lib, tex->ima);
+                                       if(tex->imaflag & TEX_ANIM5_)
+                                               ima->source= IMA_SRC_MOVIE;
+                                       if(tex->imaflag & TEX_FIELDS_)
+                                               ima->flag |= IMA_FIELDS;
+                                       if(tex->imaflag & TEX_STD_FIELD_)
+                                               ima->flag |= IMA_STD_FIELD;
+                                       if(tex->imaflag & TEX_ANTIALI_)
+                                               ima->flag |= IMA_ANTIALI;
+                               }
+                               tex->iuser.frames= tex->frames;
+                               tex->iuser.fie_ima= tex->fie_ima;
+                               tex->iuser.offset= tex->offset;
+                               tex->iuser.sfra= tex->sfra;
+                               tex->iuser.cycl= (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
+                       }
+                       for(sce= main->scene.first; sce; sce= sce->id.next) {
+                               if(sce->nodetree)
+                                       do_version_ntree_242_2(sce->nodetree);
+                       }
+                       for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+                               do_version_ntree_242_2(ntree);
+                       
+                       for(sc= main->screen.first; sc; sc= sc->id.next) {
+                               ScrArea *sa;
+                               for(sa= sc->areabase.first; sa; sa= sa->next) {
+                                       SpaceLink *sl;
+                                       for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                               if(sl->spacetype==SPACE_IMAGE)
+                                                       ((SpaceImage *)sl)->iuser.fie_ima= 2;
+                                               else if(sl->spacetype==SPACE_VIEW3D) {
+                                                       View3D *v3d= (View3D *)sl;
+                                                       if(v3d->bgpic)
+                                                               v3d->bgpic->iuser.fie_ima= 2;
+                                               }
+                                       }
+                               }
+                       }
                }
        }
 
@@ -6252,6 +6365,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
                case REND:
                        if (bhead->code==GLOB) {
                                fg= read_struct(fd, bhead, "Global");
+                               /* set right away */
+                               bfd->main->subversionfile= fg->subversion;
+                               bfd->main->minversionfile= fg->minversion;
+                               bfd->main->minsubversionfile= fg->minsubversion;
                        }
                        bhead = blo_nextbhead(fd, bhead);
                        break;
index 02b3557c094e62cd2f1d3eee2ec21867aac6cc92..60177f2c996422ccfcdfcd77b55d86c5caa34e22 100644 (file)
@@ -315,6 +315,7 @@ void IMB_antialias(struct ImBuf * ibuf);
 void IMB_filter(struct ImBuf *ibuf);
 void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
 void IMB_filter_extend(struct ImBuf *ibuf);
+void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
 
 /**
  *
@@ -537,6 +538,7 @@ void imb_freerectImBuf(struct ImBuf * ibuf);
 
 short imb_addrectfloatImBuf(struct ImBuf * ibuf);
 void imb_freerectfloatImBuf(struct ImBuf * ibuf);
+void imb_freemipmapImBuf(struct ImBuf * ibuf);
 
 #ifdef WITH_QUICKTIME
 /**
index 586dedc54e819fa9098c20d734675b9a8a125b6f..f5487bb9ac07dbdd6490d1c16c8922b75e320db4 100644 (file)
@@ -56,6 +56,8 @@
 struct _AviMovie;
 struct Mdec;
 
+#define IB_MIPMAP_LEVELS       10
+
 /**
  * \brief The basic imbuf type
  * \ingroup imbuf
@@ -70,36 +72,41 @@ struct Mdec;
  *
  * Also, that iff.h needs to be in the final release "plugins/include" dir, too!
  */
-typedef struct ImBuf{
-       short   x, y;                   /**< width and Height of our image buffer */
-       short   skipx;                  /**< Width in ints to get to the next scanline */
+typedef struct ImBuf {
+       struct ImBuf *next, *prev;      /**< allow lists of ImBufs, for caches or flipbooks */
+       short   x, y;                           /**< width and Height of our image buffer */
+       short   skipx;                          /**< Width in ints to get to the next scanline */
        unsigned char   depth;          /**< Active amount of bits/bitplanes */
        unsigned char   cbits;          /**< Amount of active bits in cmap */
        unsigned short  mincol;         /**< smallest color in colormap */
        unsigned short  maxcol;         /**< Largest color in colormap */
-       int     type;                   /**< 0=abgr, 1=bitplanes */
-       int     ftype;                  /**< File type we are going to save as */
+       int     type;                                   /**< 0=abgr, 1=bitplanes */
+       int     ftype;                                  /**< File type we are going to save as */
        unsigned int    *cmap;          /**< Color map data. */
        unsigned int    *rect;          /**< pixel values stored here */
        unsigned int    **planes;       /**< bitplanes */
-       int     flags;                  /**< Controls which components should exist. */
-       int     mall;                   /**< what is malloced internal, and can be freed */
+       int     flags;                          /**< Controls which components should exist. */
+       int     mall;                           /**< what is malloced internal, and can be freed */
        short   xorig, yorig;           /**< Cordinates of first pixel of an image used in some formats (example: targa) */
        char    name[1023];             /**< The file name assocated with this image */
        char    namenull;               /**< Unused don't want to remove it thought messes things up */
-       int     userflags;              /**< Used to set imbuf to Dirty and other stuff */
-       int     *zbuf;                  /**< z buffer data, original zbuffer */
-       float *zbuf_float;      /**< z buffer data, camera coordinates */
+       int     userflags;                      /**< Used to set imbuf to Dirty and other stuff */
+       int     *zbuf;                          /**< z buffer data, original zbuffer */
+       float *zbuf_float;              /**< z buffer data, camera coordinates */
        void *userdata; 
        unsigned char *encodedbuffer;     /**< Compressed image only used with png currently */
        unsigned int   encodedsize;       /**< Size of data written to encodedbuffer */
        unsigned int   encodedbuffersize; /**< Size of encodedbuffer */
 
        float *rect_float;              /**< floating point Rect equivilant */
+       int channels;                   /**< amount of channels in rect_float (0 = 4 channel default) */
        float dither;                   /**< random dither value, for conversion from float -> byte rect */
        
        struct MEM_CacheLimiterHandle_s * c_handle; /**< handle for cache limiter */
-       int refcounter;                /**< Refcounter for multiple users */
+       int refcounter;                 /**< Refcounter for multiple users */
+       int index;                              /**< reference index for ImBuf lists */
+       
+       struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /**< MipMap levels, a series of halved images */
 } ImBuf;
 
 /* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
@@ -138,8 +145,9 @@ typedef enum {
 #define IB_zbuf                        (1 << 13)
 
 #define IB_mem                 (1 << 14)
-#define IB_rectfloat           (1 << 15)
-#define IB_zbuffloat           (1 << 16)
+#define IB_rectfloat   (1 << 15)
+#define IB_zbuffloat   (1 << 16)
+#define IB_multilayer  (1 << 17)
 
 /*
  * The bit flag is stored in the ImBuf.ftype variable.
index 30e97328e7c673b194270a696094357c92f130b3..003d377389bfd43e0f591e2e297c32e2a5b12854 100644 (file)
@@ -62,6 +62,17 @@ void imb_freeplanesImBuf(struct ImBuf * ibuf)
        ibuf->mall &= ~IB_planes;
 }
 
+void imb_freemipmapImBuf(struct ImBuf * ibuf)
+{
+       int a;
+       
+       for(a=0; a<IB_MIPMAP_LEVELS; a++) {
+               if(ibuf->mipmap[a]) IMB_freeImBuf(ibuf->mipmap[a]);
+               ibuf->mipmap[a]= NULL;
+       }
+}
+
+/* any free rect frees mipmaps to be sure, creation is in render on first request */
 void imb_freerectfloatImBuf(struct ImBuf * ibuf)
 {
        if (ibuf==NULL) return;
@@ -73,10 +84,13 @@ void imb_freerectfloatImBuf(struct ImBuf * ibuf)
                }
        }
 
+       imb_freemipmapImBuf(ibuf);
+       
        ibuf->rect_float= NULL;
        ibuf->mall &= ~IB_rectfloat;
 }
 
+/* any free rect frees mipmaps to be sure, creation is in render on first request */
 void imb_freerectImBuf(struct ImBuf * ibuf)
 {
        if (ibuf==NULL) return;
@@ -87,6 +101,8 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
                }
        }
        
+       imb_freemipmapImBuf(ibuf);
+       
        ibuf->rect= NULL;
        ibuf->mall &= ~IB_rect;
 }
@@ -363,7 +379,8 @@ struct ImBuf *IMB_allocImBuf(short x, short y, uchar d, unsigned int flags, ucha
                ibuf->y= y;
                ibuf->depth= d;
                ibuf->ftype= TGA;
-
+               ibuf->channels= 4;      /* float option, is set to other values when buffers get assigned */
+               
                if (flags & IB_rect){
                        if (imb_addrectImBuf(ibuf)==FALSE){
                                IMB_freeImBuf(ibuf);
@@ -407,7 +424,7 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
 {
        struct ImBuf *ibuf2, tbuf;
        int flags = 0;
-       int x, y;
+       int a, x, y;
        
        if (ibuf1 == NULL) return NULL;
 
@@ -452,6 +469,8 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
        tbuf.encodedbuffer = ibuf2->encodedbuffer;
        tbuf.zbuf= NULL;
        tbuf.zbuf_float= NULL;
+       for(a=0; a<IB_MIPMAP_LEVELS; a++)
+               tbuf.mipmap[a]= NULL;
        
        // set malloc flag
        tbuf.mall               = ibuf2->mall;
index c0018d0b3360022fdf34f117b6b32deb1618174a..a4fab4a357246d14a9a50e95dba664277dd86e10 100644 (file)
@@ -181,7 +181,7 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
        /* quick method to convert floatbuf to byte */
        float *tof = ibuf->rect_float;
        float dither= ibuf->dither;
-       int i;
+       int i, channels= ibuf->channels;
        unsigned char *to = (unsigned char *) ibuf->rect;
        
        if(tof==NULL) return;
@@ -190,14 +190,26 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
                to = (unsigned char *) ibuf->rect;
        }
        
-       if(dither==0.0f) {
-               for (i = ibuf->x * ibuf->y; i > 0; i--) {
-                       to[0] = FTOCHAR(tof[0]);
-                       to[1] = FTOCHAR(tof[1]);
-                       to[2] = FTOCHAR(tof[2]);
-                       to[3] = FTOCHAR(tof[3]);
-                       to += 4; 
-                       tof += 4;
+       if(dither==0.0f || channels!=4) {
+               if(channels==1) {
+                       for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
+                               to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
+               }
+               else if(channels==3) {
+                       for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
+                               to[0] = FTOCHAR(tof[0]);
+                               to[1] = FTOCHAR(tof[1]);
+                               to[2] = FTOCHAR(tof[2]);
+                               to[3] = 255;
+                       }
+               }
+               else {
+                       for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
+                               to[0] = FTOCHAR(tof[0]);
+                               to[1] = FTOCHAR(tof[1]);
+                               to[2] = FTOCHAR(tof[2]);
+                               to[3] = FTOCHAR(tof[3]);
+                       }
                }
        }
        else {
index 343211eb6b0e9dc9ce09b2fc5506514c5c93406a..fd9dac1af2bf26155e3fa7f86e914f2ec1a7a070 100644 (file)
@@ -302,3 +302,28 @@ void IMB_filter_extend(struct ImBuf *ibuf)
        }
 }
 
+void IMB_makemipmap(ImBuf *ibuf, int use_filter)
+{
+       ImBuf *hbuf= ibuf;
+       int minsize, curmap=0;
+       
+       minsize= ibuf->x<ibuf->y?ibuf->x:ibuf->y;
+       
+       while(minsize>10 && curmap<IB_MIPMAP_LEVELS) {
+               if(use_filter) {
+                       ImBuf *nbuf= IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect, 0);
+                       IMB_filterN(nbuf, hbuf);
+                       ibuf->mipmap[curmap]= IMB_onehalf(nbuf);
+                       IMB_freeImBuf(nbuf);
+               }
+               else {
+                       ibuf->mipmap[curmap]= IMB_onehalf(hbuf);
+               }
+               hbuf= ibuf->mipmap[curmap];
+               
+               curmap++;
+               minsize= hbuf->x<hbuf->y?hbuf->x:hbuf->y;
+       }
+}
+
+
index 3027f9508cf4c11bb7f2ace8c1e31efb2cd2be33..25ca958afdb22c075a68a68f3ade287624a67824 100644 (file)
@@ -343,37 +343,69 @@ short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
        }
 }
 
-/* ********************* Tile file support ************************************ */
+/* ********************* Nicer API, MultiLayer and with Tile file support ************************************ */
+
+/* naming rules:
+   - parse name from right to left
+   - last character is channel ID, 1 char like 'A' 'R' 'G' 'B' 'X' 'Y' 'Z' 'W' 'U' 'V'
+   - separated with a dot; the Pass name (like "Depth", "Color", "Diffuse" or "Combined")
+   - separated with a dot: the Layer name (like "Lamp1" or "Walls" or "Characters")
+*/
+
+static ListBase exrhandles= {NULL, NULL};
 
 typedef struct ExrHandle {
+       struct ExrHandle *next, *prev;
+       
        InputFile *ifile;
        TiledOutputFile *tofile;
        OutputFile *ofile;
        int tilex, tiley;
        int width, height;
-       ListBase channels;
+       
+       ListBase channels;      /* flattened out, ExrChannel */
+       ListBase layers;        /* hierarchical, pointing in end to ExrChannel */
 } ExrHandle;
 
-#define CHANMAXNAME 64
+/* flattened out channel */
 typedef struct ExrChannel {
        struct ExrChannel *next, *prev;
-       char name[2*CHANMAXNAME + 1];
-       int xstride, ystride;
-       float *rect;
+       
+       char name[EXR_TOT_MAXNAME+1];   /* full name of layer+pass */
+       int xstride, ystride;           /* step to next pixel, to next scanline */
+       float *rect;                            /* first pointer to write in */
+       char chan_id;                           /* quick lookup of channel char */
 } ExrChannel;
 
-/* not threaded! write one tiled file at a time */
+
+/* hierarchical; layers -> passes -> channels[] */
+typedef struct ExrPass {
+       struct ExrPass *next, *prev;
+       char name[EXR_PASS_MAXNAME];
+       int totchan;
+       float *rect;
+       struct ExrChannel *chan[EXR_PASS_MAXCHAN];
+       char chan_id[EXR_PASS_MAXCHAN];
+} ExrPass;
+
+typedef struct ExrLayer {
+       struct ExrLayer *next, *prev;
+       char name[EXR_LAY_MAXNAME+1];
+       ListBase passes;
+} ExrLayer;
+
+/* ********************** */
+
 void *IMB_exr_get_handle(void)
 {
-       static ExrHandle data;
-       
-       memset(&data, sizeof(ExrHandle), 0);
-       
-       return &data;
+       ExrHandle *data= (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle");
+       BLI_addtail(&exrhandles, data);
+       return data;
 }
 
-/* still clumsy name handling, layers/channels can be ordered as list in list later */
-void IMB_exr_add_channel(void *handle, const char *layname, const char *channame)
+/* adds flattened ExrChannels */
+/* xstride, ystride and rect can be done in set_channel too, for tile writing */
+void IMB_exr_add_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
 {
        ExrHandle *data= (ExrHandle *)handle;
        ExrChannel *echan;
@@ -381,14 +413,19 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *channame
        echan= (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr tile channel");
        
        if(layname) {
-               char lay[CHANMAXNAME], chan[CHANMAXNAME];
-               strncpy(lay, layname, CHANMAXNAME-1);
-               strncpy(chan, channame, CHANMAXNAME-1);
+               char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1];
+               BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+               BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
 
-               sprintf(echan->name, "%s.%s", lay, chan);
+               sprintf(echan->name, "%s.%s", lay, pass);
        }
        else
-               strncpy(echan->name, channame, 2*CHANMAXNAME);
+               BLI_strncpy(echan->name, passname, EXR_TOT_MAXNAME-1);
+       
+       echan->xstride= xstride;
+       echan->ystride= ystride;
+       echan->rect= rect;
+       
        // printf("added channel %s\n", echan->name);
        BLI_addtail(&data->channels, echan);
 }
@@ -405,7 +442,9 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height)
        for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
                header.channels().insert (echan->name, Channel (FLOAT));
        
-       header.insert ("comments", StringAttribute ("Blender MultiChannel"));
+       header.compression() = RLE_COMPRESSION;
+       
+       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
        
        data->ofile = new OutputFile(filename, header);
 }
@@ -426,13 +465,14 @@ void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height
        
        header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
        header.lineOrder() = RANDOM_Y,
-       header.compression() = NO_COMPRESSION;
+       header.compression() = RLE_COMPRESSION;
        
-       header.insert ("comments", StringAttribute ("Blender MultiChannel"));
+       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
        
        data->tofile = new TiledOutputFile(filename, header);
 }
 
+/* read from file */
 int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
 {
        ExrHandle *data= (ExrHandle *)handle;
@@ -447,7 +487,7 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
                        const ChannelList &channels = data->ifile->header().channels();
                        
                        for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
-                               IMB_exr_add_channel(data, NULL, i.name());
+                               IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL);
                        
                        return 1;
                }
@@ -456,21 +496,21 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
 }
 
 /* still clumsy name handling, layers/channels can be ordered as list in list later */
-void IMB_exr_set_channel(void *handle, char *layname, char *channame, int xstride, int ystride, float *rect)
+void IMB_exr_set_channel(void *handle, char *layname, char *passname, int xstride, int ystride, float *rect)
 {
        ExrHandle *data= (ExrHandle *)handle;
        ExrChannel *echan;
-       char name[2*CHANMAXNAME + 1];
+       char name[EXR_TOT_MAXNAME + 1];
        
        if(layname) {
-               char lay[CHANMAXNAME], chan[CHANMAXNAME];
-               strncpy(lay, layname, CHANMAXNAME-1);
-               strncpy(chan, channame, CHANMAXNAME-1);
+               char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1];
+               BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+               BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
                
-               sprintf(name, "%s.%s", lay, chan);
+               sprintf(name, "%s.%s", lay, pass);
        }
        else
-               strncpy(name, channame, 2*CHANMAXNAME);
+               BLI_strncpy(name, passname, EXR_TOT_MAXNAME-1);
        
        
        for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
@@ -540,11 +580,38 @@ void IMB_exr_read_channels(void *handle)
        data->ifile->readPixels (0, data->height-1);    
 }
 
+void IMB_exr_multilayer_convert(void *handle, void *base,  
+                                                               void * (*addlayer)(void *base, char *str), 
+                                                               void (*addpass)(void *base, void *lay, char *str, 
+                                                                                               float *rect, int totchan, char *chan_id))
+{
+       ExrHandle *data= (ExrHandle *)handle;
+       ExrLayer *lay;
+       ExrPass *pass;
+
+       if(data->layers.first==NULL) {
+               printf("cannot convert multilayer, no layers in handle\n");
+               return;
+       }
+
+       for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+               void *laybase= addlayer(base, lay->name);
+               if(laybase) {
+                       for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) {
+                               addpass(base, laybase, pass->name, pass->rect, pass->totchan, pass->chan_id);
+                               pass->rect= NULL;
+                       }
+               }
+       }
+}
+
 
 void IMB_exr_close(void *handle)
 {
        ExrHandle *data= (ExrHandle *)handle;
        ExrChannel *echan;
+       ExrLayer *lay;
+       ExrPass *pass;
        
        if(data->ifile)
                delete data->ifile;
@@ -558,6 +625,191 @@ void IMB_exr_close(void *handle)
        data->tofile= NULL;
        
        BLI_freelistN(&data->channels);
+       
+       for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+               for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next)
+                       if(pass->rect)
+                               MEM_freeN(pass->rect);
+               BLI_freelistN(&lay->passes);
+       }
+       BLI_freelistN(&data->layers);
+       
+       BLI_remlink(&exrhandles, data);
+       MEM_freeN(data);
+}
+
+/* ********* */
+
+static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *passname)
+{
+       int plen, len= strlen(echan->name);
+       
+       if(len < 4) {
+               printf("multilayer read: name too short: %s\n", echan->name);
+               return 0;
+       }
+       if(echan->name[len-2]!='.') {
+               printf("multilayer read: name has no Channel: %s\n", echan->name);
+               return 0;
+       }
+       echan->chan_id= echan->name[len-1];
+       
+       len-= 3;
+       while(len>=0) {
+               if(echan->name[len]=='.')
+                       break;
+               len--;
+       }
+       BLI_strncpy(passname, echan->name+len+1, EXR_PASS_MAXNAME);
+       plen= strlen(passname);
+       if(plen < 3) {
+               printf("multilayer read: should not happen: %s\n", echan->name);
+               return 0;
+       }
+       passname[plen-2]= 0;
+       
+       if(len<1)
+               layname[0]= 0;
+       else {
+               BLI_strncpy(layname, echan->name, EXR_LAY_MAXNAME);
+               layname[len]= 0;
+       }
+       // printf("found lay %s pass %s chan %c\n", layname, passname, echan->chan_id);
+}
+
+static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname)
+{
+       ExrLayer *lay;
+       
+       for(lay= (ExrLayer *)lb->first; lay; lay= lay->next) {
+               if( strcmp(lay->name, layname)==0 )
+                       return lay;
+       }
+       lay= (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer");
+       BLI_addtail(lb, lay);
+       BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME);
+       
+       return lay;
+}
+
+static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname)
+{
+       ExrPass *pass;
+       
+       for(pass= (ExrPass *)lb->first; pass; pass= pass->next) {
+               if( strcmp(pass->name, passname)==0 )
+                       return pass;
+       }
+       
+       pass= (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass");
+
+       if(strcmp(passname, "Combined")==0)
+               BLI_addhead(lb, pass);
+       else
+               BLI_addtail(lb, pass);
+       
+       BLI_strncpy(pass->name, passname, EXR_LAY_MAXNAME);
+       
+       return pass;
+}
+
+/* creates channels, makes a hierarchy and assigns memory to channels */
+static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height)
+{
+       ExrLayer *lay;
+       ExrPass *pass;
+       ExrChannel *echan;
+       ExrHandle *data= (ExrHandle *)IMB_exr_get_handle();
+       int a;
+       char layname[EXR_TOT_MAXNAME], passname[EXR_TOT_MAXNAME];
+       
+       data->ifile= file;
+       data->width= width;
+       data->height= height;
+       
+       const ChannelList &channels = data->ifile->header().channels();
+       
+       for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+               IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL);
+       
+       /* now try to sort out how to assign memory to the channels */
+       /* first build hierarchical layer list */
+       for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
+               if( imb_exr_split_channel_name(echan, layname, passname) ) {
+                       ExrLayer *lay= imb_exr_get_layer(&data->layers, layname);
+                       ExrPass *pass= imb_exr_get_pass(&lay->passes, passname);
+                       
+                       pass->chan[pass->totchan]= echan;
+                       pass->totchan++;
+                       if(pass->totchan>=EXR_PASS_MAXCHAN)
+                               break;
+               }
+       }
+       if(echan) {
+               printf("error, too many channels in one pass: %s\n", echan->name);
+               IMB_exr_close(data);
+               return NULL;
+       }
+       
+       /* with some heuristics, try to merge the channels in buffers */
+       for(lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) {
+               for(pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) {
+                       if(pass->totchan) {
+                               pass->rect= (float *)MEM_mapallocN(width*height*pass->totchan*sizeof(float), "pass rect");
+                               if(pass->totchan==1) {
+                                       echan= pass->chan[0];
+                                       echan->rect= pass->rect;
+                                       echan->xstride= 1;
+                                       echan->ystride= width;
+                                       pass->chan_id[0]= echan->chan_id;
+                               }
+                               else {
+                                       char lookup[256];
+                                       
+                                       memset(lookup, 0, sizeof(lookup));
+                                                  
+                                       /* we can have RGB(A), XYZ(W), UVA */
+                                       if(pass->totchan==3 || pass->totchan==4) {
+                                               if(pass->chan[0]->chan_id=='B' || pass->chan[1]->chan_id=='B' ||  pass->chan[2]->chan_id=='B') {
+                                                       lookup['R']= 0;
+                                                       lookup['G']= 1;
+                                                       lookup['B']= 2;
+                                                       lookup['A']= 3;
+                                               }
+                                               else if(pass->chan[0]->chan_id=='Y' || pass->chan[1]->chan_id=='Y' ||  pass->chan[2]->chan_id=='Y') {
+                                                       lookup['X']= 0;
+                                                       lookup['Y']= 1;
+                                                       lookup['Z']= 2;
+                                                       lookup['W']= 3;
+                                               }
+                                               else {
+                                                       lookup['U']= 0;
+                                                       lookup['V']= 1;
+                                                       lookup['A']= 2;
+                                               }
+                                               for(a=0; a<pass->totchan; a++) {
+                                                       echan= pass->chan[a];
+                                                       echan->rect= pass->rect + lookup[echan->chan_id];
+                                                       echan->xstride= pass->totchan;
+                                                       echan->ystride= width*pass->totchan;
+                                                       pass->chan_id[ lookup[echan->chan_id] ]= echan->chan_id;
+                                               }
+                                       }
+                                       else { /* unknown */
+                                               for(a=0; a<pass->totchan; a++) {
+                                                       echan= pass->chan[a];
+                                                       echan->rect= pass->rect + a;
+                                                       echan->xstride= pass->totchan;
+                                                       echan->ystride= width*pass->totchan;
+                                                       pass->chan_id[a]= echan->chan_id;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       return data;
 }
 
 
@@ -598,9 +850,9 @@ static int exr_has_zbuffer(InputFile *file)
 
 static int exr_is_renderresult(InputFile *file)
 {
-       const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("comments");
+       const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("BlenderMultiChannel");
        if(comments)
-               if(comments->value() == "Blender MultiChannel")
+//             if(comments->value() == "Blender MultiChannel")
                        return 1;
        return 0;
 }
@@ -615,6 +867,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
        try
        {
                Mem_IStream membuf(mem, size); 
+               int is_multi;
                file = new InputFile(membuf);
                
                Box2i dw = file->header().dataWindow();
@@ -625,53 +878,70 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                //         dw.min.x, dw.min.y, dw.max.x, dw.max.y);
 
                //exr_print_filecontents(file);
-               int flipped= exr_is_renderresult(file);
                
-               ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
+               is_multi= exr_is_renderresult(file);
                
-               if (ibuf) 
+               /* do not make an ibuf when */
+               if(is_multi && !(flags & IB_test) && !(flags & IB_multilayer)) 
                {
+                       printf("Error: can't process EXR multilayer file\n");
+               }
+               else {
+               
+                       ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
                        ibuf->ftype = OPENEXR;
                        
                        if (!(flags & IB_test))
                        {
-                               FrameBuffer frameBuffer;
-                               float *first;
-                               int xstride = sizeof(float) * 4;
-                               int ystride = flipped ? xstride*width : - xstride*width;
-                               
-                               imb_addrectfloatImBuf(ibuf);
-                               
-                               /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
-                               first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width);
-                               /* but, since we read y-flipped (negative y stride) we move to last scanline */
-                               if(!flipped) first+= 4*(height-1)*width;
-                               
-                               frameBuffer.insert ("R", Slice (FLOAT,  (char *) first, xstride, ystride));
-                               frameBuffer.insert ("G", Slice (FLOAT,  (char *) (first+1), xstride, ystride));
-                               frameBuffer.insert ("B", Slice (FLOAT,  (char *) (first+2), xstride, ystride));
-                                                                                                                                               /* 1.0 is fill value */
-                               frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
-
-                               if(exr_has_zbuffer(file)) 
+                               if(is_multi) /* only enters with IB_multilayer flag set */
                                {
-                                       float *firstz;
+                                       /* constructs channels for reading, allocates memory in channels */
+                                       ExrHandle *handle= imb_exr_begin_read_mem(file, width, height);
+                                       if(handle) {
+                                               IMB_exr_read_channels(handle);
+                                               ibuf->userdata= handle;                 /* potential danger, the caller has to check for this! */
+                                               return ibuf;
+                                       }
+                               }
+                               else {
+                                       FrameBuffer frameBuffer;
+                                       float *first;
+                                       int xstride = sizeof(float) * 4;
+                                       int ystride = - xstride*width;
+                                       
+                                       imb_addrectfloatImBuf(ibuf);
+                                       
+                                       /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
+                                       first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width);
+                                       /* but, since we read y-flipped (negative y stride) we move to last scanline */
+                                       first+= 4*(height-1)*width;
+                                       
+                                       frameBuffer.insert ("R", Slice (FLOAT,  (char *) first, xstride, ystride));
+                                       frameBuffer.insert ("G", Slice (FLOAT,  (char *) (first+1), xstride, ystride));
+                                       frameBuffer.insert ("B", Slice (FLOAT,  (char *) (first+2), xstride, ystride));
+                                                                                                                                                       /* 1.0 is fill value */
+                                       frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
+
+                                       if(exr_has_zbuffer(file)) 
+                                       {
+                                               float *firstz;
+                                               
+                                               addzbuffloatImBuf(ibuf);
+                                               firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width);
+                                               firstz+= (height-1)*width;
+                                               frameBuffer.insert ("Z", Slice (FLOAT,  (char *)firstz , sizeof(float), -width*sizeof(float)));
+                                       }
                                        
-                                       addzbuffloatImBuf(ibuf);
-                                       firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width);
-                                       if(!flipped) firstz+= (height-1)*width;
-                                       frameBuffer.insert ("Z", Slice (FLOAT,  (char *)firstz , sizeof(float), -width*sizeof(float)));
+                                       file->setFrameBuffer (frameBuffer);
+                                       file->readPixels (dw.min.y, dw.max.y);
+                                       
+                                       IMB_rect_from_float(ibuf);
                                }
-                               
-                               file->setFrameBuffer (frameBuffer);
-                               file->readPixels (dw.min.y, dw.max.y);
-                               
-                               IMB_rect_from_float(ibuf);
                        }
+                       
+                       delete file;
                }
                
-               delete file;
-               
                return(ibuf);
                                
        }
index ff71aab5f3c6e162b8d82dcdbc9c29cb985f9c68..feceb227e4b2153017b0062753067802b09f21fc 100644 (file)
 
 /* experiment with more advanced exr api */
 
+/* Note: as for now openexr only supports 32 chars in channel names.
+   This api also supports max 8 channels per pass now. easy to fix! */
+#define EXR_LAY_MAXNAME                19
+#define EXR_PASS_MAXNAME       11
+#define EXR_TOT_MAXNAME                32
+#define EXR_PASS_MAXCHAN       8
+
+
 #ifdef WITH_OPENEXR
 void * IMB_exr_get_handle                      (void);
-void   IMB_exr_add_channel                     (void *handle, const char *layname, const char *channame);
+void   IMB_exr_add_channel                     (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect);
 
 int            IMB_exr_begin_read                      (void *handle, char *filename, int *width, int *height);
 void   IMB_exr_begin_write                     (void *handle, char *filename, int width, int height);
 void   IMB_exrtile_begin_write         (void *handle, char *filename, int width, int height, int tilex, int tiley);
 
-void   IMB_exr_set_channel                     (void *handle, char *layname, char *channame, int xstride, int ystride, float *rect);
+void   IMB_exr_set_channel                     (void *handle, char *layname, char *passname, int xstride, int ystride, float *rect);
 
 void   IMB_exr_read_channels           (void *handle);
 void   IMB_exr_write_channels          (void *handle);
 void   IMB_exrtile_write_channels      (void *handle, int partx, int party);
 
+void    IMB_exr_multilayer_convert     (void *handle, void *base,  
+                                                                        void * (*addlayer)(void *base, char *str), 
+                                                                        void (*addpass)(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id));
+
 void   IMB_exr_close                           (void *handle);
 
+
 #else
 
 /* ugly... but we only use it on pipeline.c, render module, now */
 
 void * IMB_exr_get_handle                      (void) {return NULL;}
-void   IMB_exr_add_channel                     (void *handle, const char *layname, const char *channame) {}
+void   IMB_exr_add_channel                     (void *handle, const char *layname, const char *channame, int xstride, int ystride, float *rect) {}
 
 int            IMB_exr_begin_read                      (void *handle, char *filename, int *width, int *height) {return 0;}
 void   IMB_exr_begin_write                     (void *handle, char *filename, int width, int height) {}
@@ -65,6 +78,10 @@ void IMB_exr_read_channels           (void *handle) {}
 void   IMB_exr_write_channels          (void *handle) {}
 void   IMB_exrtile_write_channels      (void *handle, int partx, int party) {}
 
+void    IMB_exr_multilayer_convert     (void *handle, void *base,  
+                                                                        void * (*addlayer)(void *base, char *str), 
+                                                                        void (*addpass)(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id)) {}
+
 void   IMB_exr_close                           (void *handle) {}
 
 #endif
index 45ef191277b770098593aecfc20f4238b1bd9311..bfa6200d23beb37b19c34b6c405dbcc052742922 100644 (file)
@@ -270,7 +270,7 @@ struct ImBuf *IMB_loadiffname(char *naam, int flags) {
 
        ibuf= IMB_loadifffile(file, flags);
 
-       if (ibuf == 0) {
+       if (ibuf == NULL) {
                if (read(file, buf, 4) != 4) buf[0] = 0;
                if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
                        ibuf = imb_ibJpegImageFromFilename(naam, flags);                        
index 41183ce91da9baa71d38436a37a6b9f38081569d..429fcb109ead01ab834366c3911cc5ce1c484ce2 100644 (file)
@@ -332,6 +332,8 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
        IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &width, &height);
 
        if (width == 0 || height == 0) return;
+       if (sbuf && sbuf->channels!=4) return;
+       if (dbuf->channels!=4) return;
        
        do_char = (sbuf && sbuf->rect && dbuf->rect);
        do_float = (sbuf && sbuf->rect_float && dbuf->rect_float);
index f5ae79fcd80e81da553025f1334a2cdad69b2fd1..f87e9797cb324ba49f54a78515569db237c7b253 100644 (file)
@@ -42,6 +42,8 @@ struct ID;
 extern void do_butspace(unsigned short event);
 extern void redraw_test_buttons(struct Object *new);
 
+extern char *image_type_pup(void);
+
 /* buttons_editing.c */
 extern void validate_editbonebutton_cb(void *bonev, void *namev);
 
index a3b12b7bafdc093a3e2d1478f24848591b456f4b..5c289cfc2a4c7fb6170f86a85347324f138734d2 100644 (file)
@@ -36,6 +36,9 @@
 struct ScrArea;
 struct SpaceImage;
 struct Render;
+struct Image;
+struct ImBuf;
+struct uiBlock;
 
 void do_imagebuts(unsigned short event);
 void calc_image_view(struct SpaceImage *sima, char mode);
@@ -51,8 +54,15 @@ void uvco_to_areaco_noclip(float *vec, int *mval);
 void what_image(struct SpaceImage *sima);
 void image_preview_event(int event);
 
+void image_info(struct Image *ima, struct ImBuf *ibuf, char *str);
+void imagespace_composite_flipbook(struct ScrArea *sa);
+
 void imagewindow_render_callbacks(struct Render *re);
 void imagewindow_toggle_render(void);
+void imagewindow_swap_render_rects(void);
+void imagewin_store_spare(void);
+
+void image_editvertex_buts(struct uiBlock *block);
 
 #endif
 
index 46444c88ae3f3f5da3004a6d79fbfff8a79f4539..6a67ebc700974ce9f92e1a98cb7b0037e3c62bcf 100644 (file)
@@ -76,7 +76,10 @@ void new_image_sima(void);
 void reload_image_sima(void);
 void save_image_sima(void);
 void save_as_image_sima(void);
+void save_image_sequence_sima(void);
 void replace_image_sima(short imageselect);
 void open_image_sima(short imageselect);
 void pack_image_sima(void);
 
+/* checks images for forced updates on frame change */
+void BIF_image_update_frame(void);
index a997efb336d474d9842ffca41e97daf1e0a6623d..789c3661db7379f8bf1bcfaa022e9bdb28519eec 100644 (file)
@@ -50,6 +50,7 @@ void BIF_renderwin_set_custom_cursor(unsigned char mask[16][2], unsigned char bi
 
 void BIF_redraw_render_rect(void);
 void BIF_swap_render_rects(void);
+void BIF_store_spare(void);
 void BIF_toggle_render_display(void);
 
 void BIF_init_render_callbacks(struct Render *re, int do_display);
index 7bf0814b82e1f71e4098d24f82dc0183f36f0663..1e84dba39cba06034ef7df9632821ee5fe72977d 100644 (file)
@@ -64,6 +64,7 @@ struct SpaceOops;
 #define IMAGE_HANDLER_PAINT                    31
 #define IMAGE_HANDLER_CURVES           32
 #define IMAGE_HANDLER_PREVIEW          33
+#define IMAGE_HANDLER_GAME_PROPERTIES  34
 
 /* action handler codes */
 #define ACTION_HANDLER_PROPERTIES      40
index 002d382be5b4ca610c45aa3c825f2240dc865bca..70978a033c228152fcc52c084956c52b85a0bed6 100644 (file)
@@ -37,7 +37,7 @@ struct ImBuf;
 struct EnvMap;
 
 void BIF_save_rendered_image(char *name);
-void BIF_save_rendered_image_fs(int zbuf);
+void BIF_save_rendered_image_fs(void);
 void BIF_save_envmap(struct EnvMap *env, char *str);
 void save_image_filesel_str(char *str);
 
index 29f9c52f79f8af837db3387cc60c2a5116bbdaed..6934899062e13d1f2e29e9c588ec70346de09534 100644 (file)
@@ -40,7 +40,6 @@ struct ID;
 struct ScrArea;
 struct BWinEvent;
 
-void clear_global_filesel_vars(void);
 void filesel_statistics(struct SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen);
 void test_flags_file(struct SpaceFile *sfile);
 void sort_filelist(struct SpaceFile *sfile);
@@ -49,9 +48,16 @@ void freefilelist(struct SpaceFile *sfile);
 void parent(struct SpaceFile *sfile);
 void swapselect_file(struct SpaceFile *sfile);
 void drawfilespace(struct ScrArea *sa, void *spacedata);
+
 void activate_fileselect(int type, char *title, char *file, void (*func)(char *));
+void activate_fileselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
+void activate_fileselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
 void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
+
 void activate_databrowse(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
+void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
 void filesel_prevspace(void);
 void free_filesel_spec(char *dir);
 void winqreadfilespace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
index 626c9e75cbc8bff8879b7299813d907b726ebeed..bbe79c1e8ff5fa1d383ca66b3eb9caf1b1a56626 100644 (file)
@@ -44,6 +44,8 @@ struct bNodeTree;
 struct Material;
 struct ID;
 struct Scene;
+struct Image;
+struct ImageUser;
 
 /* ************* API for editnode.c *********** */
 
@@ -82,6 +84,12 @@ void node_adduplicate(struct SpaceNode *snode);
 void snode_autoconnect(struct SpaceNode *snode, struct bNode *node_to, int flag);
 void node_select_linked(struct SpaceNode *snode, int out);
 
+struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree);
+
+void imagepaint_composite_tags(struct bNodeTree *ntree, struct Image *image, struct ImageUser *iuser);
+
+
+
 /* ************* drawnode.c *************** */
 struct SpaceNode;
 struct bNodeLink;
index fee04ac50a82e506cbfad5e18a87637dabe09777..aaad17453ef7293c0d5978e0335b3a3eb2fcc3c5 100644 (file)
@@ -44,8 +44,7 @@
 /* max length material array, 16 because of bits in matfrom */
 #define MAXPICKBUF      10000
 #define MAXSEQ          32
-/*  in Image struct */
-#define MAXMIPMAP       10
+
 /* in buttons.c */
 #define MAX_EFFECT      20
 
 #define B_SIMABRUSHCHANGE      377
 #define B_SIMABTEXBROWSE       378
 #define B_SIMABTEXDELETE       379
+#define B_SIMARELOAD           380
+#define B_SIMANAME                     381
+#define B_SIMAMULTI                    382
+#define B_TRANS_IMAGE          383
+#define B_SIMA_REPACK          384
+#define B_SIMA_PLAY                    385
+#define B_SIMA_RECORD          386
 
 /* BUTS: 400 */
 #define B_BUTSHOME             401
index bd0b2adaa311c9b681843bde50676f127a1204a7..75bc8ff6ed3c97102d31858a2d4c72ea836b94c1 100644 (file)
@@ -41,6 +41,8 @@ struct ColorBand;
 struct uiBlock;
 struct rctf;
 struct CurveMap;
+struct ImageUser;
+struct RenderResult;
 
 /* buts->scaflag */            
 #define BUTS_SENS_SEL          1
@@ -115,6 +117,10 @@ extern void radio_panels(void);
 extern void do_radiobuts(unsigned short event);
 extern void texture_panels(void);
 extern void do_texbuts(unsigned short event);
+void uiblock_image_panel(struct uiBlock *block, struct Image **ima_pp, struct ImageUser *iuser, 
+                                                short redraw, short imagechanged);
+void uiblock_layer_pass_buttons(struct uiBlock *block, struct RenderResult *rr, 
+                                                          struct ImageUser *iuser, int event, int x, int y, int w);
 
 /* logic */
 extern void do_logic_buts(unsigned short event);
@@ -151,18 +157,11 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 /* *********************** */
 #define B_VIEWBUTS             1100
 
-#define B_LOADBGPIC            1001
-#define B_BLENDBGPIC           1002
-#define B_BGPICBROWSE          1003
-#define B_BGPICTEX             1004
-#define B_BGPICCLEAR           1005
-#define B_BGPICTEXCLEAR                1006
-
 #define B_OBJECTPANELROT       1007
-#define B_OBJECTPANELMEDIAN    1008
+#define B_OBJECTPANELMEDIAN 1008
 #define B_ARMATUREPANEL1       1009
 #define B_ARMATUREPANEL2       1010
-#define B_OBJECTPANELPARENT    1011
+#define B_OBJECTPANELPARENT 1011
 #define B_OBJECTPANEL          1012
 #define B_ARMATUREPANEL3       1013
 #define B_OBJECTPANELSCALE     1014
@@ -213,13 +212,12 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 
 #define B_TEXTYPE              1301
 #define B_DEFTEXVAR            1302
-#define B_LOADTEXIMA   1303
+
 #define B_NAMEIMA              1304
 #define B_TEXCHANNEL   1305
 #define B_TEXREDR_PRV  1306
-#define B_TEXIMABROWSE 1307
-#define B_IMAPTEST             1308
-#define B_RELOADIMA            1309
+#define B_IMAGECHANGED 1307
+
 #define B_LOADPLUGIN   1310
 #define B_NAMEPLUGIN   1311
 #define B_COLORBAND            1312
@@ -233,20 +231,18 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_LOADTEXIMA1  1320
 #define B_TEXPRV               1321
 
+
 #define B_PLUGBUT              1325
 /* B_PLUGBUT reserves 24 buttons at least! */
 
 #define B_ENV_MAKE             1350
 #define B_ENV_FREE             1351
-#define B_ENV_DELETE           1352
+#define B_ENV_DELETE   1352
 #define B_ENV_SAVE             1353
 #define B_ENV_OB               1354
 
-#define B_PACKIMA              1355
-#define B_TEXSETFRAMES         1356
+#define B_ENV_FREE_ALL 1357
 
-#define B_ENV_FREE_ALL         1357
-#define B_UNLINKIMA            1358
 
 /* **************** animbuts = object buttons ******* */
 #define B_ANIMBUTS             1500
index deabcee590acad5750ce64fb23efef690f6a593c..d99e19ce456aadbbbc9ba0d7b043290f319296f4 100644 (file)
@@ -39,6 +39,7 @@
 struct PackedFile;
 struct anim;
 struct ImBuf;
+struct RenderResult;
 
 typedef struct PreviewImage {
        unsigned int w;
@@ -46,23 +47,43 @@ typedef struct PreviewImage {
        unsigned int * rect;
 } PreviewImage;
 
+/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
+/* should be used in conjunction with an ID * to Image. */
+typedef struct ImageUser {
+       int framenr;                            /* movies, sequences: current to display */
+       int frames;                                     /* total amount of frames to use */
+       int offset, sfra;                       /* offset within movie, start frame in global time */
+       short fie_ima, cycl;            /* fields/image in movie, cyclic flag */
+       short flag, ok;
+       
+       short multi_index, layer, pass;  /* listbase indices, for menu browsing or retrieve buffer */
+       short menunr;                                   /* localized menu entry, for handling browse event */
+} ImageUser;
+
+/* iuser->flag */
+#define        IMA_ANIM_ALWAYS         1
+#define IMA_ANIM_REFRESHED     2
+
 typedef struct Image {
        ID id;
        
-       char name[160];
+       char name[240];
        
+       ListBase ibufs;                 /* not written in file */
+       
+       /* sources from: */
        struct anim *anim;
-       struct ImBuf *ibuf;
-       struct ImBuf *mipmap[10];
+       struct RenderResult *rr;
        
        short ok, flag;
+       short source, type, pad, pad1;
        int lastframe;
 
        /* texture page */
        short tpageflag, totbind;
        short xrep, yrep;
        short twsta, twend;
-       unsigned int bindcode;
+       unsigned int bindcode;  /* only for current image... */
        unsigned int *repbind;  /* for repeat of parts of images */
        
        struct PackedFile * packedfile;
@@ -71,25 +92,25 @@ typedef struct Image {
        float lastupdate;
        int lastused;
        short animspeed;
-       short reserved1;
-       int   reserved2;
+       
+       short gen_x, gen_y, gen_type;   /* for generated images */
+       
 /*#ifdef WITH_VERSE*/
        void *vnode;            /* pointer at verse bitmap node */
 /*#endif*/
 } Image;
 
-/*  in Image struct */
-#define MAXMIPMAP      10
 
 /* **************** IMAGE ********************* */
 
 /* flag */
-#define IMA_HALVE              1
-#define IMA_BW                 2
-#define IMA_FROMANIM   4
-#define IMA_USED               8
+#define IMA_FIELDS             1
+#define IMA_STD_FIELD  2
+
 #define        IMA_REFLECT             16
 #define IMA_NOCOLLECT   32
+#define IMA_ANTIALI            64
+
 
 /* tpageflag */
 #define IMA_TILES                      1
@@ -97,5 +118,7 @@ typedef struct Image {
 #define IMA_COLCYCLE           4       /* Depreciated */
 #define IMA_MIPMAP_COMPLETE 8   /* all mipmap levels in OpenGL texture set? */
 
+/* ima->type and ima->source moved to BKE_image.h, for API */
+
 #endif
 
index efc812af09283247e12cdc81388b12721b941131..5e899dce0f64cd4cb5b6f6a45eca2ee93a32cf84 100644 (file)
@@ -182,6 +182,7 @@ typedef struct bNodeTree {
 
 /* data structs, for node->storage */
 
+/* this one has been replaced with ImageUser, keep it for do_versions() */
 typedef struct NodeImageAnim {
        int frames, sfra, nr;
        char cyclic, movie;
index 7c4dc58006a0fba66c584b4ce8b4b019b62f2bd7..a0fdd892106dfc14190dfdba334b3657460cc46d 100644 (file)
@@ -55,6 +55,7 @@ enum PF_FileStatus
        PF_USE_LOCAL,
        PF_USE_ORIGINAL,
        PF_KEEP,
+       PF_REMOVE,
        PF_NOOP,
                        
        PF_ASK
index 87ff72f702516b7d91838f6fa43ce8f7c79b0492..8f3ee4e0e3f3260d9d76cb36f5e7205004b889b5 100644 (file)
@@ -593,15 +593,16 @@ typedef struct Scene {
 #define R_AVIJPEG      16
 #define R_PNG          17
 #define R_AVICODEC     18
-#define R_QUICKTIME    19
+#define R_QUICKTIME 19
 #define R_BMP          20
 #define R_RADHDR       21
 #define R_TIFF         22
 #define R_OPENEXR      23
 #define R_FFMPEG        24
 #define R_FRAMESERVER   25
-#define R_CINEON       26
-#define R_DPX          27
+#define R_CINEON               26
+#define R_DPX                  27
+#define R_MULTILAYER   28
 
 /* subimtype, flag options for imtype */
 #define R_OPENEXR_HALF 1
index 210ecc201196cf09196e69b5ab9ef58eb9e88d24..1f5391d59b1bff7aa31ea76df820a2f62aa11aae 100644 (file)
@@ -36,7 +36,8 @@
 
 #include "DNA_listBase.h"
 #include "DNA_vec_types.h"
-#include "DNA_oops_types.h"    /* for TreeStoreElem */
+#include "DNA_oops_types.h"            /* for TreeStoreElem */
+#include "DNA_image_types.h"   /* ImageUser */
 /* Hum ... Not really nice... but needed for spacebuts. */
 #include "DNA_view2d_types.h"
 
@@ -163,31 +164,27 @@ typedef struct SpaceFile {
 
        struct direntry *filelist;
        int totfile;
+       
        char title[24];
        char dir[160];
        char file[80];
+       
        short type, ofs, flag, sort;
        short maxnamelen, collums;
        
        struct BlendHandle *libfiledata;
        
-       short retval, ipotype;
-       short menu, act;
-
-       /* changed type for compiling */
-       /* void (*returnfunc)(short); ? used with char* ....*/
-       /**
-        * @attention Called in filesel.c: 
-        * @attention returnfunc(this->retval) : short
-        * @attention returnfunc(name)         : char*
-        * @attention Other uses are limited to testing against
-        * @attention the value. How do we resolve this? Two args?
-        * @attention For now, keep the char*, as it seems stable.
-        * @attention Be warned that strange behaviour _has_ been spotted!
-        */
-       void (*returnfunc)(char*);
-               
-       short *menup;
+       unsigned short retval;          /* event */
+       short menu, act, ipotype;
+       
+       /* one day we'll add unions to dna */
+       void (*returnfunc)(char *);
+       void (*returnfunc_event)(unsigned short);
+       void (*returnfunc_args)(char *, void *, void *);
+       
+       void *arg1, *arg2;
+       short *menup;   /* pointer to menu result or ID browsing */
+       char *pupmenu;  /* optional menu in header */
 } SpaceFile;
 
 typedef struct SpaceOops {
@@ -228,18 +225,21 @@ typedef struct SpaceImage {
        View2D v2d;
        
        struct Image *image;
+       struct ImageUser iuser;
+       
        struct CurveMapping *cumap;
        short mode, menunr;
        short imanr, curtile;
        int flag;
-       short pad1, lock;
-       
-       float zoom, pad2;
+       short imtypenr, lock;
+       short showspare, pad2;
+       float zoom;
        
-       float xof, yof;                 /* user defined offset, image is centered */
+       float xof, yof;                                 /* user defined offset, image is centered */
+       float centx, centy;                             /* storage for offset while render drawing */
        
-       float centx, centy;             /* storage for offset while render drawing */
-       char *info_str;                 /* info string for render */
+       char *info_str, *info_spare;    /* info string for render */
+       struct ImBuf *spare;
 } SpaceImage;
 
 typedef struct SpaceNla{
@@ -429,9 +429,11 @@ typedef struct SpaceImaSel {
 /* sbuts->flag */
 #define SB_PRV_OSA                     1
 
-/* these values need to be hardcoded in blender.h SpaceFile: struct dna does not recognize defines */
+/* these values need to be hardcoded in structs, dna does not recognize defines */
+/* also defined in BKE */
 #define FILE_MAXDIR                    160
 #define FILE_MAXFILE           80
+#define FILE_MAX                       240
 
 /* filesel types */
 #define FILE_UNIX                      8
@@ -589,7 +591,8 @@ typedef struct SpaceImaSel {
 #define TIME_ALL_ANIM_WIN              4
 #define TIME_ALL_BUTS_WIN              8
 #define TIME_WITH_SEQ_AUDIO            16
-#define TIME_SEQ                        32
+#define TIME_SEQ                               32
+#define TIME_ALL_IMAGE_WIN             64
 
 /* sseq->mainb */
 #define SEQ_DRAW_SEQUENCE         0
index 01de2196f8c6fb87bbfe145555f55f3d9004c612..eae2a07ec6e08a28aed36ab93b25073c10b8430a 100644 (file)
@@ -35,6 +35,7 @@
 #define DNA_TEXTURE_TYPES_H
 
 #include "DNA_ID.h"
+#include "DNA_image_types.h"
 
 struct Ipo;
 struct PluginTex;
@@ -43,6 +44,7 @@ struct EnvMap;
 struct Object;
 struct Tex;
 struct Image;
+struct ImBuf;
 
 typedef struct MTex {
 
@@ -112,7 +114,7 @@ typedef struct ColorBand {
 typedef struct EnvMap {
        struct Object *object;
        struct Image *ima;              /* type ENV_LOAD */
-       struct Image *cube[6];          /* these images are dynamic, not part of the main struct */
+       struct ImBuf *cube[6];          /* these images are dynamic, not part of the main struct */
        float imat[4][4];
        float obimat[3][3];
        short type, stype;
@@ -152,19 +154,23 @@ typedef struct Tex {
        float cropxmin, cropymin, cropxmax, cropymax;
        short xrepeat, yrepeat;
        short extend;
+       
+       /* variables disabled, moved to struct iuser */
        short fie_ima;
        int len;
-       float checkerdist, nabla;
        int frames, offset, sfra;
+       
+       float checkerdist, nabla;
        float norfac;
        
+       struct ImageUser iuser;
+       
        struct Ipo *ipo;
        struct Image *ima;
        struct PluginTex *plugin;
        struct ColorBand *coba;
        struct EnvMap *env;
        
-       int fradur[4][2];
        
 } Tex;
 
@@ -234,18 +240,18 @@ typedef struct TexMapping {
 #define TEX_INTERPOL   1
 #define TEX_USEALPHA   2
 #define TEX_MIPMAP             4
-#define TEX_FIELDS             8
 #define TEX_IMAROT             16
 #define TEX_CALCALPHA  32
-#define TEX_ANIMCYCLIC 64
-#define TEX_ANIM5              128
-#define TEX_ANTIALI            256
-#define TEX_ANTISCALE  512
-#define TEX_STD_FIELD  1024
 #define TEX_NORMALMAP  2048
 #define TEX_GAUSS_MIP  4096
 
-#define TEX_MORKPATCH  16384
+/* imaflag unused, only for version check */
+#define TEX_FIELDS_            8
+#define TEX_ANIMCYCLIC_        64
+#define TEX_ANIM5_             128
+#define TEX_ANTIALI_   256
+#define TEX_ANTISCALE_ 512
+#define TEX_STD_FIELD_ 1024
 
 /* flag */
 #define TEX_COLORBAND          1
index 27ccc318067b7186a61a1ad8a4c1e94ddd5e8906..451c9c231c2801aeb8c217a3a022be5a10d32662 100644 (file)
@@ -54,17 +54,16 @@ struct RetopoViewData;
 #endif
 
 #include "DNA_listBase.h"
+#include "DNA_image_types.h"
 
 /* The near/far thing is a Win EXCEPTION. Thus, leave near/far in the
  * code, and patch for windows. */
 
 typedef struct BGpic {
     struct Image *ima;
-       struct ImBuf *ibuf;
-       struct Tex *tex;
+       struct ImageUser iuser;
     float xof, yof, size, zoom, blend;
     short xim, yim;
-       unsigned int *rect;
 } BGpic;
 
 typedef struct View3D {
index ae51f85744e2c42f5f1c6983544f687552ba5e50..c5e8fb275593eb24b2015b5a72e44b1de74ccfe0 100644 (file)
@@ -1534,6 +1534,7 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
        PyObject *pyObjImage;
        BPy_Image *py_img;
        Image *image;
+       ImBuf *ibuf;
        float originX, originY;
        float zoomX = 1.0, zoomY = 1.0;
        int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
@@ -1559,14 +1560,15 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
        /* fetch a C Image pointer from the passed-in Python object */
        py_img = ( BPy_Image * ) pyObjImage;
        image = py_img->image;
-
-       /* load the image data if necessary */
-       if( !image->ibuf )      /* if no image data is available ... */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-       if( !image->ibuf )      /* if failed to load the image */
+       ibuf = BKE_image_get_ibuf( image, NULL );
+               
+       if( !ibuf )      /* if failed to load the image */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-                       "couldn't load image data in Blender" );
-
+                                                                         "couldn't load image data in Blender" );
+       if( !ibuf->rect )      /* no float yet */
+               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                                                         "Image has no byte rect" );
+       
        /* Update the time tag of the image */
        tag_image_time(image);
 
@@ -1575,12 +1577,12 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
         * the clipping is just checked against the bounds of the image.
         * if clipW or clipH are less than zero then they include as much of
         * the image as they can. */
-       clipX = EXPP_ClampInt( clipX, 0, image->ibuf->x );
-       clipY = EXPP_ClampInt( clipY, 0, image->ibuf->y );
-       if( ( clipW < 0 ) || ( clipW > ( image->ibuf->x - clipW ) ) )
-               clipW = image->ibuf->x - clipX;
-       if( ( clipH < 0 ) || ( clipH > ( image->ibuf->y - clipH ) ) )
-               clipH = image->ibuf->y - clipY;
+       clipX = EXPP_ClampInt( clipX, 0, ibuf->x );
+       clipY = EXPP_ClampInt( clipY, 0, ibuf->y );
+       if( ( clipW < 0 ) || ( clipW > ( ibuf->x - clipW ) ) )
+               clipW = ibuf->x - clipX;
+       if( ( clipH < 0 ) || ( clipH > ( ibuf->y - clipH ) ) )
+               clipH = ibuf->y - clipY;
 
        /* -- we are "Go" to Draw! -- */
 
@@ -1626,13 +1628,13 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
        /* set the width of the image (ROW_LENGTH), and the offset to the
         * clip origin within the image in x (SKIP_PIXELS) and 
         * y (SKIP_ROWS) */
-       glPixelStorei( GL_UNPACK_ROW_LENGTH,  image->ibuf->x );
+       glPixelStorei( GL_UNPACK_ROW_LENGTH,  ibuf->x );
        glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
        glPixelStorei( GL_UNPACK_SKIP_ROWS,   clipY );
 
        /* draw the image */
        glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE, 
-               image->ibuf->rect );
+               ibuf->rect );
 
        /* restore the defaults for some parameters (we could also use a
         * glPushClientAttrib() and glPopClientAttrib() pair). */
index 9d9ac6c6184d3804c5cb61f8b29113148d7009a5..75dae874dd712337377b0396e9d3d470340398a7 100644 (file)
@@ -232,12 +232,12 @@ static PyObject *M_Image_New( PyObject * self, PyObject * args)
        if (width > 5000 || height > 5000 || width < 1 || height < 1)
                return ( EXPP_ReturnPyObjError( PyExc_TypeError,
                                        "Image width and height must be between 1 and 5000" ) );
-       image = new_image(width, height, name, 0);
+       image = BKE_add_image_size(width, height, name, 0);
        if( !image )
                return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
                                                "couldn't create PyObject Image_Type" ) );
 
-       /* reset usage count, since new_image() incremented it */
+       /* reset usage count, since BKE_add_image_size() incremented it */
        /* image->id.us--; */
        /* Strange, new images have a user count of one???, otherwise it messes up */
        
@@ -354,14 +354,13 @@ static PyObject *M_Image_Load( PyObject * self, PyObject * args )
                return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
                                                "couldn't create PyObject Image_Type" ) );
 
-       img_ptr = add_image( fname );
+       img_ptr = BKE_add_image_file( fname );
        if( !img_ptr )
                return ( EXPP_ReturnPyObjError( PyExc_IOError,
                                                "couldn't load image" ) );
 
-       /*reload the image buffers*/
-       free_image_buffers(img_ptr);
-       img_ptr->ibuf = IMB_loadiffname(img_ptr->name , 0);
+       /* force a load the image buffers*/
+       BKE_image_get_ibuf(img_ptr, NULL);
 
        image->image = img_ptr;
 
@@ -380,7 +379,7 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
 {
 
        PyObject *attr;
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        char *pixel;            /* image data */
        int index;              /* offset into image data */
        int x = 0;
@@ -391,20 +390,17 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "expected 2 integers" );
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* loading didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       if( image->ibuf->type == 1 )    /* bitplane image */
+       if( ibuf->type == 1 )   /* bitplane image */
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "unsupported bitplane image format" );
 
-       if( x > ( image->ibuf->x - 1 )
-           || y > ( image->ibuf->y - 1 )
-           || x < image->ibuf->xorig || y < image->ibuf->yorig )
+       if( x > ( ibuf->x - 1 )
+           || y > ( ibuf->y - 1 )
+           || x < ibuf->xorig || y < ibuf->yorig )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "x or y is out of range" );
 
@@ -413,9 +409,9 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
           so we calc ourselves
         */
 
-       index = ( x + y * image->ibuf->x ) * pixel_size;
+       index = ( x + y * ibuf->x ) * pixel_size;
 
-       pixel = ( char * ) image->ibuf->rect;
+       pixel = ( char * ) ibuf->rect;
        attr = Py_BuildValue( "[f,f,f,f]",
                              ( ( float ) pixel[index] ) / 255.0,
                              ( ( float ) pixel[index + 1] ) / 255.0,
@@ -440,7 +436,7 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
 static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
 {
        PyObject *attr;
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        char *pixel;            /* image data */
        int index;              /* offset into image data */
        int x = 0;
@@ -451,20 +447,17 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "expected 2 integers" );
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       if( image->ibuf->type == 1 )    /* bitplane image */
+       if( ibuf->type == 1 )   /* bitplane image */
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "unsupported bitplane image format" );
 
-       if( x > ( image->ibuf->x - 1 )
-           || y > ( image->ibuf->y - 1 )
-           || x < image->ibuf->xorig || y < image->ibuf->yorig )
+       if( x > ( ibuf->x - 1 )
+           || y > ( ibuf->y - 1 )
+           || x < ibuf->xorig || y < ibuf->yorig )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "x or y is out of range" );
 
@@ -473,9 +466,9 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
           so we calc ourselves
         */
 
-       index = ( x + y * image->ibuf->x ) * pixel_size;
+       index = ( x + y * ibuf->x ) * pixel_size;
 
-       pixel = ( char * ) image->ibuf->rect;
+       pixel = ( char * ) ibuf->rect;
        attr = Py_BuildValue( "[i,i,i,i]",
                              pixel[index],
                              pixel[index + 1],
@@ -493,7 +486,7 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
 
 static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
 {
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        char *pixel;            /* image data */
        int index;              /* offset into image data */
        int x = 0;
@@ -507,20 +500,17 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "expected 2 integers and an array of 4 floats" );
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       if( image->ibuf->type == 1 )    /* bitplane image */
+       if( ibuf->type == 1 )   /* bitplane image */
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "unsupported bitplane image format" );
 
-       if( x > ( image->ibuf->x - 1 )
-           || y > ( image->ibuf->y - 1 )
-           || x < image->ibuf->xorig || y < image->ibuf->yorig )
+       if( x > ( ibuf->x - 1 )
+           || y > ( ibuf->y - 1 )
+           || x < ibuf->xorig || y < ibuf->yorig )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "x or y is out of ruange" );
 
@@ -536,9 +526,9 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
           so we calc ourselves
         */
 
-       index = ( x + y * image->ibuf->x ) * pixel_size;
+       index = ( x + y * ibuf->x ) * pixel_size;
 
-       pixel = ( char * ) image->ibuf->rect;
+       pixel = ( char * ) ibuf->rect;
 
        pixel[index] = ( char ) ( p[0] * 255.0 );
        pixel[index + 1] = ( char ) ( p[1] * 255.0 );
@@ -553,7 +543,7 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
 
 static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
 {
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        char *pixel;            /* image data */
        int index;              /* offset into image data */
        int x = 0;
@@ -567,20 +557,17 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "expected 2 integers and an list of 4 ints" );
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       if( image->ibuf->type == 1 )    /* bitplane image */
+       if( ibuf->type == 1 )   /* bitplane image */
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                              "unsupported bitplane image format" );
 
-       if( x > ( image->ibuf->x - 1 )
-           || y > ( image->ibuf->y - 1 )
-           || x < image->ibuf->xorig || y < image->ibuf->yorig )
+       if( x > ( ibuf->x - 1 )
+           || y > ( ibuf->y - 1 )
+           || x < ibuf->xorig || y < ibuf->yorig )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "x or y is out of range" );
 
@@ -595,9 +582,9 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
           so we calc ourselves
         */
 
-       index = ( x + y * image->ibuf->x ) * pixel_size;
+       index = ( x + y * ibuf->x ) * pixel_size;
 
-       pixel = ( char * ) image->ibuf->rect;
+       pixel = ( char * ) ibuf->rect;
 
        pixel[index] = ( char ) p[0];
        pixel[index + 1] = ( char ) p[1];
@@ -612,17 +599,14 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
 
 static PyObject *Image_getMaxXY( BPy_Image * self )
 {
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        PyObject *attr;
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       attr = Py_BuildValue( "[i,i]", image->ibuf->x, image->ibuf->y );
+       attr = Py_BuildValue( "[i,i]", ibuf->x, ibuf->y );
 
        if( attr )
                return attr;
@@ -636,18 +620,15 @@ static PyObject *Image_getMaxXY( BPy_Image * self )
 
 static PyObject *Image_getMinXY( BPy_Image * self )
 {
-       Image *image = self->image;
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        PyObject *attr;
 
-       if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
+       if( !ibuf || !ibuf->rect )      /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       attr = Py_BuildValue( "[i,i]", image->ibuf->xorig,
-                             image->ibuf->yorig );
+       attr = Py_BuildValue( "[i,i]", ibuf->xorig,
+                             ibuf->yorig );
 
        if( attr )
                return attr;
@@ -713,9 +694,9 @@ static PyObject *Image_makeCurrent( BPy_Image * self )
 
 static PyObject *Image_save( BPy_Image * self )
 {
-       if( !IMB_saveiff
-           ( self->image->ibuf, self->image->name,
-             self->image->ibuf->flags ) )
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+       
+       if(!ibuf || !IMB_saveiff( ibuf, self->image->name, ibuf->flags ) )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "could not save image" );
 
@@ -849,18 +830,14 @@ static PyObject *Image_getFilename( BPy_Image * self )
 
 static PyObject *Image_getSize( BPy_Image * self )
 {
-       PyObject *attr;
-       Image *image = self->image;
-       
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+       PyObject *attr; 
        
-       if( !image->ibuf ) /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-       if( !image->ibuf )      /* didn't work */
+       if( !ibuf )     /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       attr = Py_BuildValue( "[hh]", image->ibuf->x, image->ibuf->y );
+       attr = Py_BuildValue( "[hh]", ibuf->x, ibuf->y );
 
        if( attr )
                return attr;
@@ -871,17 +848,14 @@ static PyObject *Image_getSize( BPy_Image * self )
 
 static PyObject *Image_getDepth( BPy_Image * self )
 {
+       ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
        PyObject *attr;
-       Image *image = self->image;
-
-       if( !image->ibuf )      /* if no image data available */
-               load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
 
-       if( !image->ibuf )      /* didn't work */
+       if( !ibuf )     /* didn't work */
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                              "couldn't load image data in Blender" );
 
-       attr = Py_BuildValue( "h", image->ibuf->depth );
+       attr = Py_BuildValue( "h", ibuf->depth );
 
        if( attr )
                return attr;
@@ -961,8 +935,8 @@ static PyObject *Image_reload( BPy_Image * self )
 {
        Image *image = self->image;
 
-       free_image_buffers( image );    /* force read again */
-       image->ok = 1;
+       BKE_image_signal(image, NULL, IMA_SIGNAL_RELOAD);
+
        Py_RETURN_NONE;
 }
 
@@ -982,29 +956,27 @@ static PyObject *Image_glLoad( BPy_Image * self )
        unsigned int *bind = &image->bindcode;
 
        if( *bind == 0 ) {
+               ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
 
-               if( !image->ibuf )      /* if no image data is available */
-                       load_image( image, IB_rect, G.sce,  G.scene->r.cfra );  /* loading it */
-
-               if( !image->ibuf )      /* didn't work */
+               if( !ibuf )     /* didn't work */
                        return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                                      "couldn't load image data in Blender" );
 
                glGenTextures( 1, ( GLuint * ) bind );
                glBindTexture( GL_TEXTURE_2D, *bind );
 
-               gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, image->ibuf->x,
-                                  image->ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
-                                  image->ibuf->rect );
+               gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, ibuf->x,
+                                  ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+                                  ibuf->rect );
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                                 GL_LINEAR_MIPMAP_NEAREST );
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                                 GL_LINEAR );
                glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
 
-               glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image->ibuf->x,
-                             image->ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-                             image->ibuf->rect );
+               glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ibuf->x,
+                             ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                             ibuf->rect );
 
                /* raise the nocollect flag, 
                   image is not available for garbage collection 
@@ -1176,7 +1148,7 @@ static PyObject *Image_getAttr( BPy_Image * self, char *name )
                else
                        attr = EXPP_incr_ret_False();
        } else if( strcmp( name, "has_data" ) == 0 ) {
-               if (self->image->ibuf)
+               if (self->image->ibufs.first)
                        attr = EXPP_incr_ret_True();
                else
                        attr = EXPP_incr_ret_False();
index 1e2588ea43e5a8e55fc60cb6743e1e2341c96bc0..42e8e1ca5f843c1bea459652aa287003215a6f3d 100644 (file)
@@ -208,17 +208,13 @@ static const EXPP_map_pair tex_flag_map[] = {
        {NULL, 0}
 };
 
+/* NOTE: flags moved to image... */
 static const EXPP_map_pair tex_imageflag_map[] = {
        {"InterPol", TEX_INTERPOL},
        {"UseAlpha", TEX_USEALPHA},
        {"MipMap", TEX_MIPMAP},
-       {"Fields", TEX_FIELDS},
        {"Rot90", TEX_IMAROT},
        {"CalcAlpha", TEX_CALCALPHA},
-       {"Cyclic", TEX_ANIMCYCLIC},
-       {"Movie", TEX_ANIM5},
-       {"StField", TEX_STD_FIELD},
-       {"Anti", TEX_ANTIALI},
        {"NormalMap", TEX_NORMALMAP},
        {NULL, 0}
 };
@@ -397,6 +393,10 @@ GETFUNC( getName );
 GETFUNC( getType );
 GETFUNC( getSType );
 GETFUNC( clearIpo );
+GETFUNC( getAnimMontage );
+GETFUNC( getAnimLength );
+SETFUNC( setAnimLength );
+SETFUNC( setAnimMontage );
 #endif
 
 GETFUNC( oldgetSType );
@@ -405,8 +405,6 @@ GETFUNC( oldgetType );
 GETFUNC(getProperties);
 GETFUNC( clearIpo );
 GETFUNC( getAnimFrames );
-GETFUNC( getAnimLength );
-GETFUNC( getAnimMontage );
 GETFUNC( getAnimOffset );
 GETFUNC( getAnimStart );
 GETFUNC( getBrightness );
@@ -455,8 +453,6 @@ OLDSETFUNC( setSType );
 OLDSETFUNC( setType );
 
 SETFUNC( setAnimFrames );
-SETFUNC( setAnimLength );
-SETFUNC( setAnimMontage );
 SETFUNC( setAnimOffset );
 SETFUNC( setAnimStart );
 SETFUNC( setBrightness );
@@ -552,6 +548,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
         (getter)Texture_getAnimFrames, (setter)Texture_setAnimFrames,
         "Number of frames of a movie to use",
         NULL},
+#if 0
        {"animLength",
         (getter)Texture_getAnimLength, (setter)Texture_setAnimLength,
         "Number of frames of a movie to use (0 for all)",
@@ -560,6 +557,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
         (getter)Texture_getAnimMontage, (setter)Texture_setAnimMontage,
         "Montage mode, start frames and durations",
         NULL},
+#endif
        {"animOffset",
         (getter)Texture_getAnimOffset, (setter)Texture_setAnimOffset,
         "Offsets the number of the first movie frame to use",
@@ -729,14 +727,16 @@ static PyGetSetDef BPy_Texture_getseters[] = {
         (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
         "Mipmaps enabled ('ImageFlags')",
         (void *)TEX_MIPMAP},
-       {"fields",
-        (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
-        "Use of image's fields enabled ('ImageFlags')",
-        (void *)TEX_FIELDS},
        {"rot90",
         (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
         "X/Y flip for rendering enabled ('ImageFlags')",
         (void *)TEX_IMAROT},
+#if 0
+       /* disabled, moved to image */
+       {"fields",
+        (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
+        "Use of image's fields enabled ('ImageFlags')",
+        (void *)TEX_FIELDS},
        {"cyclic",
         (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
         "Looping of animated frames enabled ('ImageFlags')",
@@ -753,6 +753,7 @@ static PyGetSetDef BPy_Texture_getseters[] = {
         (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
         "Standard field deinterlacing enabled ('ImageFlags')",
         (void *)TEX_STD_FIELD},
+#endif
        {"normalMap",
         (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
         "Use of image RGB values for normal mapping enabled ('ImageFlags')",
@@ -1174,12 +1175,8 @@ static PyObject *M_Texture_ImageFlagsDict( void )
                PyConstant_Insert(d, "INTERPOL", PyInt_FromLong(TEX_INTERPOL));
                PyConstant_Insert(d, "USEALPHA", PyInt_FromLong(TEX_USEALPHA));
                PyConstant_Insert(d, "MIPMAP", PyInt_FromLong(TEX_MIPMAP));
-               PyConstant_Insert(d, "FIELDS", PyInt_FromLong(TEX_FIELDS));
                PyConstant_Insert(d, "ROT90", PyInt_FromLong(TEX_IMAROT));
                PyConstant_Insert(d, "CALCALPHA", PyInt_FromLong(TEX_CALCALPHA));
-               PyConstant_Insert(d, "STFIELD", PyInt_FromLong(TEX_STD_FIELD));
-               PyConstant_Insert(d, "MOVIE", PyInt_FromLong(TEX_ANIM5));
-               PyConstant_Insert(d, "CYCLIC", PyInt_FromLong(TEX_ANIMCYCLIC));
                PyConstant_Insert(d, "NORMALMAP", PyInt_FromLong(TEX_NORMALMAP));
        }
        return ImageFlags;
@@ -1422,11 +1419,13 @@ static PyObject *Texture_oldgetType( BPy_Texture * self )
 
 static int Texture_setAnimFrames( BPy_Texture * self, PyObject * value )
 {
-       return EXPP_setIValueClamped ( value, &self->texture->frames,
+       return EXPP_setIValueClamped ( value, &self->texture->iuser.frames,
                                                                EXPP_TEX_ANIMFRAME_MIN,
                                                                EXPP_TEX_ANIMFRAME_MAX, 'h' );
 }
 
+#if 0
+/* this was stupid to begin with! (ton) */
 static int Texture_setAnimLength( BPy_Texture * self, PyObject * value )
 {
        return EXPP_setIValueClamped ( value, &self->texture->len,
@@ -1434,6 +1433,7 @@ static int Texture_setAnimLength( BPy_Texture * self, PyObject * value )
                                                                EXPP_TEX_ANIMLEN_MAX, 'h' );
 }
 
+/* this is too simple to keep supporting? disabled for time being (ton) */
 static int Texture_setAnimMontage( BPy_Texture * self, PyObject * value )
 {
        int fradur[4][2];
@@ -1458,17 +1458,18 @@ static int Texture_setAnimMontage( BPy_Texture * self, PyObject * value )
 
        return 0;
 }
+#endif
 
 static int Texture_setAnimOffset( BPy_Texture * self, PyObject * value )
 {
-       return EXPP_setIValueClamped ( value, &self->texture->offset,
+       return EXPP_setIValueClamped ( value, &self->texture->iuser.offset,
                                                                EXPP_TEX_ANIMOFFSET_MIN,
                                                                EXPP_TEX_ANIMOFFSET_MAX, 'h' );
 }
 
 static int Texture_setAnimStart( BPy_Texture * self, PyObject * value )
 {
-       return EXPP_setIValueClamped ( value, &self->texture->sfra,
+       return EXPP_setIValueClamped ( value, &self->texture->iuser.sfra,
                                                                EXPP_TEX_ANIMSTART_MIN,
                                                                EXPP_TEX_ANIMSTART_MAX, 'h' );
 }
@@ -1610,13 +1611,8 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
                int bitmask = TEX_INTERPOL
                                        | TEX_USEALPHA
                                        | TEX_MIPMAP
-                                       | TEX_FIELDS
                                        | TEX_IMAROT
                                        | TEX_CALCALPHA
-                                       | TEX_ANIMCYCLIC
-                                       | TEX_ANIM5
-                                       | TEX_ANTIALI
-                                       | TEX_STD_FIELD
                                        | TEX_NORMALMAP;
 
                if( !PyInt_CheckExact ( value ) ) {
@@ -1631,13 +1627,6 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
                                                        "invalid bit(s) set in mask" );
        }
 
-       /* "mipmap" and "fields" can't be set at the same time */
-
-       if( ( param & TEX_MIPMAP ) &&
-                       ( param & TEX_FIELDS ) )
-               return EXPP_ReturnIntError( PyExc_ValueError,
-                               "image flags MIPMAP and FIELDS cannot be used together" );
-
        /* everything is OK; save the new flag setting */
 
        self->texture->imaflag = param;
@@ -2024,6 +2013,8 @@ static PyObject *Texture_getAnimFrames( BPy_Texture *self )
        return attr;
 }
 
+#if 0
+/* disabled. this option was too stupid! (ton) */
 static PyObject *Texture_getAnimLength( BPy_Texture *self )
 {
        PyObject *attr = PyInt_FromLong( self->texture->len );
@@ -2055,10 +2046,11 @@ static PyObject *Texture_getAnimMontage( BPy_Texture *self )
 
        return attr;
 }
+#endif
 
 static PyObject *Texture_getAnimOffset( BPy_Texture *self )
 {
-       PyObject *attr = PyInt_FromLong( self->texture->offset );
+       PyObject *attr = PyInt_FromLong( self->texture->iuser.offset );
 
        if( !attr )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -2069,7 +2061,7 @@ static PyObject *Texture_getAnimOffset( BPy_Texture *self )
 
 static PyObject *Texture_getAnimStart( BPy_Texture *self )
 {
-       PyObject *attr = PyInt_FromLong( self->texture->sfra );
+       PyObject *attr = PyInt_FromLong( self->texture->iuser.sfra );
 
        if( !attr )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -2162,7 +2154,7 @@ static PyObject *Texture_getIntExtend( BPy_Texture * self )
 
 static PyObject *Texture_getFieldsPerImage( BPy_Texture *self )
 {
-       PyObject *attr = PyInt_FromLong( self->texture->fie_ima );
+       PyObject *attr = PyInt_FromLong( self->texture->iuser.fie_ima );
 
        if( !attr )
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
index 8ef3c09ab002deafbcc9864fd8f2ea9c94adf51f..2add056b4c83afeefdc09e1d7715d5981593993c 100644 (file)
@@ -42,6 +42,7 @@ struct View3D; /* keep me up here */
 
 #include "BIF_drawscene.h"
 #include "BIF_renderwin.h"
+#include "BIF_writeimage.h"
 
 #include "BLI_blenlib.h"
 
@@ -108,7 +109,6 @@ enum rend_constants {
 #define EXPP_RENDER_ATTR_YF_GIMETHOD         34
 #define EXPP_RENDER_ATTR_YF_GIQUALITY        35
 
-extern void save_rendered_image_cb_real(char *name, int zbuf, int confirm);
 
 /* Render doc strings */
 static char M_Render_doc[] = "The Blender Render module";
@@ -420,8 +420,8 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
        char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
        char *name_str, filepath[FILE_MAXDIR+FILE_MAXFILE];
        RenderResult *rr = NULL;
-       int zbuff = 0;
-
+       int zbuff;
+       
        if( !PyArg_ParseTuple( args, "s|i", &name_str, &zbuff ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                "expected a filename (string) and optional int" );
@@ -431,7 +431,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
                return EXPP_ReturnPyObjError( PyExc_ValueError,
                                "full filename too long" );
 
-       if (zbuff !=0   ) zbuff = 1; /*required 1/0 */
+       if (zbuff !=0   ) zbuff = 1; /*required 1/0 */ /* removed! (ton) */
 
        BLI_strncpy( filepath, self->renderContext->pic, sizeof(filepath) );
        strcat(filepath, name_str);
@@ -445,7 +445,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
                        BLI_splitdirstring(dir, str);
                        strcpy(G.ima, dir);
                }
-               save_rendered_image_cb_real(filepath, zbuff,0);
+               BIF_save_rendered_image(filepath);
        }
        return EXPP_incr_ret(Py_None);
 }
@@ -1902,11 +1902,9 @@ static int RenderData_setBackbufPath( BPy_RenderData *self, PyObject *value )
        strcpy( self->renderContext->backbuf, name );
        EXPP_allqueue( REDRAWBUTSSCENE, 0 );
 
-       ima = add_image( name );
-       if( ima ) {
-               free_image_buffers( ima );
-               ima->ok = 1;
-       }
+       ima = BKE_add_image_file( name );
+       if( ima )
+               BKE_image_signal( ima, NULL, IMA_SIGNAL_RELOAD );
 
        return 0;
 }
index 22b623816ab21f9052769a4488e9b25e486972bc..72f266630c4b53bdce5717afb27add4aa4207706 100644 (file)
@@ -59,11 +59,14 @@ typedef struct Render Render;
 typedef struct RenderPass {
        struct RenderPass *next, *prev;
        int passtype, channels;
+       char name[16];          /* amount defined in openexr_multi.h */
+       char chan_id[8];        /* amount defined in openexr_multi.h */
        float *rect;
 } RenderPass;
 
 /* a renderlayer is a full image, but with all passes and samples */
 /* size of the rects is defined in RenderResult */
+/* after render, the Combined pass is in rectf, for renderlayers read from files it is a real pass */
 typedef struct RenderLayer {
        struct RenderLayer *next, *prev;
        
@@ -75,7 +78,7 @@ typedef struct RenderLayer {
        struct Material *mat_override;
        struct Group *light_override;
        
-       float *rectf;           /* 4 float, standard rgba buffer */
+       float *rectf;           /* 4 float, standard rgba buffer (read not above!) */
        float *acolrect;        /* 4 float, optional transparent buffer, needs storage for display updates */
        
        ListBase passes;
@@ -111,6 +114,9 @@ typedef struct RenderResult {
        char exrfile[FILE_MAXDIR];
        void *exrhandle;
        
+       /* for render results in Image, verify validity for sequences */
+       int framenr;
+       
 } RenderResult;
 
 typedef struct RenderStats {
@@ -134,6 +140,7 @@ void RE_FreeRender (struct Render *re);
 void RE_FreeAllRender (void);
 
 /* get results and statistics */
+void RE_FreeRenderResult(struct RenderResult *rr);
 struct RenderResult *RE_GetResult(struct Render *re);
 void RE_GetResultImage(struct Render *re, struct RenderResult *rr);
 struct RenderStats *RE_GetStats(struct Render *re);
@@ -173,6 +180,8 @@ void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
 void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra);
 
 void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
+void RE_WriteRenderResult(RenderResult *rr, char *filename);
+struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty);
 
 /* ancient stars function... go away! */
 void RE_make_stars(struct Render *re, void (*initfunc)(void),
index 13ab6f7cd677a4f85d1641cf09f1b13ce31b1211..6c7d12c4c8c10ef484b98a5d1d3c8291ca837aaa 100644 (file)
@@ -51,6 +51,7 @@ struct ShadeInput;
 struct TexResult;
 struct Tex;
 struct Image;
+struct ImBuf;
 
 /* texture.h */
 
@@ -65,8 +66,8 @@ void render_realtime_texture(struct ShadeInput *shi);
 
 /* imagetexture.h */
 
-int imagewraposa(struct Tex *tex, struct Image *ima, float *texvec, float *dxt, float *dyt, struct TexResult *texres);
-int imagewrap(struct Tex *tex, struct Image *ima, float *texvec, struct TexResult *texres);
+int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, float *dxt, float *dyt, struct TexResult *texres);
+int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, struct TexResult *texres);
 void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float *result);
 
 #endif /* TEXTURE_EXT_H */
index c6845754a7dda8383ff52c7970bc2d652a602809..4f7420bacc2ebf565033f2ddbcd4ddd7149231fa 100644 (file)
@@ -2989,7 +2989,7 @@ void RE_Database_Free(Render *re)
        if(re->scene)
                if(re->scene->r.scemode & R_FREE_IMAGE)
                        if((re->r.scemode & R_PREVIEWBUTS)==0)
-                               free_all_imagetextures();
+                               BKE_image_free_all_textures();
 
 }