Blame img.ldr.tga.inc.c

ea5919
ea5919
ea5919
#pragma pack(push,1)
ea5919
typedef struct {
ea5919
  unsigned char  idLength;
ea5919
  unsigned char  colormapType;
ea5919
  unsigned char  imageType;
ea5919
  unsigned short colormapIndex;
ea5919
  unsigned short colormapLength;
ea5919
  unsigned char  colormapSize;
ea5919
  unsigned short xOrigin;
ea5919
  unsigned short yOrigin;
ea5919
  unsigned short width;
ea5919
  unsigned short height;
ea5919
  unsigned char  pixelSize;
ea5919
  unsigned char  attributes;
ea5919
} TgaHeader;
ea5919
#pragma pack(pop)
ea5919
ea5919
ea5919
int imageLoadTga(const char *path, int *outWidth, int *outHeight, unsigned char **pixels) {
ea5919
  *outWidth = *outHeight = 0; *pixels = NULL;
ea5919
ea5919
	FILE *f = fopen(path, "rb");
ea5919
	if (!f) {
ea5919
    fprintf(stderr, "Cannot open for read: %s\n", path);
ea5919
    fflush(stderr);
ea5919
    return FALSE;
ea5919
  }
ea5919
ea5919
	TgaHeader header = {};
ea5919
	fread(&header, sizeof(header), 1, f); // todo: endianess
ea5919
ea5919
	//printf("%d %d %d %d %d\n", header.imageType, header.width, header.height, header.colormapType, header.pixelSize);
ea5919
ea5919
	if ( header.imageType != 2
ea5919
	  || !header.width
ea5919
	  || !header.height
ea5919
	  || header.colormapType
ea5919
	  || (header.pixelSize != 24 && header.pixelSize != 32)
ea5919
  ) {
ea5919
    fprintf(stderr, "Unsupported format. Only uncompressed 24 or 32 bits TGA are supported: %s\n", path);
ea5919
    fflush(stderr);
ea5919
    return FALSE;
ea5919
	}
ea5919
ea5919
  fseek(f, header.idLength, SEEK_CUR);
ea5919
ea5919
  *outWidth = header.width;
ea5919
  *outHeight = header.height;
ea5919
  int rowSize = *outWidth*4;
ea5919
  int size = *outHeight*rowSize;
ea5919
  *pixels = (unsigned char*)calloc(1, size);
ea5919
  unsigned char *row = *pixels + size;
ea5919
  for(unsigned short r = header.height; r; --r, row -= rowSize) {
ea5919
    for(unsigned char *c = row - rowSize; c < row; c += 4) {
ea5919
      c[2] = fgetc(f);
ea5919
      c[1] = fgetc(f);
ea5919
      c[0] = fgetc(f);
ea5919
      c[3] = header.pixelSize == 32 ? fgetc(f) : 255;
ea5919
    }
ea5919
  }
ea5919
	fclose(f);
ea5919
ea5919
	return TRUE;
ea5919
}
ea5919
ea5919
ea5919
int imageSaveTga(const char *path, int width, int height, const unsigned char *pixels) {
ea5919
  if (width <= 0 || height <= 0 || !pixels) return FALSE;
ea5919
ea5919
	FILE *f = fopen(path, "wb");
ea5919
	if (!f) {
ea5919
    fprintf(stderr, "Cannot open file for write: %s\n", path);
ea5919
    fflush(stderr);
ea5919
    return FALSE;
ea5919
  }
ea5919
ea5919
	TgaHeader header = {};
ea5919
	header.imageType = 2;
ea5919
	header.width = width;
ea5919
	header.height = height;
ea5919
	header.pixelSize = 32;
ea5919
	fwrite(&header, sizeof(header), 1, f); // todo: endianess
ea5919
ea5919
  int rowSize = width*4;
ea5919
  int size = height*rowSize;
ea5919
  const unsigned char *row = pixels + size;
ea5919
  for(unsigned short r = header.height; r; --r, row -= rowSize) {
ea5919
    for(const unsigned char *c = row - rowSize; c < row; c += 4) {
ea5919
      fputc(c[2], f);
ea5919
      fputc(c[1], f);
ea5919
      fputc(c[0], f);
ea5919
      fputc(c[3], f);
ea5919
    }
ea5919
  }
ea5919
	fclose(f);
ea5919
ea5919
	return TRUE;
ea5919
}
ea5919