Implemented very basic read support for ColorMapped (Non-Encoded) TGA.

This commit is contained in:
Aaron Helton
2017-04-16 16:31:06 -04:00
parent 3dcb255e74
commit 21a423a1d9
3 changed files with 61 additions and 20 deletions

View File

@@ -8,14 +8,15 @@ typedef enum {
TGA_NO_ERR = 0,
TGA_INV_IMAGE_PNT = 1,
TGA_INV_FILE_PNT = 2,
TGA_MEM_ERR = 3,
TGA_GEN_IO_ERR = 4,
TGA_READ_ERR = 5,
TGA_WRITE_ERR = 6,
TGA_INV_FILE_NAME = 7,
TGA_IMAGE_IMMUTABLE_ERR = 8,
TGA_UNSUPPORTED = 9,
TGA_INTERNAL_ERR = 10
TGA_COLOR_MAP_ERR = 3,
TGA_MEM_ERR = 4,
TGA_GEN_IO_ERR = 5,
TGA_READ_ERR = 6,
TGA_WRITE_ERR = 7,
TGA_INV_FILE_NAME = 8,
TGA_IMAGE_IMMUTABLE_ERR = 9,
TGA_UNSUPPORTED = 10,
TGA_INTERNAL_ERR = 255
} TGAError;
typedef enum {
@@ -34,6 +35,7 @@ struct _NY_TgaMeta;
typedef struct NyTGA_Image {
uint8_t *id_field;
uint8_t *data;
uint8_t *color_map;
struct _NY_TgaMeta *_meta;
uint8_t version;
char __padding[7];

View File

@@ -138,6 +138,32 @@ error:
return 0;
}
static int _read_tga_color_map(TGAImage *image, FILE *file)
{
uint16_t c_map_size = 0;
uint16_t start = 0;
check(_tga_sanity(image), TGA_INV_IMAGE_PNT, "Invalid TGAImage Pointer.");
check(file, TGA_INV_FILE_PNT, "Invalid File Pointer.");
check(image->_meta->image_type == TGA_COLOR_MAPPED, TGA_INTERNAL_ERR,
"Image is not color-mapped. This should not have been called.");
c_map_size = ((image->_meta->c_map_depth+7)/8) * image->_meta->c_map_length;
check(c_map_size > 0, TGA_COLOR_MAP_ERR, "Image claims color map, but "
"map is of size 0.");
start = TGA_HEADER_SIZE + image->_meta->id_length +
image->_meta->c_map_start;
check(fseek(file, start, SEEK_SET) == 0, TGA_GEN_IO_ERR,
"Unable to seek to color map start.");
image->color_map = malloc(sizeof(uint8_t) * c_map_size);
check(image->color_map, TGA_MEM_ERR, "Unable to allocate color map.");
check(fread(image->color_map, c_map_size, 1, file) == 1, TGA_READ_ERR,
"Unable to read Color Map.");
return 1;
error:
return 0;
}
static int _read_tga_image_data(TGAImage *image, FILE *file)
{
check(_tga_sanity(image), TGA_INV_IMAGE_PNT, "Invalid TGAImage Pointer.");
@@ -169,7 +195,6 @@ error:
/* Most errors in this subroutine are already set by the lower-level functions.
* So the error is set using tga_error() to fetch the existing error. */
/* TODO: Implement reading for ColorMapped TGA Images. */
/* TODO: Implement reading for Encoded TGA Images. */
/* TODO: Implement reading for developer/extension areas. */
TGAImage *read_tga_image(FILE *file)
@@ -191,8 +216,12 @@ TGAImage *read_tga_image(FILE *file)
else
image->id_field = NULL;
if(image->_meta->image_type == TGA_COLOR_MAPPED ||
image->_meta->image_type == TGA_ENCODED_COLOR_MAPPED ||
if(image->_meta->image_type == TGA_COLOR_MAPPED)
check(_read_tga_color_map(image, file), tga_error(),
"Unable to read TGA ColorMap Data.");
if(image->_meta->image_type == TGA_ENCODED_COLOR_MAPPED ||
image->_meta->image_type == TGA_ENCODED_TRUECOLOR ||
image->_meta->image_type == TGA_ENCODED_MONOCHROME)
fail(TGA_UNSUPPORTED,

View File

@@ -7,28 +7,38 @@ static void print_tga_data(TGAImage *img)
printf("TGA VERSION: %d\n", img->version);
printf("WIDTH: %d, HEIGHT: %d, DEPTH: %d\n", tga_get_width(img),
tga_get_height(img), tga_get_pixel_depth(img));
printf("IMAGE TYPE: ");
switch(tga_get_image_type(img))
{
case TGA_COLOR_MAPPED:
printf("Color Mapped\n");
break;
case TGA_TRUECOLOR:
printf("Truecolor\n");
break;
case TGA_MONOCHROME:
printf("Monochrome\n");
break;
default:
printf("Unsupported\n");
}
printf("C_MAP_START: %d\n", tga_get_color_map_start(img));
printf("C_MAP_DEPTH: %d\n", tga_get_color_map_depth(img));
printf("C_MAP_LENGTH: %d\n", tga_get_color_map_length(img));
}
int main(int argc, char **argv)
{
if(argc != 3)
{
fprintf(stderr, "USAGE: TGAReader <image> <newname>\n");
return 1;
}
FILE *img_file = fopen(argv[1], "rb");
if(!img_file)
{
fprintf(stderr, "Unable to open image file.\n");
return tga_error();
}
TGAImage *img = read_tga_image(img_file);
if(!img)
{
fprintf(stderr, "Unable to read image. ERROR: %d\n", tga_error());
return tga_error();
}
print_tga_data(img);
write_tga_image(img, argv[2]);
free_tga_image(img);