Implemented very basic read support for ColorMapped (Non-Encoded) TGA.
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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,
|
||||
|
||||
28
src/test.c
28
src/test.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user