• ### Popular Now

• 13
• 18
• 19
• 27
• 10

#### Archived

This topic is now archived and is closed to further replies.

# TGA - Topdown / Downtop

This topic is 5824 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi! I''ve written a complete TGA loader (24 / 32 Compressed / Uncompressed) but some of the TGA''s are stored Top-Down or Down-Top (You can convert this in ACDSEE) but I wonder how to find out wheter the TGA is upside down or not?

##### Share on other sites
The vertical flipping is specified in bit 5 of the ImageDescriptor in the header of the TGA file. If the bit is set then the top of the image is first in the file (i.e. the images is the right way up for normal usage), otherwise the last line of the image comes first (and you'll need to flip it).

IIRC bit 4 of the ImageDescriptor controls horizontal flipping aswell - check the full specs (should be easy to find on www.wotsit.org).

Iain Hutchison
Programmer, Silicon Dreams
The views expressed here are my own, not those of my employer.

[edited by - pieman on March 21, 2002 9:30:28 AM]

##### Share on other sites
Hi again!
I've been trying to create a "Flipper" for my TGA but I'm obviously to tired to do this on my own:
if(tgaTexture->iVertical == 0){ for(int iSwap = 0; iSwap < tgaTexture->iSize; iSwap++) Test[tgaTexture->iSize-iSwap] = tgaTexture->byRawData[iSwap]; for(int i = 0; i < tgaTexture->iSize; i++) tgaTexture->byRawData = Test[i];}

The TGA IS being properly loaded..

[edited by - metus on April 8, 2002 4:35:53 PM]

##### Share on other sites
Your code is just reversing the order of all the bytes in the data stream (and it's going out of the array bounds by one element). Try this :

  long lPitch = tgaTexture->iWidth * tgaTexture->iBPP / 8;  // no of bytes in each line of imagevoid* pTempLine = malloc(lPitch);for (int y1=0; y1<tgaTexture->iHeight/2; y1++){    int y2 = tgaTexture->iHeight-1-y1;  // this is the line we'll be swapping with    void* pLine1 = (void*) ((unsigned long)tgaTexture->byRawData + (y1 * lPitch)); // upper line    void* pLine2 = (void*) ((unsigned long)tgaTexture->byRawData + (y2 * lPitch)); // lower line    // Swap the 2 lines of data    memcpy(pTempLine, pLine1,    lPitch);    memcpy(pLine1,    pLine2,    lPitch);    memcpy(pLine2,    pTempLine, lPitch);}free(pTempLine);

This assumes that "tgaTexture->iBPP" is the number of bits-per-pixel in the texture (8, 16, 24 or 32) and that "iWidth" and "iHeight" are the dimensions of the image in pixels.

You can avoid the malloc() / free() if you use the _alloca() routine to claim space on the stack - look it up in the MSDN for details (just don't try to free it - that's done automagically when the function exits).

Iain Hutchison
Programmer, Silicon Dreams
The views expressed here are my own, not those of my employer.

[edited by - pieman on April 9, 2002 10:05:02 AM]