[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28807] trunk/blender/source/blender/imbuf /intern/openexr/openexr_api.cpp: [#21385] Multilayer OpenEXR files import into other compositors upside down

Campbell Barton ideasman42 at gmail.com
Tue May 18 08:53:28 CEST 2010


Looks like its using OpenEXR 1.4x (circa 2006 if the tar.gz source
archives are anything to go by)
Would you be able to build a new OpenEXR lib?

On Tue, May 18, 2010 at 2:06 AM, Joshua Leung <aligorith at gmail.com> wrote:
> I'm getting compile errors from this on scons+mingw:
>
> Compiling ==> 'openexr_api.cpp'
> source\blender\imbuf\intern\openexr\openexr_api.cpp: In function `void
> IMB_exrtile_begin_write(void*
> , char*, int, int, int, int, int)':
> source\blender\imbuf\intern\openexr\openexr_api.cpp:482: warning:
> converting to `int' from `double'
> source\blender\imbuf\intern\openexr\openexr_api.cpp:483: warning:
> converting to `int' from `double'
> source\blender\imbuf\intern\openexr\openexr_api.cpp: In function `void
> IMB_exrtile_write_channels(vo
> id*, int, int, int)':
> source\blender\imbuf\intern\openexr\openexr_api.cpp:587: error: no
> matching function for call to `Im
> f::Slice::Slice(Imf::PixelType, char*, int&, int&, int, int, double,
> bool, bool)'
> C:/blenderdev/b250/lib/windows/gcc/openexr/include/OpenEXR/ImfFrameBuffer.h:65:
> note: candidates are
> : Imf::Slice::Slice(const Imf::Slice&)
> C:/blenderdev/b250/lib/windows/gcc/openexr/include/OpenEXR/ImfFrameBuffer.h:115:
> note:
>   Imf::Slice::Slice(Imf::PixelType, char*, size_t, size_t, int, int, double)
> source\blender\imbuf\intern\openexr\openexr_api.cpp:594: warning:
> converting to `int' from `double'
> scons: *** [C:\blenderdev\b250\build\source\blender\imbuf\intern\openexr\openexr_api.o]
> Error 1
> scons: building terminated because of errors.
>
> It looks like the gcc OpenEXR libs are an 'older' copy than the ones
> in the standard openexr includes for msvc/etc.
>
> On Tue, May 18, 2010 at 3:54 AM, Campbell Barton <ideasman42 at gmail.com> wrote:
>> Revision: 28807
>>          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28807
>> Author:   campbellbarton
>> Date:     2010-05-17 17:54:57 +0200 (Mon, 17 May 2010)
>>
>> Log Message:
>> -----------
>> [#21385] Multilayer OpenEXR files import into other compositors upside down
>> famous upside down EXR bugfix from Xavier Thomas
>>
>> - Files from blender 2.4x will be flipped on load.
>> - New files will be saved correctly
>>
>> tracker has detailed info for further reference.
>>
>> Modified Paths:
>> --------------
>>    trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp
>>
>> Modified: trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp
>> ===================================================================
>> --- trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp   2010-05-17 15:50:29 UTC (rev 28806)
>> +++ trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp   2010-05-17 15:54:57 UTC (rev 28807)
>> @@ -462,18 +462,31 @@
>>        openexr_header_compression(&header, compress);
>>        // openexr_header_metadata(&header, ibuf); // no imbuf. cant write
>>        /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
>> +
>> +       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.52.5"));
>>
>> -       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43 and newer"));
>> -
>>        data->ofile = new OutputFile(filename, header);
>>  }
>>
>>  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);
>> +       Header *header;
>>        ExrChannel *echan;
>>
>> +       /* open exr specify tiles must allign with top left frame coord but blender
>> +       render with tiles alligned to the bottom left. We work around this by saving
>> +       the whole area covered by the tyles (the data window) and defining a display
>> +       window that cover only the rendered area */
>> +
>> +       int ntx = ceil((float)width/tilex);
>> +       int nty = ceil((float)height/tiley);
>> +       Box2i dispw(V2i(0,0), V2i(width-1, height-1));
>> +       Box2i dataw(V2i( width -(ntx*tilex) , height -(nty*tiley) ), V2i(ntx*tilex-1, height-1));
>> +       V2f swc(0.0f, 0.0f);
>> +       header = new Header(dispw, dataw, 1.0, swc, 1, RANDOM_Y, RLE_COMPRESSION);
>> +
>> +
>>        data->tilex= tilex;
>>        data->tiley= tiley;
>>        data->width= width;
>> @@ -481,15 +494,17 @@
>>        data->mipmap= mipmap;
>>
>>        for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
>> -               header.channels().insert (echan->name, Channel (FLOAT));
>> +               header->channels().insert (echan->name, Channel (FLOAT));
>>
>> -       header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL));
>> -       header.lineOrder() = RANDOM_Y;
>> -       header.compression() = RLE_COMPRESSION;
>> +       header->setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL));
>> +       header->lineOrder() = RANDOM_Y;
>> +       header->compression() = RLE_COMPRESSION;
>>
>> -       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
>> -
>> -       data->tofile = new TiledOutputFile(filename, header);
>> +       header->insert ("BlenderMultiChannel", StringAttribute ("Blender V2.52.5"));
>> +
>> +       data->tofile = new TiledOutputFile(filename, *header);
>> +
>> +       delete header;
>>  }
>>
>>  /* read from file */
>> @@ -500,7 +515,7 @@
>>        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();
>> +                       Box2i dw = data->ifile->header().displayWindow();
>>                        data->width= *width  = dw.max.x - dw.min.x + 1;
>>                        data->height= *height = dw.max.y - dw.min.y + 1;
>>
>> @@ -557,19 +572,32 @@
>>        ExrHandle *data= (ExrHandle *)handle;
>>        FrameBuffer frameBuffer;
>>        ExrChannel *echan;
>> +       float *rect;
>> +       int xs, ys;
>> +       int x, y;
>>
>>        for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
>> -               float *rect= echan->rect - echan->xstride*partx - echan->ystride*party;
>>
>> +               /* coordinates for relative tile coordinates, starting from top of tile,
>> +                  striding left->right, top->bottom */
>> +               rect= echan->rect + (data->tiley-1)*echan->ystride;
>> +               xs = echan->xstride*sizeof(float);
>> +               ys = -echan->ystride*sizeof(float);
>> +
>>                frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)rect,
>> -                                                       echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
>> +                                                       xs, ys,                 //xStride, yStride
>> +                                                       1, 1, 0.0,              // xSampling, ySampling, fillValue
>> +                                                       true, true) );  // xTileCoords, yTileCoords  (use relative tile coords)
>>        }
>>
>>        data->tofile->setFrameBuffer (frameBuffer);
>>
>> +       x = partx/data->tilex;
>> +       /* flip tile grid vertically to conform to EXR coordinate system */
>> +       y = ceil((float)data->height/data->tiley) - (party/data->tiley) - 1;
>> +
>>        try {
>> -               // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
>> -               data->tofile->writeTile (partx/data->tilex, party/data->tiley, level);
>> +               data->tofile->writeTile (x, y, level);
>>        }
>>        catch (const std::exception &exc) {
>>                std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl;
>> @@ -583,9 +611,12 @@
>>        ExrChannel *echan;
>>
>>        if(data->channels.first) {
>> -               for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
>> -                       frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)echan->rect,
>> -                                                                                                       echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
>> +               for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
>> +                       float *rect = echan->rect + echan->xstride*(data->height-1)*data->width;
>> +
>> +                       frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)rect,
>> +                                                                       echan->xstride*sizeof(float), -echan->ystride*sizeof(float)));
>> +               }
>>
>>                data->ofile->setFrameBuffer (frameBuffer);
>>                try {
>> @@ -605,12 +636,21 @@
>>        ExrHandle *data= (ExrHandle *)handle;
>>        FrameBuffer frameBuffer;
>>        ExrChannel *echan;
>> -
>> +
>> +       /* check if exr was save with previous version of blender which flipped images */
>> +       const StringAttribute *ta = data->ifile->header().findTypedAttribute <StringAttribute> ("BlenderMultiChannel");
>> +       short flip = (ta && strncmp(ta->value().c_str(), "Blender V2.43", 13)==0); /* 'Blender V2.43 and newer' is covered too */
>> +
>>        for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
>>                /* no datawindow correction needed */
>> -               if(echan->rect)
>> -                       frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)echan->rect,
>> +               if(echan->rect) {
>> +                       if(flip)
>> +                               frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)echan->rect,
>>                                                                                                echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
>> +                       else
>> +                               frameBuffer.insert (echan->name, Slice (FLOAT,  (char *)(echan->rect + echan->xstride*(data->height-1)*data->width),
>> +                                                                                               echan->xstride*sizeof(float), -echan->ystride*sizeof(float)));
>> +               }
>>                else
>>                        printf("warning, channel with no rect set %s\n", echan->name);
>>        }

If the

-- 
- Campbell


More information about the Bf-committers mailing list