Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tex_tga.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2010 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * TGA codec.
25  */
26 
27 #include "precompiled.h"
28 
29 #include "lib/byte_order.h"
30 #include "tex_codec.h"
31 #include "lib/bits.h"
32 
33 #pragma pack(push, 1)
34 
36 {
37  TGA_TRUE_COLOUR = 2, // uncompressed 24 or 32 bit direct RGB
38  TGA_GREY = 3 // uncompressed 8 bit direct greyscale
39 };
40 
42 {
45 };
46 
47 typedef struct
48 {
49  u8 img_id_len; // 0 - no image identifier present
50  u8 colour_map_type; // 0 - no colour map present
51  u8 img_type; // see TgaImgType
52  u8 colour_map[5]; // unused
53 
54  u16 x_origin; // unused
55  u16 y_origin; // unused
56 
57  u16 w;
58  u16 h;
59  u8 bpp; // bits per pixel
60 
62 }
63 TgaHeader;
64 
65 // TGA file: header [img id] [colour map] image data
66 
67 #pragma pack(pop)
68 
69 
70 static Status tga_transform(Tex* UNUSED(t), size_t UNUSED(transforms))
71 {
73 }
74 
75 
76 static bool tga_is_hdr(const u8* file)
77 {
78  TgaHeader* hdr = (TgaHeader*)file;
79 
80  // the first TGA header doesn't have a magic field;
81  // we can only check if the first 4 bytes are valid
82  // .. not direct colour
83  if(hdr->colour_map_type != 0)
84  return false;
85  // .. wrong colour type (not uncompressed greyscale or RGB)
86  if(hdr->img_type != TGA_TRUE_COLOUR && hdr->img_type != TGA_GREY)
87  return false;
88 
89  // note: we can't check img_id_len or colour_map[0] - they are
90  // undefined and may assume any value.
91 
92  return true;
93 }
94 
95 
96 static bool tga_is_ext(const OsPath& extension)
97 {
98  return extension == L".tga";
99 }
100 
101 
102 static size_t tga_hdr_size(const u8* file)
103 {
104  size_t hdr_size = sizeof(TgaHeader);
105  if(file)
106  {
107  TgaHeader* hdr = (TgaHeader*)file;
108  hdr_size += hdr->img_id_len;
109  }
110  return hdr_size;
111 }
112 
113 
114 // requirements: uncompressed, direct color, bottom up
115 static Status tga_decode(rpU8 data, size_t UNUSED(size), Tex* RESTRICT t)
116 {
117  const TgaHeader* hdr = (const TgaHeader*)data;
118  const u8 type = hdr->img_type;
119  const size_t w = read_le16(&hdr->w);
120  const size_t h = read_le16(&hdr->h);
121  const size_t bpp = hdr->bpp;
122  const u8 desc = hdr->img_desc;
123 
124  size_t flags = 0;
125  flags |= (desc & TGA_TOP_DOWN)? TEX_TOP_DOWN : TEX_BOTTOM_UP;
126  if(desc & 0x0F) // alpha bits
127  flags |= TEX_ALPHA;
128  if(bpp == 8)
129  flags |= TEX_GREY;
130  if(type == TGA_TRUE_COLOUR)
131  flags |= TEX_BGR;
132 
133  // sanity checks
134  // .. storing right-to-left is just stupid;
135  // we're not going to bother converting it.
136  if(desc & TGA_RIGHT_TO_LEFT)
138 
139  t->w = w;
140  t->h = h;
141  t->bpp = bpp;
142  t->flags = flags;
143  return INFO::OK;
144 }
145 
146 
148 {
149  u8 img_desc = 0;
150  if(t->flags & TEX_TOP_DOWN)
151  img_desc |= TGA_TOP_DOWN;
152  if(t->bpp == 32)
153  img_desc |= 8; // size of alpha channel
154  TgaImgType img_type = (t->flags & TEX_GREY)? TGA_GREY : TGA_TRUE_COLOUR;
155 
156  size_t transforms = t->flags;
157  transforms &= ~TEX_ORIENTATION; // no flip needed - we can set top-down bit.
158  transforms ^= TEX_BGR; // TGA is native BGR.
159 
160  const TgaHeader hdr =
161  {
162  0, // no image identifier present
163  0, // no colour map present
164  (u8)img_type,
165  {0,0,0,0,0}, // unused (colour map)
166  0, 0, // unused (origin)
167  (u16)t->w,
168  (u16)t->h,
169  (u8)t->bpp,
170  img_desc
171  };
172  const size_t hdr_size = sizeof(hdr);
173  return tex_codec_write(t, transforms, &hdr, hdr_size, da);
174 }
175 
176 TEX_CODEC_REGISTER(tga);
u8 img_id_len
Definition: tex_tga.cpp:49
#define u8
Definition: types.h:39
Status tex_codec_write(Tex *t, size_t transforms, const void *hdr, size_t hdr_size, DynArray *da)
apply transforms and then copy header and image into output buffer.
Definition: tex_codec.cpp:176
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
const Status TEX_CODEC_CANNOT_HANDLE
Definition: tex.h:132
const Status OK
Definition: status.h:386
u8 img_type
Definition: tex_tga.cpp:51
indicates the image contains an alpha channel.
Definition: tex.h:171
provides a memory range that can be expanded but doesn't waste physical memory or relocate itself...
Definition: dynarray.h:39
indicates the image is 8bpp greyscale.
Definition: tex.h:178
indicates B and R pixel components are exchanged.
Definition: tex.h:163
flags & TEX_ORIENTATION is a field indicating orientation, i.e.
Definition: tex.h:190
u16 y_origin
Definition: tex_tga.cpp:55
TgaImgDesc
Definition: tex_tga.cpp:41
uint8_t *__restrict rpU8
Definition: path.h:75
static bool tga_is_ext(const OsPath &extension)
Definition: tex_tga.cpp:96
#define BIT(n)
pretty much the same as Bit<unsigned>.
Definition: bits.h:51
u8 img_desc
Definition: tex_tga.cpp:61
i64 Status
Error handling system.
Definition: status.h:171
stores all data describing an image.
Definition: tex.h:210
#define u16
Definition: types.h:40
static size_t tga_hdr_size(const u8 *file)
Definition: tex_tga.cpp:102
const char * extension
Definition: mongoose.cpp:1736
const Status TEX_INVALID_LAYOUT
Definition: tex.h:120
u16 read_le16(const void *p)
read a little-endian number from memory into native byte order.
Definition: byte_order.cpp:66
u8 colour_map_type
Definition: tex_tga.cpp:50
#define RESTRICT
#define TEX_CODEC_REGISTER(name)
build codec vtbl and register it.
Definition: tex_codec.h:137
static Status tga_decode(rpU8 data, size_t size, Tex *RESTRICT t)
Definition: tex_tga.cpp:115
#define WARN_RETURN(status)
Definition: status.h:255
TgaImgType
Definition: tex_tga.cpp:35
u16 x_origin
Definition: tex_tga.cpp:54
static bool tga_is_hdr(const u8 *file)
Definition: tex_tga.cpp:76
static Status tga_encode(Tex *RESTRICT t, DynArray *RESTRICT da)
Definition: tex_tga.cpp:147
static Status tga_transform(Tex *t, size_t transforms)
Definition: tex_tga.cpp:70