From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- source/blender/imbuf/intern/dds/BlockDXT.cpp | 729 ++++--- source/blender/imbuf/intern/dds/BlockDXT.h | 339 +-- source/blender/imbuf/intern/dds/CMakeLists.txt | 52 +- source/blender/imbuf/intern/dds/Color.h | 116 +- source/blender/imbuf/intern/dds/ColorBlock.cpp | 592 +++--- source/blender/imbuf/intern/dds/ColorBlock.h | 59 +- source/blender/imbuf/intern/dds/Common.h | 27 +- .../blender/imbuf/intern/dds/DirectDrawSurface.cpp | 2186 ++++++++++---------- .../blender/imbuf/intern/dds/DirectDrawSurface.h | 229 +- source/blender/imbuf/intern/dds/FlipDXT.cpp | 346 ++-- source/blender/imbuf/intern/dds/FlipDXT.h | 3 +- source/blender/imbuf/intern/dds/Image.cpp | 78 +- source/blender/imbuf/intern/dds/Image.h | 77 +- source/blender/imbuf/intern/dds/PixelFormat.h | 142 +- source/blender/imbuf/intern/dds/Stream.cpp | 107 +- source/blender/imbuf/intern/dds/Stream.h | 29 +- source/blender/imbuf/intern/dds/dds_api.cpp | 258 +-- source/blender/imbuf/intern/dds/dds_api.h | 10 +- 18 files changed, 2696 insertions(+), 2683 deletions(-) (limited to 'source/blender/imbuf/intern/dds') diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp index aae769d9882..9211f6a7ba6 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.cpp +++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -55,607 +54,599 @@ #include /*---------------------------------------------------------------------------- - BlockDXT1 + BlockDXT1 ----------------------------------------------------------------------------*/ uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const { - // Does bit expansion before interpolation. - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; - - // @@ Same as above, but faster? -// Color32 c; -// c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); -// c.u |= (c.u >> 5) & 0x070007; -// c.u |= (c.u >> 6) & 0x000300; -// color_array[0].u = c.u; - - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; - - // @@ Same as above, but faster? -// c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000); -// c.u |= (c.u >> 5) & 0x070007; -// c.u |= (c.u >> 6) & 0x000300; -// color_array[1].u = c.u; - - if ( col0.u > col1.u ) { - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - 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 = (2 * color_array[1].r + color_array[0].r) / 3; - 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; - - return 4; - } - else { - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; - - return 3; - } + // Does bit expansion before interpolation. + color_array[0].b = (col0.b << 3) | (col0.b >> 2); + color_array[0].g = (col0.g << 2) | (col0.g >> 4); + color_array[0].r = (col0.r << 3) | (col0.r >> 2); + color_array[0].a = 0xFF; + + // @@ Same as above, but faster? + // Color32 c; + // c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); + // c.u |= (c.u >> 5) & 0x070007; + // c.u |= (c.u >> 6) & 0x000300; + // color_array[0].u = c.u; + + color_array[1].r = (col1.r << 3) | (col1.r >> 2); + color_array[1].g = (col1.g << 2) | (col1.g >> 4); + color_array[1].b = (col1.b << 3) | (col1.b >> 2); + color_array[1].a = 0xFF; + + // @@ Same as above, but faster? + // c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000); + // c.u |= (c.u >> 5) & 0x070007; + // c.u |= (c.u >> 6) & 0x000300; + // color_array[1].u = c.u; + + if (col0.u > col1.u) { + // Four-color block: derive the other two colors. + color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; + 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 = (2 * color_array[1].r + color_array[0].r) / 3; + 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; + + return 4; + } + else { + // Three-color block: derive the other color. + color_array[2].r = (color_array[0].r + color_array[1].r) / 2; + color_array[2].g = (color_array[0].g + color_array[1].g) / 2; + color_array[2].b = (color_array[0].b + color_array[1].b) / 2; + color_array[2].a = 0xFF; + + // Set all components to 0 to match DXT specs. + color_array[3].r = 0x00; // color_array[2].r; + color_array[3].g = 0x00; // color_array[2].g; + color_array[3].b = 0x00; // color_array[2].b; + color_array[3].a = 0x00; + + return 3; + } } - uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const { - // Does bit expansion before interpolation. - color_array[0].b = (3 * col0.b * 22) / 8; - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (3 * col0.r * 22) / 8; - color_array[0].a = 0xFF; - - color_array[1].r = (3 * col1.r * 22) / 8; - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (3 * col1.b * 22) / 8; - color_array[1].a = 0xFF; - - int gdiff = color_array[1].g - color_array[0].g; - - if ( col0.u > col1.u ) { - // Four-color block: derive the other two colors. - color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8; - color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256; - color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8; - color_array[2].a = 0xFF; - - color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8; - color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256; - color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8; - color_array[3].a = 0xFF; - - return 4; - } - else { - // Three-color block: derive the other color. - color_array[2].r = ((col0.r + col1.r) * 33) / 8; - color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256; - color_array[2].b = ((col0.b + col1.b) * 33) / 8; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; - - return 3; - } + // Does bit expansion before interpolation. + color_array[0].b = (3 * col0.b * 22) / 8; + color_array[0].g = (col0.g << 2) | (col0.g >> 4); + color_array[0].r = (3 * col0.r * 22) / 8; + color_array[0].a = 0xFF; + + color_array[1].r = (3 * col1.r * 22) / 8; + color_array[1].g = (col1.g << 2) | (col1.g >> 4); + color_array[1].b = (3 * col1.b * 22) / 8; + color_array[1].a = 0xFF; + + int gdiff = color_array[1].g - color_array[0].g; + + if (col0.u > col1.u) { + // Four-color block: derive the other two colors. + color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8; + color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256; + color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8; + color_array[2].a = 0xFF; + + color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8; + color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256; + color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8; + color_array[3].a = 0xFF; + + return 4; + } + else { + // Three-color block: derive the other color. + color_array[2].r = ((col0.r + col1.r) * 33) / 8; + color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256; + color_array[2].b = ((col0.b + col1.b) * 33) / 8; + color_array[2].a = 0xFF; + + // Set all components to 0 to match DXT specs. + color_array[3].r = 0x00; // color_array[2].r; + color_array[3].g = 0x00; // color_array[2].g; + color_array[3].b = 0x00; // color_array[2].b; + color_array[3].a = 0x00; + + return 3; + } } // Evaluate palette assuming 3 color block. void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const { - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; + color_array[0].b = (col0.b << 3) | (col0.b >> 2); + color_array[0].g = (col0.g << 2) | (col0.g >> 4); + color_array[0].r = (col0.r << 3) | (col0.r >> 2); + color_array[0].a = 0xFF; - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; + color_array[1].r = (col1.r << 3) | (col1.r >> 2); + color_array[1].g = (col1.g << 2) | (col1.g >> 4); + color_array[1].b = (col1.b << 3) | (col1.b >> 2); + color_array[1].a = 0xFF; - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; + // Three-color block: derive the other color. + color_array[2].r = (color_array[0].r + color_array[1].r) / 2; + color_array[2].g = (color_array[0].g + color_array[1].g) / 2; + color_array[2].b = (color_array[0].b + color_array[1].b) / 2; + color_array[2].a = 0xFF; - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; + // Set all components to 0 to match DXT specs. + color_array[3].r = 0x00; // color_array[2].r; + color_array[3].g = 0x00; // color_array[2].g; + color_array[3].b = 0x00; // color_array[2].b; + color_array[3].a = 0x00; } // Evaluate palette assuming 4 color block. void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const { - color_array[0].b = (col0.b << 3) | (col0.b >> 2); - color_array[0].g = (col0.g << 2) | (col0.g >> 4); - color_array[0].r = (col0.r << 3) | (col0.r >> 2); - color_array[0].a = 0xFF; + color_array[0].b = (col0.b << 3) | (col0.b >> 2); + color_array[0].g = (col0.g << 2) | (col0.g >> 4); + color_array[0].r = (col0.r << 3) | (col0.r >> 2); + color_array[0].a = 0xFF; - color_array[1].r = (col1.r << 3) | (col1.r >> 2); - color_array[1].g = (col1.g << 2) | (col1.g >> 4); - color_array[1].b = (col1.b << 3) | (col1.b >> 2); - color_array[1].a = 0xFF; + color_array[1].r = (col1.r << 3) | (col1.r >> 2); + color_array[1].g = (col1.g << 2) | (col1.g >> 4); + color_array[1].b = (col1.b << 3) | (col1.b >> 2); + color_array[1].a = 0xFF; - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - 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; + // Four-color block: derive the other two colors. + color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; + 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 = (2 * color_array[1].r + color_array[0].r) / 3; - 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; + color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3; + 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 BlockDXT1::decodeBlock(ColorBlock *block) const { - // Decode color block. - Color32 color_array[4]; - evaluatePalette(color_array); + // 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]; - } - } + // 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 BlockDXT1::decodeBlockNV5x(ColorBlock *block) const { - // Decode color block. - Color32 color_array[4]; - evaluatePaletteNV5x(color_array); + // Decode color block. + Color32 color_array[4]; + evaluatePaletteNV5x(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]; - } - } + // 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 BlockDXT1::setIndices(int *idx) { - indices = 0; - for (uint i = 0; i < 16; i++) { - indices |= (idx[i] & 3) << (2 * i); - } + indices = 0; + for (uint i = 0; i < 16; i++) { + indices |= (idx[i] & 3) << (2 * i); + } } - /// Flip DXT1 block vertically. inline void BlockDXT1::flip4() { - swap(row[0], row[3]); - swap(row[1], row[2]); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT1 block vertically. inline void BlockDXT1::flip2() { - swap(row[0], row[1]); + swap(row[0], row[1]); } - /*---------------------------------------------------------------------------- - BlockDXT3 + BlockDXT3 ----------------------------------------------------------------------------*/ void BlockDXT3::decodeBlock(ColorBlock *block) const { - // Decode color. - color.decodeBlock(block); + // Decode color. + color.decodeBlock(block); - // Decode alpha. - alpha.decodeBlock(block); + // Decode alpha. + alpha.decodeBlock(block); } void BlockDXT3::decodeBlockNV5x(ColorBlock *block) const { - color.decodeBlockNV5x(block); - alpha.decodeBlock(block); + color.decodeBlockNV5x(block); + alpha.decodeBlock(block); } void AlphaBlockDXT3::decodeBlock(ColorBlock *block) const { - block->color(0x0).a = (alpha0 << 4) | alpha0; - block->color(0x1).a = (alpha1 << 4) | alpha1; - block->color(0x2).a = (alpha2 << 4) | alpha2; - block->color(0x3).a = (alpha3 << 4) | alpha3; - block->color(0x4).a = (alpha4 << 4) | alpha4; - block->color(0x5).a = (alpha5 << 4) | alpha5; - block->color(0x6).a = (alpha6 << 4) | alpha6; - block->color(0x7).a = (alpha7 << 4) | alpha7; - block->color(0x8).a = (alpha8 << 4) | alpha8; - block->color(0x9).a = (alpha9 << 4) | alpha9; - block->color(0xA).a = (alphaA << 4) | alphaA; - block->color(0xB).a = (alphaB << 4) | alphaB; - block->color(0xC).a = (alphaC << 4) | alphaC; - block->color(0xD).a = (alphaD << 4) | alphaD; - block->color(0xE).a = (alphaE << 4) | alphaE; - block->color(0xF).a = (alphaF << 4) | alphaF; + block->color(0x0).a = (alpha0 << 4) | alpha0; + block->color(0x1).a = (alpha1 << 4) | alpha1; + block->color(0x2).a = (alpha2 << 4) | alpha2; + block->color(0x3).a = (alpha3 << 4) | alpha3; + block->color(0x4).a = (alpha4 << 4) | alpha4; + block->color(0x5).a = (alpha5 << 4) | alpha5; + block->color(0x6).a = (alpha6 << 4) | alpha6; + block->color(0x7).a = (alpha7 << 4) | alpha7; + block->color(0x8).a = (alpha8 << 4) | alpha8; + block->color(0x9).a = (alpha9 << 4) | alpha9; + block->color(0xA).a = (alphaA << 4) | alphaA; + block->color(0xB).a = (alphaB << 4) | alphaB; + block->color(0xC).a = (alphaC << 4) | alphaC; + block->color(0xD).a = (alphaD << 4) | alphaD; + block->color(0xE).a = (alphaE << 4) | alphaE; + block->color(0xF).a = (alphaF << 4) | alphaF; } /// Flip DXT3 alpha block vertically. void AlphaBlockDXT3::flip4() { - swap(row[0], row[3]); - swap(row[1], row[2]); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT3 alpha block vertically. void AlphaBlockDXT3::flip2() { - swap(row[0], row[1]); + swap(row[0], row[1]); } /// Flip DXT3 block vertically. void BlockDXT3::flip4() { - alpha.flip4(); - color.flip4(); + alpha.flip4(); + color.flip4(); } /// Flip half DXT3 block vertically. void BlockDXT3::flip2() { - alpha.flip2(); - color.flip2(); + alpha.flip2(); + color.flip2(); } - /*---------------------------------------------------------------------------- - BlockDXT5 + BlockDXT5 ----------------------------------------------------------------------------*/ void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const { - if (alpha0() > alpha1()) { - evaluatePalette8(alpha); - } - else { - evaluatePalette6(alpha); - } + if (alpha0() > alpha1()) { + evaluatePalette8(alpha); + } + else { + evaluatePalette6(alpha); + } } 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 * 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 + // 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 * 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(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 * 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 + // 6-alpha block. + // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. + alpha[0] = alpha0(); + alpha[1] = alpha1(); + 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(uint8 index_array[16]) const { - index_array[0x0] = bits0(); - index_array[0x1] = bits1(); - index_array[0x2] = bits2(); - index_array[0x3] = bits3(); - index_array[0x4] = bits4(); - index_array[0x5] = bits5(); - index_array[0x6] = bits6(); - index_array[0x7] = bits7(); - index_array[0x8] = bits8(); - index_array[0x9] = bits9(); - index_array[0xA] = bitsA(); - index_array[0xB] = bitsB(); - index_array[0xC] = bitsC(); - index_array[0xD] = bitsD(); - index_array[0xE] = bitsE(); - index_array[0xF] = bitsF(); + index_array[0x0] = bits0(); + index_array[0x1] = bits1(); + index_array[0x2] = bits2(); + index_array[0x3] = bits3(); + index_array[0x4] = bits4(); + index_array[0x5] = bits5(); + index_array[0x6] = bits6(); + index_array[0x7] = bits7(); + index_array[0x8] = bits8(); + index_array[0x9] = bits9(); + index_array[0xA] = bitsA(); + index_array[0xB] = bitsB(); + index_array[0xC] = bitsC(); + index_array[0xD] = bitsD(); + index_array[0xE] = bitsE(); + index_array[0xF] = bitsF(); } uint AlphaBlockDXT5::index(uint index) const { - int offset = (3 * index + 16); - return uint((this->u >> offset) & 0x7); + int offset = (3 * index + 16); + return uint((this->u >> offset) & 0x7); } void AlphaBlockDXT5::setIndex(uint index, uint value) { - int offset = (3 * index + 16); - uint64 mask = uint64(0x7) << offset; - this->u = (this->u & ~mask) | (uint64(value) << offset); + int offset = (3 * index + 16); + uint64 mask = uint64(0x7) << offset; + this->u = (this->u & ~mask) | (uint64(value) << offset); } void AlphaBlockDXT5::decodeBlock(ColorBlock *block) const { - uint8 alpha_array[8]; - evaluatePalette(alpha_array); + uint8 alpha_array[8]; + evaluatePalette(alpha_array); - uint8 index_array[16]; - indices(index_array); + uint8 index_array[16]; + indices(index_array); - for (uint i = 0; i < 16; i++) { - block->color(i).a = alpha_array[index_array[i]]; - } + for (uint i = 0; i < 16; i++) { + block->color(i).a = alpha_array[index_array[i]]; + } } void AlphaBlockDXT5::flip4() { - uint64 *b = (uint64 *)this; + uint64 *b = (uint64 *)this; - // @@ The masks might have to be byte swapped. - 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; + // @@ The masks might have to be byte swapped. + 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; + *b = tmp; } void AlphaBlockDXT5::flip2() { - uint *b = (uint *)this; + uint *b = (uint *)this; - // @@ The masks might have to be byte swapped. - uint tmp = (*b & 0xFF000000); - tmp |= (*b & 0x00000FFF) << 12; - tmp |= (*b & 0x00FFF000) >> 12; + // @@ The masks might have to be byte swapped. + uint tmp = (*b & 0xFF000000); + tmp |= (*b & 0x00000FFF) << 12; + tmp |= (*b & 0x00FFF000) >> 12; - *b = tmp; + *b = tmp; } void BlockDXT5::decodeBlock(ColorBlock *block) const { - // Decode color. - color.decodeBlock(block); + // Decode color. + color.decodeBlock(block); - // Decode alpha. - alpha.decodeBlock(block); + // Decode alpha. + alpha.decodeBlock(block); } void BlockDXT5::decodeBlockNV5x(ColorBlock *block) const { - // Decode color. - color.decodeBlockNV5x(block); + // Decode color. + color.decodeBlockNV5x(block); - // Decode alpha. - alpha.decodeBlock(block); + // Decode alpha. + alpha.decodeBlock(block); } /// Flip DXT5 block vertically. void BlockDXT5::flip4() { - alpha.flip4(); - color.flip4(); + alpha.flip4(); + color.flip4(); } /// Flip half DXT5 block vertically. void BlockDXT5::flip2() { - alpha.flip2(); - color.flip2(); + alpha.flip2(); + color.flip2(); } - /// Decode ATI1 block. void BlockATI1::decodeBlock(ColorBlock *block) const { - uint8 alpha_array[8]; - alpha.evaluatePalette(alpha_array); + uint8 alpha_array[8]; + alpha.evaluatePalette(alpha_array); - uint8 index_array[16]; - alpha.indices(index_array); + uint8 index_array[16]; + alpha.indices(index_array); - 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; - } + 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; + } } /// Flip ATI1 block vertically. void BlockATI1::flip4() { - alpha.flip4(); + alpha.flip4(); } /// Flip half ATI1 block vertically. void BlockATI1::flip2() { - alpha.flip2(); + alpha.flip2(); } - /// Decode ATI2 block. void BlockATI2::decodeBlock(ColorBlock *block) const { - uint8 alpha_array[8]; - uint8 index_array[16]; + uint8 alpha_array[8]; + uint8 index_array[16]; - x.evaluatePalette(alpha_array); - x.indices(index_array); + x.evaluatePalette(alpha_array); + x.indices(index_array); - for (uint i = 0; i < 16; i++) { - Color32 & c = block->color(i); - c.r = alpha_array[index_array[i]]; - } + for (uint i = 0; i < 16; i++) { + Color32 &c = block->color(i); + c.r = alpha_array[index_array[i]]; + } - y.evaluatePalette(alpha_array); - y.indices(index_array); + y.evaluatePalette(alpha_array); + y.indices(index_array); - for (uint i = 0; i < 16; i++) { - Color32 & c = block->color(i); - c.g = alpha_array[index_array[i]]; - c.b = 0; - c.a = 255; - } + for (uint i = 0; i < 16; i++) { + Color32 &c = block->color(i); + c.g = alpha_array[index_array[i]]; + c.b = 0; + c.a = 255; + } } /// Flip ATI2 block vertically. void BlockATI2::flip4() { - x.flip4(); - y.flip4(); + x.flip4(); + y.flip4(); } /// Flip half ATI2 block vertically. void BlockATI2::flip2() { - x.flip2(); - y.flip2(); + x.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; + // 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[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[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; + 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); + // 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]; - } - } + // 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); - } + 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]); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half CTX1 block vertically. inline void BlockCTX1::flip2() { - swap(row[0], row[1]); + swap(row[0], row[1]); } -void mem_read(Stream & mem, BlockDXT1 & block) +void mem_read(Stream &mem, BlockDXT1 &block) { - mem_read(mem, block.col0.u); - mem_read(mem, block.col1.u); - mem_read(mem, block.indices); + mem_read(mem, block.col0.u); + mem_read(mem, block.col1.u); + mem_read(mem, block.indices); } -void mem_read(Stream & mem, AlphaBlockDXT3 & block) +void mem_read(Stream &mem, AlphaBlockDXT3 &block) { - for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]); + for (unsigned int i = 0; i < 4; i++) + mem_read(mem, block.row[i]); } -void mem_read(Stream & mem, BlockDXT3 & block) +void mem_read(Stream &mem, BlockDXT3 &block) { - mem_read(mem, block.alpha); - mem_read(mem, block.color); + mem_read(mem, block.alpha); + mem_read(mem, block.color); } -void mem_read(Stream & mem, AlphaBlockDXT5 & block) +void mem_read(Stream &mem, AlphaBlockDXT5 &block) { - mem_read(mem, block.u); + mem_read(mem, block.u); } -void mem_read(Stream & mem, BlockDXT5 & block) +void mem_read(Stream &mem, BlockDXT5 &block) { - mem_read(mem, block.alpha); - mem_read(mem, block.color); + mem_read(mem, block.alpha); + mem_read(mem, block.color); } -void mem_read(Stream & mem, BlockATI1 & block) +void mem_read(Stream &mem, BlockATI1 &block) { - mem_read(mem, block.alpha); + mem_read(mem, block.alpha); } -void mem_read(Stream & mem, BlockATI2 & block) +void mem_read(Stream &mem, BlockATI2 &block) { - mem_read(mem, block.x); - mem_read(mem, block.y); + mem_read(mem, block.x); + mem_read(mem, block.y); } -void mem_read(Stream & mem, BlockCTX1 & block) +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); + 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 82ec5b45d4e..c13fa42dcdc 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -59,202 +58,252 @@ /// DXT1 block. struct BlockDXT1 { - Color16 col0; - Color16 col1; - union { - uint8 row[4]; - uint indices; - }; + Color16 col0; + Color16 col1; + union { + uint8 row[4]; + uint indices; + }; - bool isFourColorMode() const; + bool isFourColorMode() const; - uint evaluatePalette(Color32 color_array[4]) const; - uint evaluatePaletteNV5x(Color32 color_array[4]) const; + uint evaluatePalette(Color32 color_array[4]) const; + uint evaluatePaletteNV5x(Color32 color_array[4]) const; - void evaluatePalette3(Color32 color_array[4]) const; - void evaluatePalette4(Color32 color_array[4]) const; + void evaluatePalette3(Color32 color_array[4]) const; + void evaluatePalette4(Color32 color_array[4]) const; - void decodeBlock(ColorBlock * block) const; - void decodeBlockNV5x(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; + void decodeBlockNV5x(ColorBlock *block) const; - void setIndices(int * idx); + void setIndices(int *idx); - void flip4(); - void flip2(); + void flip4(); + void flip2(); }; /// Return true if the block uses four color mode, false otherwise. inline bool BlockDXT1::isFourColorMode() const { - return col0.u > col1.u; + return col0.u > col1.u; } - /// DXT3 alpha block with explicit alpha. struct AlphaBlockDXT3 { - union { - struct { - 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; - }; - uint16 row[4]; - }; - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); + union { + struct { + 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; + }; + uint16 row[4]; + }; + + void decodeBlock(ColorBlock *block) const; + + void flip4(); + void flip2(); }; - /// DXT3 block. struct BlockDXT3 { - AlphaBlockDXT3 alpha; - BlockDXT1 color; + AlphaBlockDXT3 alpha; + BlockDXT1 color; - void decodeBlock(ColorBlock * block) const; - void decodeBlockNV5x(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; + void decodeBlockNV5x(ColorBlock *block) const; - void flip4(); - void flip2(); + void flip4(); + void flip2(); }; - /// DXT5 alpha block. struct AlphaBlockDXT5 { - // uint64 unions do not compile on all platforms + // uint64 unions do not compile on all platforms #if 0 - union { - struct { - uint64 alpha0 : 8; // 8 - uint64 alpha1 : 8; // 16 - uint64 bits0 : 3; // 3 - 19 - uint64 bits1 : 3; // 6 - 22 - uint64 bits2 : 3; // 9 - 25 - uint64 bits3 : 3; // 12 - 28 - uint64 bits4 : 3; // 15 - 31 - uint64 bits5 : 3; // 18 - 34 - uint64 bits6 : 3; // 21 - 37 - uint64 bits7 : 3; // 24 - 40 - uint64 bits8 : 3; // 27 - 43 - uint64 bits9 : 3; // 30 - 46 - uint64 bitsA : 3; // 33 - 49 - uint64 bitsB : 3; // 36 - 52 - uint64 bitsC : 3; // 39 - 55 - uint64 bitsD : 3; // 42 - 58 - uint64 bitsE : 3; // 45 - 61 - uint64 bitsF : 3; // 48 - 64 - }; - uint64 u; - }; + union { + struct { + uint64 alpha0 : 8; // 8 + uint64 alpha1 : 8; // 16 + uint64 bits0 : 3; // 3 - 19 + uint64 bits1 : 3; // 6 - 22 + uint64 bits2 : 3; // 9 - 25 + uint64 bits3 : 3; // 12 - 28 + uint64 bits4 : 3; // 15 - 31 + uint64 bits5 : 3; // 18 - 34 + uint64 bits6 : 3; // 21 - 37 + uint64 bits7 : 3; // 24 - 40 + uint64 bits8 : 3; // 27 - 43 + uint64 bits9 : 3; // 30 - 46 + uint64 bitsA : 3; // 33 - 49 + uint64 bitsB : 3; // 36 - 52 + uint64 bitsC : 3; // 39 - 55 + uint64 bitsD : 3; // 42 - 58 + uint64 bitsE : 3; // 45 - 61 + uint64 bitsF : 3; // 48 - 64 + }; + uint64 u; + }; #endif - uint64 u; - uint8 alpha0() const { return u & 0xffLL; } - uint8 alpha1() const { return (u >> 8) & 0xffLL; } - uint8 bits0() const { return (u >> 16) & 0x7LL; } - uint8 bits1() const { return (u >> 19) & 0x7LL; } - uint8 bits2() const { return (u >> 22) & 0x7LL; } - uint8 bits3() const { return (u >> 25) & 0x7LL; } - uint8 bits4() const { return (u >> 28) & 0x7LL; } - uint8 bits5() const { return (u >> 31) & 0x7LL; } - uint8 bits6() const { return (u >> 34) & 0x7LL; } - uint8 bits7() const { return (u >> 37) & 0x7LL; } - uint8 bits8() const { return (u >> 40) & 0x7LL; } - uint8 bits9() const { return (u >> 43) & 0x7LL; } - uint8 bitsA() const { return (u >> 46) & 0x7LL; } - uint8 bitsB() const { return (u >> 49) & 0x7LL; } - uint8 bitsC() const { return (u >> 52) & 0x7LL; } - uint8 bitsD() const { return (u >> 55) & 0x7LL; } - uint8 bitsE() const { return (u >> 58) & 0x7LL; } - uint8 bitsF() const { return (u >> 61) & 0x7LL; } - - 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; - - uint index(uint index) const; - void setIndex(uint index, uint value); - - void decodeBlock(ColorBlock * block) const; - - void flip4(); - void flip2(); + uint64 u; + uint8 alpha0() const + { + return u & 0xffLL; + } + uint8 alpha1() const + { + return (u >> 8) & 0xffLL; + } + uint8 bits0() const + { + return (u >> 16) & 0x7LL; + } + uint8 bits1() const + { + return (u >> 19) & 0x7LL; + } + uint8 bits2() const + { + return (u >> 22) & 0x7LL; + } + uint8 bits3() const + { + return (u >> 25) & 0x7LL; + } + uint8 bits4() const + { + return (u >> 28) & 0x7LL; + } + uint8 bits5() const + { + return (u >> 31) & 0x7LL; + } + uint8 bits6() const + { + return (u >> 34) & 0x7LL; + } + uint8 bits7() const + { + return (u >> 37) & 0x7LL; + } + uint8 bits8() const + { + return (u >> 40) & 0x7LL; + } + uint8 bits9() const + { + return (u >> 43) & 0x7LL; + } + uint8 bitsA() const + { + return (u >> 46) & 0x7LL; + } + uint8 bitsB() const + { + return (u >> 49) & 0x7LL; + } + uint8 bitsC() const + { + return (u >> 52) & 0x7LL; + } + uint8 bitsD() const + { + return (u >> 55) & 0x7LL; + } + uint8 bitsE() const + { + return (u >> 58) & 0x7LL; + } + uint8 bitsF() const + { + return (u >> 61) & 0x7LL; + } + + 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; + + uint index(uint index) const; + void setIndex(uint index, uint value); + + void decodeBlock(ColorBlock *block) const; + + void flip4(); + void flip2(); }; - /// DXT5 block. struct BlockDXT5 { - AlphaBlockDXT5 alpha; - BlockDXT1 color; + AlphaBlockDXT5 alpha; + BlockDXT1 color; - void decodeBlock(ColorBlock * block) const; - void decodeBlockNV5x(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; + void decodeBlockNV5x(ColorBlock *block) const; - void flip4(); - void flip2(); + void flip4(); + void flip2(); }; /// ATI1 block. struct BlockATI1 { - AlphaBlockDXT5 alpha; + AlphaBlockDXT5 alpha; - void decodeBlock(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; - void flip4(); - void flip2(); + void flip4(); + void flip2(); }; /// ATI2 block. struct BlockATI2 { - AlphaBlockDXT5 x; - AlphaBlockDXT5 y; + AlphaBlockDXT5 x; + AlphaBlockDXT5 y; - void decodeBlock(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; - void flip4(); - void flip2(); + void flip4(); + void flip2(); }; /// CTX1 block. struct BlockCTX1 { - uint8 col0[2]; - uint8 col1[2]; - union { - uint8 row[4]; - uint indices; - }; + uint8 col0[2]; + uint8 col1[2]; + union { + uint8 row[4]; + uint indices; + }; - void evaluatePalette(Color32 color_array[4]) const; - void setIndices(int * idx); + void evaluatePalette(Color32 color_array[4]) const; + void setIndices(int *idx); - void decodeBlock(ColorBlock * block) const; + void decodeBlock(ColorBlock *block) const; - void flip4(); - void flip2(); + 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); -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); +void mem_read(Stream &mem, BlockDXT1 &block); +void mem_read(Stream &mem, AlphaBlockDXT3 &block); +void mem_read(Stream &mem, BlockDXT3 &block); +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 /* __BLOCKDXT_H__ */ +#endif /* __BLOCKDXT_H__ */ diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt index c68608f4cff..2ec1ea9eb36 100644 --- a/source/blender/imbuf/intern/dds/CMakeLists.txt +++ b/source/blender/imbuf/intern/dds/CMakeLists.txt @@ -19,14 +19,14 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - . - .. - ../.. - ../../../blenkernel - ../../../blenlib - ../../../makesdna - ../../../../../intern/guardedalloc - ../../../../../intern/utfconv + . + .. + ../.. + ../../../blenkernel + ../../../blenlib + ../../../makesdna + ../../../../../intern/guardedalloc + ../../../../../intern/utfconv ) set(INC_SYS @@ -34,31 +34,31 @@ set(INC_SYS ) set(SRC - BlockDXT.h - Color.h - ColorBlock.h - Common.h - DirectDrawSurface.h - FlipDXT.h - Image.h - PixelFormat.h - Stream.h - dds_api.h + BlockDXT.h + Color.h + ColorBlock.h + Common.h + DirectDrawSurface.h + FlipDXT.h + Image.h + PixelFormat.h + Stream.h + dds_api.h - BlockDXT.cpp - ColorBlock.cpp - DirectDrawSurface.cpp - FlipDXT.cpp - Image.cpp - Stream.cpp - dds_api.cpp + BlockDXT.cpp + ColorBlock.cpp + DirectDrawSurface.cpp + FlipDXT.cpp + Image.cpp + Stream.cpp + dds_api.cpp ) set(LIB ) if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) + add_definitions(-DWITH_DDS) endif() blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h index da7b77c2854..16432ffa715 100644 --- a/source/blender/imbuf/intern/dds/Color.h +++ b/source/blender/imbuf/intern/dds/Color.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -32,62 +31,79 @@ #define __COLOR_H__ /// 32 bit color stored as BGRA. -class Color32 -{ -public: - Color32() { } - Color32(const Color32 & c) : u(c.u) { } - Color32(unsigned char R, unsigned char G, unsigned char B) { setRGBA(R, G, B, 0xFF); } - Color32(unsigned char R, unsigned char G, unsigned char B, unsigned char A) { setRGBA( R, G, B, A); } - //Color32(unsigned char c[4]) { setRGBA(c[0], c[1], c[2], c[3]); } - //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); } - //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); } - Color32(unsigned int U) : u(U) { } +class Color32 { + public: + Color32() + { + } + Color32(const Color32 &c) : u(c.u) + { + } + Color32(unsigned char R, unsigned char G, unsigned char B) + { + setRGBA(R, G, B, 0xFF); + } + Color32(unsigned char R, unsigned char G, unsigned char B, unsigned char A) + { + setRGBA(R, G, B, A); + } + //Color32(unsigned char c[4]) { setRGBA(c[0], c[1], c[2], c[3]); } + //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); } + //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); } + Color32(unsigned int U) : u(U) + { + } - void setRGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A) - { - r = R; - g = G; - b = B; - a = A; - } + void setRGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A) + { + r = R; + g = G; + b = B; + a = A; + } - void setBGRA(unsigned char B, unsigned char G, unsigned char R, unsigned char A = 0xFF) - { - r = R; - g = G; - b = B; - a = A; - } + void setBGRA(unsigned char B, unsigned char G, unsigned char R, unsigned char A = 0xFF) + { + r = R; + g = G; + b = B; + a = A; + } - operator unsigned int () const { - return u; - } + operator unsigned int() const + { + return u; + } - union { - struct { - unsigned char b, g, r, a; - }; - unsigned int u; - }; + union { + struct { + unsigned char b, g, r, a; + }; + unsigned int u; + }; }; /// 16 bit 565 BGR color. -class Color16 -{ -public: - Color16() { } - Color16(const Color16 & c) : u(c.u) { } - explicit Color16(unsigned short U) : u(U) { } +class Color16 { + public: + Color16() + { + } + Color16(const Color16 &c) : u(c.u) + { + } + explicit Color16(unsigned short U) : u(U) + { + } - union { - struct { - unsigned short b : 5; - unsigned short g : 6; - unsigned short r : 5; - }; - unsigned short u; - }; + union { + struct { + unsigned short b : 5; + unsigned short g : 6; + unsigned short r : 5; + }; + unsigned short u; + }; }; -#endif /* __COLOR_H__ */ +#endif /* __COLOR_H__ */ diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp index e0c1c168d50..73397cd036e 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.cpp +++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -33,20 +32,19 @@ #include #if 0 - // Get approximate luminance. - inline static uint colorLuminance(Color32 c) - { - return c.r + c.g + c.b; - } - - // Get the euclidean distance between the given colors. - 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); - } + // Get approximate luminance. + inline static uint colorLuminance(Color32 c) + { + return c.r + c.g + c.b; + } + + // Get the euclidean distance between the given colors. + 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); + } #endif - /// Default constructor. ColorBlock::ColorBlock() { @@ -55,138 +53,143 @@ ColorBlock::ColorBlock() /// Init the color block from an array of colors. ColorBlock::ColorBlock(const uint *linearImage) { - for (uint i = 0; i < 16; i++) { - color(i) = Color32(linearImage[i]); - } + for (uint i = 0; i < 16; i++) { + color(i) = Color32(linearImage[i]); + } } /// Init the color block with the contents of the given block. -ColorBlock::ColorBlock(const ColorBlock & block) +ColorBlock::ColorBlock(const ColorBlock &block) { - for (uint i = 0; i < 16; i++) { - color(i) = block.color(i); - } + for (uint i = 0; i < 16; i++) { + color(i) = block.color(i); + } } - /// Initialize this color block. ColorBlock::ColorBlock(const Image *img, uint x, uint y) { - init(img, x, y); + init(img, x, y); } void ColorBlock::init(const Image *img, uint x, uint y) { - init(img->width(), img->height(), (const uint *)img->pixels(), x, y); + init(img->width(), img->height(), (const uint *)img->pixels(), x, y); } void ColorBlock::init(uint w, uint h, const uint *data, uint x, uint y) { - const uint bw = MIN(w - x, 4U); - const uint bh = MIN(h - y, 4U); + const uint bw = MIN(w - x, 4U); + const uint bh = MIN(h - y, 4U); - // 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. :( - // @@ Ideally we should zero the weights of the pixels out of range. + // 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. :( + // @@ Ideally we should zero the weights of the pixels out of range. - for (uint i = 0; i < 4; i++) { - const int by = i % bh; + for (uint i = 0; i < 4; i++) { + const int by = i % bh; - for (uint e = 0; e < 4; e++) { - const int bx = e % bw; - const uint idx = (y + by) * w + x + bx; + for (uint e = 0; e < 4; e++) { + const int bx = e % bw; + const uint idx = (y + by) * w + x + bx; - color(e, i).u = data[idx]; - } - } + color(e, i).u = data[idx]; + } + } } void ColorBlock::init(uint w, uint h, const float *data, uint x, uint y) { - const uint bw = MIN(w - x, 4U); - const uint bh = MIN(h - y, 4U); - - // 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. :( - // @@ Ideally we should zero the weights of the pixels out of range. - - uint srcPlane = w * h; - - for (uint i = 0; i < 4; i++) { - const uint by = i % bh; - - for (uint e = 0; e < 4; e++) { - const uint bx = e % bw; - const uint idx = ((y + by) * w + x + bx); - - Color32 & c = color(e, i); - c.r = uint8(255 * CLAMP(data[idx + 0 * srcPlane], 0.0f, 1.0f)); // @@ Is this the right way to quantize floats to bytes? - c.g = uint8(255 * CLAMP(data[idx + 1 * srcPlane], 0.0f, 1.0f)); - c.b = uint8(255 * CLAMP(data[idx + 2 * srcPlane], 0.0f, 1.0f)); - c.a = uint8(255 * CLAMP(data[idx + 3 * srcPlane], 0.0f, 1.0f)); - } - } + const uint bw = MIN(w - x, 4U); + const uint bh = MIN(h - y, 4U); + + // 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. :( + // @@ Ideally we should zero the weights of the pixels out of range. + + uint srcPlane = w * h; + + for (uint i = 0; i < 4; i++) { + const uint by = i % bh; + + for (uint e = 0; e < 4; e++) { + const uint bx = e % bw; + const uint idx = ((y + by) * w + x + bx); + + Color32 &c = color(e, i); + c.r = uint8(255 * CLAMP(data[idx + 0 * srcPlane], + 0.0f, + 1.0f)); // @@ Is this the right way to quantize floats to bytes? + c.g = uint8(255 * CLAMP(data[idx + 1 * srcPlane], 0.0f, 1.0f)); + c.b = uint8(255 * CLAMP(data[idx + 2 * srcPlane], 0.0f, 1.0f)); + c.a = uint8(255 * CLAMP(data[idx + 3 * srcPlane], 0.0f, 1.0f)); + } + } } static inline uint8 component(Color32 c, uint i) { - if (i == 0) return c.r; - if (i == 1) return c.g; - if (i == 2) return c.b; - if (i == 3) return c.a; - if (i == 4) return 0xFF; - return 0; + if (i == 0) + return c.r; + if (i == 1) + return c.g; + if (i == 2) + return c.b; + if (i == 3) + return c.a; + if (i == 4) + return 0xFF; + return 0; } void ColorBlock::swizzle(uint x, uint y, uint z, uint w) { - for (int i = 0; i < 16; i++) { - Color32 c = m_color[i]; - m_color[i].r = component(c, x); - m_color[i].g = component(c, y); - m_color[i].b = component(c, z); - m_color[i].a = component(c, w); - } + for (int i = 0; i < 16; i++) { + Color32 c = m_color[i]; + m_color[i].r = component(c, x); + m_color[i].g = component(c, y); + m_color[i].b = component(c, z); + m_color[i].a = component(c, w); + } } - /// Returns true if the block has a single color. -bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const +bool ColorBlock::isSingleColor(Color32 mask /*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const { - uint u = m_color[0].u & mask.u; + uint u = m_color[0].u & mask.u; - for (int i = 1; i < 16; i++) { - if (u != (m_color[i].u & mask.u)) { - return false; - } - } + for (int i = 1; i < 16; i++) { + if (u != (m_color[i].u & mask.u)) { + return false; + } + } - return true; + return true; } #if 0 /// Returns true if the block has a single color, ignoring transparent pixels. bool ColorBlock::isSingleColorNoAlpha() const { - Color32 c; - int i; - for (i = 0; i < 16; i++) - { - if (m_color[i].a != 0) c = m_color[i]; - } - - Color32 mask(0xFF, 0xFF, 0xFF, 0x00); - uint u = c.u & mask.u; - - for (; i < 16; i++) - { - if (u != (m_color[i].u & mask.u)) - { - return false; - } - } - - return true; + Color32 c; + int i; + for (i = 0; i < 16; i++) + { + if (m_color[i].a != 0) c = m_color[i]; + } + + Color32 mask(0xFF, 0xFF, 0xFF, 0x00); + uint u = c.u & mask.u; + + for (; i < 16; i++) + { + if (u != (m_color[i].u & mask.u)) + { + return false; + } + } + + return true; } #endif @@ -194,24 +197,24 @@ bool ColorBlock::isSingleColorNoAlpha() const /// Count number of unique colors in this color block. uint ColorBlock::countUniqueColors() const { - uint count = 0; - - // @@ This does not have to be o(n^2) - for (int i = 0; i < 16; i++) - { - bool unique = true; - for (int j = 0; j < i; j++) { - if ( m_color[i] != m_color[j] ) { - unique = false; - } - } - - if ( unique ) { - count++; - } - } - - return count; + uint count = 0; + + // @@ This does not have to be o(n^2) + for (int i = 0; i < 16; i++) + { + bool unique = true; + for (int j = 0; j < i; j++) { + if ( m_color[i] != m_color[j] ) { + unique = false; + } + } + + if ( unique ) { + count++; + } + } + + return count; } #endif @@ -219,27 +222,28 @@ uint ColorBlock::countUniqueColors() const /// Get average color of the block. Color32 ColorBlock::averageColor() const { - uint r, g, b, a; - r = g = b = a = 0; + uint r, g, b, a; + r = g = b = a = 0; - 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; - } + 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(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16)); + return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16)); } #endif /// 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; + for (uint i = 0; i < 16; i++) { + if (m_color[i].a != 255) + return true; + } + return false; } #if 0 @@ -247,121 +251,121 @@ bool ColorBlock::hasAlpha() const /// Get diameter color range. void ColorBlock::diameterRange(Color32 *start, Color32 *end) const { - Color32 c0, c1; - uint best_dist = 0; - - for (int i = 0; i < 16; i++) { - for (int j = i+1; j < 16; j++) { - uint dist = colorDistance(m_color[i], m_color[j]); - if ( dist > best_dist ) { - best_dist = dist; - c0 = m_color[i]; - c1 = m_color[j]; - } - } - } - - *start = c0; - *end = c1; + Color32 c0, c1; + uint best_dist = 0; + + for (int i = 0; i < 16; i++) { + for (int j = i+1; j < 16; j++) { + uint dist = colorDistance(m_color[i], m_color[j]); + if ( dist > best_dist ) { + best_dist = dist; + c0 = m_color[i]; + c1 = m_color[j]; + } + } + } + + *start = c0; + *end = c1; } /// Get luminance color range. void ColorBlock::luminanceRange(Color32 *start, Color32 *end) const { - Color32 minColor, maxColor; - uint minLuminance, maxLuminance; - - maxLuminance = minLuminance = colorLuminance(m_color[0]); - - for (uint i = 1; i < 16; i++) - { - uint luminance = colorLuminance(m_color[i]); - - if (luminance > maxLuminance) { - maxLuminance = luminance; - maxColor = m_color[i]; - } - else if (luminance < minLuminance) { - minLuminance = luminance; - minColor = m_color[i]; - } - } - - *start = minColor; - *end = maxColor; + Color32 minColor, maxColor; + uint minLuminance, maxLuminance; + + maxLuminance = minLuminance = colorLuminance(m_color[0]); + + for (uint i = 1; i < 16; i++) + { + uint luminance = colorLuminance(m_color[i]); + + if (luminance > maxLuminance) { + maxLuminance = luminance; + maxColor = m_color[i]; + } + else if (luminance < minLuminance) { + minLuminance = luminance; + minColor = m_color[i]; + } + } + + *start = minColor; + *end = maxColor; } /// Get color range based on the bounding box. void ColorBlock::boundsRange(Color32 *start, Color32 *end) const { - Color32 minColor(255, 255, 255); - Color32 maxColor(0, 0, 0); - - 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; } - if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } - if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } - if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } - if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } - } - - // Offset range by 1/16 of the extents - Color32 inset; - inset.r = (maxColor.r - minColor.r) >> 4; - inset.g = (maxColor.g - minColor.g) >> 4; - inset.b = (maxColor.b - minColor.b) >> 4; - - minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; - minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; - minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; - - maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; - maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; - maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; - - *start = minColor; - *end = maxColor; + Color32 minColor(255, 255, 255); + Color32 maxColor(0, 0, 0); + + 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; } + if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } + if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } + if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } + if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } + } + + // Offset range by 1/16 of the extents + Color32 inset; + inset.r = (maxColor.r - minColor.r) >> 4; + inset.g = (maxColor.g - minColor.g) >> 4; + inset.b = (maxColor.b - minColor.b) >> 4; + + minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; + minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; + minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; + + maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; + maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; + maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; + + *start = minColor; + *end = maxColor; } /// Get color range based on the bounding box. void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const { - Color32 minColor(255, 255, 255, 255); - Color32 maxColor(0, 0, 0, 0); - - 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; } - if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } - if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; } - if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } - if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } - if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } - if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; } - } - - // Offset range by 1/16 of the extents - Color32 inset; - inset.r = (maxColor.r - minColor.r) >> 4; - inset.g = (maxColor.g - minColor.g) >> 4; - inset.b = (maxColor.b - minColor.b) >> 4; - inset.a = (maxColor.a - minColor.a) >> 4; - - minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; - minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; - minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; - minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255; - - maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; - maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; - maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; - maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0; - - *start = minColor; - *end = maxColor; + Color32 minColor(255, 255, 255, 255); + Color32 maxColor(0, 0, 0, 0); + + 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; } + if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; } + if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; } + if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; } + if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; } + if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; } + if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; } + } + + // Offset range by 1/16 of the extents + Color32 inset; + inset.r = (maxColor.r - minColor.r) >> 4; + inset.g = (maxColor.g - minColor.g) >> 4; + inset.b = (maxColor.b - minColor.b) >> 4; + inset.a = (maxColor.a - minColor.a) >> 4; + + minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255; + minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255; + minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255; + minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255; + + maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0; + maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0; + maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0; + maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0; + + *start = minColor; + *end = maxColor; } #endif @@ -369,21 +373,21 @@ void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const /// Sort colors by abosolute value in their 16 bit representation. void ColorBlock::sortColorsByAbsoluteValue() { - // Dummy selection sort. - for ( uint a = 0; a < 16; a++ ) { - uint max = a; - Color16 cmax(m_color[a]); - - for ( uint b = a+1; b < 16; b++ ) { - Color16 cb(m_color[b]); - - if ( cb.u > cmax.u ) { - max = b; - cmax = cb; - } - } - swap( m_color[a], m_color[max] ); - } + // Dummy selection sort. + for ( uint a = 0; a < 16; a++ ) { + uint max = a; + Color16 cmax(m_color[a]); + + for ( uint b = a+1; b < 16; b++ ) { + Color16 cb(m_color[b]); + + if ( cb.u > cmax.u ) { + max = b; + cmax = cb; + } + } + swap( m_color[a], m_color[max] ); + } } #endif @@ -392,29 +396,29 @@ void ColorBlock::sortColorsByAbsoluteValue() void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) const { - int mini, maxi; - mini = maxi = 0; - - float min, max; - min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis); - - for (uint i = 1; i < 16; i++) - { - const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); - - float val = dot(vec, axis); - if ( val < min ) { - mini = i; - min = val; - } - else if ( val > max ) { - maxi = i; - max = val; - } - } - - *start = m_color[mini]; - *end = m_color[maxi]; + int mini, maxi; + mini = maxi = 0; + + float min, max; + min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis); + + for (uint i = 1; i < 16; i++) + { + const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); + + float val = dot(vec, axis); + if ( val < min ) { + mini = i; + min = val; + } + else if ( val > max ) { + maxi = i; + max = val; + } + } + + *start = m_color[mini]; + *end = m_color[maxi]; } #endif @@ -422,24 +426,24 @@ void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) c /// Sort colors in the given axis. void ColorBlock::sortColors(const Vector3 & axis) { - float luma_array[16]; - - for (uint i = 0; i < 16; i++) { - const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); - luma_array[i] = dot(vec, axis); - } - - // Dummy selection sort. - for ( uint a = 0; a < 16; a++ ) { - uint min = a; - for ( uint b = a+1; b < 16; b++ ) { - if ( luma_array[b] < luma_array[min] ) { - min = b; - } - } - swap( luma_array[a], luma_array[min] ); - swap( m_color[a], m_color[min] ); - } + float luma_array[16]; + + for (uint i = 0; i < 16; i++) { + const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b); + luma_array[i] = dot(vec, axis); + } + + // Dummy selection sort. + for ( uint a = 0; a < 16; a++ ) { + uint min = a; + for ( uint b = a+1; b < 16; b++ ) { + if ( luma_array[b] < luma_array[min] ) { + min = b; + } + } + swap( luma_array[a], luma_array[min] ); + swap( m_color[a], m_color[min] ); + } } #endif @@ -447,14 +451,14 @@ void ColorBlock::sortColors(const Vector3 & axis) /// Get the volume of the color block. float ColorBlock::volume() const { - Box bounds; - bounds.clearBounds(); + Box bounds; + bounds.clearBounds(); - for (int i = 0; i < 16; i++) { - const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b); - bounds.addPointToBounds(point); - } + for (int i = 0; i < 16; i++) { + const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b); + bounds.addPointToBounds(point); + } - return bounds.volume(); + return bounds.volume(); } #endif diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index 66d1ed4e2c5..2e8a6bbda7f 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -36,65 +35,61 @@ /// Uncompressed 4x4 color block. struct ColorBlock { - ColorBlock(); - ColorBlock(const uint * linearImage); - ColorBlock(const ColorBlock & block); - ColorBlock(const Image *img, uint x, uint y); - - void init(const Image *img, uint x, uint y); - void init(uint w, uint h, const uint * data, uint x, uint y); - void init(uint w, uint h, const float * data, uint x, uint y); - - void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0 + ColorBlock(); + ColorBlock(const uint *linearImage); + ColorBlock(const ColorBlock &block); + ColorBlock(const Image *img, uint x, uint y); - bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const; - bool hasAlpha() const; + void init(const Image *img, uint x, uint y); + void init(uint w, uint h, const uint *data, uint x, uint y); + void init(uint w, uint h, const float *data, uint x, uint y); + void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0 - // Accessors - const Color32 * colors() const; + bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const; + bool hasAlpha() const; - Color32 color(uint i) const; - Color32 & color(uint i); + // Accessors + const Color32 *colors() const; - Color32 color(uint x, uint y) const; - Color32 & color(uint x, uint y); + Color32 color(uint i) const; + Color32 &color(uint i); -private: - - Color32 m_color[4 * 4]; + Color32 color(uint x, uint y) const; + Color32 &color(uint x, uint y); + private: + Color32 m_color[4 * 4]; }; - /// Get pointer to block colors. -inline const Color32 * ColorBlock::colors() const +inline const Color32 *ColorBlock::colors() const { - return m_color; + return m_color; } /// Get block color. inline Color32 ColorBlock::color(uint i) const { - return m_color[i]; + return m_color[i]; } /// Get block color. -inline Color32 & ColorBlock::color(uint i) +inline Color32 &ColorBlock::color(uint i) { - return m_color[i]; + return m_color[i]; } /// Get block color. inline Color32 ColorBlock::color(uint x, uint y) const { - return m_color[y * 4 + x]; + return m_color[y * 4 + x]; } /// Get block color. -inline Color32 & ColorBlock::color(uint x, uint y) +inline Color32 &ColorBlock::color(uint x, uint y) { - return m_color[y * 4 + x]; + return m_color[y * 4 + x]; } -#endif /* __COLORBLOCK_H__ */ +#endif /* __COLORBLOCK_H__ */ diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h index 1a7d087ec2e..56f5d54cf42 100644 --- a/source/blender/imbuf/intern/dds/Common.h +++ b/source/blender/imbuf/intern/dds/Common.h @@ -18,39 +18,36 @@ * \ingroup imbdds */ - #ifndef __COMMON_H__ #define __COMMON_H__ #ifndef MIN -#define MIN(a,b) ((a) <= (b) ? (a) : (b)) +# define MIN(a, b) ((a) <= (b) ? (a) : (b)) #endif #ifndef MAX -#define MAX(a,b) ((a) >= (b) ? (a) : (b)) +# define MAX(a, b) ((a) >= (b) ? (a) : (b)) #endif #ifndef CLAMP -#define CLAMP(x,a,b) MIN(MAX((x), (a)), (b)) +# define CLAMP(x, a, b) MIN(MAX((x), (a)), (b)) #endif -template -inline void -swap(T & a, T & b) +template inline void swap(T &a, T &b) { - T tmp = a; - a = b; - b = tmp; + 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 char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; +typedef unsigned int uint32; typedef unsigned long long uint64; // copied from nvtt src/nvimage/nvimage.h inline uint computePitch(uint w, uint bitsize, uint alignment) { - return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment; + return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment; } #endif diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index 76de84cdee5..3db9b65c461 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -53,17 +52,17 @@ #include #include -#include // printf +#include // printf #include // malloc -#include // sqrt +#include // sqrt #include /*** declarations ***/ #if !defined(DDS_MAKEFOURCC) -# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \ - (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \ - (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 )) +# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \ + (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | (uint(uint8(ch2)) << 16) | \ + (uint(uint8(ch3)) << 24)) #endif static const uint FOURCC_NVTT = DDS_MAKEFOURCC('N', 'V', 'T', 'T'); @@ -159,727 +158,716 @@ static const uint DDPF_ALPHAPREMULT = 0x00008000U; static const uint DDPF_NORMAL = 0x80000000U; static const uint DDPF_SRGB = 0x40000000U; - // 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, - - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, - DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, - DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, - - DXGI_FORMAT_BC6H_TYPELESS = 94, - DXGI_FORMAT_BC6H_UF16 = 95, - DXGI_FORMAT_BC6H_SF16 = 96, - - DXGI_FORMAT_BC7_TYPELESS = 97, - DXGI_FORMAT_BC7_UNORM = 98, - DXGI_FORMAT_BC7_UNORM_SRGB = 99, - }; - - 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, - }; - - - static const char * getDxgiFormatString(DXGI_FORMAT dxgiFormat) - { -#define CASE(format) case DXGI_FORMAT_##format: return #format - switch (dxgiFormat) - { - CASE(UNKNOWN); - - CASE(R32G32B32A32_TYPELESS); - CASE(R32G32B32A32_FLOAT); - CASE(R32G32B32A32_UINT); - CASE(R32G32B32A32_SINT); - - CASE(R32G32B32_TYPELESS); - CASE(R32G32B32_FLOAT); - CASE(R32G32B32_UINT); - CASE(R32G32B32_SINT); - - CASE(R16G16B16A16_TYPELESS); - CASE(R16G16B16A16_FLOAT); - CASE(R16G16B16A16_UNORM); - CASE(R16G16B16A16_UINT); - CASE(R16G16B16A16_SNORM); - CASE(R16G16B16A16_SINT); - - CASE(R32G32_TYPELESS); - CASE(R32G32_FLOAT); - CASE(R32G32_UINT); - CASE(R32G32_SINT); - - CASE(R32G8X24_TYPELESS); - CASE(D32_FLOAT_S8X24_UINT); - CASE(R32_FLOAT_X8X24_TYPELESS); - CASE(X32_TYPELESS_G8X24_UINT); - - CASE(R10G10B10A2_TYPELESS); - CASE(R10G10B10A2_UNORM); - CASE(R10G10B10A2_UINT); - - CASE(R11G11B10_FLOAT); - - CASE(R8G8B8A8_TYPELESS); - CASE(R8G8B8A8_UNORM); - CASE(R8G8B8A8_UNORM_SRGB); - CASE(R8G8B8A8_UINT); - CASE(R8G8B8A8_SNORM); - CASE(R8G8B8A8_SINT); - - CASE(R16G16_TYPELESS); - CASE(R16G16_FLOAT); - CASE(R16G16_UNORM); - CASE(R16G16_UINT); - CASE(R16G16_SNORM); - CASE(R16G16_SINT); - - CASE(R32_TYPELESS); - CASE(D32_FLOAT); - CASE(R32_FLOAT); - CASE(R32_UINT); - CASE(R32_SINT); - - CASE(R24G8_TYPELESS); - CASE(D24_UNORM_S8_UINT); - CASE(R24_UNORM_X8_TYPELESS); - CASE(X24_TYPELESS_G8_UINT); - - CASE(R8G8_TYPELESS); - CASE(R8G8_UNORM); - CASE(R8G8_UINT); - CASE(R8G8_SNORM); - CASE(R8G8_SINT); - - CASE(R16_TYPELESS); - CASE(R16_FLOAT); - CASE(D16_UNORM); - CASE(R16_UNORM); - CASE(R16_UINT); - CASE(R16_SNORM); - CASE(R16_SINT); - - CASE(R8_TYPELESS); - CASE(R8_UNORM); - CASE(R8_UINT); - CASE(R8_SNORM); - CASE(R8_SINT); - CASE(A8_UNORM); - - CASE(R1_UNORM); - - CASE(R9G9B9E5_SHAREDEXP); - - CASE(R8G8_B8G8_UNORM); - CASE(G8R8_G8B8_UNORM); - - CASE(BC1_TYPELESS); - CASE(BC1_UNORM); - CASE(BC1_UNORM_SRGB); - - CASE(BC2_TYPELESS); - CASE(BC2_UNORM); - CASE(BC2_UNORM_SRGB); - - CASE(BC3_TYPELESS); - CASE(BC3_UNORM); - CASE(BC3_UNORM_SRGB); - - CASE(BC4_TYPELESS); - CASE(BC4_UNORM); - CASE(BC4_SNORM); - - CASE(BC5_TYPELESS); - CASE(BC5_UNORM); - CASE(BC5_SNORM); - - CASE(B5G6R5_UNORM); - CASE(B5G5R5A1_UNORM); - CASE(B8G8R8A8_UNORM); - CASE(B8G8R8X8_UNORM); - - default: - return "UNKNOWN"; - } +// 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, + + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, +}; + +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, +}; + +static const char *getDxgiFormatString(DXGI_FORMAT dxgiFormat) +{ +#define CASE(format) \ + case DXGI_FORMAT_##format: \ + return #format + switch (dxgiFormat) { + CASE(UNKNOWN); + + CASE(R32G32B32A32_TYPELESS); + CASE(R32G32B32A32_FLOAT); + CASE(R32G32B32A32_UINT); + CASE(R32G32B32A32_SINT); + + CASE(R32G32B32_TYPELESS); + CASE(R32G32B32_FLOAT); + CASE(R32G32B32_UINT); + CASE(R32G32B32_SINT); + + CASE(R16G16B16A16_TYPELESS); + CASE(R16G16B16A16_FLOAT); + CASE(R16G16B16A16_UNORM); + CASE(R16G16B16A16_UINT); + CASE(R16G16B16A16_SNORM); + CASE(R16G16B16A16_SINT); + + CASE(R32G32_TYPELESS); + CASE(R32G32_FLOAT); + CASE(R32G32_UINT); + CASE(R32G32_SINT); + + CASE(R32G8X24_TYPELESS); + CASE(D32_FLOAT_S8X24_UINT); + CASE(R32_FLOAT_X8X24_TYPELESS); + CASE(X32_TYPELESS_G8X24_UINT); + + CASE(R10G10B10A2_TYPELESS); + CASE(R10G10B10A2_UNORM); + CASE(R10G10B10A2_UINT); + + CASE(R11G11B10_FLOAT); + + CASE(R8G8B8A8_TYPELESS); + CASE(R8G8B8A8_UNORM); + CASE(R8G8B8A8_UNORM_SRGB); + CASE(R8G8B8A8_UINT); + CASE(R8G8B8A8_SNORM); + CASE(R8G8B8A8_SINT); + + CASE(R16G16_TYPELESS); + CASE(R16G16_FLOAT); + CASE(R16G16_UNORM); + CASE(R16G16_UINT); + CASE(R16G16_SNORM); + CASE(R16G16_SINT); + + CASE(R32_TYPELESS); + CASE(D32_FLOAT); + CASE(R32_FLOAT); + CASE(R32_UINT); + CASE(R32_SINT); + + CASE(R24G8_TYPELESS); + CASE(D24_UNORM_S8_UINT); + CASE(R24_UNORM_X8_TYPELESS); + CASE(X24_TYPELESS_G8_UINT); + + CASE(R8G8_TYPELESS); + CASE(R8G8_UNORM); + CASE(R8G8_UINT); + CASE(R8G8_SNORM); + CASE(R8G8_SINT); + + CASE(R16_TYPELESS); + CASE(R16_FLOAT); + CASE(D16_UNORM); + CASE(R16_UNORM); + CASE(R16_UINT); + CASE(R16_SNORM); + CASE(R16_SINT); + + CASE(R8_TYPELESS); + CASE(R8_UNORM); + CASE(R8_UINT); + CASE(R8_SNORM); + CASE(R8_SINT); + CASE(A8_UNORM); + + CASE(R1_UNORM); + + CASE(R9G9B9E5_SHAREDEXP); + + CASE(R8G8_B8G8_UNORM); + CASE(G8R8_G8B8_UNORM); + + CASE(BC1_TYPELESS); + CASE(BC1_UNORM); + CASE(BC1_UNORM_SRGB); + + CASE(BC2_TYPELESS); + CASE(BC2_UNORM); + CASE(BC2_UNORM_SRGB); + + CASE(BC3_TYPELESS); + CASE(BC3_UNORM); + CASE(BC3_UNORM_SRGB); + + CASE(BC4_TYPELESS); + CASE(BC4_UNORM); + CASE(BC4_SNORM); + + CASE(BC5_TYPELESS); + CASE(BC5_UNORM); + CASE(BC5_SNORM); + + CASE(B5G6R5_UNORM); + CASE(B5G5R5A1_UNORM); + CASE(B8G8R8A8_UNORM); + CASE(B8G8R8X8_UNORM); + + default: + return "UNKNOWN"; + } #undef CASE - } - - static const char * getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension) - { - switch (resourceDimension) - { - default: - case D3D10_RESOURCE_DIMENSION_UNKNOWN: return "UNKNOWN"; - case D3D10_RESOURCE_DIMENSION_BUFFER: return "BUFFER"; - case D3D10_RESOURCE_DIMENSION_TEXTURE1D: return "TEXTURE1D"; - case D3D10_RESOURCE_DIMENSION_TEXTURE2D: return "TEXTURE2D"; - case D3D10_RESOURCE_DIMENSION_TEXTURE3D: return "TEXTURE3D"; - } - } +} + +static const char *getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension) +{ + switch (resourceDimension) { + default: + case D3D10_RESOURCE_DIMENSION_UNKNOWN: + return "UNKNOWN"; + case D3D10_RESOURCE_DIMENSION_BUFFER: + return "BUFFER"; + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + return "TEXTURE1D"; + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + return "TEXTURE2D"; + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + return "TEXTURE3D"; + } +} /*** implementation ***/ -void mem_read(Stream & mem, DDSPixelFormat & pf) +void mem_read(Stream &mem, DDSPixelFormat &pf) { - mem_read(mem, pf.size); - mem_read(mem, pf.flags); - mem_read(mem, pf.fourcc); - mem_read(mem, pf.bitcount); - mem_read(mem, pf.rmask); - mem_read(mem, pf.gmask); - mem_read(mem, pf.bmask); - mem_read(mem, pf.amask); + mem_read(mem, pf.size); + mem_read(mem, pf.flags); + mem_read(mem, pf.fourcc); + mem_read(mem, pf.bitcount); + mem_read(mem, pf.rmask); + mem_read(mem, pf.gmask); + mem_read(mem, pf.bmask); + mem_read(mem, pf.amask); } -void mem_read(Stream & mem, DDSCaps & caps) +void mem_read(Stream &mem, DDSCaps &caps) { - mem_read(mem, caps.caps1); - mem_read(mem, caps.caps2); - mem_read(mem, caps.caps3); - mem_read(mem, caps.caps4); + mem_read(mem, caps.caps1); + mem_read(mem, caps.caps2); + mem_read(mem, caps.caps3); + mem_read(mem, caps.caps4); } -void mem_read(Stream & mem, DDSHeader10 & header) +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); + 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) +void mem_read(Stream &mem, DDSHeader &header) { - mem_read(mem, header.fourcc); - mem_read(mem, header.size); - mem_read(mem, header.flags); - mem_read(mem, header.height); - mem_read(mem, header.width); - mem_read(mem, header.pitch); - mem_read(mem, header.depth); - mem_read(mem, header.mipmapcount); - 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); - } + mem_read(mem, header.fourcc); + mem_read(mem, header.size); + mem_read(mem, header.flags); + mem_read(mem, header.height); + mem_read(mem, header.width); + mem_read(mem, header.pitch); + mem_read(mem, header.depth); + mem_read(mem, header.mipmapcount); + 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); + } } -namespace -{ +namespace { struct FormatDescriptor { - uint format; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; + uint format; + uint bitcount; + uint rmask; + uint gmask; + uint bmask; + uint amask; }; -static const FormatDescriptor s_d3dFormats[] = -{ - { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 }, - { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, /* DXGI_FORMAT_B8G8R8A8_UNORM */ - { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, /* DXGI_FORMAT_B8G8R8X8_UNORM */ - { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, /* DXGI_FORMAT_B5G6R5_UNORM */ - { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 }, - { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, /* DXGI_FORMAT_B5G5R5A1_UNORM */ - { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 }, - { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 }, - { D3DFMT_A8, 8, 0, 0, 0, 8 }, /* DXGI_FORMAT_A8_UNORM */ - { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 }, - { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 }, - { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, /* DXGI_FORMAT_R10G10B10A2 */ - { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, /* DXGI_FORMAT_R8G8B8A8_UNORM */ - { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 }, - { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, /* DXGI_FORMAT_R16G16_UNORM */ - { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 }, - { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, - - { D3DFMT_L8, 8, 8, 0, 0, 0 }, /* DXGI_FORMAT_R8_UNORM */ - { D3DFMT_L16, 16, 16, 0, 0, 0 }, /* DXGI_FORMAT_R16_UNORM */ +static const FormatDescriptor s_d3dFormats[] = { + {D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0}, + {D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}, /* DXGI_FORMAT_B8G8R8A8_UNORM */ + {D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0}, /* DXGI_FORMAT_B8G8R8X8_UNORM */ + {D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0}, /* DXGI_FORMAT_B5G6R5_UNORM */ + {D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0}, + {D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000}, /* DXGI_FORMAT_B5G5R5A1_UNORM */ + {D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000}, + {D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0}, + {D3DFMT_A8, 8, 0, 0, 0, 8}, /* DXGI_FORMAT_A8_UNORM */ + {D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00}, + {D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0}, + {D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000}, /* DXGI_FORMAT_R10G10B10A2 */ + {D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000}, /* DXGI_FORMAT_R8G8B8A8_UNORM */ + {D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0}, + {D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0}, /* DXGI_FORMAT_R16G16_UNORM */ + {D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000}, + {D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000}, + + {D3DFMT_L8, 8, 8, 0, 0, 0}, /* DXGI_FORMAT_R8_UNORM */ + {D3DFMT_L16, 16, 16, 0, 0, 0}, /* DXGI_FORMAT_R16_UNORM */ }; static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]); -} // namespace +} // namespace static uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { - for (int i = 0; i < s_d3dFormatCount; i++) - { - if (s_d3dFormats[i].bitcount == bitcount && - s_d3dFormats[i].rmask == rmask && - s_d3dFormats[i].gmask == gmask && - s_d3dFormats[i].bmask == bmask && - s_d3dFormats[i].amask == amask) - { - return s_d3dFormats[i].format; - } - } - - return 0; + for (int i = 0; i < s_d3dFormatCount; i++) { + if (s_d3dFormats[i].bitcount == bitcount && s_d3dFormats[i].rmask == rmask && + s_d3dFormats[i].gmask == gmask && s_d3dFormats[i].bmask == bmask && + s_d3dFormats[i].amask == amask) { + return s_d3dFormats[i].format; + } + } + + return 0; } - - DDSHeader::DDSHeader() { - this->fourcc = FOURCC_DDS; - this->size = 124; - this->flags = (DDSD_CAPS|DDSD_PIXELFORMAT); - this->height = 0; - this->width = 0; - this->pitch = 0; - this->depth = 0; - this->mipmapcount = 0; - for (uint i = 0; i < 11; i++) this->reserved[i] = 0; - - // Store version information on the reserved header attributes. - this->reserved[9] = FOURCC_NVTT; - this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision - - this->pf.size = 32; - this->pf.flags = 0; - this->pf.fourcc = 0; - this->pf.bitcount = 0; - this->pf.rmask = 0; - this->pf.gmask = 0; - this->pf.bmask = 0; - this->pf.amask = 0; - this->caps.caps1 = DDSCAPS_TEXTURE; - this->caps.caps2 = 0; - 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; + this->fourcc = FOURCC_DDS; + this->size = 124; + this->flags = (DDSD_CAPS | DDSD_PIXELFORMAT); + this->height = 0; + this->width = 0; + this->pitch = 0; + this->depth = 0; + this->mipmapcount = 0; + for (uint i = 0; i < 11; i++) + this->reserved[i] = 0; + + // Store version information on the reserved header attributes. + this->reserved[9] = FOURCC_NVTT; + this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision + + this->pf.size = 32; + this->pf.flags = 0; + this->pf.fourcc = 0; + this->pf.bitcount = 0; + this->pf.rmask = 0; + this->pf.gmask = 0; + this->pf.bmask = 0; + this->pf.amask = 0; + this->caps.caps1 = DDSCAPS_TEXTURE; + this->caps.caps2 = 0; + 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(uint w) { - this->flags |= DDSD_WIDTH; - this->width = w; + this->flags |= DDSD_WIDTH; + this->width = w; } void DDSHeader::setHeight(uint h) { - this->flags |= DDSD_HEIGHT; - this->height = h; + this->flags |= DDSD_HEIGHT; + this->height = h; } void DDSHeader::setDepth(uint d) { - this->flags |= DDSD_DEPTH; - this->depth = d; + this->flags |= DDSD_DEPTH; + this->depth = d; } void DDSHeader::setMipmapCount(uint count) { - if (count == 0 || count == 1) - { - this->flags &= ~DDSD_MIPMAPCOUNT; - this->mipmapcount = 1; - - if (this->caps.caps2 == 0) { - this->caps.caps1 = DDSCAPS_TEXTURE; - } - else { - this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX; - } - } - else - { - this->flags |= DDSD_MIPMAPCOUNT; - this->mipmapcount = count; - - this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - } + if (count == 0 || count == 1) { + this->flags &= ~DDSD_MIPMAPCOUNT; + this->mipmapcount = 1; + + if (this->caps.caps2 == 0) { + this->caps.caps1 = DDSCAPS_TEXTURE; + } + else { + this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX; + } + } + else { + this->flags |= DDSD_MIPMAPCOUNT; + this->mipmapcount = count; + + this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + } } void DDSHeader::setTexture2D() { - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - this->header10.arraySize = 1; + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + this->header10.arraySize = 1; } void DDSHeader::setTexture3D() { - this->caps.caps2 = DDSCAPS2_VOLUME; + this->caps.caps2 = DDSCAPS2_VOLUME; - this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; - this->header10.arraySize = 1; + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; + this->header10.arraySize = 1; } void DDSHeader::setTextureCube() { - this->caps.caps1 |= DDSCAPS_COMPLEX; - this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES; + 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; + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + this->header10.arraySize = 6; } void DDSHeader::setLinearSize(uint size) { - this->flags &= ~DDSD_PITCH; - this->flags |= DDSD_LINEARSIZE; - this->pitch = size; + this->flags &= ~DDSD_PITCH; + this->flags |= DDSD_LINEARSIZE; + this->pitch = size; } void DDSHeader::setPitch(uint pitch) { - this->flags &= ~DDSD_LINEARSIZE; - this->flags |= DDSD_PITCH; - this->pitch = pitch; + this->flags &= ~DDSD_LINEARSIZE; + this->flags |= DDSD_PITCH; + this->pitch = pitch; } void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3) { - // set fourcc pixel format. - this->pf.flags = DDPF_FOURCC; - this->pf.fourcc = DDS_MAKEFOURCC(c0, c1, c2, c3); - - this->pf.bitcount = 0; - this->pf.rmask = 0; - this->pf.gmask = 0; - this->pf.bmask = 0; - this->pf.amask = 0; + // set fourcc pixel format. + this->pf.flags = DDPF_FOURCC; + this->pf.fourcc = DDS_MAKEFOURCC(c0, c1, c2, c3); + + this->pf.bitcount = 0; + this->pf.rmask = 0; + this->pf.gmask = 0; + this->pf.bmask = 0; + this->pf.amask = 0; } void DDSHeader::setFormatCode(uint32 code) { - // set fourcc pixel format. - this->pf.flags = DDPF_FOURCC; - this->pf.fourcc = code; - - this->pf.bitcount = 0; - this->pf.rmask = 0; - this->pf.gmask = 0; - this->pf.bmask = 0; - this->pf.amask = 0; + // set fourcc pixel format. + this->pf.flags = DDPF_FOURCC; + this->pf.fourcc = code; + + this->pf.bitcount = 0; + this->pf.rmask = 0; + this->pf.gmask = 0; + this->pf.bmask = 0; + this->pf.amask = 0; } void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3) { - this->pf.bitcount = DDS_MAKEFOURCC(c0, c1, c2, c3); + this->pf.bitcount = DDS_MAKEFOURCC(c0, c1, c2, c3); } - void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { - // Make sure the masks are correct. - if ((rmask & gmask) || - (rmask & bmask) || - (rmask & amask) || - (gmask & bmask) || - (gmask & amask) || - (bmask & amask)) - { - printf("DDS: bad RGBA masks, pixel format not set\n"); - return; - } - - if (rmask != 0 || gmask != 0 || bmask != 0) - { - if (gmask == 0 && bmask == 0) - { - this->pf.flags = DDPF_LUMINANCE; - } - else - { - this->pf.flags = DDPF_RGB; - } - - if (amask != 0) { - this->pf.flags |= DDPF_ALPHAPIXELS; - } - } - else if (amask != 0) - { - this->pf.flags |= DDPF_ALPHA; - } - - if (bitcount == 0) - { - // Compute bit count from the masks. - uint total = rmask | gmask | bmask | amask; - while (total != 0) { - bitcount++; - total >>= 1; - } - } - - // D3DX functions do not like this: - this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); - /*if (this->pf.fourcc) { - this->pf.flags |= DDPF_FOURCC; - }*/ - - if (!(bitcount > 0 && bitcount <= 32)) { - printf("DDS: bad bit count, pixel format not set\n"); - return; - } - this->pf.bitcount = bitcount; - this->pf.rmask = rmask; - this->pf.gmask = gmask; - this->pf.bmask = bmask; - this->pf.amask = amask; + // Make sure the masks are correct. + if ((rmask & gmask) || (rmask & bmask) || (rmask & amask) || (gmask & bmask) || + (gmask & amask) || (bmask & amask)) { + printf("DDS: bad RGBA masks, pixel format not set\n"); + return; + } + + if (rmask != 0 || gmask != 0 || bmask != 0) { + if (gmask == 0 && bmask == 0) { + this->pf.flags = DDPF_LUMINANCE; + } + else { + this->pf.flags = DDPF_RGB; + } + + if (amask != 0) { + this->pf.flags |= DDPF_ALPHAPIXELS; + } + } + else if (amask != 0) { + this->pf.flags |= DDPF_ALPHA; + } + + if (bitcount == 0) { + // Compute bit count from the masks. + uint total = rmask | gmask | bmask | amask; + while (total != 0) { + bitcount++; + total >>= 1; + } + } + + // D3DX functions do not like this: + this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); + /*if (this->pf.fourcc) { + this->pf.flags |= DDPF_FOURCC; + }*/ + + if (!(bitcount > 0 && bitcount <= 32)) { + printf("DDS: bad bit count, pixel format not set\n"); + return; + } + this->pf.bitcount = bitcount; + this->pf.rmask = rmask; + this->pf.gmask = gmask; + this->pf.bmask = bmask; + this->pf.amask = amask; } void DDSHeader::setDX10Format(uint format) { - //this->pf.flags = 0; - this->pf.fourcc = FOURCC_DX10; - this->header10.dxgiFormat = format; + //this->pf.flags = 0; + this->pf.fourcc = FOURCC_DX10; + this->header10.dxgiFormat = format; } void DDSHeader::setNormalFlag(bool b) { - if (b) this->pf.flags |= DDPF_NORMAL; - else this->pf.flags &= ~DDPF_NORMAL; + if (b) + this->pf.flags |= DDPF_NORMAL; + else + this->pf.flags &= ~DDPF_NORMAL; } void DDSHeader::setSrgbFlag(bool b) { - if (b) this->pf.flags |= DDPF_SRGB; - else this->pf.flags &= ~DDPF_SRGB; + if (b) + this->pf.flags |= DDPF_SRGB; + else + this->pf.flags &= ~DDPF_SRGB; } void DDSHeader::setHasAlphaFlag(bool b) { - if (b) this->pf.flags |= DDPF_ALPHAPIXELS; - else this->pf.flags &= ~DDPF_ALPHAPIXELS; + if (b) + this->pf.flags |= DDPF_ALPHAPIXELS; + else + this->pf.flags &= ~DDPF_ALPHAPIXELS; } void DDSHeader::setUserVersion(int version) { - this->reserved[7] = FOURCC_UVER; - this->reserved[8] = version; + this->reserved[7] = FOURCC_UVER; + this->reserved[8] = version; } #if 0 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); - - this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat); - this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension); - this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag); - this->header10.arraySize = POSH_LittleU32(this->header10.arraySize); - this->header10.reserved = POSH_LittleU32(this->header10.reserved); + 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); + + this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat); + this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension); + this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag); + this->header10.arraySize = POSH_LittleU32(this->header10.arraySize); + this->header10.reserved = POSH_LittleU32(this->header10.reserved); } #endif bool DDSHeader::hasDX10Header() const { - return this->pf.fourcc == FOURCC_DX10; + return this->pf.fourcc == FOURCC_DX10; } uint DDSHeader::signature() const { - return this->reserved[9]; + return this->reserved[9]; } uint DDSHeader::toolVersion() const { - return this->reserved[10]; + return this->reserved[10]; } uint DDSHeader::userVersion() const { - if (this->reserved[7] == FOURCC_UVER) { - return this->reserved[8]; - } - return 0; + if (this->reserved[7] == FOURCC_UVER) { + return this->reserved[8]; + } + return 0; } bool DDSHeader::isNormalMap() const { - return (pf.flags & DDPF_NORMAL) != 0; + return (pf.flags & DDPF_NORMAL) != 0; } bool DDSHeader::isSrgb() const { - return (pf.flags & DDPF_SRGB) != 0; + return (pf.flags & DDPF_SRGB) != 0; } bool DDSHeader::hasAlpha() const { - return (pf.flags & DDPF_ALPHAPIXELS) != 0; + return (pf.flags & DDPF_ALPHAPIXELS) != 0; } uint DDSHeader::d3d9Format() const { - if (pf.flags & DDPF_FOURCC) { - return pf.fourcc; - } - else { - return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); - } + if (pf.flags & DDPF_FOURCC) { + return pf.fourcc; + } + else { + return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); + } } DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header() { - mem_read(stream, header); + mem_read(stream, header); - // some ATI2 compressed normal maps do not have their - // normal flag set, so force it here (the original nvtt don't do - // this, but the decompressor has a -forcenormal flag) - if (header.pf.fourcc == FOURCC_ATI2) header.setNormalFlag(true); + // some ATI2 compressed normal maps do not have their + // normal flag set, so force it here (the original nvtt don't do + // this, but the decompressor has a -forcenormal flag) + if (header.pf.fourcc == FOURCC_ATI2) + header.setNormalFlag(true); } DirectDrawSurface::~DirectDrawSurface() @@ -888,666 +876,642 @@ DirectDrawSurface::~DirectDrawSurface() bool DirectDrawSurface::isValid() const { - if (header.fourcc != FOURCC_DDS || header.size != 124) - { - return false; - } + if (header.fourcc != FOURCC_DDS || header.size != 124) { + return false; + } - const uint required = (DDSD_WIDTH|DDSD_HEIGHT/*|DDSD_CAPS|DDSD_PIXELFORMAT*/); - if ( (header.flags & required) != required ) { - return false; - } + const uint required = (DDSD_WIDTH | DDSD_HEIGHT /*|DDSD_CAPS|DDSD_PIXELFORMAT*/); + if ((header.flags & required) != required) { + return false; + } - if (header.pf.size != 32) { - return false; - } + if (header.pf.size != 32) { + return false; + } - /* in some files DDSCAPS_TEXTURE is missing: silently ignore */ + /* in some files DDSCAPS_TEXTURE is missing: silently ignore */ #if 0 - if (!(header.caps.caps1 & DDSCAPS_TEXTURE)) { - return false; - } + if (!(header.caps.caps1 & DDSCAPS_TEXTURE)) { + return false; + } #endif - return true; + return true; } bool DirectDrawSurface::isSupported() const { - if (header.hasDX10Header()) - { - if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) - { - return true; - } - - return false; - } - else - { - if (header.pf.flags & DDPF_FOURCC) - { - if (header.pf.fourcc != FOURCC_DXT1 && - header.pf.fourcc != FOURCC_DXT2 && - header.pf.fourcc != FOURCC_DXT3 && - header.pf.fourcc != FOURCC_DXT4 && - header.pf.fourcc != FOURCC_DXT5 && - header.pf.fourcc != FOURCC_RXGB && - header.pf.fourcc != FOURCC_ATI1 && - header.pf.fourcc != FOURCC_ATI2) - { - // Unknown fourcc code. - return false; - } - } - else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) - { - // All RGB and luminance formats are supported now. - } - else - { - return false; - } - - if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) - { - // Cubemaps must contain all faces. - return false; - } - - if (isTexture3D()) - { - // @@ 3D textures not supported yet. - return false; - } - } - - return true; + if (header.hasDX10Header()) { + if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) { + return true; + } + + return false; + } + else { + if (header.pf.flags & DDPF_FOURCC) { + if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 && + header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 && + header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB && + header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) { + // Unknown fourcc code. + return false; + } + } + else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) { + // All RGB and luminance formats are supported now. + } + else { + return false; + } + + if (isTextureCube() && + (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) { + // Cubemaps must contain all faces. + return false; + } + + if (isTexture3D()) { + // @@ 3D textures not supported yet. + return false; + } + } + + return true; } bool DirectDrawSurface::hasAlpha() const { - if (header.hasDX10Header()) - { - /* TODO: Update hasAlpha to handle all DX10 formats. */ - return - header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM || - header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM; - } - else - { - if (header.pf.flags & DDPF_RGB) - { - return header.pf.amask != 0; - } - else if (header.pf.flags & DDPF_FOURCC) - { - if (header.pf.fourcc == FOURCC_RXGB || - header.pf.fourcc == FOURCC_ATI1 || - header.pf.fourcc == FOURCC_ATI2 || - header.pf.flags & DDPF_NORMAL) - { - return false; - } - else - { - // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) - return true; - } - } - - return false; - } + if (header.hasDX10Header()) { + /* TODO: Update hasAlpha to handle all DX10 formats. */ + return header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM || + header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM; + } + else { + if (header.pf.flags & DDPF_RGB) { + return header.pf.amask != 0; + } + else if (header.pf.flags & DDPF_FOURCC) { + if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 || + header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) { + return false; + } + else { + // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) + return true; + } + } + + return false; + } } uint DirectDrawSurface::mipmapCount() const { - if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount; - else return 1; + if (header.flags & DDSD_MIPMAPCOUNT) + return header.mipmapcount; + else + return 1; } uint DirectDrawSurface::fourCC() const { - return header.pf.fourcc; + return header.pf.fourcc; } uint DirectDrawSurface::width() const { - if (header.flags & DDSD_WIDTH) return header.width; - else return 1; + if (header.flags & DDSD_WIDTH) + return header.width; + else + return 1; } uint DirectDrawSurface::height() const { - if (header.flags & DDSD_HEIGHT) return header.height; - else return 1; + if (header.flags & DDSD_HEIGHT) + return header.height; + else + return 1; } uint DirectDrawSurface::depth() const { - if (header.flags & DDSD_DEPTH) return header.depth; - else return 1; + if (header.flags & DDSD_DEPTH) + return header.depth; + else + return 1; } bool DirectDrawSurface::isTexture1D() const { - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D; - } - return false; + if (header.hasDX10Header()) { + return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D; + } + return false; } bool DirectDrawSurface::isTexture2D() const { - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D; - } - else - { - return !isTexture3D() && !isTextureCube(); - } + if (header.hasDX10Header()) { + return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D; + } + else { + return !isTexture3D() && !isTextureCube(); + } } bool DirectDrawSurface::isTexture3D() const { - if (header.hasDX10Header()) - { - return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D; - } - else - { - return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0; - } + if (header.hasDX10Header()) { + return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D; + } + else { + return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0; + } } bool DirectDrawSurface::isTextureCube() const { - return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0; + return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0; } void DirectDrawSurface::setNormalFlag(bool b) { - header.setNormalFlag(b); + header.setNormalFlag(b); } void DirectDrawSurface::setHasAlphaFlag(bool b) { - header.setHasAlphaFlag(b); + header.setHasAlphaFlag(b); } void DirectDrawSurface::setUserVersion(int version) { - header.setUserVersion(version); + header.setUserVersion(version); } void DirectDrawSurface::mipmap(Image *img, uint face, uint mipmap) { - stream.seek(offset(face, mipmap)); - - uint w = width(); - uint h = height(); - - // Compute width and height. - for (uint m = 0; m < mipmap; m++) - { - w = MAX(1U, w / 2); - h = MAX(1U, h / 2); - } - - img->allocate(w, h); - - if (hasAlpha()) - { - img->setFormat(Image::Format_ARGB); - } - else - { - img->setFormat(Image::Format_RGB); - } - - if (header.hasDX10Header()) - { - // So far only block formats supported. - readBlockImage(img); - } - else - { - if (header.pf.flags & DDPF_RGB) - { - readLinearImage(img); - } - else if (header.pf.flags & DDPF_FOURCC) - { - readBlockImage(img); - } - } + stream.seek(offset(face, mipmap)); + + uint w = width(); + uint h = height(); + + // Compute width and height. + for (uint m = 0; m < mipmap; m++) { + w = MAX(1U, w / 2); + h = MAX(1U, h / 2); + } + + img->allocate(w, h); + + if (hasAlpha()) { + img->setFormat(Image::Format_ARGB); + } + else { + img->setFormat(Image::Format_RGB); + } + + if (header.hasDX10Header()) { + // So far only block formats supported. + readBlockImage(img); + } + else { + if (header.pf.flags & DDPF_RGB) { + readLinearImage(img); + } + else if (header.pf.flags & DDPF_FOURCC) { + readBlockImage(img); + } + } } // It was easier to copy this function from upstream than to resync. // This should be removed if a resync ever occurs. void *DirectDrawSurface::readData(uint &rsize) { - uint header_size = 128; // sizeof(DDSHeader); - if (header.hasDX10Header()) - { - header_size += 20; // sizeof(DDSHeader10); - } + uint header_size = 128; // sizeof(DDSHeader); + if (header.hasDX10Header()) { + header_size += 20; // sizeof(DDSHeader10); + } - uint size = stream.size - header_size; - rsize = size; + uint size = stream.size - header_size; + rsize = size; - unsigned char *data = (unsigned char *)malloc(sizeof(*data) * size); + unsigned char *data = (unsigned char *)malloc(sizeof(*data) * size); - stream.seek(header_size); - mem_read(stream, data, size); + stream.seek(header_size); + mem_read(stream, data, size); - if (stream.failed) { - free(data); - data = NULL; - rsize = 0; - } + if (stream.failed) { + free(data); + data = NULL; + rsize = 0; + } - // Maybe check if size == rsize? assert() isn't in this scope... + // Maybe check if size == rsize? assert() isn't in this scope... - return data; + return data; } void DirectDrawSurface::readLinearImage(Image *img) { - const uint w = img->width(); - const uint h = img->height(); + const uint w = img->width(); + const uint h = img->height(); - uint rshift, rsize; - PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize); + uint rshift, rsize; + PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize); - uint gshift, gsize; - PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize); + uint gshift, gsize; + PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize); - uint bshift, bsize; - PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize); + uint bshift, bsize; + PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize); - uint ashift, asize; - PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize); + uint ashift, asize; + PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize); - uint byteCount = (header.pf.bitcount + 7) / 8; + uint 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"); - return; - } + if (byteCount > 4) { + /* just in case... we could have segfaults later on if byteCount > 4 */ + printf("DDS: bitcount too large"); + return; + } - // Read linear RGB images. - for (uint y = 0; y < h; y++) - { - for (uint x = 0; x < w; x++) - { - uint c = 0; - mem_read(stream, (unsigned char *)(&c), byteCount); + // Read linear RGB images. + for (uint y = 0; y < h; y++) { + for (uint x = 0; x < w; x++) { + uint c = 0; + mem_read(stream, (unsigned char *)(&c), byteCount); - Color32 pixel(0, 0, 0, 0xFF); - pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8); - pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8); - pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8); - pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8); + Color32 pixel(0, 0, 0, 0xFF); + pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8); + pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8); + pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8); + pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8); - img->pixel(x, y) = pixel; - } - } + img->pixel(x, y) = pixel; + } + } } void DirectDrawSurface::readBlockImage(Image *img) { - const uint w = img->width(); - const uint h = img->height(); - - const uint bw = (w + 3) / 4; - const uint bh = (h + 3) / 4; - - for (uint by = 0; by < bh; by++) - { - for (uint bx = 0; bx < bw; bx++) - { - ColorBlock block; - - // Read color block. - readBlock(&block); - - // Write color block. - for (uint y = 0; y < MIN(4U, h-4*by); y++) - { - for (uint x = 0; x < MIN(4U, w-4*bx); x++) - { - img->pixel(4*bx+x, 4*by+y) = block.color(x, y); - } - } - } - } + const uint w = img->width(); + const uint h = img->height(); + + const uint bw = (w + 3) / 4; + const uint bh = (h + 3) / 4; + + for (uint by = 0; by < bh; by++) { + for (uint bx = 0; bx < bw; bx++) { + ColorBlock block; + + // Read color block. + readBlock(&block); + + // Write color block. + for (uint y = 0; y < MIN(4U, h - 4 * by); y++) { + for (uint x = 0; x < MIN(4U, w - 4 * bx); x++) { + img->pixel(4 * bx + x, 4 * by + y) = block.color(x, y); + } + } + } + } } static Color32 buildNormal(uint8 x, uint8 y) { - 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 = sqrt(1 - nx*nx - ny*ny); - uint8 z = CLAMP(int(255.0f * (nz + 1) / 2.0f), 0, 255); - - return Color32(x, y, z); + 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 = sqrt(1 - nx * nx - ny * ny); + uint8 z = CLAMP(int(255.0f * (nz + 1) / 2.0f), 0, 255); + + return Color32(x, y, z); } - void DirectDrawSurface::readBlock(ColorBlock *rgba) { - uint fourcc = header.pf.fourcc; - - // Map DX10 block formats to fourcc codes. - if (header.hasDX10Header()) - { - if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1; - if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3; - if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5; - if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1; - if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2; - } - - - if (fourcc == FOURCC_DXT1) - { - BlockDXT1 block; - mem_read(stream, block); - block.decodeBlock(rgba); - } - else if (fourcc == FOURCC_DXT2 || - header.pf.fourcc == FOURCC_DXT3) - { - BlockDXT3 block; - mem_read(stream, block); - block.decodeBlock(rgba); - } - else if (fourcc == FOURCC_DXT4 || - header.pf.fourcc == FOURCC_DXT5 || - header.pf.fourcc == FOURCC_RXGB) - { - BlockDXT5 block; - mem_read(stream, block); - block.decodeBlock(rgba); - - if (fourcc == FOURCC_RXGB) - { - // Swap R & A. - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - uint tmp = c.r; - c.r = c.a; - c.a = tmp; - } - } - } - else if (fourcc == FOURCC_ATI1) - { - BlockATI1 block; - mem_read(stream, block); - block.decodeBlock(rgba); - } - else if (fourcc == FOURCC_ATI2) - { - BlockATI2 block; - mem_read(stream, block); - block.decodeBlock(rgba); - } - - // If normal flag set, convert to normal. - if (header.pf.flags & DDPF_NORMAL) - { - if (fourcc == FOURCC_ATI2) - { - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - c = buildNormal(c.r, c.g); - } - } - else if (fourcc == FOURCC_DXT5) - { - for (int i = 0; i < 16; i++) - { - Color32 & c = rgba->color(i); - c = buildNormal(c.a, c.g); - } - } - } + uint fourcc = header.pf.fourcc; + + // Map DX10 block formats to fourcc codes. + if (header.hasDX10Header()) { + if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) + fourcc = FOURCC_DXT1; + if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) + fourcc = FOURCC_DXT3; + if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) + fourcc = FOURCC_DXT5; + if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) + fourcc = FOURCC_ATI1; + if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) + fourcc = FOURCC_ATI2; + } + + if (fourcc == FOURCC_DXT1) { + BlockDXT1 block; + mem_read(stream, block); + block.decodeBlock(rgba); + } + else if (fourcc == FOURCC_DXT2 || header.pf.fourcc == FOURCC_DXT3) { + BlockDXT3 block; + mem_read(stream, block); + block.decodeBlock(rgba); + } + else if (fourcc == FOURCC_DXT4 || header.pf.fourcc == FOURCC_DXT5 || + header.pf.fourcc == FOURCC_RXGB) { + BlockDXT5 block; + mem_read(stream, block); + block.decodeBlock(rgba); + + if (fourcc == FOURCC_RXGB) { + // Swap R & A. + for (int i = 0; i < 16; i++) { + Color32 &c = rgba->color(i); + uint tmp = c.r; + c.r = c.a; + c.a = tmp; + } + } + } + else if (fourcc == FOURCC_ATI1) { + BlockATI1 block; + mem_read(stream, block); + block.decodeBlock(rgba); + } + else if (fourcc == FOURCC_ATI2) { + BlockATI2 block; + mem_read(stream, block); + block.decodeBlock(rgba); + } + + // If normal flag set, convert to normal. + if (header.pf.flags & DDPF_NORMAL) { + if (fourcc == FOURCC_ATI2) { + for (int i = 0; i < 16; i++) { + Color32 &c = rgba->color(i); + c = buildNormal(c.r, c.g); + } + } + else if (fourcc == FOURCC_DXT5) { + for (int i = 0; i < 16; i++) { + Color32 &c = rgba->color(i); + c = buildNormal(c.a, c.g); + } + } + } } - uint DirectDrawSurface::blockSize() const { - switch (header.pf.fourcc) - { - case FOURCC_DXT1: - case FOURCC_ATI1: - return 8; - case FOURCC_DXT2: - case FOURCC_DXT3: - case FOURCC_DXT4: - case FOURCC_DXT5: - case FOURCC_RXGB: - case FOURCC_ATI2: - return 16; - case FOURCC_DX10: - switch (header.header10.dxgiFormat) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - return 8; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - return 16; - }; - }; - - // Not a block image. - return 0; + switch (header.pf.fourcc) { + case FOURCC_DXT1: + case FOURCC_ATI1: + return 8; + case FOURCC_DXT2: + case FOURCC_DXT3: + case FOURCC_DXT4: + case FOURCC_DXT5: + case FOURCC_RXGB: + case FOURCC_ATI2: + return 16; + case FOURCC_DX10: + switch (header.header10.dxgiFormat) { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 8; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + return 16; + }; + }; + + // Not a block image. + return 0; } uint DirectDrawSurface::mipmapSize(uint mipmap) const { - uint w = width(); - uint h = height(); - uint d = depth(); - - for (uint m = 0; m < mipmap; m++) - { - w = MAX(1U, w / 2); - h = MAX(1U, h / 2); - d = MAX(1U, d / 2); - } - - if (header.pf.flags & DDPF_FOURCC) - { - // @@ How are 3D textures aligned? - w = (w + 3) / 4; - h = (h + 3) / 4; - return blockSize() * w * h; - } - else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) - { - uint pitch = computePitch(w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects. - - return pitch * h * d; - } - else { - printf("DDS: mipmap format not supported\n"); - return(0); - }; + uint w = width(); + uint h = height(); + uint d = depth(); + + for (uint m = 0; m < mipmap; m++) { + w = MAX(1U, w / 2); + h = MAX(1U, h / 2); + d = MAX(1U, d / 2); + } + + if (header.pf.flags & DDPF_FOURCC) { + // @@ How are 3D textures aligned? + w = (w + 3) / 4; + h = (h + 3) / 4; + return blockSize() * w * h; + } + else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) { + uint pitch = computePitch( + w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects. + + return pitch * h * d; + } + else { + printf("DDS: mipmap format not supported\n"); + return (0); + }; } uint DirectDrawSurface::faceSize() const { - const uint count = mipmapCount(); - uint size = 0; + const uint count = mipmapCount(); + uint size = 0; - for (uint m = 0; m < count; m++) - { - size += mipmapSize(m); - } + for (uint m = 0; m < count; m++) { + size += mipmapSize(m); + } - return size; + return size; } uint DirectDrawSurface::offset(const uint face, const uint mipmap) { - uint size = 128; // sizeof(DDSHeader); + uint size = 128; // sizeof(DDSHeader); - if (header.hasDX10Header()) - { - size += 20; // sizeof(DDSHeader10); - } + if (header.hasDX10Header()) { + size += 20; // sizeof(DDSHeader10); + } - if (face != 0) - { - size += face * faceSize(); - } + if (face != 0) { + size += face * faceSize(); + } - for (uint m = 0; m < mipmap; m++) - { - size += mipmapSize(m); - } + for (uint m = 0; m < mipmap; m++) { + size += mipmapSize(m); + } - return size; + return size; } - void DirectDrawSurface::printInfo() const { - printf("Flags: 0x%.8X\n", header.flags); - if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n"); - if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n"); - if (header.flags & DDSD_WIDTH) printf("\tDDSD_WIDTH\n"); - if (header.flags & DDSD_HEIGHT) printf("\tDDSD_HEIGHT\n"); - if (header.flags & DDSD_DEPTH) printf("\tDDSD_DEPTH\n"); - if (header.flags & DDSD_PITCH) printf("\tDDSD_PITCH\n"); - if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n"); - if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n"); - - printf("Height: %u\n", header.height); - printf("Width: %u\n", header.width); - printf("Depth: %u\n", header.depth); - if (header.flags & DDSD_PITCH) printf("Pitch: %u\n", header.pitch); - else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %u\n", header.pitch); - printf("Mipmap count: %u\n", header.mipmapcount); - - printf("Pixel Format:\n"); - printf("\tFlags: 0x%.8X\n", header.pf.flags); - if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n"); - if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n"); - if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n"); - if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n"); - if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED1) printf("\t\tDDPF_PALETTEINDEXED1\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED2) printf("\t\tDDPF_PALETTEINDEXED2\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED4) printf("\t\tDDPF_PALETTEINDEXED4\n"); - if (header.pf.flags & DDPF_PALETTEINDEXED8) printf("\t\tDDPF_PALETTEINDEXED8\n"); - if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n"); - if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n"); - - if (header.pf.fourcc != 0) { - // Display fourcc code even when DDPF_FOURCC flag not set. - printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n", - (int)((header.pf.fourcc >> 0) & 0xFF), - (int)((header.pf.fourcc >> 8) & 0xFF), - (int)((header.pf.fourcc >> 16) & 0xFF), - (int)((header.pf.fourcc >> 24) & 0xFF), - header.pf.fourcc); - } - - if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0)) - { - printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", - (int)(header.pf.bitcount >> 0) & 0xFF, - (int)(header.pf.bitcount >> 8) & 0xFF, - (int)(header.pf.bitcount >> 16) & 0xFF, - (int)(header.pf.bitcount >> 24) & 0xFF, - header.pf.bitcount); - } - else - { - printf("\tBit count: %u\n", header.pf.bitcount); - } - - printf("\tRed mask: 0x%.8X\n", header.pf.rmask); - printf("\tGreen mask: 0x%.8X\n", header.pf.gmask); - printf("\tBlue mask: 0x%.8X\n", header.pf.bmask); - printf("\tAlpha mask: 0x%.8X\n", header.pf.amask); - - printf("Caps:\n"); - printf("\tCaps 1: 0x%.8X\n", header.caps.caps1); - if (header.caps.caps1 & DDSCAPS_COMPLEX) printf("\t\tDDSCAPS_COMPLEX\n"); - if (header.caps.caps1 & DDSCAPS_TEXTURE) printf("\t\tDDSCAPS_TEXTURE\n"); - if (header.caps.caps1 & DDSCAPS_MIPMAP) printf("\t\tDDSCAPS_MIPMAP\n"); - - printf("\tCaps 2: 0x%.8X\n", header.caps.caps2); - if (header.caps.caps2 & DDSCAPS2_VOLUME) printf("\t\tDDSCAPS2_VOLUME\n"); - else if (header.caps.caps2 & DDSCAPS2_CUBEMAP) - { - printf("\t\tDDSCAPS2_CUBEMAP\n"); - if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n"); - else { - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n"); - if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n"); - } - } - - printf("\tCaps 3: 0x%.8X\n", header.caps.caps3); - printf("\tCaps 4: 0x%.8X\n", header.caps.caps4); - - if (header.hasDX10Header()) - { - printf("DX10 Header:\n"); - printf("\tDXGI Format: %u (%s)\n", header.header10.dxgiFormat, getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat)); - printf("\tResource dimension: %u (%s)\n", header.header10.resourceDimension, getD3d10ResourceDimensionString((D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension)); - printf("\tMisc flag: %u\n", header.header10.miscFlag); - printf("\tArray size: %u\n", header.header10.arraySize); - } - - if (header.reserved[9] == FOURCC_NVTT) - { - int major = (header.reserved[10] >> 16) & 0xFF; - int minor = (header.reserved[10] >> 8) & 0xFF; - int revision= header.reserved[10] & 0xFF; - - printf("Version:\n"); - printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision); - } - - if (header.reserved[7] == FOURCC_UVER) - { - printf("User Version: %u\n", header.reserved[8]); - } + printf("Flags: 0x%.8X\n", header.flags); + if (header.flags & DDSD_CAPS) + printf("\tDDSD_CAPS\n"); + if (header.flags & DDSD_PIXELFORMAT) + printf("\tDDSD_PIXELFORMAT\n"); + if (header.flags & DDSD_WIDTH) + printf("\tDDSD_WIDTH\n"); + if (header.flags & DDSD_HEIGHT) + printf("\tDDSD_HEIGHT\n"); + if (header.flags & DDSD_DEPTH) + printf("\tDDSD_DEPTH\n"); + if (header.flags & DDSD_PITCH) + printf("\tDDSD_PITCH\n"); + if (header.flags & DDSD_LINEARSIZE) + printf("\tDDSD_LINEARSIZE\n"); + if (header.flags & DDSD_MIPMAPCOUNT) + printf("\tDDSD_MIPMAPCOUNT\n"); + + printf("Height: %u\n", header.height); + printf("Width: %u\n", header.width); + printf("Depth: %u\n", header.depth); + if (header.flags & DDSD_PITCH) + printf("Pitch: %u\n", header.pitch); + else if (header.flags & DDSD_LINEARSIZE) + printf("Linear size: %u\n", header.pitch); + printf("Mipmap count: %u\n", header.mipmapcount); + + printf("Pixel Format:\n"); + printf("\tFlags: 0x%.8X\n", header.pf.flags); + if (header.pf.flags & DDPF_RGB) + printf("\t\tDDPF_RGB\n"); + if (header.pf.flags & DDPF_LUMINANCE) + printf("\t\tDDPF_LUMINANCE\n"); + if (header.pf.flags & DDPF_FOURCC) + printf("\t\tDDPF_FOURCC\n"); + if (header.pf.flags & DDPF_ALPHAPIXELS) + printf("\t\tDDPF_ALPHAPIXELS\n"); + if (header.pf.flags & DDPF_ALPHA) + printf("\t\tDDPF_ALPHA\n"); + if (header.pf.flags & DDPF_PALETTEINDEXED1) + printf("\t\tDDPF_PALETTEINDEXED1\n"); + if (header.pf.flags & DDPF_PALETTEINDEXED2) + printf("\t\tDDPF_PALETTEINDEXED2\n"); + if (header.pf.flags & DDPF_PALETTEINDEXED4) + printf("\t\tDDPF_PALETTEINDEXED4\n"); + if (header.pf.flags & DDPF_PALETTEINDEXED8) + printf("\t\tDDPF_PALETTEINDEXED8\n"); + if (header.pf.flags & DDPF_ALPHAPREMULT) + printf("\t\tDDPF_ALPHAPREMULT\n"); + if (header.pf.flags & DDPF_NORMAL) + printf("\t\tDDPF_NORMAL\n"); + + if (header.pf.fourcc != 0) { + // Display fourcc code even when DDPF_FOURCC flag not set. + printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n", + (int)((header.pf.fourcc >> 0) & 0xFF), + (int)((header.pf.fourcc >> 8) & 0xFF), + (int)((header.pf.fourcc >> 16) & 0xFF), + (int)((header.pf.fourcc >> 24) & 0xFF), + header.pf.fourcc); + } + + if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0)) { + printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", + (int)(header.pf.bitcount >> 0) & 0xFF, + (int)(header.pf.bitcount >> 8) & 0xFF, + (int)(header.pf.bitcount >> 16) & 0xFF, + (int)(header.pf.bitcount >> 24) & 0xFF, + header.pf.bitcount); + } + else { + printf("\tBit count: %u\n", header.pf.bitcount); + } + + printf("\tRed mask: 0x%.8X\n", header.pf.rmask); + printf("\tGreen mask: 0x%.8X\n", header.pf.gmask); + printf("\tBlue mask: 0x%.8X\n", header.pf.bmask); + printf("\tAlpha mask: 0x%.8X\n", header.pf.amask); + + printf("Caps:\n"); + printf("\tCaps 1: 0x%.8X\n", header.caps.caps1); + if (header.caps.caps1 & DDSCAPS_COMPLEX) + printf("\t\tDDSCAPS_COMPLEX\n"); + if (header.caps.caps1 & DDSCAPS_TEXTURE) + printf("\t\tDDSCAPS_TEXTURE\n"); + if (header.caps.caps1 & DDSCAPS_MIPMAP) + printf("\t\tDDSCAPS_MIPMAP\n"); + + printf("\tCaps 2: 0x%.8X\n", header.caps.caps2); + if (header.caps.caps2 & DDSCAPS2_VOLUME) + printf("\t\tDDSCAPS2_VOLUME\n"); + else if (header.caps.caps2 & DDSCAPS2_CUBEMAP) { + printf("\t\tDDSCAPS2_CUBEMAP\n"); + if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) + printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n"); + else { + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) + printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n"); + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) + printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n"); + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) + printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n"); + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) + printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n"); + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) + printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n"); + if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) + printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n"); + } + } + + printf("\tCaps 3: 0x%.8X\n", header.caps.caps3); + printf("\tCaps 4: 0x%.8X\n", header.caps.caps4); + + if (header.hasDX10Header()) { + printf("DX10 Header:\n"); + printf("\tDXGI Format: %u (%s)\n", + header.header10.dxgiFormat, + getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat)); + printf("\tResource dimension: %u (%s)\n", + header.header10.resourceDimension, + getD3d10ResourceDimensionString( + (D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension)); + printf("\tMisc flag: %u\n", header.header10.miscFlag); + printf("\tArray size: %u\n", header.header10.arraySize); + } + + if (header.reserved[9] == FOURCC_NVTT) { + int major = (header.reserved[10] >> 16) & 0xFF; + int minor = (header.reserved[10] >> 8) & 0xFF; + int revision = header.reserved[10] & 0xFF; + + printf("Version:\n"); + printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision); + } + + if (header.reserved[7] == FOURCC_UVER) { + printf("User Version: %u\n", header.reserved[8]); + } } diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 8166e6b0831..54bd1ad2dcd 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -58,136 +57,132 @@ #include struct DDSPixelFormat { - uint size; - uint flags; - uint fourcc; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; + uint size; + uint flags; + uint fourcc; + uint bitcount; + uint rmask; + uint gmask; + uint bmask; + uint amask; }; struct DDSCaps { - uint caps1; - uint caps2; - uint caps3; - uint caps4; + 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; + uint dxgiFormat; + uint resourceDimension; + uint miscFlag; + uint arraySize; + uint reserved; }; /// DDS file header. 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; - uint notused; - DDSHeader10 header10; - - - // Helper methods. - DDSHeader(); - - void setWidth(uint w); - void setHeight(uint h); - void setDepth(uint d); - void setMipmapCount(uint count); - void setTexture2D(); - void setTexture3D(); - void setTextureCube(); - void setLinearSize(uint size); - void setPitch(uint pitch); - void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); - void setFormatCode(uint code); - void setSwizzleCode(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 setSrgbFlag(bool b); - void setHasAlphaFlag(bool b); - void setUserVersion(int version); - - /*void swapBytes();*/ - - bool hasDX10Header() const; - uint signature() const; - uint toolVersion() const; - uint userVersion() const; - bool isNormalMap() const; - bool isSrgb() const; - bool hasAlpha() const; - uint d3d9Format() const; + uint fourcc; + uint size; + uint flags; + uint height; + uint width; + uint pitch; + uint depth; + uint mipmapcount; + uint reserved[11]; + DDSPixelFormat pf; + DDSCaps caps; + uint notused; + DDSHeader10 header10; + + // Helper methods. + DDSHeader(); + + void setWidth(uint w); + void setHeight(uint h); + void setDepth(uint d); + void setMipmapCount(uint count); + void setTexture2D(); + void setTexture3D(); + void setTextureCube(); + void setLinearSize(uint size); + void setPitch(uint pitch); + void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); + void setFormatCode(uint code); + void setSwizzleCode(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 setSrgbFlag(bool b); + void setHasAlphaFlag(bool b); + void setUserVersion(int version); + + /*void swapBytes();*/ + + bool hasDX10Header() const; + uint signature() const; + uint toolVersion() const; + uint userVersion() const; + bool isNormalMap() const; + bool isSrgb() const; + bool hasAlpha() const; + uint d3d9Format() const; }; /// DirectDraw Surface. (DDS) -class DirectDrawSurface -{ -public: - DirectDrawSurface(unsigned char *mem, uint size); - ~DirectDrawSurface(); - - bool isValid() const; - bool isSupported() const; - - bool hasAlpha() const; - - uint mipmapCount() const; - uint fourCC() const; - uint width() const; - uint height() const; - uint depth() const; - bool isTexture1D() const; - bool isTexture2D() const; - bool isTexture3D() const; - bool isTextureCube() const; - - void setNormalFlag(bool b); - void setHasAlphaFlag(bool b); - void setUserVersion(int version); - - void mipmap(Image *img, uint f, uint m); - void *readData(uint &size); - // void mipmap(FloatImage *img, uint f, uint m); - - void printInfo() const; - -private: - - uint blockSize() const; - uint faceSize() const; - uint mipmapSize(uint m) const; - - uint offset(uint f, uint m); - - void readLinearImage(Image * img); - void readBlockImage(Image * img); - void readBlock(ColorBlock * rgba); - - -private: - Stream stream; // memory where DDS file resides - DDSHeader header; +class DirectDrawSurface { + public: + DirectDrawSurface(unsigned char *mem, uint size); + ~DirectDrawSurface(); + + bool isValid() const; + bool isSupported() const; + + bool hasAlpha() const; + + uint mipmapCount() const; + uint fourCC() const; + uint width() const; + uint height() const; + uint depth() const; + bool isTexture1D() const; + bool isTexture2D() const; + bool isTexture3D() const; + bool isTextureCube() const; + + void setNormalFlag(bool b); + void setHasAlphaFlag(bool b); + void setUserVersion(int version); + + void mipmap(Image *img, uint f, uint m); + void *readData(uint &size); + // void mipmap(FloatImage *img, uint f, uint m); + + void printInfo() const; + + private: + uint blockSize() const; + uint faceSize() const; + uint mipmapSize(uint m) const; + + uint offset(uint f, uint m); + + void readLinearImage(Image *img); + void readBlockImage(Image *img); + void readBlock(ColorBlock *rgba); + + private: + Stream stream; // memory where DDS file resides + DDSHeader header; }; -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); +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 /* __DIRECTDRAWSURFACE_H__ */ +#endif /* __DIRECTDRAWSURFACE_H__ */ diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp index 50488b923db..0660d5ce5cc 100644 --- a/source/blender/imbuf/intern/dds/FlipDXT.cpp +++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp @@ -50,207 +50,205 @@ typedef void (*FlipBlockFunction)(uint8_t *block); // Flips a full DXT1 block in the y direction. static void FlipDXT1BlockFull(uint8_t *block) { - // A DXT1 block layout is: - // [0-1] color0. - // [2-3] color1. - // [4-7] color bitmap, 2 bits per pixel. - // So each of the 4-7 bytes represents one line, flipping a block is just - // flipping those bytes. - uint8_t tmp = block[4]; - block[4] = block[7]; - block[7] = tmp; - tmp = block[5]; - block[5] = block[6]; - block[6] = tmp; + // A DXT1 block layout is: + // [0-1] color0. + // [2-3] color1. + // [4-7] color bitmap, 2 bits per pixel. + // So each of the 4-7 bytes represents one line, flipping a block is just + // flipping those bytes. + uint8_t tmp = block[4]; + block[4] = block[7]; + block[7] = tmp; + tmp = block[5]; + block[5] = block[6]; + block[6] = tmp; } // Flips the first 2 lines of a DXT1 block in the y direction. static void FlipDXT1BlockHalf(uint8_t *block) { - // See layout above. - uint8_t tmp = block[4]; - block[4] = block[5]; - block[5] = tmp; + // See layout above. + uint8_t tmp = block[4]; + block[4] = block[5]; + block[5] = tmp; } // Flips a full DXT3 block in the y direction. static void FlipDXT3BlockFull(uint8_t *block) { - // A DXT3 block layout is: - // [0-7] alpha bitmap, 4 bits per pixel. - // [8-15] a DXT1 block. - - // We can flip the alpha bits at the byte level (2 bytes per line). - uint8_t tmp = block[0]; - - block[0] = block[6]; - block[6] = tmp; - tmp = block[1]; - block[1] = block[7]; - block[7] = tmp; - tmp = block[2]; - block[2] = block[4]; - block[4] = tmp; - tmp = block[3]; - block[3] = block[5]; - block[5] = tmp; - - // And flip the DXT1 block using the above function. - FlipDXT1BlockFull(block + 8); + // A DXT3 block layout is: + // [0-7] alpha bitmap, 4 bits per pixel. + // [8-15] a DXT1 block. + + // We can flip the alpha bits at the byte level (2 bytes per line). + uint8_t tmp = block[0]; + + block[0] = block[6]; + block[6] = tmp; + tmp = block[1]; + block[1] = block[7]; + block[7] = tmp; + tmp = block[2]; + block[2] = block[4]; + block[4] = tmp; + tmp = block[3]; + block[3] = block[5]; + block[5] = tmp; + + // And flip the DXT1 block using the above function. + FlipDXT1BlockFull(block + 8); } // Flips the first 2 lines of a DXT3 block in the y direction. static void FlipDXT3BlockHalf(uint8_t *block) { - // See layout above. - uint8_t tmp = block[0]; - - block[0] = block[2]; - block[2] = tmp; - tmp = block[1]; - block[1] = block[3]; - block[3] = tmp; - FlipDXT1BlockHalf(block + 8); + // See layout above. + uint8_t tmp = block[0]; + + block[0] = block[2]; + block[2] = tmp; + tmp = block[1]; + block[1] = block[3]; + block[3] = tmp; + FlipDXT1BlockHalf(block + 8); } // Flips a full DXT5 block in the y direction. static void FlipDXT5BlockFull(uint8_t *block) { - // A DXT5 block layout is: - // [0] alpha0. - // [1] alpha1. - // [2-7] alpha bitmap, 3 bits per pixel. - // [8-15] a DXT1 block. - - // The alpha bitmap doesn't easily map lines to bytes, so we have to - // interpret it correctly. Extracted from - // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt : - // - // The 6 "bits" bytes of the block are decoded into one 48-bit integer: - // - // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + - // 256 * (bits_4 + 256 * bits_5)))) - // - // bits is a 48-bit unsigned integer, from which a three-bit control code - // is extracted for a texel at location (x,y) in the block using: - // - // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] - // - // where bit 47 is the most significant and bit 0 is the least - // significant bit. - unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); - unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]); - // swap lines 0 and 1 in line_0_1. - unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | - ((line_0_1 & 0xfff000) >> 12); - // swap lines 2 and 3 in line_2_3. - unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | - ((line_2_3 & 0xfff000) >> 12); - - block[2] = line_3_2 & 0xff; - block[3] = (line_3_2 & 0xff00) >> 8; - block[4] = (line_3_2 & 0xff0000) >> 16; - block[5] = line_1_0 & 0xff; - block[6] = (line_1_0 & 0xff00) >> 8; - block[7] = (line_1_0 & 0xff0000) >> 16; - - // And flip the DXT1 block using the above function. - FlipDXT1BlockFull(block + 8); + // A DXT5 block layout is: + // [0] alpha0. + // [1] alpha1. + // [2-7] alpha bitmap, 3 bits per pixel. + // [8-15] a DXT1 block. + + // The alpha bitmap doesn't easily map lines to bytes, so we have to + // interpret it correctly. Extracted from + // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt : + // + // The 6 "bits" bytes of the block are decoded into one 48-bit integer: + // + // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + + // 256 * (bits_4 + 256 * bits_5)))) + // + // bits is a 48-bit unsigned integer, from which a three-bit control code + // is extracted for a texel at location (x,y) in the block using: + // + // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] + // + // where bit 47 is the most significant and bit 0 is the least + // significant bit. + unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); + unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]); + // swap lines 0 and 1 in line_0_1. + unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12); + // swap lines 2 and 3 in line_2_3. + unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | ((line_2_3 & 0xfff000) >> 12); + + block[2] = line_3_2 & 0xff; + block[3] = (line_3_2 & 0xff00) >> 8; + block[4] = (line_3_2 & 0xff0000) >> 16; + block[5] = line_1_0 & 0xff; + block[6] = (line_1_0 & 0xff00) >> 8; + block[7] = (line_1_0 & 0xff0000) >> 16; + + // And flip the DXT1 block using the above function. + FlipDXT1BlockFull(block + 8); } // Flips the first 2 lines of a DXT5 block in the y direction. static void FlipDXT5BlockHalf(uint8_t *block) { - // See layout above. - unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); - unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | - ((line_0_1 & 0xfff000) >> 12); - block[2] = line_1_0 & 0xff; - block[3] = (line_1_0 & 0xff00) >> 8; - block[4] = (line_1_0 & 0xff0000) >> 16; - FlipDXT1BlockHalf(block + 8); + // See layout above. + unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); + unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12); + block[2] = line_1_0 & 0xff; + block[3] = (line_1_0 & 0xff00) >> 8; + block[4] = (line_1_0 & 0xff0000) >> 16; + FlipDXT1BlockHalf(block + 8); } // Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate. -int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data) +int FlipDXTCImage( + unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data) { - // must have valid dimensions - if (width == 0 || height == 0) - return 0; - // height must be a power-of-two - if ((height & (height - 1)) != 0) - return 0; - - FlipBlockFunction full_block_function; - FlipBlockFunction half_block_function; - unsigned int block_bytes = 0; - - switch (fourcc) { - case FOURCC_DXT1: - full_block_function = FlipDXT1BlockFull; - half_block_function = FlipDXT1BlockHalf; - block_bytes = 8; - break; - case FOURCC_DXT3: - full_block_function = FlipDXT3BlockFull; - half_block_function = FlipDXT3BlockHalf; - block_bytes = 16; - break; - case FOURCC_DXT5: - full_block_function = FlipDXT5BlockFull; - half_block_function = FlipDXT5BlockHalf; - block_bytes = 16; - break; - default: - return 0; - } - - unsigned int mip_width = width; - unsigned int mip_height = height; - - for (unsigned int i = 0; i < levels; ++i) { - unsigned int blocks_per_row = (mip_width + 3) / 4; - unsigned int blocks_per_col = (mip_height + 3) / 4; - unsigned int blocks = blocks_per_row * blocks_per_col; - - if (mip_height == 1) { - // no flip to do, and we're done. - break; - } - else if (mip_height == 2) { - // flip the first 2 lines in each block. - for (unsigned int i = 0; i < blocks_per_row; ++i) { - half_block_function(data + i * block_bytes); - } - } - else { - // flip each block. - for (unsigned int i = 0; i < blocks; ++i) - full_block_function(data + i * block_bytes); - - // swap each block line in the first half of the image with the - // corresponding one in the second half. - // note that this is a no-op if mip_height is 4. - unsigned int row_bytes = block_bytes * blocks_per_row; - uint8_t *temp_line = new uint8_t[row_bytes]; - - for (unsigned int y = 0; y < blocks_per_col / 2; ++y) { - uint8_t *line1 = data + y * row_bytes; - uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes; - - memcpy(temp_line, line1, row_bytes); - memcpy(line1, line2, row_bytes); - memcpy(line2, temp_line, row_bytes); - } - - delete[] temp_line; - } - - // mip levels are contiguous. - data += block_bytes * blocks; - mip_width = MAX(1U, mip_width >> 1); - mip_height = MAX(1U, mip_height >> 1); - } - - return 1; + // must have valid dimensions + if (width == 0 || height == 0) + return 0; + // height must be a power-of-two + if ((height & (height - 1)) != 0) + return 0; + + FlipBlockFunction full_block_function; + FlipBlockFunction half_block_function; + unsigned int block_bytes = 0; + + switch (fourcc) { + case FOURCC_DXT1: + full_block_function = FlipDXT1BlockFull; + half_block_function = FlipDXT1BlockHalf; + block_bytes = 8; + break; + case FOURCC_DXT3: + full_block_function = FlipDXT3BlockFull; + half_block_function = FlipDXT3BlockHalf; + block_bytes = 16; + break; + case FOURCC_DXT5: + full_block_function = FlipDXT5BlockFull; + half_block_function = FlipDXT5BlockHalf; + block_bytes = 16; + break; + default: + return 0; + } + + unsigned int mip_width = width; + unsigned int mip_height = height; + + for (unsigned int i = 0; i < levels; ++i) { + unsigned int blocks_per_row = (mip_width + 3) / 4; + unsigned int blocks_per_col = (mip_height + 3) / 4; + unsigned int blocks = blocks_per_row * blocks_per_col; + + if (mip_height == 1) { + // no flip to do, and we're done. + break; + } + else if (mip_height == 2) { + // flip the first 2 lines in each block. + for (unsigned int i = 0; i < blocks_per_row; ++i) { + half_block_function(data + i * block_bytes); + } + } + else { + // flip each block. + for (unsigned int i = 0; i < blocks; ++i) + full_block_function(data + i * block_bytes); + + // swap each block line in the first half of the image with the + // corresponding one in the second half. + // note that this is a no-op if mip_height is 4. + unsigned int row_bytes = block_bytes * blocks_per_row; + uint8_t *temp_line = new uint8_t[row_bytes]; + + for (unsigned int y = 0; y < blocks_per_col / 2; ++y) { + uint8_t *line1 = data + y * row_bytes; + uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes; + + memcpy(temp_line, line1, row_bytes); + memcpy(line1, line2, row_bytes); + memcpy(line2, temp_line, row_bytes); + } + + delete[] temp_line; + } + + // mip levels are contiguous. + data += block_bytes * blocks; + mip_width = MAX(1U, mip_width >> 1); + mip_height = MAX(1U, mip_height >> 1); + } + + return 1; } diff --git a/source/blender/imbuf/intern/dds/FlipDXT.h b/source/blender/imbuf/intern/dds/FlipDXT.h index 7d70395f1fa..b7056742430 100644 --- a/source/blender/imbuf/intern/dds/FlipDXT.h +++ b/source/blender/imbuf/intern/dds/FlipDXT.h @@ -20,6 +20,7 @@ #include "BLI_sys_types.h" /* flip compressed DXT image vertically to fit OpenGL convention */ -int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data); +int FlipDXTCImage( + unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data); #endif diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp index 642194fa39b..6f0fff75818 100644 --- a/source/blender/imbuf/intern/dds/Image.cpp +++ b/source/blender/imbuf/intern/dds/Image.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -31,7 +30,7 @@ #include #include -#include // printf +#include // printf Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL) { @@ -39,87 +38,86 @@ Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL) Image::~Image() { - free(); + free(); } void Image::allocate(uint w, uint h) { - free(); - m_width = w; - m_height = h; - m_data = new Color32[w * h]; + free(); + m_width = w; + m_height = h; + m_data = new Color32[w * h]; } void Image::free() { - if (m_data) delete [] m_data; - m_data = NULL; + if (m_data) + delete[] m_data; + m_data = NULL; } - uint Image::width() const { - return m_width; + return m_width; } uint Image::height() const { - return m_height; + return m_height; } -const Color32 * Image::scanline(uint h) const +const Color32 *Image::scanline(uint h) const { - if (h >= m_height) { - printf("DDS: scanline beyond dimensions of image\n"); - return m_data; - } - return m_data + h * m_width; + if (h >= m_height) { + printf("DDS: scanline beyond dimensions of image\n"); + return m_data; + } + return m_data + h * m_width; } Color32 *Image::scanline(uint h) { - if (h >= m_height) { - printf("DDS: scanline beyond dimensions of image\n"); - return m_data; - } - return m_data + h * m_width; + if (h >= m_height) { + printf("DDS: scanline beyond dimensions of image\n"); + return m_data; + } + return m_data + h * m_width; } const Color32 *Image::pixels() const { - return m_data; + return m_data; } Color32 *Image::pixels() { - return m_data; + return m_data; } -const Color32 & Image::pixel(uint idx) const +const Color32 &Image::pixel(uint idx) const { - if (idx >= m_width * m_height) { - printf("DDS: pixel beyond dimensions of image\n"); - return m_data[0]; - } - return m_data[idx]; + if (idx >= m_width * m_height) { + printf("DDS: pixel beyond dimensions of image\n"); + return m_data[0]; + } + return m_data[idx]; } -Color32 & Image::pixel(uint idx) +Color32 &Image::pixel(uint idx) { - if (idx >= m_width * m_height) { - printf("DDS: pixel beyond dimensions of image\n"); - return m_data[0]; - } - return m_data[idx]; + if (idx >= m_width * m_height) { + printf("DDS: pixel beyond dimensions of image\n"); + return m_data[0]; + } + return m_data[idx]; } - Image::Format Image::format() const { - return m_format; + return m_format; } void Image::setFormat(Image::Format f) { - m_format = f; + m_format = f; } diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index fa8cacd3142..b6191b7e96c 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -35,64 +34,60 @@ #include /// 32 bit RGBA image. -class Image -{ -public: +class Image { + public: + enum Format { + Format_RGB, + Format_ARGB, + }; - enum Format - { - Format_RGB, - Format_ARGB, - }; + Image(); + ~Image(); - Image(); - ~Image(); - - void allocate(uint w, uint h); + void allocate(uint w, uint h); #if 0 - bool load(const char *name); + bool load(const char *name); - void wrap(void *data, uint w, uint h); - void unwrap(); + void wrap(void *data, uint w, uint h); + void unwrap(); #endif - uint width() const; - uint height() const; + uint width() const; + uint height() const; - const Color32 *scanline(uint h) const; - Color32 *scanline(uint h); + const Color32 *scanline(uint h) const; + Color32 *scanline(uint h); - const Color32 *pixels() const; - Color32 *pixels(); + const Color32 *pixels() const; + Color32 *pixels(); - const Color32 & pixel(uint idx) const; - Color32 & pixel(uint idx); + const Color32 &pixel(uint idx) const; + Color32 &pixel(uint idx); - const Color32 & pixel(uint x, uint y) const; - Color32 & pixel(uint x, uint y); + const Color32 &pixel(uint x, uint y) const; + Color32 &pixel(uint x, uint y); - Format format() const; - void setFormat(Format f); + Format format() const; + void setFormat(Format f); -private: - void free(); + private: + void free(); -private: - uint m_width; - uint m_height; - Format m_format; - Color32 *m_data; + private: + uint m_width; + uint m_height; + Format m_format; + Color32 *m_data; }; - -inline const Color32 & Image::pixel(uint x, uint y) const +inline const Color32 &Image::pixel(uint x, uint y) const { - return pixel(y * width() + x); + return pixel(y * width() + x); } -inline Color32 & Image::pixel(uint x, uint y) +inline Color32 &Image::pixel(uint x, uint y) { - return pixel(y * width() + x); + return pixel(y * width() + x); } -#endif /* __IMAGE_H__ */ +#endif /* __IMAGE_H__ */ diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h index 7c50245858f..07912b86f47 100644 --- a/source/blender/imbuf/intern/dds/PixelFormat.h +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) @@ -54,79 +53,78 @@ #include - 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; - } - } - - inline float quantizeCeil(float f, int inbits, int outbits) - { - //uint i = f * (float(1 << inbits) - 1); - //i = convert(i, inbits, outbits); - //float result = float(i) / (float(1 << outbits) - 1); - //nvCheck(result >= f); - float result; - int offset = 0; - do { - uint i = offset + uint(f * (float(1 << inbits) - 1)); - i = convert(i, inbits, outbits); - result = float(i) / (float(1 << outbits) - 1); - offset++; - } while (result < f); - - return result; - } +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; + } +} + +inline float quantizeCeil(float f, int inbits, int outbits) +{ + //uint i = f * (float(1 << inbits) - 1); + //i = convert(i, inbits, outbits); + //float result = float(i) / (float(1 << outbits) - 1); + //nvCheck(result >= f); + float result; + int offset = 0; + do { + uint i = offset + uint(f * (float(1 << inbits) - 1)); + i = convert(i, inbits, outbits); + result = float(i) / (float(1 << outbits) - 1); + offset++; + } while (result < f); + + return result; +} #if 0 - inline float quantizeRound(float f, int bits) - { - float scale = float(1 << bits); - return fround(f * scale) / scale; - } - - inline float quantizeFloor(float f, int bits) - { - float scale = float(1 << bits); - return floor(f * scale) / scale; - } + inline float quantizeRound(float f, int bits) + { + float scale = float(1 << bits); + return fround(f * scale) / scale; + } + + inline float quantizeFloor(float f, int bits) + { + float scale = float(1 << bits); + return floor(f * scale) / scale; + } #endif - } // PixelFormat namespace +} // namespace PixelFormat -#endif /* __PIXELFORMAT_H__ */ +#endif /* __PIXELFORMAT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp index 993fa7734ba..271717f165c 100644 --- a/source/blender/imbuf/intern/dds/Stream.cpp +++ b/source/blender/imbuf/intern/dds/Stream.cpp @@ -18,86 +18,85 @@ * \ingroup imbdds */ - #include -#include // printf -#include // memcpy +#include // printf +#include // memcpy static const char *msg_error_seek = "DDS: trying to seek beyond end of stream (corrupt file?)"; static const char *msg_error_read = "DDS: trying to read beyond end of stream (corrupt file?)"; unsigned int Stream::seek(unsigned int p) { - if (p > size) { - set_failed(msg_error_seek); - } - else { - pos = p; - } + if (p > size) { + set_failed(msg_error_seek); + } + else { + pos = p; + } - return pos; + return pos; } -unsigned int mem_read(Stream & mem, unsigned long long & i) +unsigned int mem_read(Stream &mem, unsigned long long &i) { - if (mem.pos + 8 > mem.size) { - mem.set_failed(msg_error_seek); - return(0); - } - memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian - mem.pos += 8; - return(8); + if (mem.pos + 8 > mem.size) { + mem.set_failed(msg_error_seek); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian + mem.pos += 8; + return (8); } -unsigned int mem_read(Stream & mem, unsigned int & i) +unsigned int mem_read(Stream &mem, unsigned int &i) { - if (mem.pos + 4 > mem.size) { - mem.set_failed(msg_error_read); - return(0); - } - memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian - mem.pos += 4; - return(4); + if (mem.pos + 4 > mem.size) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian + mem.pos += 4; + return (4); } -unsigned int mem_read(Stream & mem, unsigned short & i) +unsigned int mem_read(Stream &mem, unsigned short &i) { - if (mem.pos + 2 > mem.size) { - mem.set_failed(msg_error_read); - return(0); - } - memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian - mem.pos += 2; - return(2); + if (mem.pos + 2 > mem.size) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian + mem.pos += 2; + return (2); } -unsigned int mem_read(Stream & mem, unsigned char & i) +unsigned int mem_read(Stream &mem, unsigned char &i) { - if (mem.pos + 1 > mem.size) { - mem.set_failed(msg_error_read); - return(0); - } - i = (mem.mem + mem.pos)[0]; - mem.pos += 1; - return(1); + if (mem.pos + 1 > mem.size) { + mem.set_failed(msg_error_read); + return (0); + } + i = (mem.mem + mem.pos)[0]; + mem.pos += 1; + return (1); } -unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt) +unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt) { - if (mem.pos + cnt > mem.size) { - mem.set_failed(msg_error_read); - return(0); - } - memcpy(i, mem.mem + mem.pos, cnt); - mem.pos += cnt; - return(cnt); + if (mem.pos + cnt > mem.size) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(i, mem.mem + mem.pos, cnt); + mem.pos += cnt; + return (cnt); } void Stream::set_failed(const char *msg) { - if (!failed) { - puts(msg); - failed = true; - } + if (!failed) { + puts(msg); + failed = true; + } } diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h index b9fba2ef8b2..35662e8f24e 100644 --- a/source/blender/imbuf/intern/dds/Stream.h +++ b/source/blender/imbuf/intern/dds/Stream.h @@ -18,26 +18,27 @@ * \ingroup imbdds */ - /* simple memory stream functions with buffer overflow check */ #ifndef __STREAM_H__ #define __STREAM_H__ struct Stream { - unsigned char *mem; // location in memory - unsigned int size; // size - unsigned int pos; // current position - bool failed; // error occured when seeking - Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0), failed(false) {} - unsigned int seek(unsigned int p); - void set_failed(const char *msg); + unsigned char *mem; // location in memory + unsigned int size; // size + unsigned int pos; // current position + bool failed; // error occured when seeking + Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0), failed(false) + { + } + unsigned int seek(unsigned int p); + void set_failed(const char *msg); }; -unsigned int mem_read(Stream & mem, unsigned long long & i); -unsigned int mem_read(Stream & mem, unsigned int & i); -unsigned int mem_read(Stream & mem, unsigned short & i); -unsigned int mem_read(Stream & mem, unsigned char & i); -unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt); +unsigned int mem_read(Stream &mem, unsigned long long &i); +unsigned int mem_read(Stream &mem, unsigned int &i); +unsigned int mem_read(Stream &mem, unsigned short &i); +unsigned int mem_read(Stream &mem, unsigned char &i); +unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt); -#endif /* __STREAM_H__ */ +#endif /* __STREAM_H__ */ diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp index fa88f81b55a..6a76e231e37 100644 --- a/source/blender/imbuf/intern/dds/dds_api.cpp +++ b/source/blender/imbuf/intern/dds/dds_api.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - extern "C" { #include "BLI_utildefines.h" } @@ -28,11 +27,11 @@ extern "C" { #include #include #include -#include // printf +#include // printf #include -#if defined (WIN32) -#include "utfconv.h" +#if defined(WIN32) +# include "utfconv.h" #endif extern "C" { @@ -47,138 +46,149 @@ extern "C" { int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/) { - return(0); /* todo: finish this function */ + return (0); /* todo: finish this function */ - /* check image buffer */ - if (ibuf == 0) return (0); - if (ibuf->rect == 0) return (0); + /* check image buffer */ + if (ibuf == 0) + return (0); + if (ibuf->rect == 0) + return (0); - /* open file for writing */ - std::ofstream fildes; + /* open file for writing */ + std::ofstream fildes; -#if defined (WIN32) - wchar_t *wname = alloc_utf16_from_8(name, 0); - fildes.open(wname); - free(wname); +#if defined(WIN32) + wchar_t *wname = alloc_utf16_from_8(name, 0); + fildes.open(wname); + free(wname); #else - fildes.open(name); + fildes.open(name); #endif - /* write header */ - fildes << "DDS "; - fildes.close(); + /* write header */ + fildes << "DDS "; + fildes.close(); - return(1); + return (1); } -int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes +int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes { - /* heuristic check to see if mem contains a DDS file */ - /* header.fourcc == FOURCC_DDS */ - if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0); - /* header.size == 124 */ - if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0); - return(1); + /* heuristic check to see if mem contains a DDS file */ + /* header.fourcc == FOURCC_DDS */ + if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) + return (0); + /* header.size == 124 */ + if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) + return (0); + return (1); } -struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +struct ImBuf *imb_load_dds(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]) { - struct ImBuf *ibuf = NULL; - DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */ - unsigned char bits_per_pixel; - unsigned int *rect; - Image img; - unsigned int numpixels = 0; - int col; - unsigned char *cp = (unsigned char *) &col; - Color32 pixel; - Color32 *pixels = 0; - - /* OCIO_TODO: never was able to save DDS, so can't test loading - * but profile used to be set to sRGB and can't see rect_float here, so - * default byte space should work fine - */ - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - if (!imb_is_a_dds(mem)) - return (0); - - /* check if DDS is valid and supported */ - if (!dds.isValid()) { - /* no need to print error here, just testing if it is a DDS */ - if (flags & IB_test) - return (0); - - printf("DDS: not valid; header follows\n"); - dds.printInfo(); - return(0); - } - if (!dds.isSupported()) { - printf("DDS: format not supported\n"); - return(0); - } - if ((dds.width() > 65535) || (dds.height() > 65535)) { - printf("DDS: dimensions too large\n"); - return(0); - } - - /* convert DDS into ImBuf */ - dds.mipmap(&img, 0, 0); /* load first face, first mipmap */ - pixels = img.pixels(); - numpixels = dds.width() * dds.height(); - bits_per_pixel = 24; - if (img.format() == Image::Format_ARGB) { - /* check that there is effectively an alpha channel */ - for (unsigned int i = 0; i < numpixels; i++) { - pixel = pixels[i]; - if (pixel.a != 255) { - bits_per_pixel = 32; - break; - } - } - } - ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); - if (ibuf == 0) return(0); /* memory allocation failed */ - - ibuf->ftype = IMB_FTYPE_DDS; - ibuf->dds_data.fourcc = dds.fourCC(); - ibuf->dds_data.nummipmaps = dds.mipmapCount(); - - if ((flags & IB_test) == 0) { - if (!imb_addrectImBuf(ibuf)) return(ibuf); - if (ibuf->rect == 0) return(ibuf); - - rect = ibuf->rect; - cp[3] = 0xff; /* default alpha if alpha channel is not present */ - - for (unsigned int i = 0; i < numpixels; i++) { - pixel = pixels[i]; - cp[0] = pixel.r; /* set R component of col */ - cp[1] = pixel.g; /* set G component of col */ - cp[2] = pixel.b; /* set B component of col */ - if (dds.hasAlpha()) - cp[3] = pixel.a; /* set A component of col */ - rect[i] = col; - } - - if (ibuf->dds_data.fourcc != FOURCC_DDS) { - ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size); - - /* flip compressed texture */ - if (ibuf->dds_data.data) { - FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data); - } - } - else { - ibuf->dds_data.data = NULL; - ibuf->dds_data.size = 0; - } - - /* flip uncompressed texture */ - IMB_flipy(ibuf); - } - - return(ibuf); + struct ImBuf *ibuf = NULL; + DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */ + unsigned char bits_per_pixel; + unsigned int *rect; + Image img; + unsigned int numpixels = 0; + int col; + unsigned char *cp = (unsigned char *)&col; + Color32 pixel; + Color32 *pixels = 0; + + /* OCIO_TODO: never was able to save DDS, so can't test loading + * but profile used to be set to sRGB and can't see rect_float here, so + * default byte space should work fine + */ + colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); + + if (!imb_is_a_dds(mem)) + return (0); + + /* check if DDS is valid and supported */ + if (!dds.isValid()) { + /* no need to print error here, just testing if it is a DDS */ + if (flags & IB_test) + return (0); + + printf("DDS: not valid; header follows\n"); + dds.printInfo(); + return (0); + } + if (!dds.isSupported()) { + printf("DDS: format not supported\n"); + return (0); + } + if ((dds.width() > 65535) || (dds.height() > 65535)) { + printf("DDS: dimensions too large\n"); + return (0); + } + + /* convert DDS into ImBuf */ + dds.mipmap(&img, 0, 0); /* load first face, first mipmap */ + pixels = img.pixels(); + numpixels = dds.width() * dds.height(); + bits_per_pixel = 24; + if (img.format() == Image::Format_ARGB) { + /* check that there is effectively an alpha channel */ + for (unsigned int i = 0; i < numpixels; i++) { + pixel = pixels[i]; + if (pixel.a != 255) { + bits_per_pixel = 32; + break; + } + } + } + ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); + if (ibuf == 0) + return (0); /* memory allocation failed */ + + ibuf->ftype = IMB_FTYPE_DDS; + ibuf->dds_data.fourcc = dds.fourCC(); + ibuf->dds_data.nummipmaps = dds.mipmapCount(); + + if ((flags & IB_test) == 0) { + if (!imb_addrectImBuf(ibuf)) + return (ibuf); + if (ibuf->rect == 0) + return (ibuf); + + rect = ibuf->rect; + cp[3] = 0xff; /* default alpha if alpha channel is not present */ + + for (unsigned int i = 0; i < numpixels; i++) { + pixel = pixels[i]; + cp[0] = pixel.r; /* set R component of col */ + cp[1] = pixel.g; /* set G component of col */ + cp[2] = pixel.b; /* set B component of col */ + if (dds.hasAlpha()) + cp[3] = pixel.a; /* set A component of col */ + rect[i] = col; + } + + if (ibuf->dds_data.fourcc != FOURCC_DDS) { + ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size); + + /* flip compressed texture */ + if (ibuf->dds_data.data) { + FlipDXTCImage( + dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data); + } + } + else { + ibuf->dds_data.data = NULL; + ibuf->dds_data.size = 0; + } + + /* flip uncompressed texture */ + IMB_flipy(ibuf); + } + + return (ibuf); } -} // extern "C" +} // extern "C" diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h index cbe19ab3e90..12db8aa6416 100644 --- a/source/blender/imbuf/intern/dds/dds_api.h +++ b/source/blender/imbuf/intern/dds/dds_api.h @@ -18,7 +18,6 @@ * \ingroup imbdds */ - #ifndef __DDS_API_H__ #define __DDS_API_H__ @@ -28,9 +27,12 @@ extern "C" { #include "../../IMB_imbuf.h" -int imb_is_a_dds(const unsigned char *mem); /* use only first 32 bytes of mem */ -int imb_save_dds(struct ImBuf *ibuf, const char *name, int flags); -struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); +int imb_is_a_dds(const unsigned char *mem); /* use only first 32 bytes of mem */ +int imb_save_dds(struct ImBuf *ibuf, const char *name, int flags); +struct ImBuf *imb_load_dds(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); #ifdef __cplusplus } -- cgit v1.2.3