Pyrogenesis  trunk
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  **/
39 class ITexCodec
40 {
41 public:
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 
121 public:
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 
135 public:
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 
149 public:
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 
163 public:
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  **/
185 extern 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  **/
197 extern 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  **/
208 extern 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  **/
229 typedef const u8* RowPtr;
230 extern 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  **/
242 extern 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 Status transform(Tex *t, size_t transforms) const =0
transform the texture&#39;s pixel format.
Stores all data describing an image.
Definition: tex.h:208
Status tex_codec_transform(Tex *t, size_t transforms)
transform the texture&#39;s pixel format.
Definition: tex_codec.cpp:84
provides a memory range that can be expanded but doesn&#39;t waste physical memory or relocate itself...
Definition: dynarray.h:39
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:156
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
virtual const wchar_t * get_name() const =0
name of codec for debug purposes.
virtual bool is_ext(const OsPath &extension) const =0
is the extension that of a file format supported by this codec?
Definition: tex_codec.h:148
uint8_t u8
Definition: types.h:37
Definition: tex_codec.h:162
virtual size_t hdr_size(const u8 *file) const =0
return size of the file header supported by this codec.
Definition: path.h:79
i64 Status
Error handling system.
Definition: status.h:169
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:170
Definition: tex_codec.h:134
Definition: tex_codec.h:120
const char * extension
Definition: mongoose.cpp:1741
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
#define RESTRICT
Definition: code_annotation.h:332
virtual bool is_hdr(const u8 *file) const =0
indicate if the data appears to be an instance of this codec&#39;s header, i.e.
Status tex_codec_for_header(const u8 *data, size_t data_size, const ITexCodec **c)
find codec that recognizes the header&#39;s magic field.
Definition: tex_codec.cpp:66
virtual method table for TexCodecs.
Definition: tex_codec.h:39
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
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:128
const u8 * RowPtr
allocate an array of row pointers that point into the given texture data.
Definition: tex_codec.h:229
virtual ~ITexCodec()
Definition: tex_codec.h:117
virtual Status decode(u8 *data, size_t size, Tex *RESTRICT t) const =0
decode the file into a Tex structure.
virtual const wchar_t * get_name() const
name of codec for debug purposes.
Definition: tex_codec.h:142
virtual Status encode(Tex *RESTRICT t, DynArray *RESTRICT da) const =0
encode the texture data into the codec&#39;s file format (in memory).