1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __I_IMAGE_H_INCLUDED__
\r
6 #define __I_IMAGE_H_INCLUDED__
\r
8 #include "IReferenceCounted.h"
\r
9 #include "position2d.h"
\r
12 #include "irrAllocator.h"
\r
20 //! Interface for software image data.
\r
21 /** Image loaders create these images from files. IVideoDrivers convert
\r
22 these images into their (hardware) textures.
\r
23 NOTE: Floating point formats are not well supported yet. Basically only getData() works for them.
\r
25 class IImage : public virtual IReferenceCounted
\r
30 IImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, bool deleteMemory) :
\r
31 Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false)
\r
33 BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
\r
34 Pitch = BytesPerPixel * Size.Width;
\r
43 if (DeleteMipMapsMemory)
\r
44 Allocator.deallocate(MipMapsData);
\r
47 //! Returns the color format
\r
48 ECOLOR_FORMAT getColorFormat() const
\r
53 //! Returns width and height of image data.
\r
54 const core::dimension2d<u32>& getDimension() const
\r
59 //! Returns bits per pixel.
\r
60 u32 getBitsPerPixel() const
\r
63 return getBitsPerPixelFromFormat(Format);
\r
66 //! Returns bytes per pixel
\r
67 u32 getBytesPerPixel() const
\r
69 return BytesPerPixel;
\r
72 //! Returns image data size in bytes
\r
73 u32 getImageDataSizeInBytes() const
\r
75 return getDataSizeFromFormat(Format, Size.Width, Size.Height);
\r
78 //! Returns image data size in pixels
\r
79 u32 getImageDataSizeInPixels() const
\r
81 return Size.Width * Size.Height;
\r
84 //! Returns pitch of image
\r
85 u32 getPitch() const
\r
90 //! Returns mask for red value of a pixel
\r
91 u32 getRedMask() const
\r
108 //! Returns mask for green value of a pixel
\r
109 u32 getGreenMask() const
\r
126 //! Returns mask for blue value of a pixel
\r
127 u32 getBlueMask() const
\r
144 //! Returns mask for alpha value of a pixel
\r
145 u32 getAlphaMask() const
\r
162 //! Use this to get a pointer to the image data.
\r
164 \return Pointer to the image data. What type of data is pointed to
\r
165 depends on the color format of the image. For example if the color
\r
166 format is ECF_A8R8G8B8, it is of u32. */
\r
167 void* getData() const
\r
172 //! Lock function. Use this to get a pointer to the image data.
\r
173 /** Use getData instead.
\r
174 \return Pointer to the image data. What type of data is pointed to
\r
175 depends on the color format of the image. For example if the color
\r
176 format is ECF_A8R8G8B8, it is of u32. Be sure to call unlock() after
\r
177 you don't need the pointer any more. */
\r
178 _IRR_DEPRECATED_ void* lock()
\r
183 //! Unlock function.
\r
184 /** Should be called after the pointer received by lock() is not
\r
186 _IRR_DEPRECATED_ void unlock()
\r
190 //! Get the mipmap size for this image for a certain mipmap level
\r
191 /** level 0 will be full image size. Every further level is half the size.
\r
192 Doesn't care if the image actually has mipmaps, just which size would be needed. */
\r
193 core::dimension2du getMipMapsSize(u32 mipmapLevel) const
\r
195 return getMipMapsSize(Size, mipmapLevel);
\r
199 //! Calculate mipmap size for a certain level
\r
200 /** level 0 will be full image size. Every further level is half the size. */
\r
201 static core::dimension2du getMipMapsSize(const core::dimension2du& sizeLevel0, u32 mipmapLevel)
\r
203 core::dimension2du result(sizeLevel0);
\r
205 while (i != mipmapLevel)
\r
207 if (result.Width>1)
\r
208 result.Width >>= 1;
\r
209 if (result.Height>1)
\r
213 if ( result.Width == 1 && result.Height == 1 && i < mipmapLevel )
\r
214 return core::dimension2du(0,0);
\r
220 //! Get mipmaps data.
\r
221 /** Note that different mip levels are just behind each other in memory block.
\r
222 So if you just get level 1 you also have the data for all other levels.
\r
223 There is no level 0 - use getData to get the original image data.
\r
225 void* getMipMapsData(irr::u32 mipLevel=1) const
\r
227 if ( MipMapsData && mipLevel > 0)
\r
229 size_t dataSize = 0;
\r
230 core::dimension2du mipSize(Size);
\r
231 u32 i = 1; // We want the start of data for this level, not end.
\r
233 while (i != mipLevel)
\r
235 if (mipSize.Width > 1)
\r
236 mipSize.Width >>= 1;
\r
238 if (mipSize.Height > 1)
\r
239 mipSize.Height >>= 1;
\r
241 dataSize += getDataSizeFromFormat(Format, mipSize.Width, mipSize.Height);
\r
244 if ( mipSize.Width == 1 && mipSize.Height == 1 && i < mipLevel)
\r
248 return MipMapsData + dataSize;
\r
254 //! Set mipmaps data.
\r
255 /** This method allows you to put custom mipmaps data for
\r
257 \param data A byte array with pixel color information
\r
258 \param ownForeignMemory If true, the image will use the data
\r
259 pointer directly and own it afterward. If false, the memory
\r
260 will by copied internally.
\r
261 \param deleteMemory Whether the memory is deallocated upon
\r
263 void setMipMapsData(void* data, bool ownForeignMemory, bool deleteMemory)
\r
265 if (data != MipMapsData)
\r
267 if (DeleteMipMapsMemory)
\r
269 Allocator.deallocate(MipMapsData);
\r
271 DeleteMipMapsMemory = false;
\r
276 if (ownForeignMemory)
\r
278 MipMapsData = static_cast<u8*>(data);
\r
280 DeleteMipMapsMemory = deleteMemory;
\r
285 u32 width = Size.Width;
\r
286 u32 height = Size.Height;
\r
296 dataSize += getDataSizeFromFormat(Format, width, height);
\r
297 } while (width != 1 || height != 1);
\r
299 MipMapsData = Allocator.allocate(dataSize);
\r
300 memcpy(MipMapsData, data, dataSize);
\r
302 DeleteMipMapsMemory = true;
\r
312 //! Returns a pixel
\r
313 virtual SColor getPixel(u32 x, u32 y) const = 0;
\r
316 virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) = 0;
\r
318 //! Copies the image into the target, scaling the image to fit
\r
319 /** NOTE: mipmaps are ignored */
\r
320 virtual void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) =0;
\r
322 //! Copies the image into the target, scaling the image to fit
\r
323 /** NOTE: mipmaps are ignored */
\r
324 virtual void copyToScaling(IImage* target) =0;
\r
326 //! copies this surface into another
\r
327 /** NOTE: mipmaps are ignored */
\r
328 virtual void copyTo(IImage* target, const core::position2d<s32>& pos=core::position2d<s32>(0,0)) =0;
\r
330 //! copies this surface into another
\r
331 /** NOTE: mipmaps are ignored */
\r
332 virtual void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) =0;
\r
334 //! copies this surface into another, using the alpha mask and cliprect and a color to add with
\r
335 /** NOTE: mipmaps are ignored
\r
336 \param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
\r
338 virtual void copyToWithAlpha(IImage* target, const core::position2d<s32>& pos,
\r
339 const core::rect<s32>& sourceRect, const SColor &color,
\r
340 const core::rect<s32>* clipRect = 0,
\r
341 bool combineAlpha=false) =0;
\r
343 //! copies this surface into another, scaling it to fit, applying a box filter
\r
344 /** NOTE: mipmaps are ignored */
\r
345 virtual void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false) = 0;
\r
347 //! fills the surface with given color
\r
348 virtual void fill(const SColor &color) =0;
\r
350 //! Inform whether the image is compressed
\r
351 _IRR_DEPRECATED_ bool isCompressed() const
\r
353 return IImage::isCompressedFormat(Format);
\r
356 //! Check whether the image has MipMaps
\r
357 /** \return True if image has MipMaps, else false. */
\r
358 _IRR_DEPRECATED_ bool hasMipMaps() const
\r
360 return (getMipMapsData() != 0);
\r
363 //! get the amount of Bits per Pixel of the given color format
\r
364 static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format)
\r
383 case ECF_PVRTC_RGB2:
\r
385 case ECF_PVRTC_ARGB2:
\r
386 case ECF_PVRTC2_ARGB2:
\r
388 case ECF_PVRTC_RGB4:
\r
390 case ECF_PVRTC_ARGB4:
\r
391 case ECF_PVRTC2_ARGB4:
\r
396 case ECF_ETC2_ARGB:
\r
416 case ECF_A16B16G16R16F:
\r
422 case ECF_A32B32G32R32F:
\r
429 //! calculate image data size in bytes for selected format, width and height.
\r
430 static u32 getDataSizeFromFormat(ECOLOR_FORMAT format, u32 width, u32 height)
\r
437 imageSize = ((width + 3) / 4) * ((height + 3) / 4) * 8;
\r
443 imageSize = ((width + 3) / 4) * ((height + 3) / 4) * 16;
\r
445 case ECF_PVRTC_RGB2:
\r
446 case ECF_PVRTC_ARGB2:
\r
447 imageSize = (core::max_<u32>(width, 16) * core::max_<u32>(height, 8) * 2 + 7) / 8;
\r
449 case ECF_PVRTC_RGB4:
\r
450 case ECF_PVRTC_ARGB4:
\r
451 imageSize = (core::max_<u32>(width, 8) * core::max_<u32>(height, 8) * 4 + 7) / 8;
\r
453 case ECF_PVRTC2_ARGB2:
\r
454 imageSize = core::ceil32(width / 8.0f) * core::ceil32(height / 4.0f) * 8;
\r
456 case ECF_PVRTC2_ARGB4:
\r
459 imageSize = core::ceil32(width / 4.0f) * core::ceil32(height / 4.0f) * 8;
\r
461 case ECF_ETC2_ARGB:
\r
462 imageSize = core::ceil32(width / 4.0f) * core::ceil32(height / 4.0f) * 16;
\r
464 default: // uncompressed formats
\r
465 imageSize = getBitsPerPixelFromFormat(format) / 8 * width;
\r
466 imageSize *= height;
\r
473 // Define to check for all compressed image formats cases in a switch
\r
474 #define IRR_CASE_IIMAGE_COMPRESSED_FORMAT\
\r
480 case ECF_PVRTC_RGB2:\
\r
481 case ECF_PVRTC_ARGB2:\
\r
482 case ECF_PVRTC2_ARGB2:\
\r
483 case ECF_PVRTC_RGB4:\
\r
484 case ECF_PVRTC_ARGB4:\
\r
485 case ECF_PVRTC2_ARGB4:\
\r
487 case ECF_ETC2_RGB:\
\r
488 case ECF_ETC2_ARGB:
\r
490 //! check if this is compressed color format
\r
491 static bool isCompressedFormat(const ECOLOR_FORMAT format)
\r
495 IRR_CASE_IIMAGE_COMPRESSED_FORMAT
\r
502 //! check if the color format is only viable for depth/stencil textures
\r
503 static bool isDepthFormat(const ECOLOR_FORMAT format)
\r
516 //! Check if the color format uses floating point values for pixels
\r
517 static bool isFloatingPointFormat(const ECOLOR_FORMAT format)
\r
519 if (isCompressedFormat(format))
\r
526 case ECF_A16B16G16R16F:
\r
529 case ECF_A32B32G32R32F:
\r
538 ECOLOR_FORMAT Format;
\r
539 core::dimension2d<u32> Size;
\r
548 bool DeleteMipMapsMemory;
\r
550 core::irrAllocator<u8> Allocator;
\r
553 } // end namespace video
\r
554 } // end namespace irr
\r