/src/ogre/OgreMain/include/OgreImage.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef _Image_H__ |
29 | | #define _Image_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | #include "OgreCommon.h" |
33 | | #include "OgrePixelFormat.h" |
34 | | |
35 | | namespace Ogre { |
36 | | /** \addtogroup Core |
37 | | * @{ |
38 | | */ |
39 | | /** \addtogroup Image |
40 | | * @{ |
41 | | */ |
42 | | |
43 | | enum ImageFlags |
44 | | { |
45 | | IF_COMPRESSED = 0x00000001, |
46 | | IF_CUBEMAP = 0x00000002, |
47 | | IF_3D_TEXTURE = 0x00000004 |
48 | | }; |
49 | | /** Class representing an image file. |
50 | | |
51 | | The Image class usually holds uncompressed image data and is the |
52 | | only object that can be loaded in a texture. Image objects handle |
53 | | image data decoding themselves by the means of locating the correct |
54 | | Codec object for each data type. |
55 | | @par |
56 | | Typically, you would want to use an Image object to load a texture |
57 | | when extra processing needs to be done on an image before it is |
58 | | loaded or when you want to blit to an existing texture. |
59 | | */ |
60 | | class _OgreExport Image : public ImageAlloc |
61 | | { |
62 | | friend class ImageCodec; |
63 | | public: |
64 | | /** Standard constructor. |
65 | | * |
66 | | * allocates a buffer of given size if buffer pointer is NULL. |
67 | | */ |
68 | | Image(PixelFormat format = PF_UNKNOWN, uint32 width = 0, uint32 height = 0, uint32 depth = 1, |
69 | | uchar* buffer = NULL, bool autoDelete = true); |
70 | | /** Copy-constructor - copies all the data from the target image. |
71 | | */ |
72 | | Image( const Image &img ); |
73 | | |
74 | | /** |
75 | | * allocates a buffer of given size if needed |
76 | | * |
77 | | * - If the current allocation is equal to the requested size, this does nothing |
78 | | * - Otherwise any current allocation is freed, and memory of specified size is allocated |
79 | | * |
80 | | * @see loadDynamicImage |
81 | | */ |
82 | | void create(PixelFormat format, uint32 width, uint32 height, uint32 depth = 1, uint32 numFaces = 1, |
83 | | uint32 numMipMaps = 0); |
84 | | |
85 | | /** Standard destructor. |
86 | | */ |
87 | | ~Image(); |
88 | | |
89 | | /** Assignment operator - copies all the data from the target image. |
90 | | */ |
91 | | Image & operator = ( const Image & img ); |
92 | | |
93 | | /** |
94 | | * sets all pixels to the specified colour |
95 | | * |
96 | | * format conversion is performed as needed |
97 | | */ |
98 | | void setTo(const ColourValue& col); |
99 | | |
100 | | /** Flips (mirrors) the image around the Y-axis. |
101 | | |
102 | | An example of an original and flipped image: |
103 | | <pre> |
104 | | originalimg |
105 | | 00000000000 |
106 | | 00000000000 |
107 | | 00000000000 |
108 | | 00000000000 |
109 | | 00000000000 |
110 | | ------------> flip axis |
111 | | 00000000000 |
112 | | 00000000000 |
113 | | 00000000000 |
114 | | 00000000000 |
115 | | 00000000000 |
116 | | originalimg |
117 | | </pre> |
118 | | */ |
119 | | Image & flipAroundY(); |
120 | | |
121 | | /** Flips (mirrors) the image around the X-axis. |
122 | | |
123 | | An example of an original and flipped image: |
124 | | <pre> |
125 | | flip axis |
126 | | | |
127 | | originalimg|gmilanigiro |
128 | | 00000000000|00000000000 |
129 | | 00000000000|00000000000 |
130 | | 00000000000|00000000000 |
131 | | 00000000000|00000000000 |
132 | | 00000000000|00000000000 |
133 | | </pre> |
134 | | */ |
135 | | Image & flipAroundX(); |
136 | | |
137 | | /** Stores a pointer to raw data in memory. The pixel format has to be specified. |
138 | | |
139 | | This method loads an image into memory held in the object. The |
140 | | pixel format will be either greyscale or RGB with an optional |
141 | | Alpha component. |
142 | | The type can be determined by calling getFormat(). |
143 | | @note |
144 | | Whilst typically your image is likely to be a simple 2D image, |
145 | | you can define complex images including cube maps, volume maps, |
146 | | and images including custom mip levels. The layout of the |
147 | | internal memory should be: |
148 | | <ul><li>face 0, mip 0 (top), width x height (x depth)</li> |
149 | | <li>face 0, mip 1, width/2 x height/2 (x depth/2)</li> |
150 | | <li>face 0, mip 2, width/4 x height/4 (x depth/4)</li> |
151 | | <li>.. remaining mips for face 0 .. </li> |
152 | | <li>face 1, mip 0 (top), width x height (x depth)</li |
153 | | <li>.. and so on. </li> |
154 | | </ul> |
155 | | Of course, you will never have multiple faces (cube map) and |
156 | | depth too. |
157 | | @param data |
158 | | The data pointer |
159 | | @param width |
160 | | Width of image |
161 | | @param height |
162 | | Height of image |
163 | | @param depth |
164 | | Image Depth (in 3d images, numbers of layers, otherwise 1) |
165 | | @param format |
166 | | Pixel Format |
167 | | @param autoDelete |
168 | | If memory associated with this buffer is to be destroyed |
169 | | with the Image object. Note: it's important that if you set |
170 | | this option to true, that you allocated the memory using OGRE_ALLOC_T |
171 | | with a category of MEMCATEGORY_GENERAL to ensure the freeing of memory |
172 | | matches up. |
173 | | @param numFaces |
174 | | The number of faces the image data has inside (6 for cubemaps, 1 otherwise) |
175 | | @param numMipMaps |
176 | | The number of mipmaps the image data has inside |
177 | | @note |
178 | | The memory associated with this buffer is NOT destroyed with the |
179 | | Image object, unless autoDelete is set to true. |
180 | | |
181 | | The size of the buffer must be numFaces * PixelUtil::getMemorySize(width, height, depth, format) |
182 | | */ |
183 | | Image& loadDynamicImage(uchar* data, uint32 width, uint32 height, uint32 depth, PixelFormat format, |
184 | | bool autoDelete = false, uint32 numFaces = 1, uint32 numMipMaps = 0); |
185 | | |
186 | | /// @overload |
187 | | Image& loadDynamicImage(uchar* data, uint32 width, uint32 height, PixelFormat format) |
188 | 0 | { |
189 | 0 | return loadDynamicImage(data, width, height, 1, format); |
190 | 0 | } |
191 | | /** Loads raw data from a stream. See the function |
192 | | loadDynamicImage for a description of the parameters. |
193 | | |
194 | | The size of the buffer must be numFaces * PixelUtil::getMemorySize(width, height, depth, format) |
195 | | @note |
196 | | Whilst typically your image is likely to be a simple 2D image, |
197 | | you can define complex images including cube maps |
198 | | and images including custom mip levels. The layout of the |
199 | | internal memory should be: |
200 | | <ul><li>face 0, mip 0 (top), width x height (x depth)</li> |
201 | | <li>face 0, mip 1, width/2 x height/2 (x depth/2)</li> |
202 | | <li>face 0, mip 2, width/4 x height/4 (x depth/4)</li> |
203 | | <li>.. remaining mips for face 0 .. </li> |
204 | | <li>face 1, mip 0 (top), width x height (x depth)</li |
205 | | <li>.. and so on. </li> |
206 | | </ul> |
207 | | Of course, you will never have multiple faces (cube map) and |
208 | | depth too. |
209 | | */ |
210 | | Image& loadRawData(const DataStreamPtr& stream, uint32 width, uint32 height, uint32 depth, |
211 | | PixelFormat format, uint32 numFaces = 1, uint32 numMipMaps = 0); |
212 | | /// @overload |
213 | | Image& loadRawData(const DataStreamPtr& stream, uint32 width, uint32 height, PixelFormat format) |
214 | 0 | { |
215 | 0 | return loadRawData(stream, width, height, 1, format); |
216 | 0 | } |
217 | | |
218 | | /** Loads an image file. |
219 | | |
220 | | This method loads an image into memory. Any format for which |
221 | | an associated ImageCodec is registered can be loaded. |
222 | | This can include complex formats like DDS with embedded custom |
223 | | mipmaps, cube faces and volume textures. |
224 | | The type can be determined by calling getFormat(). |
225 | | @param |
226 | | filename Name of an image file to load. |
227 | | @param |
228 | | groupName Name of the resource group to search for the image |
229 | | @note |
230 | | The memory associated with this buffer is destroyed with the |
231 | | Image object. |
232 | | */ |
233 | | Image & load( const String& filename, const String& groupName ); |
234 | | |
235 | | /** Loads an image file from a stream. |
236 | | |
237 | | This method works in the same way as the filename-based load |
238 | | method except it loads the image from a DataStream object. |
239 | | This DataStream is expected to contain the |
240 | | encoded data as it would be held in a file. |
241 | | Any format for which an associated ImageCodec is registered |
242 | | can be loaded. |
243 | | This can include complex formats like DDS with embedded custom |
244 | | mipmaps, cube faces and volume textures. |
245 | | The type can be determined by calling getFormat(). |
246 | | @param |
247 | | stream The source data. |
248 | | @param |
249 | | type The type of the image. Used to decide what decompression |
250 | | codec to use. Can be left blank if the stream data includes |
251 | | a header to identify the data. |
252 | | @see |
253 | | Image::load( const String& filename ) |
254 | | */ |
255 | | Image & load(const DataStreamPtr& stream, String type = BLANKSTRING ); |
256 | | |
257 | | /** Utility method to combine 2 separate images into this one, with the first |
258 | | image source supplying the RGB channels, and the second image supplying the |
259 | | alpha channel (as luminance or separate alpha). |
260 | | @param rgbFilename Filename of image supplying the RGB channels (any alpha is ignored) |
261 | | @param alphaFilename Filename of image supplying the alpha channel. If a luminance image the |
262 | | single channel is used directly, if an RGB image then the values are |
263 | | converted to greyscale. |
264 | | @param groupName The resource group from which to load the images |
265 | | @param format The destination format |
266 | | */ |
267 | | Image & loadTwoImagesAsRGBA(const String& rgbFilename, const String& alphaFilename, |
268 | | const String& groupName, PixelFormat format = PF_BYTE_RGBA); |
269 | | |
270 | | /** Utility method to combine 2 separate images into this one, with the first |
271 | | image source supplying the RGB channels, and the second image supplying the |
272 | | alpha channel (as luminance or separate alpha). |
273 | | @param rgbStream Stream of image supplying the RGB channels (any alpha is ignored) |
274 | | @param alphaStream Stream of image supplying the alpha channel. If a luminance image the |
275 | | single channel is used directly, if an RGB image then the values are |
276 | | converted to greyscale. |
277 | | @param format The destination format |
278 | | @param rgbType The type of the RGB image. Used to decide what decompression |
279 | | codec to use. Can be left blank if the stream data includes |
280 | | a header to identify the data. |
281 | | @param alphaType The type of the alpha image. Used to decide what decompression |
282 | | codec to use. Can be left blank if the stream data includes |
283 | | a header to identify the data. |
284 | | */ |
285 | | Image& loadTwoImagesAsRGBA(const DataStreamPtr& rgbStream, const DataStreamPtr& alphaStream, |
286 | | PixelFormat format = PF_BYTE_RGBA, |
287 | | const String& rgbType = BLANKSTRING, |
288 | | const String& alphaType = BLANKSTRING); |
289 | | |
290 | | /** Utility method to combine 2 separate images into this one, with the first |
291 | | image source supplying the RGB channels, and the second image supplying the |
292 | | alpha channel (as luminance or separate alpha). |
293 | | @param rgb Image supplying the RGB channels (any alpha is ignored) |
294 | | @param alpha Image supplying the alpha channel. If a luminance image the |
295 | | single channel is used directly, if an RGB image then the values are |
296 | | converted to greyscale. |
297 | | @param format The destination format |
298 | | */ |
299 | | Image & combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat format = PF_BYTE_RGBA); |
300 | | |
301 | | |
302 | | /** Save the image as a file. |
303 | | |
304 | | Saving and loading are implemented by back end (sometimes third |
305 | | party) codecs. Implemented saving functionality is more limited |
306 | | than loading in some cases. Particularly DDS file format support |
307 | | is currently limited to true colour or single channel float32, |
308 | | square, power of two textures with no mipmaps. Volumetric support |
309 | | is currently limited to DDS files. |
310 | | */ |
311 | | void save(const String& filename); |
312 | | |
313 | | /** Encode the image and return a stream to the data. |
314 | | @param formatextension An extension to identify the image format |
315 | | to encode into, e.g. "jpg" or "png" |
316 | | */ |
317 | | DataStreamPtr encode(const String& formatextension); |
318 | | |
319 | | /** Returns a pointer to the internal image buffer at the specified pixel location. |
320 | | |
321 | | Be careful with this method. You will almost certainly |
322 | | prefer to use getPixelBox, especially with complex images |
323 | | which include many faces or custom mipmaps. |
324 | | */ |
325 | | uchar* getData(uint32 x = 0, uint32 y = 0, uint32 z = 0) |
326 | 676 | { |
327 | 676 | assert((!mBuffer && (x + y + z) == 0) || (x < mWidth && y < mHeight && z < mDepth)); |
328 | 676 | return mBuffer + mPixelSize * (z * mWidth * mHeight + mWidth * y + x); |
329 | 676 | } |
330 | | |
331 | | /// @overload |
332 | | const uchar* getData(uint32 x = 0, uint32 y = 0, uint32 z = 0) const |
333 | 0 | { |
334 | 0 | assert(mBuffer); |
335 | 0 | assert(x < mWidth && y < mHeight && z < mDepth); |
336 | 0 | return mBuffer + mPixelSize * (z * mWidth * mHeight + mWidth * y + x); |
337 | 0 | } |
338 | | |
339 | | /// @overload |
340 | | template <typename T> T* getData(uint32 x = 0, uint32 y = 0, uint32 z = 0) |
341 | 0 | { |
342 | 0 | return reinterpret_cast<T*>(getData(x, y, z)); |
343 | 0 | } |
344 | | |
345 | | /// @overload |
346 | | template <typename T> const T* getData(uint32 x = 0, uint32 y = 0, uint32 z = 0) const |
347 | | { |
348 | | return reinterpret_cast<const T*>(getData(x, y, z)); |
349 | | } |
350 | | |
351 | | /** Returns the size of the data buffer in bytes |
352 | | */ |
353 | 0 | size_t getSize() const { return mBufSize; } |
354 | | |
355 | | /** Returns the number of mipmaps contained in the image. |
356 | | */ |
357 | 0 | uint32 getNumMipmaps() const { return mNumMipmaps; } |
358 | | |
359 | | /** Returns true if the image has the appropriate flag set. |
360 | | */ |
361 | 0 | bool hasFlag(const ImageFlags imgFlag) const { return (mFlags & imgFlag) != 0; } |
362 | | |
363 | | /** Gets the width of the image in pixels. |
364 | | */ |
365 | 676 | uint32 getWidth(void) const { return mWidth; } |
366 | | |
367 | | /** Gets the height of the image in pixels. |
368 | | */ |
369 | 676 | uint32 getHeight(void) const { return mHeight; } |
370 | | |
371 | | /** Gets the depth of the image. |
372 | | */ |
373 | 0 | uint32 getDepth(void) const { return mDepth; } |
374 | | |
375 | | /** Get the number of faces of the image. This is usually 6 for a cubemap, and |
376 | | 1 for a normal image. |
377 | | */ |
378 | 0 | uint32 getNumFaces(void) const { return hasFlag(IF_CUBEMAP) ? 6 : 1; } |
379 | | |
380 | | /** Gets the physical width in bytes of each row of pixels. |
381 | | */ |
382 | 676 | size_t getRowSpan(void) const { return mWidth * mPixelSize; } |
383 | | |
384 | | /** Returns the image format. |
385 | | */ |
386 | 676 | PixelFormat getFormat() const { return mFormat; } |
387 | | |
388 | | /** Returns the number of bits per pixel. |
389 | | */ |
390 | 0 | uchar getBPP() const { return mPixelSize * 8;} |
391 | | |
392 | | /** Returns true if the image has an alpha component. |
393 | | */ |
394 | | bool getHasAlpha() const; |
395 | | |
396 | | /** Does gamma adjustment. |
397 | | @note |
398 | | Basic algo taken from Titan Engine, copyright (c) 2000 Ignacio |
399 | | Castano Iguado |
400 | | */ |
401 | | static void applyGamma( uchar *buffer, Real gamma, size_t size, uchar bpp ); |
402 | | |
403 | | /** |
404 | | * Get colour value from a certain location in the image. The z coordinate |
405 | | * is only valid for cubemaps and volume textures. This uses the first (largest) |
406 | | * mipmap. |
407 | | */ |
408 | | ColourValue getColourAt(uint32 x, uint32 y, uint32 z) const; |
409 | | |
410 | | /** |
411 | | * Set colour value at a certain location in the image. The z coordinate |
412 | | * is only valid for cubemaps and volume textures. This uses the first (largest) |
413 | | * mipmap. |
414 | | */ |
415 | | void setColourAt(ColourValue const &cv, uint32 x, uint32 y, uint32 z); |
416 | | |
417 | | /** |
418 | | * Get a PixelBox encapsulating the image data of a mipmap |
419 | | */ |
420 | | PixelBox getPixelBox(uint32 face = 0, uint32 mipmap = 0) const; |
421 | | |
422 | | /// Delete all the memory held by this image, if owned by this image (not dynamic) |
423 | | void freeMemory(); |
424 | | |
425 | | enum Filter |
426 | | { |
427 | | FILTER_NEAREST, |
428 | | FILTER_LINEAR, |
429 | | FILTER_BILINEAR = FILTER_LINEAR |
430 | | }; |
431 | | /** Scale a 1D, 2D or 3D image volume. |
432 | | @param src PixelBox containing the source pointer, dimensions and format |
433 | | @param dst PixelBox containing the destination pointer, dimensions and format |
434 | | @param filter Which filter to use |
435 | | This function can do pixel format conversion in the process. |
436 | | @note dst and src can point to the same PixelBox object without any problem |
437 | | */ |
438 | | static void scale(const PixelBox &src, const PixelBox &dst, Filter filter = FILTER_BILINEAR); |
439 | | |
440 | | /** Resize a 2D image, applying the appropriate filter. */ |
441 | | void resize(ushort width, ushort height, Filter filter = FILTER_BILINEAR); |
442 | | |
443 | | /// Static function to calculate size in bytes from the number of mipmaps, faces and the dimensions |
444 | | static size_t calculateSize(uint32 mipmaps, uint32 faces, uint32 width, uint32 height, uint32 depth, PixelFormat format); |
445 | | |
446 | | /// Static function to get an image type string from a stream via magic numbers |
447 | | OGRE_DEPRECATED static String getFileExtFromMagic(DataStreamPtr stream); |
448 | | |
449 | | private: |
450 | | /// The width of the image in pixels |
451 | | uint32 mWidth; |
452 | | /// The height of the image in pixels |
453 | | uint32 mHeight; |
454 | | /// The depth of the image |
455 | | uint32 mDepth; |
456 | | /// The number of mipmaps the image contains |
457 | | uint32 mNumMipmaps; |
458 | | /// The size of the image buffer |
459 | | size_t mBufSize; |
460 | | /// Image specific flags. |
461 | | int mFlags; |
462 | | |
463 | | /// The pixel format of the image |
464 | | PixelFormat mFormat; |
465 | | |
466 | | uchar* mBuffer; |
467 | | /// The number of bytes per pixel |
468 | | uchar mPixelSize; |
469 | | /// A bool to determine if we delete the buffer or the calling app does |
470 | | bool mAutoDelete; |
471 | | }; |
472 | | |
473 | | typedef std::vector<Image*> ImagePtrList; |
474 | | typedef std::vector<const Image*> ConstImagePtrList; |
475 | | |
476 | | /** @} */ |
477 | | /** @} */ |
478 | | |
479 | | } // namespace |
480 | | |
481 | | #endif |