Reading TGA shows nulls instead of color data

228 Views Asked by At

I'm trying to write a simple TGA-Loader and I found that reading some images produced a lot of unwanted nulls after a certain point. There are six images I'm testing: Each of them has 32x32 pixels with BGR-colors. Now four images are read fine, while the remaining two are only read until the 17th byte. From there on they consist of nulls, which looks like that:

0 : 220 164 55
1 : 232 173 57
2 : 241 177 51
...
16: 252 181 41
17: 249 180 41
18: 0 0 0
19: 0 0 0

ifstream myFile(filePath);

// Read Header

struct tgaHeader *header = new struct tgaHeader;

myFile.read((char *) &header->imageIDlength, 1);
myFile.read((char *) &header->colormapType, 1);
myFile.read((char *) &header->imageType, 1);

myFile.read((char *) &header->colormapBegin, 2);
myFile.read((char *) &header->colormapLength, 2);

myFile.read((char *) &header->sizeOfEntryInPallette, 1);

myFile.read((char *) &header->xOrigin, 2);
myFile.read((char *) &header->yOrigin, 2);
myFile.read((char *) &header->width, 2);
myFile.read((char *) &header->height, 2);

myFile.read((char *) &header->bitsPerPoint, 1);
myFile.read((char *) &header->attributeByte, 1);

// Test if Format is supported

if(header->imageIDlength != 0   ||
   header->colormapType != 0    || header->colormapBegin != 0 || header->colormapLength != 0 ||
   header->imageType != 2       || header->xOrigin != 0       || header->yOrigin != 0        ||
   !(header->bitsPerPoint == 24 || header->bitsPerPoint == 32))
{
    myFile.close();
    throw runtime_error("image format is not supported");
}

// Since only TGA-files with no Image-ID and no Colormap are supported,
// here immediatly the image data can be read.

uint16_t bytesPerPoint    = header->bitsPerPoint / 8;
unsigned long long imSize = static_cast<long long> (header->width) *  header->height * bytesPerPoint;

vector<uint8_t> * pixels = new vector<uint8_t> (imSize);
myFile.read((char *) pixels->data(), imSize);

unsigned long long i;
for(i=0; i < imSize; i+=3) {

    uint8_t t0 = pixels->at(i+0);       // swap from BGR to RGB
    uint8_t t1 = pixels->at(i+1);
    uint8_t t2 = pixels->at(i+2);

    (*pixels)[i+0] = t2;
    (*pixels)[i+1] = t1;
    (*pixels)[i+2] = t0;

}

// Further Meta-Data following the image data are ignored.

myFile.close();

return pixels;

TgaHeaderis a defined struct that contains uint8_t and uint16_t fields. I have removed exception handling for clarity, I have never recognized any errors while reading the data. IrfanView and Gimp were able to open the problematic images and in a binary viewer no nulls were found. I have chosen only images with no Image-ID and no colormap and equivalent headers, so this shouldn't be a problem either.
So why are these nulls there?

1

There are 1 best solutions below

0
On BEST ANSWER

Finally I found the issue: For reasons I cannot see the ifstream position jumped to ca. 450. From there on the header could be read even though the header informations are located in the first 18 bytes. As a consequence after reading the header I simply set the ifstream position to the point were the color data began:

vector<uint8_t> * imRawData = new vector<uint8_t> (imSize);

myFile->seekg(ios_base::beg + 18);
myFile->read((char *) imRawData->data(), imSize);