Orange: more exr & imbuf cleanup
[blender.git] / source / blender / imbuf / intern / openexr / openexr_api.cpp
index 86beab537ef2430509ed961053a534be446b6bd7..c90278c45146e5f261c8bb8d2049ee80c1b64471 100644 (file)
@@ -39,8 +39,6 @@ extern "C"
 #include "IMB_imbuf.h"
        
 #include "IMB_allocimbuf.h"
 #include "IMB_imbuf.h"
        
 #include "IMB_allocimbuf.h"
-#include "BKE_global.h"
-#include "DNA_scene_types.h"
 }
 
 #include <iostream>
 }
 
 #include <iostream>
@@ -150,27 +148,18 @@ static void openexr_header_compression(Header *header, int compression)
        }
 }
 
        }
 }
 
-short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
+static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
 {
        
        int width = ibuf->x;
        int height = ibuf->y;
 {
        
        int width = ibuf->x;
        int height = ibuf->y;
-       
-       if (flags & IB_mem) 
-       {
-               printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
-               imb_addencodedbufferImBuf(ibuf);
-               ibuf->encodedsize = 0;    
-               return(0);
-       } 
-       
        int write_zbuf = (flags & IB_zbuf) && ibuf->zbuf != NULL;   // summarize
        
        try
        {
                Header header (width, height);
                
        int write_zbuf = (flags & IB_zbuf) && ibuf->zbuf != NULL;   // summarize
        
        try
        {
                Header header (width, height);
                
-               openexr_header_compression(&header, G.scene->r.quality);
+               openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS);
                
                header.channels().insert ("R", Channel (HALF));
                header.channels().insert ("G", Channel (HALF));
                
                header.channels().insert ("R", Channel (HALF));
                header.channels().insert ("G", Channel (HALF));
@@ -249,30 +238,18 @@ short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
        return (1);
 }
 
        return (1);
 }
 
-short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
+static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
 {
        
        int width = ibuf->x;
        int height = ibuf->y;
 {
        
        int width = ibuf->x;
        int height = ibuf->y;
-       
-       if (flags & IB_mem) 
-       {
-               printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
-               imb_addencodedbufferImBuf(ibuf);
-               ibuf->encodedsize = 0;    
-               return(0);
-       } 
-       
-       if (ibuf->rect_float==NULL)
-               return(0);
-       
        int write_zbuf = (flags & IB_zbuf) && ibuf->zbuf != NULL;   // summarize
        
        try
        {
                Header header (width, height);
                
        int write_zbuf = (flags & IB_zbuf) && ibuf->zbuf != NULL;   // summarize
        
        try
        {
                Header header (width, height);
                
-               openexr_header_compression(&header, G.scene->r.quality);
+               openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS);
                
                header.channels().insert ("R", Channel (FLOAT));
                header.channels().insert ("G", Channel (FLOAT));
                
                header.channels().insert ("R", Channel (FLOAT));
                header.channels().insert ("G", Channel (FLOAT));
@@ -313,18 +290,57 @@ short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
 }
 
 
 }
 
 
+short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
+{
+       if (flags & IB_mem) 
+       {
+               printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
+               imb_addencodedbufferImBuf(ibuf);
+               ibuf->encodedsize = 0;    
+               return(0);
+       } 
+       
+       if (ibuf->ftype & OPENEXR_HALF) 
+               return imb_save_openexr_half(ibuf, name, flags);
+       else {
+               /* when no float rect, we save as half (16 bits is sufficient) */
+               if (ibuf->rect_float==NULL)
+                       return imb_save_openexr_half(ibuf, name, flags);
+               else
+                       return imb_save_openexr_float(ibuf, name, flags);
+       }
+}
+
+
+typedef struct RGBA
+{
+       float r;
+       float g;
+       float b;
+       float a;
+} RGBA;
 
 
+
+static void exr_print_filecontents(InputFile *file)
+{
+       const ChannelList &channels = file->header().channels();
+       
+       for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+       {
+               const Channel &channel = i.channel();
+               printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
+       }
+       
+}
 struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
 {
 struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
 {
-       struct ImBuf *ibuf = 0;
+       struct ImBuf *ibuf = NULL;
        InputFile *file = NULL;
        
        InputFile *file = NULL;
        
-//     printf("OpenEXR-load: testing input, size is %d\n", size);
        if (imb_is_a_openexr(mem) == 0) return(NULL);
        
        try
        {
        if (imb_is_a_openexr(mem) == 0) return(NULL);
        
        try
        {
-//             printf("OpenEXR-load: Creating InputFile from mem source\n");
                Mem_IStream membuf(mem, size); 
                file = new InputFile(membuf);
                
                Mem_IStream membuf(mem, size); 
                file = new InputFile(membuf);
                
@@ -334,99 +350,40 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                
 //             printf("OpenEXR-load: image data window %d %d %d %d\n", 
 //                        dw.min.x, dw.min.y, dw.max.x, dw.max.y);
                
 //             printf("OpenEXR-load: image data window %d %d %d %d\n", 
 //                        dw.min.x, dw.min.y, dw.max.x, dw.max.y);
+
+//             exr_print_filecontents(file);
                
                
-               const ChannelList &channels = file->header().channels();
-               
-               for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
-               {
-                       const Channel &channel = i.channel();
-//                     printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
-                       if (channel.type != 1)
-                       {
-                               printf("OpenEXR-load: Can only process HALF input !!\n");
-                               return(NULL);
-                       }
-               }
-               
-               RGBAZ *pixels = new RGBAZ[height * width];
-               
-               FrameBuffer frameBuffer;
-               
-               frameBuffer.insert ("R",
-                                                       Slice (HALF,
-                                                                  (char *) &pixels[0].r,
-                                                                  sizeof (pixels[0]) * 1,
-                                                                  sizeof (pixels[0]) * width));
-               
-               frameBuffer.insert ("G",
-                                                       Slice (HALF,
-                                                                  (char *) &pixels[0].g,
-                                                                  sizeof (pixels[0]) * 1,
-                                                                  sizeof (pixels[0]) * width));
-               
-               frameBuffer.insert ("B",
-                                                       Slice (HALF,
-                                                                  (char *) &pixels[0].b,
-                                                                  sizeof (pixels[0]) * 1,
-                                                                  sizeof (pixels[0]) * width));
-               
-               frameBuffer.insert ("A",
-                                                       Slice (HALF,
-                                                                  (char *) &pixels[0].a,
-                                                                  sizeof (pixels[0]) * 1,
-                                                                  sizeof (pixels[0]) * width));
-               
-               // FIXME ? Would be able to read Z data or other channels here ! 
-               
-//             printf("OpenEXR-load: Reading pixel data\n");
-               file->setFrameBuffer (frameBuffer);
-               file->readPixels (dw.min.y, dw.max.y);
-               
-//             printf("OpenEXR-load: Converting to Blender float ibuf\n");
-               
-               int bytesperpixel = 4; // since OpenEXR fills in unknown channels
-               ibuf = IMB_allocImBuf(width, height, 8 * bytesperpixel, 0, 0);
+               ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
                
                if (ibuf) 
                {
                        ibuf->ftype = OPENEXR;
                        
                
                if (ibuf) 
                {
                        ibuf->ftype = OPENEXR;
                        
-                       imb_addrectImBuf(ibuf);
-                       imb_addrectfloatImBuf(ibuf);
-                       
                        if (!(flags & IB_test))
                        {
                        if (!(flags & IB_test))
                        {
-                               unsigned char *to = (unsigned char *) ibuf->rect;
-                               float *tof = ibuf->rect_float;
-                               RGBAZ *from = pixels;
-                               RGBAZ prescale;
+                               FrameBuffer frameBuffer;
                                
                                
-                               for (int i = ibuf->x * ibuf->y; i > 0; i--) 
-                               {
-                                       to[0] = (unsigned char)(from->r > 1.0 ? 1.0 : (float)from->r)  * 255;
-                                       to[1] = (unsigned char)(from->g > 1.0 ? 1.0 : (float)from->g)  * 255;
-                                       to[2] = (unsigned char)(from->b > 1.0 ? 1.0 : (float)from->b)  * 255;
-                                       to[3] = (unsigned char)(from->a > 1.0 ? 1.0 : (float)from->a)  * 255;
-                                       to += 4; 
-                                       
-                                       tof[0] = from->r;
-                                       tof[1] = from->g;
-                                       tof[2] = from->b;
-                                       tof[3] = from->a;
-                                       
-                                       from++;
-                               }
+                               imb_addrectfloatImBuf(ibuf);
+                               
+                               float *first= ibuf->rect_float + 4*(height-1)*width;
+                               int xstride = sizeof(float) * 4;
+                               int ystride = - xstride*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));
+                               frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride));
+                               
+                               // FIXME ? Would be able to read Z data or other channels here ! 
+                               
+                               file->setFrameBuffer (frameBuffer);
+                               file->readPixels (dw.min.y, dw.max.y);
+                               
+                               IMB_rect_from_float(ibuf);
                        }
                        }
-                       
-                       IMB_flipy(ibuf);
-                       
-               } 
-               else 
-                       printf("Couldn't allocate memory for OpenEXR image\n");
-               
-//             printf("OpenEXR-load: Done\n");
-               
+               }
                return(ibuf);
                return(ibuf);
+                               
        }
        catch (const std::exception &exc)
        {
        }
        catch (const std::exception &exc)
        {
@@ -437,5 +394,6 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
        }
        
 }
        }
        
 }
-       
+
+
 } // export "C"
 } // export "C"