Converting images from upper-left to bottom-left origin

Started by
2 comments, last by stylin 18 years, 6 months ago
CONTEXT: These days I was revising my TGA image loading methods and found out that some images use top-left origin instead of the most used nowadays bottom-left origin. So, I've read the TGA specification and discovered that the 17th byte of the image header contains the information I wanted: whether coordinates system origin is upper-left or bottom-right. Then I wrote a method that, after all the image loading and such, swap the lines and make every texture bottom-left origin. PROBLEM: As you can see from the source code below, everything is working fine, but the readibility is not so good (and I'm using C style functions).

// Check if the image has upper-left origin. If so, swap lines so that
// the origin stays at the image bottom-left
if ( header[17] & 0x00000020 ) {
  unsigned int lineSize = auxTex.bytesPerPixel * auxTex.width;
  unsigned int halfHeight = auxTex.height / 2;
  GLubyte* tempLine = new GLubyte[ lineSize ];

  // Swap lines using a temporary line
  for (int currentLine = 0; currentLine < halfHeight; ++currentLine ) {
    memcpy( tempLine, auxTex.imageData + (currentLine * lineSize), lineSize );
    memcpy( auxTex.imageData + (currentLine * lineSize), auxTex.imageData + ((auxTex.width - currentLine - 1) * lineSize), lineSize );
    memcpy( auxTex.imageData + ((auxTex.width - currentLine - 1) * lineSize), tempLine, lineSize );
  }

  delete [] tempLine;
}

QUESTION: Do you have any advices on how to rewrite this block of code so it looks more friendly? Is there any ultra-secret STL algorithm that can do the job in one pass? Thanks a lot!
Advertisement
The std::reverse algorithm was designed for scenarios like this, but you have to provide it with an iterator of some sort. For working directly with in-memory data as you are, I'd say what you have is fine -- and in fact, perfectly readable and understandable to me. As soon as I saw that you were reversing the data top-to-bottom and using a variable "halfHeight", I understood that you were performing an in-place swap moving from the top and bottom of the image toward the middle.
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
Quote:Original post by MajinMusashi
QUESTION: Do you have any advices on how to rewrite this block of code so it looks more friendly? Is there any ultra-secret STL algorithm that can do the job in one pass?
I'll post a std::reverse method just for comparison; see if it fits your performance needs:
template< unsigned int width >struct scanline { unsigned char scanline_[width]; };// ...if( header[17] & 0x00000020 ) {   // size and point our scanline iterator at image data   unsigned int lineSize = auxTex.bytesPerPixel * auxTex.width;   scanline<lineSize> * sl = (scanline<lineSize> *)(auxTex.imageData)   // and reverse image data   std::reverse( sl, sl+auxTex.height );}


EDITED: to correct typos and add friendliness

[Edited by - stylin on October 5, 2005 1:54:09 PM]
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
ERRATA: The above method does not work; it errors unless you feed it compile-time constant arguments (as I was naively doing in my test app).

I've tried using array pointers, obviously with the same result. Does anyone know if this can be done without using a temp copy array?
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid

This topic is closed to new replies.

Advertisement