56 const unsigned long DDS_CAPS = 0x00000001;
57 const unsigned long DDS_HEIGHT = 0x00000002;
58 const unsigned long DDS_WIDTH = 0x00000004;
59 const unsigned long DDS_PITCH = 0x00000008;
60 const unsigned long DDS_BACKBUFFERCOUNT = 0x00000020;
61 const unsigned long DDS_ZBUFFERBITDEPTH = 0x00000040;
62 const unsigned long DDS_ALPHABITDEPTH = 0x00000080;
63 const unsigned long DDS_LPSURFACE = 0x00000800;
64 const unsigned long DDS_PIXELFORMAT = 0x00001000;
65 const unsigned long DDS_CKDESTOVERLAY = 0x00002000;
66 const unsigned long DDS_CKDESTBLT = 0x00004000;
67 const unsigned long DDS_CKSRCOVERLAY = 0x00008000;
68 const unsigned long DDS_CKSRCBLT = 0x00010000;
69 const unsigned long DDS_MIPMAPCOUNT = 0x00020000;
70 const unsigned long DDS_REFRESHRATE = 0x00040000;
71 const unsigned long DDS_LINEARSIZE = 0x00080000;
72 const unsigned long DDS_TEXTURESTAGE = 0x00100000;
73 const unsigned long DDS_FVF = 0x00200000;
74 const unsigned long DDS_SRCVBHANDLE = 0x00400000;
75 const unsigned long DDS_DEPTH = 0x00800000;
76 const unsigned long DDS_ALL = 0x007FF9EE;
77 const unsigned long DDS_REQUIRED_FLAGS = DDS_CAPS|DDS_PIXELFORMAT|DDS_WIDTH|DDS_HEIGHT;
80 const unsigned long DDPF_ALPHAPIXELS = 0x00000001;
81 const unsigned long DDPF_ALPHA = 0x00000002;
82 const unsigned long DDPF_FOURCC = 0x00000004;
83 const unsigned long DDPF_INDEXED4 = 0x00000008;
84 const unsigned long DDPF_INDEXEDTO8 = 0x00000010;
85 const unsigned long DDPF_INDEXED8 = 0x00000020;
86 const unsigned long DDPF_RGB = 0x00000040;
87 const unsigned long DDPF_RGBA = 0x00000041;
88 const unsigned long DDPF_COMPRESSED = 0x00000080;
89 const unsigned long DDPF_RGBTOYUV = 0x00000100;
90 const unsigned long DDPF_YUV = 0x00000200;
91 const unsigned long DDPF_ZBUFFER = 0x00000400;
92 const unsigned long DDPF_PALETTEINDEXED1 = 0x00000800;
93 const unsigned long DDPF_PALETTEINDEXED2 = 0x00001000;
94 const unsigned long DDPF_ZPIXELS = 0x00002000;
95 const unsigned long DDPF_STENCILBUFFER = 0x00004000;
96 const unsigned long DDPF_ALPHAPREMULT = 0x00008000;
97 const unsigned long DDPF_LUMINANCE = 0x00020000;
98 const unsigned long DDPF_BUMPLUMINANCE = 0x00040000;
99 const unsigned long DDPF_BUMPDUDV = 0x00080000;
102 const unsigned long DDSCAPS_COMPLEX = 0x00000008;
103 const unsigned long DDSCAPS_TEXTURE = 0x00001000;
104 const unsigned long DDSCAPS_MIPMAP = 0x00400000;
107 const unsigned long DDSCAPS2_VOLUME = 0x00200000;
108 const unsigned long DDSCAPS2_CUBEMAP = 0x00000200;
109 const unsigned long DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400;
110 const unsigned long DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800;
111 const unsigned long DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000;
112 const unsigned long DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000;
113 const unsigned long DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000;
114 const unsigned long DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000;
115 const unsigned long DDSCAPS2_CUBEMAP_FACES = DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_NEGATIVEX |
116 DDSCAPS2_CUBEMAP_POSITIVEY | DDSCAPS2_CUBEMAP_NEGATIVEY |
117 DDSCAPS2_CUBEMAP_POSITIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEZ ;
119 inline unsigned int makeFourCC(
unsigned int ch0,
unsigned int ch1,
unsigned int ch2,
unsigned int ch3)
121 return ch0 | (ch1 << 8) | ( ch2 << 16) | ( ch3 << 24 );
124 inline bool isFourCC(
const char* code,
unsigned int fcc)
126 return makeFourCC(code[0], code[1], code[2], code[3]) == fcc;
131 #define IS_BGRA8(pf) \ 132 ((pf.dwFlags & DDPF_RGB) && \ 133 (pf.dwFlags & DDPF_ALPHAPIXELS) && \ 134 (pf.dwRGBBitCount == 32)) 136 #define IS_BGRX8(pf) \ 137 ((pf.dwFlags & DDPF_RGB) && \ 138 !(pf.dwFlags & DDPF_ALPHAPIXELS) && \ 139 (pf.dwRGBBitCount == 32)) 141 #define IS_BGR8(pf) \ 142 ((pf.dwFlags & DDPF_RGB) && \ 143 !(pf.dwFlags & DDPF_ALPHAPIXELS) && \ 144 (pf.dwRGBBitCount == 24)) 146 #define IS_GRAY8(pf) \ 147 ((((pf.dwFlags & DDPF_LUMINANCE) || (pf.dwFlags & DDPF_ALPHA) ) && \ 148 (pf.dwRGBBitCount == 8) && !(pf.dwFlags & DDPF_ALPHAPIXELS) ) || \ 149 isFourCC("G8 ", pf.dwFourCC ) ) 151 #define IS_GRAY8_ALPHA8(pf) \ 152 (((pf.dwFlags & DDPF_LUMINANCE) && \ 153 (pf.dwRGBBitCount == 16) && (pf.dwFlags & DDPF_ALPHAPIXELS)) || \ 154 isFourCC("AG8 ", pf.dwFourCC ) ) 156 #define IS_PALETTE8(pf) isFourCC("P8 ", pf.dwFourCC) 158 #define IS_DXT1(pf) isFourCC("DXT1", pf.dwFourCC) 160 #define IS_DXT3(pf) isFourCC("DXT3", pf.dwFourCC) 162 #define IS_DXT5(pf) isFourCC("DXT5", pf.dwFourCC) 167 unsigned int dwFlags;
168 unsigned int dwHeight;
169 unsigned int dwWidth;
170 unsigned int dwPitchOrLinearSize;
171 unsigned int dwDepth;
172 unsigned int dwMipMapCount;
173 unsigned int dwReserved1[ 11 ];
179 unsigned int dwFlags;
180 unsigned int dwFourCC;
181 unsigned int dwRGBBitCount;
182 unsigned int dwRBitMask;
183 unsigned int dwGBitMask;
184 unsigned int dwBBitMask;
185 unsigned int dwAlphaBitMask;
191 unsigned int dwCaps1;
192 unsigned int dwCaps2;
193 unsigned int dwReserved[2];
196 unsigned int dwReserved2;
205 DDS_IMAGE_CUBEMAP = 4
251 file->
read(signature,4);
252 if (strncmp(signature,
"DDS ", 4) != 0)
259 DDSURFACEDESC2 header;
260 memset(&header, 0,
sizeof(header));
262 file->
read(&header,
sizeof(header));
264 if (header.dwSize != 124 || header.ddpfPixelFormat.dwSize != 32)
271 if ((header.dwFlags & DDS_REQUIRED_FLAGS) != DDS_REQUIRED_FLAGS )
274 if ((header.ddsCaps.dwCaps1 & DDSCAPS_TEXTURE) != DDSCAPS_TEXTURE)
277 int image_type = header.dwDepth ? DDS_IMAGE_3D : DDS_IMAGE_2D;
279 if (header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
281 bool allfaces = (header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_FACES) != DDSCAPS2_CUBEMAP_FACES;
290 image_type = DDS_IMAGE_CUBEMAP;
293 bool reverse_rgba_bgra =
false;
294 if (header.ddpfPixelFormat.dwRBitMask != 0xFF)
295 reverse_rgba_bgra =
true;
302 int mipmaps = (header.dwFlags & DDS_MIPMAPCOUNT) ? header.dwMipMapCount : 1;
303 int hasalpha = header.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS;
313 int rgb = header.ddpfPixelFormat.dwFlags & DDPF_RGB;
315 int bitcount = header.ddpfPixelFormat.dwRGBBitCount;
317 if (rgb && bitcount == 8)
320 header.ddpfPixelFormat.dwFlags &= ~DDPF_RGB;
321 header.ddpfPixelFormat.dwFlags |= DDPF_LUMINANCE;
325 if (image_type == DDS_IMAGE_CUBEMAP)
328 std::vector< ref<Image> > image;
329 for(
int i=0; i<mipmaps; ++i)
331 image.push_back(
new Image );
337 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
343 if (image_type == DDS_IMAGE_2D)
346 if (image_type == DDS_IMAGE_CUBEMAP)
349 if (image_type == DDS_IMAGE_3D)
353 for(
int face=0; face<max_face; ++face)
355 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
362 int offset = req_mem * face;
363 file->
read(image[i]->pixels() + offset, req_mem);
365 if(reverse_rgba_bgra)
368 if (
IS_BGRX8(header.ddpfPixelFormat))
374 if (
IS_BGR8(header.ddpfPixelFormat))
376 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
382 if (image_type == DDS_IMAGE_2D)
385 if (image_type == DDS_IMAGE_CUBEMAP)
388 if (image_type == DDS_IMAGE_3D)
392 for(
int face=0; face<max_face; ++face)
394 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
401 int offset = req_mem * face;
402 file->
read(image[i]->pixels() + offset, req_mem);
404 if(reverse_rgba_bgra)
410 if (
IS_GRAY8(header.ddpfPixelFormat))
412 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
418 if (image_type == DDS_IMAGE_2D)
421 if (image_type == DDS_IMAGE_CUBEMAP)
424 if (image_type == DDS_IMAGE_3D)
428 for(
int face=0; face<max_face; ++face)
430 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
437 int offset = req_mem*face;
438 file->
read(image[i]->pixels() + offset, req_mem);
445 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
451 if (image_type == DDS_IMAGE_2D)
454 if (image_type == DDS_IMAGE_CUBEMAP)
457 if (image_type == DDS_IMAGE_3D)
461 for(
int face=0; face<max_face; ++face)
463 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
470 int offset = req_mem*face;
471 file->
read(image[i]->pixels() + offset, req_mem);
481 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
487 if (image_type == DDS_IMAGE_2D)
490 if (image_type == DDS_IMAGE_CUBEMAP)
493 if (image_type == DDS_IMAGE_3D)
497 for(
int face=0; face<max_face; ++face)
501 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
507 int req_mem1 = w*h*d*1;
508 int req_mem4 = w*h*d*4;
509 int offset = req_mem4*face;
511 file->
read( image[i]->pixels() + offset, req_mem1 );
520 if (
IS_DXT1(header.ddpfPixelFormat) )
524 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
530 if (image_type == DDS_IMAGE_2D)
533 if (image_type == DDS_IMAGE_CUBEMAP)
536 if (image_type == DDS_IMAGE_3D)
540 for(
int face=0; face<max_face; ++face)
542 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
549 int offset = req_mem*face;
550 file->
read(image[i]->pixels() + offset, req_mem);
555 if (
IS_DXT3(header.ddpfPixelFormat) )
557 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
563 if (image_type == DDS_IMAGE_2D)
566 if (image_type == DDS_IMAGE_CUBEMAP)
569 if (image_type == DDS_IMAGE_3D)
573 for(
int face=0; face<max_face; ++face)
575 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
582 int offset = req_mem*face;
583 file->
read(image[i]->pixels() + offset, req_mem);
588 if (
IS_DXT5(header.ddpfPixelFormat) )
590 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
596 if (image_type == DDS_IMAGE_2D)
599 if (image_type == DDS_IMAGE_CUBEMAP)
602 if (image_type == DDS_IMAGE_3D)
606 for(
int face=0; face<max_face; ++face)
608 for(
int i=0, w = header.dwWidth, h = header.dwHeight, d = header.dwDepth; i<mipmaps; ++i, w/=2, h/=2, d/=2)
615 int offset = req_mem*face;
616 file->
read(image[i]->pixels() + offset, req_mem);
634 if (image_type == DDS_IMAGE_2D && !s3tc_compressed)
636 for (
int i=0; i<(int)image.size(); ++i)
637 internal_FlipVertically(image[i]);
640 if (image_type == DDS_IMAGE_3D)
647 if (image_type == DDS_IMAGE_CUBEMAP)
662 image.erase(image.begin());
663 img->setMipmaps(image);
674 file->
read(signature, 4);
675 if (strncmp(signature,
"DDS ", 4) != 0)
681 DDSURFACEDESC2 header;
682 memset(&header, 0,
sizeof(header));
690 header.dwPitchOrLinearSize = file->
readUInt32();
694 file->
read(header.dwReserved1, 11*
sizeof(
unsigned long));
695 header.ddpfPixelFormat.dwSize = file->
readUInt32();
696 header.ddpfPixelFormat.dwFlags = file->
readUInt32();
697 header.ddpfPixelFormat.dwFourCC = file->
readUInt32();
698 header.ddpfPixelFormat.dwRGBBitCount = file->
readUInt32();
699 header.ddpfPixelFormat.dwRBitMask = file->
readUInt32();
700 header.ddpfPixelFormat.dwGBitMask = file->
readUInt32();
701 header.ddpfPixelFormat.dwBBitMask = file->
readUInt32();
702 header.ddpfPixelFormat.dwAlphaBitMask = file->
readUInt32();
705 header.ddsCaps.dwReserved[0] = file->
readUInt32();
706 header.ddsCaps.dwReserved[1] = file->
readUInt32();
711 if (header.dwSize != 124 || header.ddpfPixelFormat.dwSize != 32)
716 if ((header.dwFlags & DDS_REQUIRED_FLAGS) != DDS_REQUIRED_FLAGS )
719 if ((header.ddsCaps.dwCaps1 & DDSCAPS_TEXTURE) != DDSCAPS_TEXTURE)
long long read(void *buffer, long long byte_count)
Reads byte_count bytes from a file. Returns the number of bytes actually read.
VLCORE_EXPORT FileSystem * defFileSystem()
Returns the default FileSystem used by VisualizationLibrary.
An abstract class representing a file.
void convert8ToRGBA(const TPalette3x256 &palette, void *buf, int w, int h, unsigned char alpha, int bytealign=1)
A simple String formatting class.
void setObjectName(const char *name)
The name of the object, by default set to the object's class name in debug builds.
static void warning(const String &message)
Use this function to provide information about situations that might lead to errors or loss of data...
void swapBytes32_BGRA_RGBA(void *buf, int bytecount)
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
virtual ref< VirtualFile > locateFile(const String &full_path, const String &alternate_path=String()) const
Looks for a VirtualFile on the disk and in the currently active FileSystem.
void fillRGBA32_Alpha(void *buf, int bytecount, unsigned char alpha)
int requiredMemory() const
Returns the number of bytes requested to store the image.
virtual void close()=0
Closes the file.
const String & path() const
Returns the path of the file.
Visualization Library main namespace.
void fillGray8Alpha8_Alpha(void *buf, int bytecount, unsigned char alpha)
VLCORE_EXPORT ref< Image > loadDDS(VirtualFile *file)
The type is implicitly defined by the EImageFormat value, for ex.
VL_COMPILE_TIME_CHECK(sizeof(i8) *8==8)
virtual bool open(EOpenMode mode)=0
Opens the file in the specified mode.
VLCORE_EXPORT bool isDDS(VirtualFile *file)
unsigned int readUInt32(bool little_endian_data=true)
Reads single entry.
Implements a generic 1d, 2d, 3d and cubemap image that can have mipmaps.
The ref<> class is used to reference-count an Object.
std::string toStdString() const
Returns a UTF8 encoded std::string.
#define IS_GRAY8_ALPHA8(pf)
void swapBytes24_BGR_RGB(void *buf, int bytecount)
unsigned char TPalette4x256[256 *4]