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)
This commit is contained in:
@@ -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 */
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user