diff options
author | Ton Roosendaal <ton@blender.org> | 2006-01-09 22:17:37 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-01-09 22:17:37 +0300 |
commit | e62fed936e171b5d5ee71ed7caa23ea730d006ee (patch) | |
tree | 2515251448c1b5333496a3139aaac3ad5920d33b /source/blender/imbuf | |
parent | bdef14bf81ef896ea0774df752fd606d763632b3 (diff) |
Orange: more exr & imbuf cleanup
- 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)
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/allocimbuf.c | 9 | ||||
-rw-r--r-- | source/blender/imbuf/intern/divers.c | 26 | ||||
-rw-r--r-- | source/blender/imbuf/intern/filter.c | 66 | ||||
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 130 |
5 files changed, 113 insertions, 119 deletions
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index aa69e680c35..63ffeb02603 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -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 diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 8344e9753a2..137795eec3f 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -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); } diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index a56f16f71db..07ba4ee5f73 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -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; + } + +} diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index e51f85ab2d6..9e62a9edfb5 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -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++; } } } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 76a128cb200..c90278c4514 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -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) { |