Orange: more exr & imbuf cleanup
authorTon Roosendaal <ton@blender.org>
Mon, 9 Jan 2006 19:17:37 +0000 (19:17 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 9 Jan 2006 19:17:37 +0000 (19:17 +0000)
- Reading exr images now goes OK. I've unified the code for reading
  'half' and 'float' (was nicely possible!). And removed useless copying
  of data around.

- Fixed bug in allocating new rects, like for making mipmaps. flag issues.

- filter code accidentally incremented wrong pointer (crash on mipmap too)

source/blender/blenkernel/intern/writeavi.c
source/blender/imbuf/IMB_imbuf.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

index a97f1c1..0d94215 100644 (file)
@@ -43,9 +43,6 @@
 #include "BKE_bad_level_calls.h"
 #include "BKE_global.h"
 
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
 /* RPW 11-21-2002 */
 #include "DNA_scene_types.h"
 /* RPW - End */
index aa69e68..63ffeb0 100644 (file)
@@ -330,6 +330,7 @@ int imb_get_anim_type(char * name);
 void IMB_de_interlace(struct ImBuf *ibuf);
 void IMB_interlace(struct ImBuf *ibuf);
 void IMB_gamwarp(struct ImBuf *ibuf, double gamma);
+void IMB_rect_from_float(struct ImBuf *ibuf);
 
 /**
  * Change the ordering of the colour bytes pointed to by rect from
index 8344e97..137795e 100644 (file)
@@ -146,6 +146,7 @@ short addzbufImBuf(struct ImBuf * ibuf)
        size = ibuf->x * ibuf->y * sizeof(unsigned int);
        if ( (ibuf->zbuf = MEM_mallocN(size, "addzbufImBuf")) ){
                ibuf->mall |= IB_zbuf;
+               ibuf->flags |= IB_zbuf;
                return (TRUE);
        }
 
@@ -166,6 +167,7 @@ short imb_addencodedbufferImBuf(struct ImBuf * ibuf)
 
        if ( (ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf") )){
                ibuf->mall |= IB_mem;
+               ibuf->flags |= IB_mem;
                return (TRUE);
        }
 
@@ -205,6 +207,7 @@ short imb_enlargeencodedbufferImBuf(struct ImBuf * ibuf)
        ibuf->encodedsize = encodedsize;
        ibuf->encodedbuffer = newbuffer;
        ibuf->mall |= IB_mem;
+       ibuf->flags |= IB_mem;
 
        return (TRUE);
 }
@@ -220,8 +223,9 @@ short imb_addrectfloatImBuf(struct ImBuf * ibuf)
        size = ibuf->x * ibuf->y;
        size = size * 4 * sizeof(float);
        
-       if ( (ibuf->rect_float = MEM_mallocN(size, "imb_addrectImBuf")) ){
+       if ( (ibuf->rect_float = MEM_mallocN(size, "imb_addrectfloatImBuf")) ){
                ibuf->mall |= IB_rectfloat;
+               ibuf->flags |= IB_rectfloat;
                return (TRUE);
        }
        
@@ -241,6 +245,7 @@ short imb_addrectImBuf(struct ImBuf * ibuf)
 
        if ( (ibuf->rect = MEM_mallocN(size, "imb_addrectImBuf")) ){
                ibuf->mall |= IB_rect;
+               ibuf->flags |= IB_rect;
                if (ibuf->depth > 32) return (addzbufImBuf(ibuf));
                else return (TRUE);
        }
@@ -264,6 +269,7 @@ short imb_addcmapImBuf(struct ImBuf *ibuf)
                if (min > sizeof(dfltcmap)) min = sizeof(dfltcmap);
                memcpy(ibuf->cmap, dfltcmap, min);
                ibuf->mall |= IB_cmap;
+               ibuf->flags |= IB_cmap;
                return (TRUE);
        }
 
@@ -299,6 +305,7 @@ short imb_addplanesImBuf(struct ImBuf *ibuf)
                point2 += size;
        }
        ibuf->mall |= IB_planes;
+       ibuf->flags |= IB_planes;
 
        return (TRUE);
 }
index a56f16f..07ba4ee 100644 (file)
@@ -38,6 +38,7 @@
 #include "imbuf_patch.h"
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
+#include "IMB_allocimbuf.h"
 #include "IMB_divers.h"
 
 void imb_checkncols(struct ImBuf *ibuf)
@@ -164,3 +165,28 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
                }
        }
 }
+
+void IMB_rect_from_float(struct ImBuf *ibuf)
+{
+       /* quick method to convert floatbuf to byte */
+       float *tof = ibuf->rect_float;
+       int i;
+       unsigned char *to = (unsigned char *) ibuf->rect;
+       
+       if(tof==NULL) return;
+       if(to==NULL) {
+               imb_addrectImBuf(ibuf);
+               to = (unsigned char *) ibuf->rect;
+       }
+       
+       for (i = ibuf->x * ibuf->y; i > 0; i--) 
+       {
+               to[0] = tof[0] > 1.0 ? 255 : (unsigned char)(tof[0] * 255.0f);
+               to[1] = tof[1] > 1.0 ? 255 : (unsigned char)(tof[1] * 255.0f);
+               to[2] = tof[2] > 1.0 ? 255 : (unsigned char)(tof[2] * 255.0f);
+               to[3] = tof[3] > 1.0 ? 255 : (unsigned char)(tof[3] * 255.0f);
+               to += 4; 
+               tof += 4;
+       }
+                               
+}
index e51f85a..9e62a9e 100644 (file)
@@ -67,21 +67,21 @@ static void filtrow(unsigned char *point, int x)
 
 static void filtrowf(float *point, int x)
 {
-        float c1,c2,c3,error;
-
-        if (x>1){
-                c1 = c2 = *point;
-                error = 2;
-                for(x--;x>0;x--){
-                        c3 = point[4];
-                        c1 += (c2 * 2) + c3 + error;
-                        *point = c1 / 4.0;
-                        point += 4;
-                        c1=c2;
-                        c2=c3;
-                }
-                *point = (c1 + (c2 * 2) + c2 + error) / 4.0;
-        }
+       float c1,c2,c3,error;
+       
+       if (x>1){
+               c1 = c2 = *point;
+               error = 2;
+               for(x--;x>0;x--){
+                       c3 = point[4];
+                       c1 += (c2 * 2) + c3 + error;
+                       *point = c1 / 4.0;
+                       point += 4;
+                       c1=c2;
+                       c2=c3;
+               }
+               *point = (c1 + (c2 * 2) + c2 + error) / 4.0;
+       }
 }
 
 
@@ -111,23 +111,23 @@ static void filtcolum(unsigned char *point, int y, int skip)
 
 static void filtcolumf(float *point, int y, int skip)
 {
-        float c1,c2,c3,error, *point2;
-
-        if (y>1){
-                c1 = c2 = *point;
-                point2 = point;
-                error = 2;
-                for(y--;y>0;y--){
-                        point2 += skip;
-                        c3 = *point2;
-                        c1 += (c2 * 2) + c3 +error;
-                        *point = c1 / 4;
-                        point=point2;
-                        c1=c2;
-                        c2=c3;
-                }
-                *point = (c1 + (c2 * 2) + c2 + error) / 4;
-        }
+       float c1,c2,c3,error, *point2;
+       
+       if (y>1){
+               c1 = c2 = *point;
+               point2 = point;
+               error = 2;
+               for(y--;y>0;y--){
+                       point2 += skip;
+                       c3 = *point2;
+                       c1 += (c2 * 2) + c3 +error;
+                       *point = c1 / 4;
+                       point=point2;
+                       c1=c2;
+                       c2=c3;
+               }
+               *point = (c1 + (c2 * 2) + c2 + error) / 4;
+       }
 }
 
 void IMB_filtery(struct ImBuf *ibuf)
@@ -162,7 +162,7 @@ void IMB_filtery(struct ImBuf *ibuf)
                        filtcolumf(pointf,y,skip);
                        pointf++;
                        filtcolumf(pointf,y,skip);
-                       point++;
+                       pointf++;
                }
        }
 }
index 76a128c..c90278c 100644 (file)
@@ -311,17 +311,36 @@ short imb_save_openexr(struct ImBuf *ibuf, char *name, int 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 *ibuf = 0;
+       struct ImBuf *ibuf = NULL;
        InputFile *file = NULL;
        
-//     printf("OpenEXR-load: testing input, size is %d\n", size);
        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);
                
@@ -331,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);
+
+//             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;
                        
-                       imb_addrectImBuf(ibuf);
-                       imb_addrectfloatImBuf(ibuf);
-                       
                        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);
+                               
        }
        catch (const std::exception &exc)
        {