diff options
-rw-r--r-- | source/blender/imbuf/intern/dds/BlockDXT.cpp | 172 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/BlockDXT.h | 79 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/ColorBlock.cpp | 67 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/ColorBlock.h | 23 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/Common.h | 18 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/DirectDrawSurface.cpp | 586 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/DirectDrawSurface.h | 111 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/Image.cpp | 14 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/Image.h | 29 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/PixelFormat.h | 110 |
10 files changed, 773 insertions, 436 deletions
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp index 5290a677678..24a090d93f6 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.cpp +++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp @@ -64,7 +64,7 @@ BlockDXT1 ----------------------------------------------------------------------------*/ -unsigned int BlockDXT1::evaluatePalette(Color32 color_array[4]) const +uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const { // Does bit expansion before interpolation. color_array[0].b = (col0.b << 3) | (col0.b >> 2); @@ -179,9 +179,9 @@ void BlockDXT1::decodeBlock(ColorBlock * block) const evaluatePalette(color_array); // Write color block. - for( unsigned int j = 0; j < 4; j++ ) { - for( unsigned int i = 0; i < 4; i++ ) { - unsigned int idx = (row[j] >> (2 * i)) & 3; + for( uint j = 0; j < 4; j++ ) { + for( uint i = 0; i < 4; i++ ) { + uint idx = (row[j] >> (2 * i)) & 3; block->color(i, j) = color_array[idx]; } } @@ -190,7 +190,7 @@ void BlockDXT1::decodeBlock(ColorBlock * block) const void BlockDXT1::setIndices(int * idx) { indices = 0; - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { indices |= (idx[i] & 3) << (2 * i); } } @@ -199,16 +199,14 @@ void BlockDXT1::setIndices(int * idx) /// Flip DXT1 block vertically. inline void BlockDXT1::flip4() { - unsigned char tmp; - swap(row[0], row[3], tmp); - swap(row[1], row[2], tmp); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT1 block vertically. inline void BlockDXT1::flip2() { - unsigned char tmp; - swap(row[0], row[1], tmp); + swap(row[0], row[1]); } @@ -248,16 +246,14 @@ void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const /// Flip DXT3 alpha block vertically. void AlphaBlockDXT3::flip4() { - unsigned short tmp; - swap(row[0], row[3], tmp); - swap(row[1], row[2], tmp); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT3 alpha block vertically. void AlphaBlockDXT3::flip2() { - unsigned short tmp; - swap(row[0], row[1], tmp); + swap(row[0], row[1]); } /// Flip DXT3 block vertically. @@ -279,7 +275,7 @@ void BlockDXT3::flip2() BlockDXT5 ----------------------------------------------------------------------------*/ -void AlphaBlockDXT5::evaluatePalette(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const { if (alpha0 > alpha1) { evaluatePalette8(alpha); @@ -289,35 +285,35 @@ void AlphaBlockDXT5::evaluatePalette(unsigned char alpha[8]) const } } -void AlphaBlockDXT5::evaluatePalette8(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const { // 8-alpha block: derive the other six alphas. // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. alpha[0] = alpha0; alpha[1] = alpha1; - alpha[2] = (6 * alpha0 + 1 * alpha1) / 7; // bit code 010 - alpha[3] = (5 * alpha0 + 2 * alpha1) / 7; // bit code 011 - alpha[4] = (4 * alpha0 + 3 * alpha1) / 7; // bit code 100 - alpha[5] = (3 * alpha0 + 4 * alpha1) / 7; // bit code 101 - alpha[6] = (2 * alpha0 + 5 * alpha1) / 7; // bit code 110 - alpha[7] = (1 * alpha0 + 6 * alpha1) / 7; // bit code 111 + alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010 + alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011 + alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100 + alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101 + alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110 + alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111 } -void AlphaBlockDXT5::evaluatePalette6(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const { // 6-alpha block. // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. alpha[0] = alpha0; alpha[1] = alpha1; - alpha[2] = (4 * alpha0 + 1 * alpha1) / 5; // Bit code 010 - alpha[3] = (3 * alpha0 + 2 * alpha1) / 5; // Bit code 011 - alpha[4] = (2 * alpha0 + 3 * alpha1) / 5; // Bit code 100 - alpha[5] = (1 * alpha0 + 4 * alpha1) / 5; // Bit code 101 + alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010 + alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011 + alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100 + alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101 alpha[6] = 0x00; // Bit code 110 alpha[7] = 0xFF; // Bit code 111 } -void AlphaBlockDXT5::indices(unsigned char index_array[16]) const +void AlphaBlockDXT5::indices(uint8 index_array[16]) const { index_array[0x0] = bits0; index_array[0x1] = bits1; @@ -337,52 +333,52 @@ void AlphaBlockDXT5::indices(unsigned char index_array[16]) const index_array[0xF] = bitsF; } -unsigned int AlphaBlockDXT5::index(unsigned int index) const +uint AlphaBlockDXT5::index(uint index) const { int offset = (3 * index + 16); - return (this->u >> offset) & 0x7; + return uint((this->u >> offset) & 0x7); } -void AlphaBlockDXT5::setIndex(unsigned int index, unsigned int value) +void AlphaBlockDXT5::setIndex(uint index, uint value) { int offset = (3 * index + 16); - unsigned long long mask = ((unsigned long long)(0x7)) << offset; - this->u = (this->u & ~mask) | (((unsigned long long)(value)) << offset); + uint64 mask = uint64(0x7) << offset; + this->u = (this->u & ~mask) | (uint64(value) << offset); } void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; + uint8 alpha_array[8]; evaluatePalette(alpha_array); - unsigned char index_array[16]; + uint8 index_array[16]; indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { block->color(i).a = alpha_array[index_array[i]]; } } void AlphaBlockDXT5::flip4() { - unsigned long long * b = (unsigned long long *)this; + uint64 * b = (uint64 *)this; // @@ The masks might have to be byte swapped. - unsigned long long tmp = (*b & (unsigned long long)(0x000000000000FFFFLL)); - tmp |= (*b & (unsigned long long)(0x000000000FFF0000LL)) << 36; - tmp |= (*b & (unsigned long long)(0x000000FFF0000000LL)) << 12; - tmp |= (*b & (unsigned long long)(0x000FFF0000000000LL)) >> 12; - tmp |= (*b & (unsigned long long)(0xFFF0000000000000LL)) >> 36; + uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL)); + tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36; + tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12; + tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12; + tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36; *b = tmp; } void AlphaBlockDXT5::flip2() { - unsigned int * b = (unsigned int *)this; + uint * b = (uint *)this; // @@ The masks might have to be byte swapped. - unsigned int tmp = (*b & 0xFF000000); + uint tmp = (*b & 0xFF000000); tmp |= (*b & 0x00000FFF) << 12; tmp |= (*b & 0x00FFF000) >> 12; @@ -396,6 +392,7 @@ void BlockDXT5::decodeBlock(ColorBlock * block) const // Decode alpha. alpha.decodeBlock(block); + } /// Flip DXT5 block vertically. @@ -416,13 +413,13 @@ void BlockDXT5::flip2() /// Decode ATI1 block. void BlockATI1::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; + uint8 alpha_array[8]; alpha.evaluatePalette(alpha_array); - unsigned char index_array[16]; + uint8 index_array[16]; alpha.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.b = c.g = c.r = alpha_array[index_array[i]]; c.a = 255; @@ -445,13 +442,13 @@ void BlockATI1::flip2() /// Decode ATI2 block. void BlockATI2::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; - unsigned char index_array[16]; + uint8 alpha_array[8]; + uint8 index_array[16]; x.evaluatePalette(alpha_array); x.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.r = alpha_array[index_array[i]]; } @@ -459,7 +456,7 @@ void BlockATI2::decodeBlock(ColorBlock * block) const y.evaluatePalette(alpha_array); y.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.g = alpha_array[index_array[i]]; c.b = 0; @@ -481,6 +478,68 @@ void BlockATI2::flip2() y.flip2(); } + +void BlockCTX1::evaluatePalette(Color32 color_array[4]) const +{ + // Does bit expansion before interpolation. + color_array[0].b = 0x00; + color_array[0].g = col0[1]; + color_array[0].r = col0[0]; + color_array[0].a = 0xFF; + + color_array[1].r = 0x00; + color_array[1].g = col0[1]; + color_array[1].b = col1[0]; + color_array[1].a = 0xFF; + + color_array[2].r = 0x00; + color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; + color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; + color_array[2].a = 0xFF; + + color_array[3].r = 0x00; + color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; + color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; + color_array[3].a = 0xFF; +} + +void BlockCTX1::decodeBlock(ColorBlock * block) const +{ + // Decode color block. + Color32 color_array[4]; + evaluatePalette(color_array); + + // Write color block. + for( uint j = 0; j < 4; j++ ) { + for( uint i = 0; i < 4; i++ ) { + uint idx = (row[j] >> (2 * i)) & 3; + block->color(i, j) = color_array[idx]; + } + } +} + +void BlockCTX1::setIndices(int * idx) +{ + indices = 0; + for(uint i = 0; i < 16; i++) { + indices |= (idx[i] & 3) << (2 * i); + } +} + + +/// Flip CTX1 block vertically. +inline void BlockCTX1::flip4() +{ + swap(row[0], row[3]); + swap(row[1], row[2]); +} + +/// Flip half CTX1 block vertically. +inline void BlockCTX1::flip2() +{ + swap(row[0], row[1]); +} + void mem_read(Stream & mem, BlockDXT1 & block) { mem_read(mem, block.col0.u); @@ -521,3 +580,12 @@ void mem_read(Stream & mem, BlockATI2 & block) mem_read(mem, block.y); } +void mem_read(Stream & mem, BlockCTX1 & block) +{ + mem_read(mem, block.col0[0]); + mem_read(mem, block.col0[1]); + mem_read(mem, block.col1[0]); + mem_read(mem, block.col1[1]); + mem_read(mem, block.indices); +} + diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index 1f710360c3c..5c232201f0c 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -58,6 +58,7 @@ #ifndef _DDS_BLOCKDXT_H #define _DDS_BLOCKDXT_H +#include <Common.h> #include <Color.h> #include <ColorBlock.h> #include <Stream.h> @@ -68,14 +69,14 @@ struct BlockDXT1 Color16 col0; Color16 col1; union { - unsigned char row[4]; - unsigned int indices; + uint8 row[4]; + uint indices; }; bool isFourColorMode() const; - unsigned int evaluatePalette(Color32 color_array[4]) const; - unsigned int evaluatePaletteFast(Color32 color_array[4]) const; + uint evaluatePalette(Color32 color_array[4]) const; + uint evaluatePaletteFast(Color32 color_array[4]) const; void evaluatePalette3(Color32 color_array[4]) const; void evaluatePalette4(Color32 color_array[4]) const; @@ -90,7 +91,7 @@ struct BlockDXT1 /// Return true if the block uses four color mode, false otherwise. inline bool BlockDXT1::isFourColorMode() const { - return col0.u >= col1.u; // @@ > or >= ? + return col0.u > col1.u; } @@ -99,24 +100,24 @@ struct AlphaBlockDXT3 { union { struct { - unsigned int alpha0 : 4; - unsigned int alpha1 : 4; - unsigned int alpha2 : 4; - unsigned int alpha3 : 4; - unsigned int alpha4 : 4; - unsigned int alpha5 : 4; - unsigned int alpha6 : 4; - unsigned int alpha7 : 4; - unsigned int alpha8 : 4; - unsigned int alpha9 : 4; - unsigned int alphaA : 4; - unsigned int alphaB : 4; - unsigned int alphaC : 4; - unsigned int alphaD : 4; - unsigned int alphaE : 4; - unsigned int alphaF : 4; + uint alpha0 : 4; + uint alpha1 : 4; + uint alpha2 : 4; + uint alpha3 : 4; + uint alpha4 : 4; + uint alpha5 : 4; + uint alpha6 : 4; + uint alpha7 : 4; + uint alpha8 : 4; + uint alpha9 : 4; + uint alphaA : 4; + uint alphaB : 4; + uint alphaC : 4; + uint alphaD : 4; + uint alphaE : 4; + uint alphaF : 4; }; - unsigned short row[4]; + uint16 row[4]; }; void decodeBlock(ColorBlock * block) const; @@ -163,16 +164,16 @@ struct AlphaBlockDXT5 unsigned int bitsE : 3; // 45 - 61 unsigned int bitsF : 3; // 48 - 64 }; - unsigned long long u; + uint64 u; }; - void evaluatePalette(unsigned char alpha[8]) const; - void evaluatePalette8(unsigned char alpha[8]) const; - void evaluatePalette6(unsigned char alpha[8]) const; - void indices(unsigned char index_array[16]) const; + void evaluatePalette(uint8 alpha[8]) const; + void evaluatePalette8(uint8 alpha[8]) const; + void evaluatePalette6(uint8 alpha[8]) const; + void indices(uint8 index_array[16]) const; - unsigned int index(unsigned int index) const; - void setIndex(unsigned int index, unsigned int value); + uint index(uint index) const; + void setIndex(uint index, uint value); void decodeBlock(ColorBlock * block) const; @@ -216,6 +217,25 @@ struct BlockATI2 void flip2(); }; +/// CTX1 block. +struct BlockCTX1 +{ + uint8 col0[2]; + uint8 col1[2]; + union { + uint8 row[4]; + uint indices; + }; + + void evaluatePalette(Color32 color_array[4]) const; + void setIndices(int * idx); + + void decodeBlock(ColorBlock * block) const; + + void flip4(); + void flip2(); +}; + void mem_read(Stream & mem, BlockDXT1 & block); void mem_read(Stream & mem, AlphaBlockDXT3 & block); void mem_read(Stream & mem, BlockDXT3 & block); @@ -223,5 +243,6 @@ void mem_read(Stream & mem, AlphaBlockDXT5 & block); void mem_read(Stream & mem, BlockDXT5 & block); void mem_read(Stream & mem, BlockATI1 & block); void mem_read(Stream & mem, BlockATI2 & block); +void mem_read(Stream & mem, BlockCTX1 & block); #endif // _DDS_BLOCKDXT_H diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp index 63997f93c8c..0199d15ada7 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.cpp +++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp @@ -39,13 +39,13 @@ #include <Common.h> // Get approximate luminance. - inline static unsigned int colorLuminance(Color32 c) + inline static uint colorLuminance(Color32 c) { return c.r + c.g + c.b; } // Get the euclidean distance between the given colors. - inline static unsigned int colorDistance(Color32 c0, Color32 c1) + inline static uint colorDistance(Color32 c0, Color32 c1) { return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b); } @@ -59,22 +59,22 @@ ColorBlock::ColorBlock() /// Init the color block with the contents of the given block. ColorBlock::ColorBlock(const ColorBlock & block) { - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { color(i) = block.color(i); } } /// Initialize this color block. -ColorBlock::ColorBlock(const Image * img, unsigned int x, unsigned int y) +ColorBlock::ColorBlock(const Image * img, uint x, uint y) { init(img, x, y); } -void ColorBlock::init(const Image * img, unsigned int x, unsigned int y) +void ColorBlock::init(const Image * img, uint x, uint y) { - const unsigned int bw = min(img->width() - x, 4U); - const unsigned int bh = min(img->height() - y, 4U); + const uint bw = min(img->width() - x, 4U); + const uint bh = min(img->height() - y, 4U); static int remainder[] = { 0, 0, 0, 0, @@ -86,10 +86,10 @@ void ColorBlock::init(const Image * img, unsigned int x, unsigned int y) // Blocks that are smaller than 4x4 are handled by repeating the pixels. // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :( - for(unsigned int i = 0; i < 4; i++) { + for(uint i = 0; i < 4; i++) { //const int by = i % bh; const int by = remainder[(bh - 1) * 4 + i]; - for(unsigned int e = 0; e < 4; e++) { + for(uint e = 0; e < 4; e++) { //const int bx = e % bw; const int bx = remainder[(bw - 1) * 4 + e]; color(e, i) = img->pixel(x + bx, y + by); @@ -111,7 +111,7 @@ void ColorBlock::splatX() { for(int i = 0; i < 16; i++) { - unsigned char x = m_color[i].r; + uint8 x = m_color[i].r; m_color[i] = Color32(x, x, x, x); } } @@ -120,16 +120,16 @@ void ColorBlock::splatY() { for(int i = 0; i < 16; i++) { - unsigned char y = m_color[i].g; + uint8 y = m_color[i].g; m_color[i] = Color32(y, y, y, y); } } /// Count number of unique colors in this color block. -unsigned int ColorBlock::countUniqueColors() const +uint ColorBlock::countUniqueColors() const { - unsigned int count = 0; + uint count = 0; // @@ This does not have to be o(n^2) for(int i = 0; i < 16; i++) @@ -152,17 +152,27 @@ unsigned int ColorBlock::countUniqueColors() const /// Get average color of the block. Color32 ColorBlock::averageColor() const { - unsigned int r, g, b, a; + uint r, g, b, a; r = g = b = a = 0; - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { r += m_color[i].r; g += m_color[i].g; b += m_color[i].b; a += m_color[i].a; } - return Color32((unsigned char)(r / 16), (unsigned char)(g / 16), (unsigned char)(b / 16), (unsigned char)(a / 16)); + return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16)); +} + +/// Return true if the block is not fully opaque. +bool ColorBlock::hasAlpha() const +{ + for (uint i = 0; i < 16; i++) + { + if (m_color[i].a != 255) return true; + } + return false; } @@ -170,11 +180,11 @@ Color32 ColorBlock::averageColor() const void ColorBlock::diameterRange(Color32 * start, Color32 * end) const { Color32 c0, c1; - unsigned int best_dist = 0; + uint best_dist = 0; for(int i = 0; i < 16; i++) { for (int j = i+1; j < 16; j++) { - unsigned int dist = colorDistance(m_color[i], m_color[j]); + uint dist = colorDistance(m_color[i], m_color[j]); if( dist > best_dist ) { best_dist = dist; c0 = m_color[i]; @@ -191,13 +201,13 @@ void ColorBlock::diameterRange(Color32 * start, Color32 * end) const void ColorBlock::luminanceRange(Color32 * start, Color32 * end) const { Color32 minColor, maxColor; - unsigned int minLuminance, maxLuminance; + uint minLuminance, maxLuminance; maxLuminance = minLuminance = colorLuminance(m_color[0]); - for(unsigned int i = 1; i < 16; i++) + for(uint i = 1; i < 16; i++) { - unsigned int luminance = colorLuminance(m_color[i]); + uint luminance = colorLuminance(m_color[i]); if (luminance > maxLuminance) { maxLuminance = luminance; @@ -219,7 +229,7 @@ void ColorBlock::boundsRange(Color32 * start, Color32 * end) const Color32 minColor(255, 255, 255); Color32 maxColor(0, 0, 0); - for(unsigned int i = 0; i < 16; i++) + for(uint i = 0; i < 16; i++) { if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } @@ -253,7 +263,7 @@ void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const Color32 minColor(255, 255, 255, 255); Color32 maxColor(0, 0, 0, 0); - for(unsigned int i = 0; i < 16; i++) + for(uint i = 0; i < 16; i++) { if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } @@ -290,11 +300,11 @@ void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const void ColorBlock::sortColorsByAbsoluteValue() { // Dummy selection sort. - for( unsigned int a = 0; a < 16; a++ ) { - unsigned int max = a; + for( uint a = 0; a < 16; a++ ) { + uint max = a; Color16 cmax(m_color[a]); - for( unsigned int b = a+1; b < 16; b++ ) { + for( uint b = a+1; b < 16; b++ ) { Color16 cb(m_color[b]); if( cb.u > cmax.u ) { @@ -302,9 +312,6 @@ void ColorBlock::sortColorsByAbsoluteValue() cmax = cb; } } - Color32 tmp; - swap( m_color[a], m_color[max], tmp ); + swap( m_color[a], m_color[max] ); } } - - diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index eba372768ad..72049be5f3c 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -45,16 +45,17 @@ struct ColorBlock { ColorBlock(); ColorBlock(const ColorBlock & block); - ColorBlock(const Image * img, unsigned int x, unsigned int y); + ColorBlock(const Image * img, uint x, uint y); - void init(const Image * img, unsigned int x, unsigned int y); + void init(const Image * img, uint x, uint y); void swizzleDXT5n(); void splatX(); void splatY(); - unsigned int countUniqueColors() const; + uint countUniqueColors() const; Color32 averageColor() const; + bool hasAlpha() const; void diameterRange(Color32 * start, Color32 * end) const; void luminanceRange(Color32 * start, Color32 * end) const; @@ -69,11 +70,11 @@ struct ColorBlock // Accessors const Color32 * colors() const; - Color32 color(unsigned int i) const; - Color32 & color(unsigned int i); + Color32 color(uint i) const; + Color32 & color(uint i); - Color32 color(unsigned int x, unsigned int y) const; - Color32 & color(unsigned int x, unsigned int y); + Color32 color(uint x, uint y) const; + Color32 & color(uint x, uint y); private: @@ -89,25 +90,25 @@ inline const Color32 * ColorBlock::colors() const } /// Get block color. -inline Color32 ColorBlock::color(unsigned int i) const +inline Color32 ColorBlock::color(uint i) const { return m_color[i]; } /// Get block color. -inline Color32 & ColorBlock::color(unsigned int i) +inline Color32 & ColorBlock::color(uint i) { return m_color[i]; } /// Get block color. -inline Color32 ColorBlock::color(unsigned int x, unsigned int y) const +inline Color32 ColorBlock::color(uint x, uint y) const { return m_color[y * 4 + x]; } /// Get block color. -inline Color32 & ColorBlock::color(unsigned int x, unsigned int y) +inline Color32 & ColorBlock::color(uint x, uint y) { return m_color[y * 4 + x]; } diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h index 5aa8972e437..0c687e2ca9a 100644 --- a/source/blender/imbuf/intern/dds/Common.h +++ b/source/blender/imbuf/intern/dds/Common.h @@ -37,8 +37,20 @@ #ifndef clamp #define clamp(x,a,b) min(max((x), (a)), (b)) #endif -#ifndef swap -#define swap(a,b,tmp) tmp=a; a=b; b=tmp; -#endif + +template<typename T> +inline void +swap(T & a, T & b) +{ + T tmp = a; + a = b; + b = tmp; +} + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; +typedef unsigned int uint32; +typedef unsigned long long uint64; #endif diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index c28f8b5b72d..dafe58a40a7 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -55,9 +55,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include <Common.h> #include <DirectDrawSurface.h> #include <BlockDXT.h> +#include <PixelFormat.h> #include <stdio.h> // printf #include <math.h> // sqrt @@ -66,92 +66,220 @@ #if !defined(MAKEFOURCC) # define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((unsigned int)((unsigned char)(ch0)) | \ - ((unsigned int)((unsigned char)(ch1)) << 8) | \ - ((unsigned int)((unsigned char)(ch2)) << 16) | \ - ((unsigned int)((unsigned char)(ch3)) << 24 )) + ((uint)((unsigned char)(ch0)) | \ + ((uint)((unsigned char)(ch1)) << 8) | \ + ((uint)((unsigned char)(ch2)) << 16) | \ + ((uint)((unsigned char)(ch3)) << 24 )) #endif -static const unsigned int FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); -static const unsigned int FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); -static const unsigned int FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); -static const unsigned int FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); -static const unsigned int FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); -static const unsigned int FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); -static const unsigned int FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); -static const unsigned int FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); -static const unsigned int FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); - -// RGB formats. -static const unsigned int D3DFMT_R8G8B8 = 20; -static const unsigned int D3DFMT_A8R8G8B8 = 21; -static const unsigned int D3DFMT_X8R8G8B8 = 22; -static const unsigned int D3DFMT_R5G6B5 = 23; -static const unsigned int D3DFMT_X1R5G5B5 = 24; -static const unsigned int D3DFMT_A1R5G5B5 = 25; -static const unsigned int D3DFMT_A4R4G4B4 = 26; -static const unsigned int D3DFMT_R3G3B2 = 27; -static const unsigned int D3DFMT_A8 = 28; -static const unsigned int D3DFMT_A8R3G3B2 = 29; -static const unsigned int D3DFMT_X4R4G4B4 = 30; -static const unsigned int D3DFMT_A2B10G10R10 = 31; -static const unsigned int D3DFMT_A8B8G8R8 = 32; -static const unsigned int D3DFMT_X8B8G8R8 = 33; -static const unsigned int D3DFMT_G16R16 = 34; -static const unsigned int D3DFMT_A2R10G10B10 = 35; -static const unsigned int D3DFMT_A16B16G16R16 = 36; +static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); +static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); +static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); +static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); +static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); +static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); +static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); +static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); +static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); + +// 32 bit RGB formats. +static const uint D3DFMT_R8G8B8 = 20; +static const uint D3DFMT_A8R8G8B8 = 21; +static const uint D3DFMT_X8R8G8B8 = 22; +static const uint D3DFMT_R5G6B5 = 23; +static const uint D3DFMT_X1R5G5B5 = 24; +static const uint D3DFMT_A1R5G5B5 = 25; +static const uint D3DFMT_A4R4G4B4 = 26; +static const uint D3DFMT_R3G3B2 = 27; +static const uint D3DFMT_A8 = 28; +static const uint D3DFMT_A8R3G3B2 = 29; +static const uint D3DFMT_X4R4G4B4 = 30; +static const uint D3DFMT_A2B10G10R10 = 31; +static const uint D3DFMT_A8B8G8R8 = 32; +static const uint D3DFMT_X8B8G8R8 = 33; +static const uint D3DFMT_G16R16 = 34; +static const uint D3DFMT_A2R10G10B10 = 35; + +static const uint D3DFMT_A16B16G16R16 = 36; // Palette formats. -static const unsigned int D3DFMT_A8P8 = 40; -static const unsigned int D3DFMT_P8 = 41; +static const uint D3DFMT_A8P8 = 40; +static const uint D3DFMT_P8 = 41; // Luminance formats. -static const unsigned int D3DFMT_L8 = 50; -static const unsigned int D3DFMT_A8L8 = 51; -static const unsigned int D3DFMT_A4L4 = 52; +static const uint D3DFMT_L8 = 50; +static const uint D3DFMT_A8L8 = 51; +static const uint D3DFMT_A4L4 = 52; +static const uint D3DFMT_L16 = 81; // Floating point formats -static const unsigned int D3DFMT_R16F = 111; -static const unsigned int D3DFMT_G16R16F = 112; -static const unsigned int D3DFMT_A16B16G16R16F = 113; -static const unsigned int D3DFMT_R32F = 114; -static const unsigned int D3DFMT_G32R32F = 115; -static const unsigned int D3DFMT_A32B32G32R32F = 116; +static const uint D3DFMT_R16F = 111; +static const uint D3DFMT_G16R16F = 112; +static const uint D3DFMT_A16B16G16R16F = 113; +static const uint D3DFMT_R32F = 114; +static const uint D3DFMT_G32R32F = 115; +static const uint D3DFMT_A32B32G32R32F = 116; -static const unsigned int DDSD_CAPS = 0x00000001U; -static const unsigned int DDSD_PIXELFORMAT = 0x00001000U; -static const unsigned int DDSD_WIDTH = 0x00000004U; -static const unsigned int DDSD_HEIGHT = 0x00000002U; -static const unsigned int DDSD_PITCH = 0x00000008U; -static const unsigned int DDSD_MIPMAPCOUNT = 0x00020000U; -static const unsigned int DDSD_LINEARSIZE = 0x00080000U; -static const unsigned int DDSD_DEPTH = 0x00800000U; +static const uint DDSD_CAPS = 0x00000001U; +static const uint DDSD_PIXELFORMAT = 0x00001000U; +static const uint DDSD_WIDTH = 0x00000004U; +static const uint DDSD_HEIGHT = 0x00000002U; +static const uint DDSD_PITCH = 0x00000008U; +static const uint DDSD_MIPMAPCOUNT = 0x00020000U; +static const uint DDSD_LINEARSIZE = 0x00080000U; +static const uint DDSD_DEPTH = 0x00800000U; -static const unsigned int DDSCAPS_COMPLEX = 0x00000008U; -static const unsigned int DDSCAPS_TEXTURE = 0x00001000U; -static const unsigned int DDSCAPS_MIPMAP = 0x00400000U; -static const unsigned int DDSCAPS2_VOLUME = 0x00200000U; -static const unsigned int DDSCAPS2_CUBEMAP = 0x00000200U; - -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U; -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U; -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U; -static const unsigned int DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U; - -static const unsigned int DDPF_ALPHAPIXELS = 0x00000001U; -static const unsigned int DDPF_ALPHA = 0x00000002U; -static const unsigned int DDPF_FOURCC = 0x00000004U; -static const unsigned int DDPF_RGB = 0x00000040U; -static const unsigned int DDPF_PALETTEINDEXED1 = 0x00000800U; -static const unsigned int DDPF_PALETTEINDEXED2 = 0x00001000U; -static const unsigned int DDPF_PALETTEINDEXED4 = 0x00000008U; -static const unsigned int DDPF_PALETTEINDEXED8 = 0x00000020U; -static const unsigned int DDPF_LUMINANCE = 0x00020000U; -static const unsigned int DDPF_ALPHAPREMULT = 0x00008000U; -static const unsigned int DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. +static const uint DDSCAPS_COMPLEX = 0x00000008U; +static const uint DDSCAPS_TEXTURE = 0x00001000U; +static const uint DDSCAPS_MIPMAP = 0x00400000U; +static const uint DDSCAPS2_VOLUME = 0x00200000U; +static const uint DDSCAPS2_CUBEMAP = 0x00000200U; + +static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U; +static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U; +static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U; +static const uint DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U; + +static const uint DDPF_ALPHAPIXELS = 0x00000001U; +static const uint DDPF_ALPHA = 0x00000002U; +static const uint DDPF_FOURCC = 0x00000004U; +static const uint DDPF_RGB = 0x00000040U; +static const uint DDPF_PALETTEINDEXED1 = 0x00000800U; +static const uint DDPF_PALETTEINDEXED2 = 0x00001000U; +static const uint DDPF_PALETTEINDEXED4 = 0x00000008U; +static const uint DDPF_PALETTEINDEXED8 = 0x00000020U; +static const uint DDPF_LUMINANCE = 0x00020000U; +static const uint DDPF_ALPHAPREMULT = 0x00008000U; +static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. + + // DX10 formats. + enum DXGI_FORMAT + { + DXGI_FORMAT_UNKNOWN = 0, + + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + + DXGI_FORMAT_R11G11B10_FLOAT = 26, + + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + + DXGI_FORMAT_R1_UNORM = 66, + + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + }; + + enum D3D10_RESOURCE_DIMENSION + { + D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D10_RESOURCE_DIMENSION_BUFFER = 1, + D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4, + }; /*** implementation ***/ @@ -175,6 +303,15 @@ void mem_read(Stream & mem, DDSCaps & caps) mem_read(mem, caps.caps4); } +void mem_read(Stream & mem, DDSHeader10 & header) +{ + mem_read(mem, header.dxgiFormat); + mem_read(mem, header.resourceDimension); + mem_read(mem, header.miscFlag); + mem_read(mem, header.arraySize); + mem_read(mem, header.reserved); +} + void mem_read(Stream & mem, DDSHeader & header) { mem_read(mem, header.fourcc); @@ -185,12 +322,19 @@ void mem_read(Stream & mem, DDSHeader & header) mem_read(mem, header.pitch); mem_read(mem, header.depth); mem_read(mem, header.mipmapcount); - for (unsigned int i = 0; i < 11; i++) mem_read(mem, header.reserved[i]); + for (uint i = 0; i < 11; i++) mem_read(mem, header.reserved[i]); mem_read(mem, header.pf); mem_read(mem, header.caps); mem_read(mem, header.notused); + + if (header.hasDX10Header()) + { + mem_read(mem, header.header10); + } } + + DDSHeader::DDSHeader() { this->fourcc = FOURCC_DDS; @@ -201,11 +345,11 @@ DDSHeader::DDSHeader() this->pitch = 0; this->depth = 0; this->mipmapcount = 0; - for (unsigned int i = 0; i < 11; i++) this->reserved[i] = 0; + for (uint i = 0; i < 11; i++) this->reserved[i] = 0; // Store version information on the reserved header attributes. this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T'); - this->reserved[10] = (0 << 16) | (9 << 8) | (3); // major.minor.revision + this->reserved[10] = (0 << 16) | (9 << 8) | (5); // major.minor.revision this->pf.size = 32; this->pf.flags = 0; @@ -220,29 +364,35 @@ DDSHeader::DDSHeader() this->caps.caps3 = 0; this->caps.caps4 = 0; this->notused = 0; + + this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN; + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; + this->header10.miscFlag = 0; + this->header10.arraySize = 0; + this->header10.reserved = 0; } -void DDSHeader::setWidth(unsigned int w) +void DDSHeader::setWidth(uint w) { this->flags |= DDSD_WIDTH; this->width = w; } -void DDSHeader::setHeight(unsigned int h) +void DDSHeader::setHeight(uint h) { this->flags |= DDSD_HEIGHT; this->height = h; } -void DDSHeader::setDepth(unsigned int d) +void DDSHeader::setDepth(uint d) { this->flags |= DDSD_DEPTH; this->height = d; } -void DDSHeader::setMipmapCount(unsigned int count) +void DDSHeader::setMipmapCount(uint count) { - if (count == 0) + if (count == 0 || count == 1) { this->flags &= ~DDSD_MIPMAPCOUNT; this->mipmapcount = 0; @@ -265,35 +415,40 @@ void DDSHeader::setMipmapCount(unsigned int count) void DDSHeader::setTexture2D() { - // nothing to do here. + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; } void DDSHeader::setTexture3D() { this->caps.caps2 = DDSCAPS2_VOLUME; + + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; } void DDSHeader::setTextureCube() { this->caps.caps1 |= DDSCAPS_COMPLEX; this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES; + + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + this->header10.arraySize = 6; } -void DDSHeader::setLinearSize(unsigned int size) +void DDSHeader::setLinearSize(uint size) { this->flags &= ~DDSD_PITCH; this->flags |= DDSD_LINEARSIZE; this->pitch = size; } -void DDSHeader::setPitch(unsigned int pitch) +void DDSHeader::setPitch(uint pitch) { this->flags &= ~DDSD_LINEARSIZE; this->flags |= DDSD_PITCH; this->pitch = pitch; } -void DDSHeader::setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3) +void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3) { // set fourcc pixel format. this->pf.flags = DDPF_FOURCC; @@ -305,7 +460,7 @@ void DDSHeader::setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, this->pf.amask = 0; } -void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask) +void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { // Make sure the masks are correct. if ((rmask & gmask) || \ @@ -327,15 +482,25 @@ void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsign if (bitcount == 0) { // Compute bit count from the masks. - unsigned int total = rmask | gmask | bmask | amask; + uint total = rmask | gmask | bmask | amask; while(total != 0) { bitcount++; total >>= 1; } - // @@ Align to 8? } - this->pf.fourcc = 0; + if (!(bitcount > 0 && bitcount <= 32)) { + printf("DDS: bad bit count, pixel format not set\n"); + return; + } + + // Align to 8. + if (bitcount < 8) bitcount = 8; + else if (bitcount < 16) bitcount = 16; + else if (bitcount < 24) bitcount = 24; + else bitcount = 32; + + this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); this->pf.bitcount = bitcount; this->pf.rmask = rmask; this->pf.gmask = gmask; @@ -343,46 +508,24 @@ void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsign this->pf.amask = amask; } +void DDSHeader::setDX10Format(uint format) +{ + this->pf.flags = 0; + this->header10.dxgiFormat = format; +} + void DDSHeader::setNormalFlag(bool b) { if (b) this->pf.flags |= DDPF_NORMAL; else this->pf.flags &= ~DDPF_NORMAL; } -/* -void DDSHeader::swapBytes() -{ - this->fourcc = POSH_LittleU32(this->fourcc); - this->size = POSH_LittleU32(this->size); - this->flags = POSH_LittleU32(this->flags); - this->height = POSH_LittleU32(this->height); - this->width = POSH_LittleU32(this->width); - this->pitch = POSH_LittleU32(this->pitch); - this->depth = POSH_LittleU32(this->depth); - this->mipmapcount = POSH_LittleU32(this->mipmapcount); - - for(int i = 0; i < 11; i++) { - this->reserved[i] = POSH_LittleU32(this->reserved[i]); - } - - this->pf.size = POSH_LittleU32(this->pf.size); - this->pf.flags = POSH_LittleU32(this->pf.flags); - this->pf.fourcc = POSH_LittleU32(this->pf.fourcc); - this->pf.bitcount = POSH_LittleU32(this->pf.bitcount); - this->pf.rmask = POSH_LittleU32(this->pf.rmask); - this->pf.gmask = POSH_LittleU32(this->pf.gmask); - this->pf.bmask = POSH_LittleU32(this->pf.bmask); - this->pf.amask = POSH_LittleU32(this->pf.amask); - this->caps.caps1 = POSH_LittleU32(this->caps.caps1); - this->caps.caps2 = POSH_LittleU32(this->caps.caps2); - this->caps.caps3 = POSH_LittleU32(this->caps.caps3); - this->caps.caps4 = POSH_LittleU32(this->caps.caps4); - this->notused = POSH_LittleU32(this->notused); +bool DDSHeader::hasDX10Header() const +{ + return this->pf.flags == 0; } -*/ - -DirectDrawSurface::DirectDrawSurface(unsigned char *mem, unsigned int size) : stream(mem, size), header() +DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header() { mem_read(stream, header); } @@ -398,7 +541,7 @@ bool DirectDrawSurface::isValid() const return false; } - const unsigned int required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); + const uint required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); if( (header.flags & required) != required ) { return false; } @@ -436,19 +579,7 @@ bool DirectDrawSurface::isSupported() const } else if (header.pf.flags & DDPF_RGB) { - if (header.pf.bitcount == 24) - { - return true; - } - else if (header.pf.bitcount == 32) - { - return true; - } - else - { - // Unsupported pixel format. - return false; - } + // All RGB formats are supported now. } else { @@ -471,26 +602,26 @@ bool DirectDrawSurface::isSupported() const } -unsigned int DirectDrawSurface::mipmapCount() const +uint DirectDrawSurface::mipmapCount() const { if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount; else return 0; } -unsigned int DirectDrawSurface::width() const +uint DirectDrawSurface::width() const { if (header.flags & DDSD_WIDTH) return header.width; else return 1; } -unsigned int DirectDrawSurface::height() const +uint DirectDrawSurface::height() const { if (header.flags & DDSD_HEIGHT) return header.height; else return 1; } -unsigned int DirectDrawSurface::depth() const +uint DirectDrawSurface::depth() const { if (header.flags & DDSD_DEPTH) return header.depth; else return 1; @@ -527,18 +658,18 @@ bool DirectDrawSurface::isTextureCube() const return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0; } -void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipmap) +void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap) { stream.seek(offset(face, mipmap)); - unsigned int w = width(); - unsigned int h = height(); + uint w = width(); + uint h = height(); // Compute width and height. - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { - w = max(w/2, 1U); - h = max(h/2, 1U); + w = max(1U, w / 2); + h = max(1U, h / 2); } img->allocate(w, h); @@ -553,73 +684,30 @@ void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipm } } -/* helper function for readLinearImage */ -void maskShiftAndSize(unsigned int mask, unsigned int * shift, unsigned int * size) -{ - if (!mask) - { - *shift = 0; - *size = 0; - return; - } - - *shift = 0; - while((mask & 1) == 0) { - ++(*shift); - mask >>= 1; - } - - *size = 0; - while((mask & 1) == 1) { - ++(*size); - mask >>= 1; - } -} - -/* helper function for readLinearImage */ -unsigned int convert(unsigned int c, unsigned int inbits, unsigned int outbits) -{ - if (inbits == 0) { - return 0; - } - else if (inbits == outbits) - { - return c; - } - else if (inbits > outbits) - { - // truncate - return c >> (inbits - outbits); - } - else - { - // bitexpand - return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); - } -} - void DirectDrawSurface::readLinearImage(Image * img) { - const unsigned int w = img->width(); - const unsigned int h = img->height(); - - unsigned int rshift, rsize; - maskShiftAndSize(header.pf.rmask, &rshift, &rsize); - unsigned int gshift, gsize; - maskShiftAndSize(header.pf.gmask, &gshift, &gsize); + const uint w = img->width(); + const uint h = img->height(); + + uint rshift, rsize; + PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize); - unsigned int bshift, bsize; - maskShiftAndSize(header.pf.bmask, &bshift, &bsize); + uint gshift, gsize; + PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize); - unsigned int ashift, asize; - maskShiftAndSize(header.pf.amask, &ashift, &asize); + uint bshift, bsize; + PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize); + + uint ashift, asize; + PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize); + + uint byteCount = (header.pf.bitcount + 7) / 8; - unsigned int byteCount = (header.pf.bitcount + 7) / 8; if (byteCount > 4) { /* just in case... we could have segfaults later on if byteCount > 4 */ - printf("DDS: bitcount too large (file corrupt?)"); + printf("DDS: bitcount too large"); return; } @@ -629,18 +717,18 @@ void DirectDrawSurface::readLinearImage(Image * img) } // Read linear RGB images. - for (unsigned int y = 0; y < h; y++) + for (uint y = 0; y < h; y++) { - for (unsigned int x = 0; x < w; x++) + for (uint x = 0; x < w; x++) { - unsigned int c = 0; + uint c = 0; mem_read(stream, (unsigned char *)(&c), byteCount); Color32 pixel(0, 0, 0, 0xFF); - pixel.r = convert(c >> rshift, rsize, 8); - pixel.g = convert(c >> gshift, gsize, 8); - pixel.b = convert(c >> bshift, bsize, 8); - pixel.a = convert(c >> ashift, asize, 8); + pixel.r = PixelFormat::convert(c >> rshift, rsize, 8); + pixel.g = PixelFormat::convert(c >> gshift, gsize, 8); + pixel.b = PixelFormat::convert(c >> bshift, bsize, 8); + pixel.a = PixelFormat::convert(c >> ashift, asize, 8); img->pixel(x, y) = pixel; } @@ -649,15 +737,15 @@ void DirectDrawSurface::readLinearImage(Image * img) void DirectDrawSurface::readBlockImage(Image * img) { - const unsigned int w = img->width(); - const unsigned int h = img->height(); + const uint w = img->width(); + const uint h = img->height(); - const unsigned int bw = (w + 3) / 4; - const unsigned int bh = (h + 3) / 4; + const uint bw = (w + 3) / 4; + const uint bh = (h + 3) / 4; - for (unsigned int by = 0; by < bh; by++) + for (uint by = 0; by < bh; by++) { - for (unsigned int bx = 0; bx < bw; bx++) + for (uint bx = 0; bx < bw; bx++) { ColorBlock block; @@ -665,9 +753,9 @@ void DirectDrawSurface::readBlockImage(Image * img) readBlock(&block); // Write color block. - for (unsigned int y = 0; y < min(4U, h-4*by); y++) + for (uint y = 0; y < min(4U, h-4*by); y++) { - for (unsigned int x = 0; x < min(4U, w-4*bx); x++) + for (uint x = 0; x < min(4U, w-4*bx); x++) { img->pixel(4*bx+x, 4*by+y) = block.color(x, y); } @@ -676,12 +764,13 @@ void DirectDrawSurface::readBlockImage(Image * img) } } -static Color32 buildNormal(unsigned char x, unsigned char y) +static Color32 buildNormal(uint8 x, uint8 y) { - float nx = 2 * (x / 255) - 1; - float ny = 2 * (x / 255) - 1; - float nz = sqrt(1 - nx*nx - ny*ny); - unsigned char z = clamp(int(255 * (nz + 1) / 2), 0, 255); + float nx = 2 * (x / 255.0f) - 1; + float ny = 2 * (y / 255.0f) - 1; + float nz = 0.0f; + if (1 - nx*nx - ny*ny > 0) nz = sqrtf(1 - nx*nx - ny*ny); + uint8 z = clamp(int(255.0f * (nz + 1) / 2.0f), 0, 255); return Color32(x, y, z); } @@ -716,7 +805,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba) for (int i = 0; i < 16; i++) { Color32 & c = rgba->color(i); - unsigned int tmp = c.r; + uint tmp = c.r; c.r = c.a; c.a = tmp; } @@ -751,14 +840,14 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba) for (int i = 0; i < 16; i++) { Color32 & c = rgba->color(i); - c = buildNormal(c.g, c.a); + c = buildNormal(c.a, c.g); } } } } -unsigned int DirectDrawSurface::blockSize() const +uint DirectDrawSurface::blockSize() const { switch(header.pf.fourcc) { @@ -778,13 +867,13 @@ unsigned int DirectDrawSurface::blockSize() const return 0; } -unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const +uint DirectDrawSurface::mipmapSize(uint mipmap) const { - unsigned int w = width(); - unsigned int h = height(); - unsigned int d = depth(); + uint w = width(); + uint h = height(); + uint d = depth(); - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { w = max(1U, w / 2); h = max(1U, h / 2); @@ -801,10 +890,10 @@ unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const else if (header.pf.flags & DDPF_RGB) { // Align pixels to bytes. - unsigned int byteCount = (header.pf.bitcount + 7) / 8; + uint byteCount = (header.pf.bitcount + 7) / 8; // Align pitch to 4 bytes. - unsigned int pitch = 4 * ((w * byteCount + 3) / 4); + uint pitch = 4 * ((w * byteCount + 3) / 4); return pitch * h * d; } @@ -814,12 +903,12 @@ unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const }; } -unsigned int DirectDrawSurface::faceSize() const +uint DirectDrawSurface::faceSize() const { - const unsigned int count = mipmapCount(); - unsigned int size = 0; + const uint count = mipmapCount(); + uint size = 0; - for (unsigned int m = 0; m < count; m++) + for (uint m = 0; m < count; m++) { size += mipmapSize(m); } @@ -827,16 +916,16 @@ unsigned int DirectDrawSurface::faceSize() const return size; } -unsigned int DirectDrawSurface::offset(const unsigned int face, const unsigned int mipmap) +uint DirectDrawSurface::offset(const uint face, const uint mipmap) { - unsigned int size = sizeof(DDSHeader); + uint size = 128; //sizeof(DDSHeader); if (face != 0) { size += face * faceSize(); } - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { size += mipmapSize(m); } @@ -911,6 +1000,15 @@ void DirectDrawSurface::printInfo() const printf("\tCaps 3: 0x%.8X\n", header.caps.caps3); printf("\tCaps 4: 0x%.8X\n", header.caps.caps4); + if (header.pf.flags == 0) + { + printf("DX10 Header:\n"); + printf("\tDXGI Format: %u\n", header.header10.dxgiFormat); + printf("\tResource dimension: %u\n", header.header10.resourceDimension); + printf("\tMisc flag: %u\n", header.header10.miscFlag); + printf("\tArray size: %u\n", header.header10.arraySize); + } + if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T')) { int major = (header.reserved[10] >> 16) & 0xFF; diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 2b3319d05a1..d29d82f53f9 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -58,92 +58,110 @@ #ifndef _DDS_DIRECTDRAWSURFACE_H #define _DDS_DIRECTDRAWSURFACE_H +#include <Common.h> #include <Stream.h> #include <ColorBlock.h> #include <Image.h> -struct DDSPixelFormat { - unsigned int size; - unsigned int flags; - unsigned int fourcc; - unsigned int bitcount; - unsigned int rmask; - unsigned int gmask; - unsigned int bmask; - unsigned int amask; +struct DDSPixelFormat +{ + uint size; + uint flags; + uint fourcc; + uint bitcount; + uint rmask; + uint gmask; + uint bmask; + uint amask; }; -struct DDSCaps { - unsigned int caps1; - unsigned int caps2; - unsigned int caps3; - unsigned int caps4; +struct DDSCaps +{ + uint caps1; + uint caps2; + uint caps3; + uint caps4; +}; + +/// DDS file header for DX10. +struct DDSHeader10 +{ + uint dxgiFormat; + uint resourceDimension; + uint miscFlag; + uint arraySize; + uint reserved; }; /// DDS file header. -struct DDSHeader { - unsigned int fourcc; - unsigned int size; - unsigned int flags; - unsigned int height; - unsigned int width; - unsigned int pitch; - unsigned int depth; - unsigned int mipmapcount; - unsigned int reserved[11]; +struct DDSHeader +{ + uint fourcc; + uint size; + uint flags; + uint height; + uint width; + uint pitch; + uint depth; + uint mipmapcount; + uint reserved[11]; DDSPixelFormat pf; DDSCaps caps; - unsigned int notused; - + uint notused; + DDSHeader10 header10; + + // Helper methods. DDSHeader(); - void setWidth(unsigned int w); - void setHeight(unsigned int h); - void setDepth(unsigned int d); - void setMipmapCount(unsigned int count); + void setWidth(uint w); + void setHeight(uint h); + void setDepth(uint d); + void setMipmapCount(uint count); void setTexture2D(); void setTexture3D(); void setTextureCube(); - void setLinearSize(unsigned int size); - void setPitch(unsigned int pitch); - void setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3); - void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); + void setLinearSize(uint size); + void setPitch(uint pitch); + void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); + void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); + void setDX10Format(uint format); void setNormalFlag(bool b); - /* void swapBytes(); */ + bool hasDX10Header() const; }; /// DirectDraw Surface. (DDS) class DirectDrawSurface { public: - DirectDrawSurface(unsigned char *mem, unsigned int size); + DirectDrawSurface(unsigned char *mem, uint size); ~DirectDrawSurface(); bool isValid() const; bool isSupported() const; - unsigned int mipmapCount() const; - unsigned int width() const; - unsigned int height() const; - unsigned int depth() const; + uint mipmapCount() const; + uint width() const; + uint height() const; + uint depth() const; bool isTexture2D() const; bool isTexture3D() const; bool isTextureCube() const; - bool hasAlpha() const; /* false for DXT1, true for all others */ + bool hasAlpha() const; /* false for DXT1, true for all other DXTs */ - void mipmap(Image * img, unsigned int f, unsigned int m); + void mipmap(Image * img, uint f, uint m); + // void mipmap(FloatImage * img, uint f, uint m); void printInfo() const; private: - unsigned int blockSize() const; - unsigned int faceSize() const; - unsigned int mipmapSize(unsigned int m) const; + uint blockSize() const; + uint faceSize() const; + uint mipmapSize(uint m) const; - unsigned int offset(unsigned int f, unsigned int m); + uint offset(uint f, uint m); void readLinearImage(Image * img); void readBlockImage(Image * img); @@ -158,5 +176,6 @@ private: void mem_read(Stream & mem, DDSPixelFormat & pf); void mem_read(Stream & mem, DDSCaps & caps); void mem_read(Stream & mem, DDSHeader & header); +void mem_read(Stream & mem, DDSHeader10 & header); #endif // _DDS_DIRECTDRAWSURFACE_H diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp index f3e6fa38955..d8be7857c3f 100644 --- a/source/blender/imbuf/intern/dds/Image.cpp +++ b/source/blender/imbuf/intern/dds/Image.cpp @@ -48,7 +48,7 @@ Image::~Image() free(); } -void Image::allocate(unsigned int w, unsigned int h) +void Image::allocate(uint w, uint h) { free(); m_width = w; @@ -63,17 +63,17 @@ void Image::free() } -unsigned int Image::width() const +uint Image::width() const { return m_width; } -unsigned int Image::height() const +uint Image::height() const { return m_height; } -const Color32 * Image::scanline(unsigned int h) const +const Color32 * Image::scanline(uint h) const { if (h >= m_height) { printf("DDS: scanline beyond dimensions of image"); @@ -82,7 +82,7 @@ const Color32 * Image::scanline(unsigned int h) const return m_data + h * m_width; } -Color32 * Image::scanline(unsigned int h) +Color32 * Image::scanline(uint h) { if (h >= m_height) { printf("DDS: scanline beyond dimensions of image"); @@ -101,7 +101,7 @@ Color32 * Image::pixels() return m_data; } -const Color32 & Image::pixel(unsigned int idx) const +const Color32 & Image::pixel(uint idx) const { if (idx >= m_width * m_height) { printf("DDS: pixel beyond dimensions of image"); @@ -110,7 +110,7 @@ const Color32 & Image::pixel(unsigned int idx) const return m_data[idx]; } -Color32 & Image::pixel(unsigned int idx) +Color32 & Image::pixel(uint idx) { if (idx >= m_width * m_height) { printf("DDS: pixel beyond dimensions of image"); diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 10356774777..0241839d01d 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -37,6 +37,7 @@ #ifndef _DDS_IMAGE_H #define _DDS_IMAGE_H +#include <Common.h> #include <Color.h> /// 32 bit RGBA image. @@ -53,28 +54,28 @@ public: Image(); ~Image(); - void allocate(unsigned int w, unsigned int h); + void allocate(uint w, uint h); /* bool load(const char * name); - void wrap(void * data, unsigned int w, unsigned int h); + void wrap(void * data, uint w, uint h); void unwrap(); */ - unsigned int width() const; - unsigned int height() const; + uint width() const; + uint height() const; - const Color32 * scanline(unsigned int h) const; - Color32 * scanline(unsigned int h); + const Color32 * scanline(uint h) const; + Color32 * scanline(uint h); const Color32 * pixels() const; Color32 * pixels(); - const Color32 & pixel(unsigned int idx) const; - Color32 & pixel(unsigned int idx); + const Color32 & pixel(uint idx) const; + Color32 & pixel(uint idx); - const Color32 & pixel(unsigned int x, unsigned int y) const; - Color32 & pixel(unsigned int x, unsigned int y); + const Color32 & pixel(uint x, uint y) const; + Color32 & pixel(uint x, uint y); Format format() const; void setFormat(Format f); @@ -83,19 +84,19 @@ private: void free(); private: - unsigned int m_width; - unsigned int m_height; + uint m_width; + uint m_height; Format m_format; Color32 * m_data; }; -inline const Color32 & Image::pixel(unsigned int x, unsigned int y) const +inline const Color32 & Image::pixel(uint x, uint y) const { return pixel(y * width() + x); } -inline Color32 & Image::pixel(unsigned int x, unsigned int y) +inline Color32 & Image::pixel(uint x, uint y) { return pixel(y * width() + x); } diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h new file mode 100644 index 00000000000..93f55f8266a --- /dev/null +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -0,0 +1,110 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributors: Amorilia (amorilia@gamebox.net) + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* + * This file is based on a similar file from the NVIDIA texture tools + * (http://nvidia-texture-tools.googlecode.com/) + * + * Original license from NVIDIA follows. + */ + +// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com> +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#ifndef _DDS_PIXELFORMAT_H +#define _DDS_PIXELFORMAT_H + +#include <Common.h> + + namespace PixelFormat + { + + // Convert component @a c having @a inbits to the returned value having @a outbits. + inline uint convert(uint c, uint inbits, uint outbits) + { + if (inbits == 0) + { + return 0; + } + else if (inbits >= outbits) + { + // truncate + return c >> (inbits - outbits); + } + else + { + // bitexpand + return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); + } + } + + // Get pixel component shift and size given its mask. + inline void maskShiftAndSize(uint mask, uint * shift, uint * size) + { + if (!mask) + { + *shift = 0; + *size = 0; + return; + } + + *shift = 0; + while((mask & 1) == 0) { + ++(*shift); + mask >>= 1; + } + + *size = 0; + while((mask & 1) == 1) { + ++(*size); + mask >>= 1; + } + } + + } // PixelFormat namespace + +#endif // _DDS_IMAGE_PIXELFORMAT_H |