I didn't want to reinvent the wheel, so I downloaded libtga which seemed to have a convenient and simple API. Building was easy, but I stumbled upon a weird segmentation fault I can not explain. A small example:
#include <stdio.h>
#include "tga.h"
#define TEST
int main()
{
TGA *tga;
TGAData data;
tga = TGAOpen("test.tga", "r");
if(!tga || tga->last != TGA_OK)
{ printf("TGAOpen failed\n"); return 1; }
if(TGAReadImage(tga, &data) != TGA_OK)
{ printf("TGAReadImage failed\n"); return 1; }
TGAHeader *header = &tga->hdr;
printf("image dimensions:\n width: %d\t height:%d\t depth:%d bpp\n",
header->width, header->height, header->depth);
tbyte *img = data.img_data;
if (img== NULL)
{
printf("Pointer wrong\n");
return 1;
}
printf("pointer: %p\n", img);
printf("test %hhu\n", img[0]);
#ifdef TEST
for(int i=0; i<header->height; i++)
{
for(int j=0; j<header->width; j++)
{
int index = 4*(i*header->width + j);
printf("%3d %3d %3d %3d | ", img[index], img[index+1], img[index+2], img[index+3]);
}
printf("\n");
}
#endif
TGAClose(tga);
return 0;
}
I compile the program with: gcc -g --std=c99 -O0 tgatest.c -L./lib -ltga -I./include
Now, if "TEST" is defined everything works fine and the values for each pixel are printed to stdout (I use a 4x4 image). If I don't define "TEST" it throws a segmentation fault at line
printf("test %hhu\n", img[0]);
I don't understand why. Debugging shows that "img" is "Address 0x1 out of bounds", but with "TEST" it is a valid address. Any suggestions how to further investigate this? I thought the compiler may optimize things away, but -O0 doesn't change anything. Same for the --std=c99.
According to the tgalib documentation you need to set TGA_IMAGE_DATA
on data->flags
before calling TGAReadImage
to ensure that the image data will be read. It's possible that in the TEST build the garbage on the stack under the data variable happens to have this bit set, but not in the other build.
Adding a line like the following immediately before the TGAReadImage
call should do the trick:
data.flags = TGA_IMAGE_DATA;