2 This is a small image library.
4 Copyright (C) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * author: John Tsiombikas 2004
24 * modified: John Tsiombikas 2005
27 #include "3dengfx_config.h"
35 #include "color_bits.h"
36 #include "common/byteorder.h"
39 uint8_t idlen; /* id field length */
40 uint8_t cmap_type; /* color map type (0:no color map, 1:color map present) */
41 uint8_t img_type; /* image type:
43 * 1: uncomp. color-mapped 9: RLE color-mapped
44 * 2: uncomp. true color 10: RLE true color
45 * 3: uncomp. black/white 11: RLE black/white */
46 uint16_t cmap_first; /* color map first entry index */
47 uint16_t cmap_len; /* color map length */
48 uint8_t cmap_entry_sz; /* color map entry size */
49 uint16_t img_x; /* X-origin of the image */
50 uint16_t img_y; /* Y-origin of the image */
51 uint16_t img_width; /* image width */
52 uint16_t img_height; /* image height */
53 uint8_t img_bpp; /* bits per pixel */
54 uint8_t img_desc; /* descriptor:
55 * bits 0 - 3: alpha or overlay bits
56 * bits 5 & 4: origin (0 = bottom/left, 1 = top/right)
57 * bits 7 & 6: data interleaving */
61 uint32_t ext_off; /* extension area offset */
62 uint32_t devdir_off; /* developer directory offset */
63 char sig[18]; /* signature with . and \0 */
66 /*static void print_tga_info(struct tga_header *hdr);*/
68 int check_tga(FILE *fp) {
69 struct tga_footer foot;
71 fseek(fp, -18, SEEK_END);
72 fread(foot.sig, 1, 18, fp);
75 return strcmp(foot.sig, "TRUEVISION-XFILE.") == 0 ? 1 : 0;
78 void *load_tga(FILE *fp, unsigned long *xsz, unsigned long *ysz) {
79 struct tga_header hdr;
80 unsigned long x, y, sz;
85 fseek(fp, 0, SEEK_SET);
86 hdr.idlen = fgetc(fp);
87 hdr.cmap_type = fgetc(fp);
88 hdr.img_type = fgetc(fp);
89 hdr.cmap_first = read_int16_le(fp);
90 hdr.cmap_len = read_int16_le(fp);
91 hdr.cmap_entry_sz = fgetc(fp);
92 hdr.img_x = read_int16_le(fp);
93 hdr.img_y = read_int16_le(fp);
94 hdr.img_width = read_int16_le(fp);
95 hdr.img_height = read_int16_le(fp);
96 hdr.img_bpp = fgetc(fp);
97 hdr.img_desc = fgetc(fp);
104 /* only read true color images */
105 if(hdr.img_type != 2) {
107 fprintf(stderr, "only true color tga images supported\n");
111 fseek(fp, hdr.idlen, SEEK_CUR); /* skip the image ID */
113 /* skip the color map if it exists */
114 if(hdr.cmap_type == 1) {
115 fseek(fp, hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR);
121 if(!(pix = malloc(sz * 4))) {
130 ptr = pix + ((hdr.img_desc & 0x20) ? i : y-(i+1)) * x;
133 unsigned char r, g, b, a;
137 a = (hdr.img_desc & 0xf) ? fgetc(fp) : 255;
139 *ptr++ = PACK_COLOR32(a, r, g, b);
151 int save_tga(FILE *fp, void *pixels, unsigned long xsz, unsigned long ysz) {
152 struct tga_header hdr;
153 struct tga_footer ftr;
154 unsigned long pix_count = xsz * ysz;
155 uint32_t *pptr = pixels;
156 unsigned long save_flags;
159 save_flags = get_image_save_flags();
161 memset(&hdr, 0, sizeof hdr);
164 hdr.img_height = ysz;
166 if(save_flags & IMG_SAVE_ALPHA) {
168 hdr.img_desc = 8 | 0x20; /* 8 alpha bits, origin top-left */
171 hdr.img_desc = 0x20; /* no alpha bits, origin top-left */
174 if(save_flags & IMG_SAVE_INVERT) {
175 hdr.img_desc ^= 0x20;
180 strcpy(ftr.sig, "TRUEVISION-XFILE.");
182 /* write the header */
184 fwrite(&hdr.idlen, 1, 1, fp);
185 fwrite(&hdr.cmap_type, 1, 1, fp);
186 fwrite(&hdr.img_type, 1, 1, fp);
187 write_int16_le(fp, hdr.cmap_first);
188 write_int16_le(fp, hdr.cmap_len);
189 fwrite(&hdr.cmap_entry_sz, 1, 1, fp);
190 write_int16_le(fp, hdr.img_x);
191 write_int16_le(fp, hdr.img_y);
192 write_int16_le(fp, hdr.img_width);
193 write_int16_le(fp, hdr.img_height);
194 fwrite(&hdr.img_bpp, 1, 1, fp);
195 fwrite(&hdr.img_desc, 1, 1, fp);
197 /* write the pixels */
198 for(i=0; i<pix_count; i++) {
199 fputc((*pptr >> BLUE_SHIFT32) & 0xff, fp);
200 fputc((*pptr >> GREEN_SHIFT32) & 0xff, fp);
201 fputc((*pptr >> RED_SHIFT32) & 0xff, fp);
203 if(save_flags & IMG_SAVE_ALPHA) {
204 fputc((*pptr >> ALPHA_SHIFT32) & 0xff, fp);
210 /* write the footer */
211 write_int32_le(fp, ftr.ext_off);
212 write_int32_le(fp, ftr.devdir_off);
221 static void print_tga_info(struct tga_header *hdr) {
222 static const char *img_type_str[] = {
224 "uncompressed color-mapped",
225 "uncompressed true color",
226 "uncompressed black & white",
233 printf("id field length: %d\n", (int)hdr->idlen);
234 printf("color map present: %s\n", hdr->cmap_type ? "yes" : "no");
235 printf("image type: %s\n", img_type_str[hdr->img_type]);
236 printf("color-map start: %d\n", (int)hdr->cmap_first);
237 printf("color-map length: %d\n", (int)hdr->cmap_len);
238 printf("color-map entry size: %d\n", (int)hdr->cmap_entry_sz);
239 printf("image origin: %d, %d\n", (int)hdr->img_x, (int)hdr->img_y);
240 printf("image size: %d, %d\n", (int)hdr->img_width, (int)hdr->img_height);
241 printf("bpp: %d\n", (int)hdr->img_bpp);
242 printf("attribute bits (alpha/overlay): %d\n", (int)(hdr->img_desc & 0xf));
243 printf("origin: %s-", (hdr->img_desc & 0x20) ? "top" : "bottom");
244 printf("%s\n", (hdr->img_desc & 0x10) ? "right" : "left");
248 #endif /* IMGLIB_USE_TGA */