Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
tex_codec.h
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 * support routines and interface for texture codecs.
25 */
26
27#ifndef INCLUDED_TEX_CODEC
28#define INCLUDED_TEX_CODEC
29
30#include "tex.h"
31#include "tex_internal.h" // for codec's convenience
32
33/**
34 * virtual method table for TexCodecs.
35 * rationale: this works in C and also allows storing name and next in vtbl.
36 * 'template method'-style interface to increase code reuse and
37 * simplify writing new codecs.
38 **/
40{
41public:
42 /**
43 * decode the file into a Tex structure.
44 *
45 * @param data input data array (non-const, because the texture
46 * may have to be flipped in-place - see "texture orientation").
47 * @param size [bytes] of data, always >= 4
48 * (this is usually enough to compare the header's "magic" field,
49 * and no legitimate file will be smaller)
50 * @param t output texture object
51 * @return Status
52 **/
53 virtual Status decode(u8* data, size_t size, Tex* RESTRICT t) const = 0;
54
55 /**
56 * encode the texture data into the codec's file format (in memory).
57 *
58 * @param t input texture object. note: non-const because encoding may
59 * require a Tex::transform.
60 * @param da output data array, allocated by codec.
61 * rationale: some codecs cannot calculate the output size beforehand
62 * (e.g. PNG output via libpng), so the output memory cannot be allocated
63 * by the caller.
64 * @return Status
65 **/
66 virtual Status encode(Tex* RESTRICT t, DynArray* RESTRICT da) const = 0;
67
68 /**
69 * transform the texture's pixel format.
70 *
71 * @param t texture object
72 * @param transforms: OR-ed combination of TEX_* flags that are to
73 * be changed. note: the codec needs only handle situations specific
74 * to its format; generic pixel format transforms are handled by
75 * the caller.
76 **/
77 virtual Status transform(Tex* t, size_t transforms) const = 0;
78
79 /**
80 * indicate if the data appears to be an instance of this codec's header,
81 * i.e. can this codec decode it?
82 *
83 * @param file input data; only guaranteed to be 4 bytes!
84 * (this should be enough to examine the header's 'magic' field)
85 * @return bool
86 **/
87 virtual bool is_hdr(const u8* file) const = 0;
88
89 /**
90 * is the extension that of a file format supported by this codec?
91 *
92 * rationale: cannot just return the extension string and have
93 * caller compare it (-> smaller code) because a codec's file format
94 * may have several valid extensions (e.g. jpg and jpeg).
95 *
96 * @param extension (including '.')
97 * @return bool
98 **/
99 virtual bool is_ext(const OsPath& extension) const = 0;
100
101 /**
102 * return size of the file header supported by this codec.
103 *
104 * @param file the specific header to return length of (taking its
105 * variable-length fields into account). if NULL, return minimum
106 * guaranteed header size, i.e. the header without any
107 * variable-length fields.
108 * @return size [bytes]
109 **/
110 virtual size_t hdr_size(const u8* file) const = 0;
111
112 /**
113 * name of codec for debug purposes. typically set via TEX_CODEC_REGISTER.
114 **/
115 virtual const wchar_t* get_name() const = 0;
116
117 virtual ~ITexCodec() {}
118};
119
121public:
122 virtual Status decode(u8* data, size_t size, Tex* RESTRICT t) const;
123 virtual Status encode(Tex* RESTRICT t, DynArray* RESTRICT da) const;
124 virtual Status transform(Tex* t, size_t transforms) const;
125 virtual bool is_hdr(const u8* file) const;
126 virtual bool is_ext(const OsPath& extension) const;
127 virtual size_t hdr_size(const u8* file) const;
128 virtual const wchar_t* get_name() const {
129 static const wchar_t *name = L"png";
130 return name;
131 };
132};
133
135public:
136 virtual Status decode(u8* data, size_t size, Tex* RESTRICT t) const;
137 virtual Status encode(Tex* RESTRICT t, DynArray* RESTRICT da) const;
138 virtual Status transform(Tex* t, size_t transforms) const;
139 virtual bool is_hdr(const u8* file) const;
140 virtual bool is_ext(const OsPath& extension) const;
141 virtual size_t hdr_size(const u8* file) const;
142 virtual const wchar_t* get_name() const {
143 static const wchar_t *name = L"dds";
144 return name;
145 };
146};
147
149public:
150 virtual Status decode(u8* data, size_t size, Tex* RESTRICT t) const;
151 virtual Status encode(Tex* RESTRICT t, DynArray* RESTRICT da) const;
152 virtual Status transform(Tex* t, size_t transforms) const;
153 virtual bool is_hdr(const u8* file) const;
154 virtual bool is_ext(const OsPath& extension) const;
155 virtual size_t hdr_size(const u8* file) const;
156 virtual const wchar_t* get_name() const {
157 static const wchar_t *name = L"tga";
158 return name;
159 };
160};
161
163public:
164 virtual Status decode(u8* data, size_t size, Tex* RESTRICT t) const;
165 virtual Status encode(Tex* RESTRICT t, DynArray* RESTRICT da) const;
166 virtual Status transform(Tex* t, size_t transforms) const;
167 virtual bool is_hdr(const u8* file) const;
168 virtual bool is_ext(const OsPath& extension) const;
169 virtual size_t hdr_size(const u8* file) const;
170 virtual const wchar_t* get_name() const {
171 static const wchar_t *name = L"bmp";
172 return name;
173 };
174};
175
176/**
177 * Find codec that recognizes the desired output file extension.
178 *
179 * @param extension
180 * @param c (out) vtbl of responsible codec
181 * @return Status; ERR::RES_UNKNOWN_FORMAT (without warning, because this is
182 * called by tex_is_known_extension) if no codec indicates they can
183 * handle the given extension.
184 **/
185extern Status tex_codec_for_filename(const OsPath& extension, const ITexCodec** c);
186
187/**
188 * find codec that recognizes the header's magic field.
189 *
190 * @param data typically contents of file, but need only include the
191 * (first 4 bytes of) header.
192 * @param data_size [bytes]
193 * @param c (out) vtbl of responsible codec
194 * @return Status; ERR::RES_UNKNOWN_FORMAT if no codec indicates they can
195 * handle the given format (header).
196 **/
197extern Status tex_codec_for_header(const u8* data, size_t data_size, const ITexCodec** c);
198
199/**
200 * transform the texture's pixel format.
201 * tries each codec's transform method once, or until one indicates success.
202 *
203 * @param t texture object
204 * @param transforms: OR-ed combination of TEX_* flags that are to
205 * be changed.
206 * @return Status
207 **/
208extern Status tex_codec_transform(Tex* t, size_t transforms);
209
210/**
211 * allocate an array of row pointers that point into the given texture data.
212 * for texture decoders that support output via row pointers (e.g. PNG),
213 * this allows flipping the image vertically (useful when matching bottom-up
214 * textures to a global orientation) directly, which is much more
215 * efficient than transforming later via copying all pixels.
216 *
217 * @param data the texture data into which row pointers will point.
218 * note: we don't allocate it here because this function is
219 * needed for encoding, too (where data is already present).
220 * @param h height [pixels] of texture.
221 * @param pitch size [bytes] of one texture row, i.e. width*bytes_per_pixel.
222 * @param src_flags TexFlags of source texture. used to extract its
223 * orientation.
224 * @param dst_orientation desired orientation of the output data.
225 * can be one of TEX_BOTTOM_UP, TEX_TOP_DOWN, or 0 for the
226 * "global orientation".
227 * depending on src and dst, the row array is flipped if necessary.
228 **/
229typedef const u8* RowPtr;
230extern std::vector<RowPtr> tex_codec_alloc_rows(const u8* data, size_t h, size_t pitch, size_t src_flags, size_t dst_orientation);
231
232/**
233 * apply transforms and then copy header and image into output buffer.
234 *
235 * @param t input texture object
236 * @param transforms transformations to be applied to pixel format
237 * @param hdr header data
238 * @param hdr_size [bytes]
239 * @param da output data array (will be expanded as necessary)
240 * @return Status
241 **/
242extern Status tex_codec_write(Tex* t, size_t transforms, const void* hdr, size_t hdr_size, DynArray* da);
243
244#endif // #ifndef INCLUDED_TEX_CODEC
virtual method table for TexCodecs.
Definition: tex_codec.h:40
virtual ~ITexCodec()
Definition: tex_codec.h:117
virtual bool is_hdr(const u8 *file) const =0
indicate if the data appears to be an instance of this codec's header, i.e.
virtual const wchar_t * get_name() const =0
name of codec for debug purposes.
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const =0
encode the texture data into the codec's file format (in memory).
virtual size_t hdr_size(const u8 *file) const =0
return size of the file header supported by this codec.
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const =0
decode the file into a Tex structure.
virtual Status transform(Tex *t, size_t transforms) const =0
transform the texture's pixel format.
virtual bool is_ext(const OsPath &extension) const =0
is the extension that of a file format supported by this codec?
Definition: path.h:80
Definition: tex_codec.h:162
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const
encode the texture data into the codec's file format (in memory).
Definition: tex_bmp.cpp:127
virtual bool is_ext(const OsPath &extension) const
is the extension that of a file format supported by this codec?
Definition: tex_bmp.cpp:77
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:170
virtual size_t hdr_size(const u8 *file) const
return size of the file header supported by this codec.
Definition: tex_bmp.cpp:83
virtual Status transform(Tex *t, size_t transforms) const
transform the texture's pixel format.
Definition: tex_bmp.cpp:63
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const
decode the file into a Tex structure.
Definition: tex_bmp.cpp:98
virtual bool is_hdr(const u8 *file) const
indicate if the data appears to be an instance of this codec's header, i.e.
Definition: tex_bmp.cpp:69
Definition: tex_codec.h:134
virtual Status transform(Tex *t, size_t transforms) const
transform the texture's pixel format.
Definition: tex_dds.cpp:630
virtual bool is_ext(const OsPath &extension) const
is the extension that of a file format supported by this codec?
Definition: tex_dds.cpp:600
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const
decode the file into a Tex structure.
Definition: tex_dds.cpp:612
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const
encode the texture data into the codec's file format (in memory).
Definition: tex_dds.cpp:620
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:142
virtual size_t hdr_size(const u8 *file) const
return size of the file header supported by this codec.
Definition: tex_dds.cpp:606
virtual bool is_hdr(const u8 *file) const
indicate if the data appears to be an instance of this codec's header, i.e.
Definition: tex_dds.cpp:594
Definition: tex_codec.h:120
virtual Status transform(Tex *t, size_t transforms) const
transform the texture's pixel format.
Definition: tex_png.cpp:110
virtual bool is_ext(const OsPath &extension) const
is the extension that of a file format supported by this codec?
Definition: tex_png.cpp:249
virtual size_t hdr_size(const u8 *file) const
return size of the file header supported by this codec.
Definition: tex_png.cpp:255
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const
encode the texture data into the codec's file format (in memory).
Definition: tex_png.cpp:307
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:128
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const
decode the file into a Tex structure.
Definition: tex_png.cpp:272
virtual bool is_hdr(const u8 *file) const
indicate if the data appears to be an instance of this codec's header, i.e.
Definition: tex_png.cpp:241
Definition: tex_codec.h:148
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const
decode the file into a Tex structure.
Definition: tex_tga.cpp:115
virtual size_t hdr_size(const u8 *file) const
return size of the file header supported by this codec.
Definition: tex_tga.cpp:102
virtual Status transform(Tex *t, size_t transforms) const
transform the texture's pixel format.
Definition: tex_tga.cpp:70
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const
encode the texture data into the codec's file format (in memory).
Definition: tex_tga.cpp:147
virtual bool is_hdr(const u8 *file) const
indicate if the data appears to be an instance of this codec's header, i.e.
Definition: tex_tga.cpp:76
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:156
virtual bool is_ext(const OsPath &extension) const
is the extension that of a file format supported by this codec?
Definition: tex_tga.cpp:96
Stores all data describing an image.
Definition: tex.h:209
#define RESTRICT
Definition: code_annotation.h:334
i64 Status
Error handling system.
Definition: status.h:173
provides a memory range that can be expanded but doesn't waste physical memory or relocate itself.
Definition: dynarray.h:40
Status tex_codec_for_filename(const OsPath &extension, const ITexCodec **c)
Find codec that recognizes the desired output file extension.
Definition: tex_codec.cpp:50
const u8 * RowPtr
allocate an array of row pointers that point into the given texture data.
Definition: tex_codec.h:229
std::vector< RowPtr > tex_codec_alloc_rows(const u8 *data, size_t h, size_t pitch, size_t src_flags, size_t dst_orientation)
Definition: tex_codec.cpp:120
Status tex_codec_for_header(const u8 *data, size_t data_size, const ITexCodec **c)
find codec that recognizes the header's magic field.
Definition: tex_codec.cpp:66
Status tex_codec_transform(Tex *t, size_t transforms)
transform the texture's pixel format.
Definition: tex_codec.cpp:84
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:142
uint8_t u8
Definition: types.h:37