openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openexr-devel] C API calls


From: Florian Kainz
Subject: Re: [Openexr-devel] C API calls
Date: Thu, 20 Jul 2006 11:40:20 -0700
User-agent: Mozilla Thunderbird 1.0 (X11/20041207)

*   Make sure that the file you are trying to read does actually
    contain an image.  Start with a file that you know is good.
    You can download a number of images from www.openexr.com.

*   The ImfInputReadPixels call in your code should read

        ImfInputReadPixels (fp, y1, y2);

*   Your code snippets do not show how you compute width and
    height from the data window.  Assuming that

        width  = x2 - x1 + 1;
        height = y2 - y1 + 1;

    the ImfSetFrameBuffer call is incorrect; you will get a
    crash if x1 != 0 or y1 != 0.  The call should read

        ImfInputSetFrameBuffer (fp, rgba - x1 - width * y1, 1, width);

    Once your file reader works, I strongly encourage you to test
    it on all of the OpenEXR sample images that you can download
    from www.openexr.com, in particular the DisplayWindow/t??.exr
    files.

*   The C API is only for situations where for some reason you
    really cannot use C++.  You are probably better off using
    the C++ API, as you did in the first version of your code.

    The calls in the C API are straightforward wrappers around
    the corresponding C++ calls.  For example,

        ImfInputReadPixels (inputFile, s1, s2);

    is equivalent to

        inputFile.readPixels (s1, s2);

    The main difference is how errors are handled: the C++ call
    throws exceptions, while the C call returns 1 for success or
    0 for failure.  In C++ you handle errors like this:

        try
        {
            ...
            inputFile.readPixels (s1, s2);
        }
        catch (std::exception &e)
        {
            std::cerr << e.what() << std::endl;
        }

    In C you do this:

        if (!ImfInputReadPixels (inputFile, s1, s2))
        {
            fprintf (stderr, "%s\n", ImfErrorMessage());
            return 0;
        }


Thomas Lock wrote:
I finally got it to work in debug mode, which exposed an error that wasn't
coming up in release mode (not sure why). It was missing 1 library file to
link to. I'm going to get reading and writing to work first in debug mode
and then worry about release mode.
At this point i have the writing working (verified with 2 other apps), but
the reading seems to have a non-fatal error (image is black but correct
dimensions). I don't think the buffer is getting filled properly. This
function is simply the opposite of what the writing function does, so once
the buffer is filled and converted to my array the rest is done outside this
function. I added the lines of code i believe the problem is related to, but
i can't seem to find any documentation on the C API so i am guessing.

ImfRgba *rgba;

rgba = (ImfRgba *)malloc(width * height * sizeof(ImfRgba));

header = ImfInputHeader(fp);

ImfHeaderDataWindow(header,&x1,&y1,&x2,&y2);

ImfInputSetFrameBuffer(fp, rgba , 1, width);

ImfInputReadPixels(fp, height, 0 );



----- Original Message ----- From: "Florian Kainz" <address@hidden>
To: "Thomas Lock" <address@hidden>
Cc: <address@hidden>
Sent: Thursday, July 20, 2006 12:05 AM
Subject: Re: [Openexr-devel] C API calls


What does "fail" mean in this case?  Does the application crash?
If it does, have you tried using a debugger to get a stack trace?

Does ImfOpenOutputFile return a null pointer?  If you do get a null
pointer, have you tried calling ImfErrorMessage() to find get some
diagnostic output?  Your example contains no error checking code.
Unlike the C++ interface, the C interface does not throw exceptions;
you must explicitly check the return values of the functions you call.

Thomas Lock wrote:
Hi Drew

            I completely rewrote my code to meet the C API calls. This
time
i get zero warnings or errors but the app specifically fails on this
call
"file = ImfOpenOutputFile(filenames, header, IMF_WRITE_RGBA );". I tried
a
variety of filename options and nothing seems to work. I can't verify if
my
remaining code works, but i believe it is correct.

extern "C" void WINAPI writeOpenEXR (char *filename, int width, int
height,
float* Bits128)
{
       int LineWidth=width*4;
       float fwidth;
       const char fileName[] = "c:\foo2.exr";
       const char *filenames = "c:\foo2.exr";

       ImfOutputFile *file;
       ImfRgba *base;
       base = (ImfRgba *)malloc(width * height * sizeof(ImfRgba));
       fwidth = (float)width;
       ImfHeader *header;
       header = ImfNewHeader();
       ImfHeaderSetDisplayWindow(header, 0, 0, width - 1, height - 1);
       ImfHeaderSetDataWindow(header, 0, 0, width - 1, height - 1);
       ImfHeaderSetScreenWindowWidth(header, fwidth);
       file = ImfOpenOutputFile(filenames, header, IMF_WRITE_RGBA );

       ImfDeleteHeader(header);

       for(int h=0;h<height;h++)for(int b=0;b<width;b++)
      {
           ImfHalf half;

           int i=h*LineWidth+(b<<2);
           int j=h*LineWidth+b;

           ImfFloatToHalf(Bits128[i], &half);
           base[j].b = half;

           ImfFloatToHalf(Bits128[i + 1], &half);
           base[j].g = half;

           ImfFloatToHalf(Bits128[i + 2], &half);
           base[j].r = half;

           ImfFloatToHalf(Bits128[i + 3], &half);
           base[j].a = half;
       }

       ImfOutputSetFrameBuffer( file, base, 1, width );
       ImfOutputWritePixels(file, height );
       ImfCloseOutputFile(file);

       free(base);
}




_______________________________________________
Openexr-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/openexr-devel










reply via email to

[Prev in Thread] Current Thread [Next in Thread]