views:

56

answers:

2

Hello, I am loading an image using the OpenEXR library.

This works fine, except the image is loaded rotated 180 degrees. I use the loop shown below to reverse the array but sometimes the program will quit and xcode will give me an EXEC_BAD_ACCESS error (Which I assume is the same as an access violation in msvc). It does not happen everytime, just once every 5-10 times.

Ideally I'd want to reverse the array in place, although that led to errors everytime and using memcpy would fail but without causing an error, just a blank image. I'd like to know what's causing this problem first.

Here is the code I am using: (Rgba is a struct of 4 "Half"s r, g, b, and a, defined in OpenEXR)

Rgba* readRgba(const char filename[], int& width, int& height){
    Rgba* pixelBuffer = new Rgba[width * height];
    Rgba* temp = new Rgba[width * height];

    // ....EXR Loading code....

    // TODO: *Sometimes* the following code results in a bad memory access error. No idea why.
    // Flip the image to conform with OpenGL coordinates.
    for (int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j];
        }
    }

        delete pixelBuffer;

        return temp;
}

Thanks in advance!

+4  A: 

Change:

        temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j];

to:

        temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j - 1];

(Hint: think about what happens when i = 0 and j = 0 !)

Paul R
Oh yeah, I drew a diagram of how the reversal would work, spent a while figuring it out carefully and forgot to -1! Thanks.I still have the same problem though, every 5-10 runs.
usm
+1  A: 

And here's how you can optimize this code, to save memory and for cycles:

 Rgba* readRgba(const char filename[], int& width, int& height)
 {
    Rgba* pixelBuffer = new Rgba[width * height];
    Rgba tempPixel;

    // ....EXR Loading code....

    // Flip the image to conform with OpenGL coordinates.
    for (int i = 0; i <= height/2; i++)
      for(int j = 0; j < width && (i*width + j) <= (height*width/2); j++)
      {
        tempPixel =  pixelBuffer[i*width + j];
        pixelBuffer[i*width + j] = pixelBuffer[height*width - (i*width + j) -1];
        pixelBuffer[height*width - (i*width + j) -1] = tempPixel;
      }

    return pixelBuffer;
 }

Note that optimal (from a memory usage best practices point of view) would be to pass pixelBuffer* as a parameter and already allocated. It's a good practice to allocate and release the memory in the same piece of code.

John Paul
Thanks, my attempts to reverse half the array failed for various reasons. The error seems to go away now, but it still doesn't explain why it only happened sometimes, so I think I'll leave the question open for a little longer.I've noticed that you're doing i*height now (instead of i*width). Is this because I was reading the image elements in the wrong order or for performance reasons? Thanks.
usm
doing i*height was a mistake :) sorry about that. I will correct the code. In my test I reversed a matrix with the height equal to the width, therefore I did not have this problem. But now if you use the code with i*height instead of i*width you will have problems if height <> width. I will correct the code snippet. Thanks for pointing out my mistake :)
John Paul
I am using the loaded files as OpenGL textures, this (generally) means height = width, which is probably why the code worked fine for me. It's a shame that I don't have an answer to why I only got the error sometimes, but since your code works and has the method I originally planned to use, I'll accept your answer.
usm
I'm sorry but I can't tell why you had the error.. the code you originally posted with Paul's correction should work. It may be connected to the way you load the file. As an exercise you can try to implement a simple program that generates a matrix with random numbers and then reverses it with your original function.
John Paul