Jump to content
  • Advertisement
Sign in to follow this  
silvia_steven_2000

TGA Color Correction

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi All I was trying to create a DX9 texture from a TGA file. I ended with two problems. the image some times was flipped and the color were dimmed or dark. one of the guys on gamedev DX forum game me a hint for the flipped image which is something to do with pixel direction. I used the TGA pixel direction bits and solved the first problem. now the same guy game another hint for the second problem which is the use of gamma correction. I extracted the gamma value form the TGA file and it used to be 2.0 then I modified all of the pixel color components (RGB) by raising there values to the power of 1/gamma but still I did not get the intended results and the image still dark. right now I started to think in another direction. the TGA file contains a color correction table of 256 entry , each entry is 4 shorts for the ARGB components. I do not know how is this table is used. I guess replace the pixel color component with the corresponding entry in the correction table. still I am confused about this since the pixel color component is 1 byte while the short is 2 bytes. any help or hints is really appreciated. thanks allot, I really appreciate your time.

Share this post


Link to post
Share on other sites
Advertisement
Are you sure it's not due to some other error in your code? I saw your other post on this, and the flip thing is obvious (2 bits I believe specify where the origin is), but other than that I've simply read the RGB values and used them directly as textures and never run into the colour problems you've described, and I've never messed with the gamma and colour correction stuff.

Maybe if you post the relevent portion(s) of your loading code someone can spot the problem.

Share this post


Link to post
Share on other sites
I totally agree with you. Yes there might be something wrong with my loading routine. but what drives me crazy is that the texture looks exactly like the image but it is dark. if there is something wrong with loading then I would get a distorted image. I am not using lighting and I do not think there is something wrong with render states since I just get the desired result when swithing to D3Dx. here what I do :

//Image size in bytes
int numBytes = m_numPixels * m_bpp;

//Allocate memory for image data
m_buf = new unsigned char[numBytes];

//Read the whole image data into memory buffer
m_file->Read(m_buf, numBytes, 1);


//BGR2RGB
for(int i = 0; i < m_numPixels; i = i + 3)
{
unsigned char R = m_buf[i + 2];
m_buf[i + 2] = m_buf;
m_buf = R;
}


//Allocate memory for the image in ARGB format
m_imageData = malloc(m_numPixels * 4);

//Temporary pointer
unsigned char* uCharPtr = (unsigned char*)m_imageData;

int i = 0;
int j = 0;

//Copy the RGB pixels to XRGB buffer
for(int pixel = 0; pixel < m_numPixels; pixel++)
{
uCharPtr[i + 0] = 1;
uCharPtr[i + 1] = m_buf[j + 0];
uCharPtr[i + 2] = m_buf[j + 1];
uCharPtr[i + 3] = m_buf[j + 2];
i = i + 4;
j = j + 3;
}

Share this post


Link to post
Share on other sites

for(int i = 0; i < m_numPixels; i = i + 3)
{
unsigned char R = m_buf[i + 2];
m_buf[i + 2] = m_buf;
m_buf = R;

}



You've got that part mixed up, you're either looping by pixels or looping by bytes, not both. Think about what's going on there, or go for the easy fix below:

for(int i = 0; i < numBytes; i = i + 3)

What you should be seeing is the first 1/3 of the image BGR, the rest RGB, which doesn't sound like it should make the image darker... .If the above doesn't fix it there are more problems elsewhere.

Share this post


Link to post
Share on other sites
well you may have problems depending on the bpp.

you'll need to do this: loop through the buffer at the size of the buffer. and increment based on the number of BYTES per pixel (bpp / 8). Because if you don't have a 24 bpp image and you're swaping the bytes of a 32 you may get some messy results.

NeHe had a guy write some decent TGA loading code.

faster way of swaping bytes.
[edit faster to cache the value];
int bytesPerPixel = image.bpp / 8;
for(int i =0; i < image.size; i += bytesPerPixel) {
image.buffer ^= image.buffer[i+2] ^= image.buffer ^= image.buffer[i + 2];
}

that's a XOR of the B and R bytes and will swap them really fast. and no temp variable!

To understand this a bit better.

take
let C = B XOR A;
now C XOR A will yeild B
and C XOR B will yeild A

so in the example we XOR B With R to get our known value.
Then we XOR that with R to get B then so forth.
but the known value is the last changed.

It makes more sence on paper.

[Edited by - anonuser on June 18, 2005 5:47:59 PM]

Share this post


Link to post
Share on other sites
I am really confused: it is working now: here is the change I did:

//I am now using i < m_numPixels * m_bpp but this is not the reason why
//I used to get wrong colors

//Conver from BGR to RGB
for(int i = 0; i < m_numPixels * m_bpp; i = i + 3)
{
unsigned char R = m_buf[i + 2];
m_buf[i + 2] = m_buf;
m_buf = R;
}


//Allocate memory for the image in XRGB format
m_imageData = malloc(m_numPixels * 4);

//Temporary pointer
unsigned char* uCharPtr = (unsigned char*)m_imageData;

int i = 0;
int j = 0;

//Copy the RGB pixels to XRGB buffer
for(int pixel = 0; pixel < m_numPixels; pixel++)
{
uCharPtr[i + 0] = m_buf[j + 1];
uCharPtr[i + 1] = m_buf[j + 0];
uCharPtr[i + 2] = m_buf[j + 2];
uCharPtr[i + 3] = 255
i = i + 4;
j = j + 3;
}

why did that work I can not find out an explanation
I was using:

uCharPtr[i + 0] = 255; // A
uCharPtr[i + 1] = m_buf[j + 0]; // R
uCharPtr[i + 2] = m_buf[j + 1]; // G
uCharPtr[i + 3] = m_buf[j + 2]; // B

why the 4 byte ARGB pixel is mapped like :

i + 0 : j + 1 G
i + 1 : j + 0 R
i + 2 : j + 2 B
i + 3 : Alpha

I was expecting something like:

i + 0 : A
i + 1 : j + 0 R
i + 2 : j + 1 G
i + 3 : j + 2 B

or

i + 0 : j + 2 B
i + 1 : j + 1 G
i + 2 : j + 0 R
i + 3 : A

Share this post


Link to post
Share on other sites
TGA's come BGR not RGB.

So you should have been getting funky colors.

that's why i gave you the byte swapping code.

number of pixels by bpp will give the size of the image.


and depending on the bpp (24 or 32) you will not or will get the alpha channel.
That's why you check for both. If you plan on dealing with OpenGL you'll submit as RGB and RGBA respective.

Share this post


Link to post
Share on other sites
I already know that TGA image comes with BGR and that is why I convert to RGB first but my confusion is because I could not figure out how d3d put the A, R, G, B bytes in the 32 bit number. what I did is very simple:

1- I converted the image buffer from BGR 24 bit blocks to RGB 24 bits
2- I want to put these blocks into a new 32 bit block buffer of the
format XRGB, X = 255, RGB = RGB from the converted TGA

my problem was how to map the converted TGA's RGB buffer to DX9 XRGB buffer. if we index the four bytes of the (XRGB) from right to left as 0 to 3 , then I put 255 in 3, R in 2 , G in 1 and B in 0. I got the wrong image but when I put them : 255 in 3, R in 2, G in 0, B in 1 it worked fine. that is what drove me crazy !!!!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!