Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/openexr/openexr_api.cpp')
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp95
1 files changed, 51 insertions, 44 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b124cb2f80c..b59908fef39 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -180,7 +180,7 @@ static void openexr_header_compression(Header *header, int compression)
static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
{
-
+ int channels = ibuf->channels;
int width = ibuf->x;
int height = ibuf->y;
int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize
@@ -194,7 +194,7 @@ static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
header.channels().insert ("R", Channel (HALF));
header.channels().insert ("G", Channel (HALF));
header.channels().insert ("B", Channel (HALF));
- if (ibuf->depth==32)
+ if (ibuf->depth==32 && channels >= 4)
header.channels().insert ("A", Channel (HALF));
if (write_zbuf) // z we do as float always
header.channels().insert ("Z", Channel (FLOAT));
@@ -207,29 +207,29 @@ static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
RGBAZ *to = pixels;
int xstride= sizeof (RGBAZ);
int ystride= xstride*width;
-
+
/* indicate used buffers */
frameBuffer.insert ("R", Slice (HALF, (char *) &pixels[0].r, xstride, ystride));
frameBuffer.insert ("G", Slice (HALF, (char *) &pixels[0].g, xstride, ystride));
frameBuffer.insert ("B", Slice (HALF, (char *) &pixels[0].b, xstride, ystride));
- if (ibuf->depth==32)
+ if (ibuf->depth==32 && channels >= 4)
frameBuffer.insert ("A", Slice (HALF, (char *) &pixels[0].a, xstride, ystride));
if (write_zbuf)
- frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width,
+ frameBuffer.insert ("Z", Slice (FLOAT, (char *)(ibuf->zbuf_float + (height-1)*width),
sizeof(float), sizeof(float) * -width));
if(ibuf->rect_float) {
float *from;
for (int i = ibuf->y-1; i >= 0; i--)
{
- from= ibuf->rect_float + 4*i*width;
+ from= ibuf->rect_float + channels*i*width;
for (int j = ibuf->x; j > 0; j--)
{
to->r = from[0];
- to->g = from[1];
- to->b = from[2];
- to->a = from[3];
+ to->g = (channels >= 2)? from[1]: from[0];
+ to->b = (channels >= 3)? from[2]: from[0];
+ to->a = (channels >= 4)? from[3]: from[0];
to++; from += 4;
}
}
@@ -239,14 +239,14 @@ static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
for (int i = ibuf->y-1; i >= 0; i--)
{
- from= (unsigned char *)(ibuf->rect + i*width);
+ from= (unsigned char *)ibuf->rect + channels*i*width;
for (int j = ibuf->x; j > 0; j--)
{
to->r = (float)(from[0])/255.0;
- to->g = (float)(from[1])/255.0;
- to->b = (float)(from[2])/255.0;
- to->a = (float)(from[3])/255.0;
+ to->g = (float)((channels >= 2)? from[1]: from[0])/255.0;
+ to->b = (float)((channels >= 3)? from[2]: from[0])/255.0;
+ to->a = (float)((channels >= 4)? from[3]: from[0])/255.0;
to++; from += 4;
}
}
@@ -272,7 +272,7 @@ static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
{
-
+ int channels = ibuf->channels;
int width = ibuf->x;
int height = ibuf->y;
int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize
@@ -286,24 +286,29 @@ static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
header.channels().insert ("R", Channel (FLOAT));
header.channels().insert ("G", Channel (FLOAT));
header.channels().insert ("B", Channel (FLOAT));
- if (ibuf->depth==32)
+ if (ibuf->depth==32 && channels >= 4)
header.channels().insert ("A", Channel (FLOAT));
if (write_zbuf)
header.channels().insert ("Z", Channel (FLOAT));
FrameBuffer frameBuffer;
OutputFile *file = new OutputFile(name, header);
- float *first= ibuf->rect_float + 4*(height-1)*width;
- int xstride = sizeof(float) * 4;
+ int xstride = sizeof(float) * channels;
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));
- if (ibuf->depth==32)
- frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride));
+ float *rect[4] = {NULL, NULL, NULL, NULL};
+
+ rect[0]= ibuf->rect_float + channels*(height-1)*width;
+ rect[1]= (channels >= 2)? rect[0]+1: rect[0];
+ rect[2]= (channels >= 3)? rect[0]+2: rect[0];
+ rect[3]= (channels >= 4)? rect[0]+3: rect[0];
+
+ frameBuffer.insert ("R", Slice (FLOAT, (char *)rect[0], xstride, ystride));
+ frameBuffer.insert ("G", Slice (FLOAT, (char *)rect[1], xstride, ystride));
+ frameBuffer.insert ("B", Slice (FLOAT, (char *)rect[2], xstride, ystride));
+ if (ibuf->depth==32 && channels >= 4)
+ frameBuffer.insert ("A", Slice (FLOAT, (char *)rect[3], xstride, ystride));
if (write_zbuf)
- frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width,
+ frameBuffer.insert ("Z", Slice (FLOAT, (char *) (ibuf->zbuf_float + (height-1)*width),
sizeof(float), sizeof(float) * -width));
file->setFrameBuffer (frameBuffer);
file->writePixels (height);
@@ -362,6 +367,7 @@ typedef struct ExrHandle {
OutputFile *ofile;
int tilex, tiley;
int width, height;
+ int mipmap;
ListBase channels; /* flattened out, ExrChannel */
ListBase layers; /* hierarchical, pointing in end to ExrChannel */
@@ -450,7 +456,7 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in
data->ofile = new OutputFile(filename, header);
}
-void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height, int tilex, int tiley)
+void IMB_exrtile_begin_write(void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley)
{
ExrHandle *data= (ExrHandle *)handle;
Header header (width, height);
@@ -460,11 +466,12 @@ void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height
data->tiley= tiley;
data->width= width;
data->height= height;
+ data->mipmap= mipmap;
for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
header.channels().insert (echan->name, Channel (FLOAT));
- header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
+ header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL));
header.lineOrder() = RANDOM_Y;
header.compression() = RLE_COMPRESSION;
@@ -478,7 +485,7 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
{
ExrHandle *data= (ExrHandle *)handle;
- if(BLI_exists(filename)) {
+ if(BLI_exists(filename) && BLI_filepathsize(filename)>32) { /* 32 is arbitrary, but zero length files crashes exr */
data->ifile = new InputFile(filename);
if(data->ifile) {
Box2i dw = data->ifile->header().dataWindow();
@@ -533,7 +540,7 @@ void IMB_exrtile_clear_channels(void *handle)
BLI_freelistN(&data->channels);
}
-void IMB_exrtile_write_channels(void *handle, int partx, int party)
+void IMB_exrtile_write_channels(void *handle, int partx, int party, int level)
{
ExrHandle *data= (ExrHandle *)handle;
FrameBuffer frameBuffer;
@@ -550,7 +557,7 @@ void IMB_exrtile_write_channels(void *handle, int partx, int party)
try {
// printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
- data->tofile->writeTile (partx/data->tilex, party/data->tiley);
+ data->tofile->writeTile (partx/data->tilex, party/data->tiley, level);
}
catch (const std::exception &exc) {
std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl;
@@ -620,7 +627,6 @@ void IMB_exr_multilayer_convert(void *handle, void *base,
void IMB_exr_close(void *handle)
{
ExrHandle *data= (ExrHandle *)handle;
- ExrChannel *echan;
ExrLayer *lay;
ExrPass *pass;
@@ -783,28 +789,28 @@ static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height)
/* 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;
+ lookup[(unsigned int)'R']= 0;
+ lookup[(unsigned int)'G']= 1;
+ lookup[(unsigned int)'B']= 2;
+ lookup[(unsigned int)'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;
+ lookup[(unsigned int)'X']= 0;
+ lookup[(unsigned int)'Y']= 1;
+ lookup[(unsigned int)'Z']= 2;
+ lookup[(unsigned int)'W']= 3;
}
else {
- lookup['U']= 0;
- lookup['V']= 1;
- lookup['A']= 2;
+ lookup[(unsigned int)'U']= 0;
+ lookup[(unsigned int)'V']= 1;
+ lookup[(unsigned int)'A']= 2;
}
for(a=0; a<pass->totchan; a++) {
echan= pass->chan[a];
- echan->rect= pass->rect + lookup[echan->chan_id];
+ echan->rect= pass->rect + lookup[(unsigned int)echan->chan_id];
echan->xstride= pass->totchan;
echan->ystride= width*pass->totchan;
- pass->chan_id[ lookup[echan->chan_id] ]= echan->chan_id;
+ pass->chan_id[ (unsigned int)lookup[(unsigned int)echan->chan_id] ]= echan->chan_id;
}
}
else { /* unknown */
@@ -836,6 +842,7 @@ typedef struct RGBA
} RGBA;
+#if 0
static void exr_print_filecontents(InputFile *file)
{
const ChannelList &channels = file->header().channels();
@@ -846,6 +853,7 @@ static void exr_print_filecontents(InputFile *file)
printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
}
}
+#endif
static int exr_has_zbuffer(InputFile *file)
{
@@ -853,7 +861,6 @@ static int exr_has_zbuffer(InputFile *file)
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
{
- const Channel &channel = i.channel();
if(strcmp("Z", i.name())==0)
return 1;
}