-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtga.c
110 lines (91 loc) · 2.87 KB
/
tga.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* KallistiOS ##version##
tga.c
(c)2000-2001 Benoit Miller
TGA image loader.
20-Jan-2002 Paul Boese:
flip y-axis so it loads like all the other kos
image loaders.
06-Apr-2002 Dan Potter:
Split into its own library, adapted for kos_img_t
*/
#include <kos.h>
#include <assert.h>
#include "tga.h"
typedef struct {
uint8 image_id_length __attribute__((packed)); /* Length of Image ID field */
uint8 colormap_type __attribute__((packed)); /* Color Map type */
uint8 image_type __attribute__((packed)); /* Image Type code */
uint16 colormap_origin __attribute__((packed)); /* Color Map origin */
uint16 colormap_length __attribute__((packed)); /* Color Map length */
uint8 colormap_entry_size __attribute__((packed)); /* Color Map entry size */
uint16 x_origin __attribute__((packed)); /* X origin of image */
uint16 y_origin __attribute__((packed)); /* Y origin of image */
uint16 width __attribute__((packed)); /* Image width */
uint16 height __attribute__((packed)); /* Image height */
uint8 pixel_size __attribute__((packed)); /* Image pixel size */
uint8 img_descriptor __attribute__((packed)); /* Image descriptor byte */
} tga_hdr;
/* Loads a TGA file into a kos_img_t struct */
int tga_to_img(const char *fn, kos_img_t *rv) {
tga_hdr tgah;
file_t fd;
uint8 r, g, b, a;
int x, y;
int num_bytes;
uint16 *image;
assert( rv != NULL );
/* Open the file */
fd = fs_open(fn, O_RDONLY);
if (fd < 0) {
dbglog(DBG_ERROR, "tga_load(%s): Couldn't open file\n", fn);
return -1;
}
/* Load the TGA header */
fs_read(fd, &tgah, sizeof(tgah));
if (tgah.image_type != 2) {
dbglog(DBG_ERROR, "tga_load(%s): Not an unmapped RGB image\n", fn);
fs_close(fd);
return -2;
}
if (tgah.pixel_size != 32) {
dbglog(DBG_ERROR, "tga_load(%s): TGA data is not 32bpp\n", fn);
fs_close(fd);
return -3;
}
if (tgah.img_descriptor & 0x20) {
dbglog(DBG_ERROR, "tga_load(%s): Not a TrueVision image\n", fn);
fs_close(fd);
return -4;
}
/* Setup the output structure */
rv->w = tgah.width;
rv->h = tgah.height;
rv->byte_count = num_bytes = rv->w * rv->h * 2;
rv->data = malloc(num_bytes);
rv->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB4444, 0);
/* Don't care for the image identification field */
fs_seek(fd, tgah.image_id_length, SEEK_CUR);
/* Don't care for the color map */
fs_seek(fd, tgah.colormap_length * tgah.colormap_entry_size, SEEK_CUR);
/* Read the image */
image = ((uint16*)(rv->data)) + (tgah.width * tgah.height);
for (y=0; y<tgah.height; y++) {
image -= tgah.width;
for (x=0; x<tgah.width; x++) {
fs_read(fd, &b, 1);
fs_read(fd, &g, 1);
fs_read(fd, &r, 1);
fs_read(fd, &a, 1);
/* Cheap scaling to ARGB4444 */
a = a >> 4 & 0x0f;
r = r >> 4 & 0x0f;
g = g >> 4 & 0x0f;
b = b >> 4 & 0x0f;
/* Store the final pixel */
image[x] = (a<<12) | (r<<8) | (g<<4) | b;
}
}
/* Close the file */
fs_close(fd);
return 0;
}