This commit is a modified version of patch #6860
authorKent Mein <mein@cs.umn.edu>
Mon, 25 Jun 2007 19:50:25 +0000 (19:50 +0000)
committerKent Mein <mein@cs.umn.edu>
Mon, 25 Jun 2007 19:50:25 +0000 (19:50 +0000)
It adds read only dds support.  (Writing will come later)

Kent

42 files changed:
config/darwin-config.py
config/linux2-config.py
config/linuxcross-config.py
config/openbsd3-config.py
config/sunos5-config.py
config/win32-mingw-config.py
config/win32-vc-config.py
source/Makefile
source/blender/SConscript
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/Makefile
source/blender/blenkernel/intern/image.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/SConscript
source/blender/imbuf/intern/Makefile
source/blender/imbuf/intern/dds/BlockDXT.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/BlockDXT.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/Color.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/ColorBlock.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/ColorBlock.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/Common.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/DirectDrawSurface.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/DirectDrawSurface.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/Image.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/Image.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/Makefile [new file with mode: 0644]
source/blender/imbuf/intern/dds/SConscript [new file with mode: 0644]
source/blender/imbuf/intern/dds/Stream.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/Stream.h [new file with mode: 0644]
source/blender/imbuf/intern/dds/dds_api.cpp [new file with mode: 0644]
source/blender/imbuf/intern/dds/dds_api.h [new file with mode: 0644]
source/blender/imbuf/intern/readimage.c
source/blender/imbuf/intern/util.c
source/blender/imbuf/intern/writeimage.c
source/blender/makesdna/DNA_scene_types.h
source/blender/src/Makefile
source/blender/src/SConscript
source/blender/src/buttons_scene.c
source/blender/src/filesel.c
source/blender/src/writeimage.c
source/nan_definitions.mk
tools/btools.py

index 86135a3f46f0d5b52fc161914df8c90c377d03b5..9d2a797898eae81b50733ea34a4bb7ec459bf810 100644 (file)
@@ -52,6 +52,7 @@ BF_OPENEXR = '/usr/local'
 BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
 BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
 
+WITH_BF_DDS = 'true'
 
 WITH_BF_JPEG = 'true'
 BF_JPEG = LIBDIR + '/jpeg'
index a041f518ba70654a8ad144bb3df2e12d1ed08089..edc7f26c690eb889fcf166f89456812e384b6248 100644 (file)
@@ -32,6 +32,8 @@ BF_OPENEXR = '/usr'
 BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
 BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = '/usr'
 BF_JPEG_INC = '${BF_JPEG}/include'
index 1c2288a84306acc603eb379ed8ba884d62459942..e6c4e8769b42dee8621414b15044f9857bbe6111 100644 (file)
@@ -39,6 +39,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
 BF_OPENEXR_LIB = ' Half IlmImf Iex '
 BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = LIBDIR + '/jpeg'
 BF_JPEG_INC = '${BF_JPEG}/include'
index b3579d4ac65a677a0bc98b0ef25234936bba486d..f7f254973af9b42b106713d7be106af4a81fc05d 100644 (file)
@@ -28,6 +28,8 @@ BF_OPENEXR = '/usr/local'
 BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
 BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = '/usr/local'
 BF_JPEG_INC = '${BF_JPEG}/include'
index 7939e2109938018b34559410f3fd632757e061e4..b3ca0e267ff117a4b6be809178da8e325b13fd42 100644 (file)
@@ -29,6 +29,8 @@ BF_OPENEXR_INC = ['${BF_OPENEXR}/include', '${BF_OPENEXR}/include/OpenEXR' ]
 BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
 BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = '/usr/local'
 BF_JPEG_INC = '${BF_JPEG}/include'
index 95c096c4bacc7244fbee62773d3d760c0ce7b960..b0dc6e152b2de44c835216d260c7e3c4eaca23ee 100644 (file)
@@ -42,6 +42,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
 BF_OPENEXR_LIB = ' Half IlmImf Iex '
 BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = LIBDIR + '/jpeg'
 BF_JPEG_INC = '${BF_JPEG}/include'
index feaa97f887a6142330a4ec8fcd5951ba23f475ad..d1a63022ac8bee1296928e943f7e1c7d817657d4 100644 (file)
@@ -50,6 +50,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEX
 BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
 BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_msvc'
 
+WITH_BF_DDS = 'true'
+
 WITH_BF_JPEG = 'true'
 BF_JPEG = LIBDIR + '/jpeg'
 BF_JPEG_INC = '${BF_JPEG}/include'
index d2969f41301405f3ce11b412163fb1c334ff63b0..5161f6b73c517b7ee8bd34411d391c33f6a01093 100644 (file)
@@ -169,6 +169,10 @@ endif
 
 COMLIB += $(OCGDIR)/blender/imbuf/cineon/$(DEBUG_DIR)libcineon.a
 
+ifeq ($(WITH_DDS), true)
+    COMLIB += $(OCGDIR)/blender/imbuf/dds/$(DEBUG_DIR)libdds.a
+endif
+
 ifeq ($(WITH_FREETYPE2), true)
     ifeq ($(OS), windows)
       ifeq ($(FREE_WINDOWS), true)
index 410c2667ff78ae8da60a922b06fe473c0b9dedaf..56a661238f810756e48650907e36b7ed2dd5f953 100644 (file)
@@ -23,6 +23,9 @@ if env['WITH_BF_YAFRAY'] == 1:
 if env['WITH_BF_INTERNATIONAL'] == 1:
     SConscript (['ftfont/SConscript'])
 
+if env['WITH_BF_DDS'] == 1:
+    SConscript (['imbuf/intern/dds/SConscript'])
+
 if env['WITH_BF_OPENEXR'] == 1:
     SConscript (['imbuf/intern/openexr/SConscript'])
 
index d7b48105d3db92351e319163245a360598b6009c..5316c50694af8c65ea00f6f7b85d51d2b72eff82 100644 (file)
@@ -27,6 +27,9 @@ if env['WITH_BF_VERSE']:
 if env['WITH_BF_OPENEXR'] == 1:
     defs += ' WITH_OPENEXR'
 
+if env['WITH_BF_DDS'] == 1:
+    defs += ' WITH_DDS'
+
 if env['WITH_BF_FFMPEG'] == 1:
     defs += ' WITH_FFMPEG'
     incs += ' ' + env['BF_FFMPEG_INC']
index a6b14a72690cdc82889058092c21a6b63c0ff77d..1d16ebfd4cdb9a95445982ee4561306973dedc53 100644 (file)
@@ -101,6 +101,10 @@ ifeq ($(WITH_OPENEXR), true)
     CPPFLAGS += -DWITH_OPENEXR
 endif
 
+ifeq ($(WITH_DDS), true)
+    CPPFLAGS += -DWITH_DDS
+endif
+
 ifeq ($(WITH_QUICKTIME), true)
        CPPFLAGS += -I../../quicktime
        CPPFLAGS += -DWITH_QUICKTIME
index 21fa38fd83d5a6e020b645dac3b409bc9bf5be9c..dd666163c62bf84de8a08c9d015e43dd565a7410 100644 (file)
@@ -633,6 +633,10 @@ int BKE_imtype_to_ftype(int imtype)
                return RADHDR;
        else if (imtype==R_PNG)
                return PNG;
+#ifdef WITH_DDS
+       else if (imtype==R_DDS)
+               return DDS;
+#endif
        else if (imtype==R_BMP)
                return BMP;
        else if (imtype==R_TIFF)
@@ -663,6 +667,10 @@ int BKE_ftype_to_imtype(int ftype)
                return R_RADHDR;
        else if (ftype & PNG)
                return R_PNG;
+#ifdef WITH_DDS
+       else if (ftype & DDS)
+               return R_DDS;
+#endif
        else if (ftype & BMP)
                return R_BMP;
        else if (ftype & TIF)
@@ -719,6 +727,12 @@ void BKE_add_image_extension(char *string, int imtype)
                if(!BLI_testextensie(string, ".png"))
                        extension= ".png";
        }
+#ifdef WITH_DDS
+       else if(imtype==R_DDS) {
+               if(!BLI_testextensie(string, ".dds"))
+                       extension= ".dds";
+       }
+#endif
        else if(imtype==R_RAWTGA) {
                if(!BLI_testextensie(string, ".tga"))
                        extension= ".tga";
@@ -771,6 +785,11 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
        else if ((imtype==R_PNG)) {
                ibuf->ftype= PNG;
        }
+#ifdef WITH_DDS
+       else if ((imtype==R_DDS)) {
+               ibuf->ftype= DDS;
+       }
+#endif
        else if ((imtype==R_BMP)) {
                ibuf->ftype= BMP;
        }
index f5487bb9ac07dbdd6490d1c16c8922b75e320db4..d43b78df0b6d6bb4c404b58b8cfed12980c3306f 100644 (file)
@@ -174,6 +174,10 @@ typedef enum {
 #define CINEON                 (1 << 21)
 #define DPX                            (1 << 20)
 
+#ifdef WITH_DDS
+#define DDS                            (1 << 19)
+#endif
+
 #define RAWTGA         (TGA | 1)
 
 #define JPG_STD                (JPG | (0 << 8))
@@ -216,6 +220,10 @@ typedef enum {
 #define IS_tiff(x)             (x->ftype & TIF)
 #define IS_radhdr(x)   (x->ftype & RADHDR)
 
+#ifdef WITH_DDS
+#define IS_dds(x)              (x->ftype & DDS)
+#endif
+
 #define IMAGIC         0732
 #define IS_iris(x)             (x->ftype == IMAGIC)
 
index 7d3503dfe2d17565c4b8372579fd764a74085ec9..f9e46b20d9a55bbe3f7af8b106a37cef40a332b8 100644 (file)
@@ -20,6 +20,9 @@ if env['WITH_BF_VERSE']:
 if env['WITH_BF_OPENEXR'] == 1:
     defs.append('WITH_OPENEXR')
 
+if env['WITH_BF_DDS'] == 1:
+    defs.append('WITH_DDS')
+
 if env['WITH_BF_FFMPEG'] == 1:
     defs.append('WITH_FFMPEG')
     incs += ' ' + env['BF_FFMPEG_INC']
index f51844aad96e4b55ae64c0ec6d05d2d610a3ef26..29332747a310fc53e7554075ac731f48558c3d66 100644 (file)
@@ -46,6 +46,10 @@ ifeq ($(WITH_OPENEXR), true)
     CFLAGS += -DWITH_OPENEXR
 endif
 
+ifeq ($(WITH_DDS), true)
+    DIRS += dds
+    CPPFLAGS += -DWITH_DDS
+endif
 
 ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
     CFLAGS += -funsigned-char
@@ -80,4 +84,3 @@ ifeq ($(WITH_FFMPEG), true)
    CPPFLAGS += -DWITH_FFMPEG
    CPPFLAGS += $(NAN_FFMPEGCFLAGS)
 endif
-
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
new file mode 100644 (file)
index 0000000..5290a67
--- /dev/null
@@ -0,0 +1,523 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+// 
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#include <Common.h>
+#include <Stream.h>
+#include <ColorBlock.h>
+#include <BlockDXT.h>
+
+/*----------------------------------------------------------------------------
+       BlockDXT1
+----------------------------------------------------------------------------*/
+
+unsigned int 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;
+       }
+}
+
+// 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[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;
+               
+       // 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[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;
+               
+       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);
+       
+       // Write color block.
+       for( unsigned int j = 0; j < 4; j++ ) {
+               for( unsigned int i = 0; i < 4; i++ ) {
+                       unsigned int idx = (row[j] >> (2 * i)) & 3;
+                       block->color(i, j) = color_array[idx];
+               }
+       }       
+}
+
+void BlockDXT1::setIndices(int * idx)
+{
+       indices = 0;
+       for(unsigned int i = 0; i < 16; i++) {
+               indices |= (idx[i] & 3) << (2 * i);
+       }
+}
+
+
+/// Flip DXT1 block vertically.
+inline void BlockDXT1::flip4()
+{
+       unsigned char tmp;
+       swap(row[0], row[3], tmp);
+       swap(row[1], row[2], tmp);
+}
+
+/// Flip half DXT1 block vertically.
+inline void BlockDXT1::flip2()
+{
+       unsigned char tmp;
+       swap(row[0], row[1], tmp);
+}
+
+
+/*----------------------------------------------------------------------------
+       BlockDXT3
+----------------------------------------------------------------------------*/
+
+void BlockDXT3::decodeBlock(ColorBlock * block) const
+{
+       // Decode color.
+       color.decodeBlock(block);
+       
+       // Decode alpha.
+       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;
+}
+
+/// Flip DXT3 alpha block vertically.
+void AlphaBlockDXT3::flip4()
+{
+       unsigned short tmp;
+       swap(row[0], row[3], tmp);
+       swap(row[1], row[2], tmp);
+}
+
+/// Flip half DXT3 alpha block vertically.
+void AlphaBlockDXT3::flip2()
+{
+       unsigned short tmp;
+       swap(row[0], row[1], tmp);
+}
+
+/// Flip DXT3 block vertically.
+void BlockDXT3::flip4()
+{
+       alpha.flip4();
+       color.flip4();
+}
+
+/// Flip half DXT3 block vertically.
+void BlockDXT3::flip2()
+{
+       alpha.flip2();
+       color.flip2();
+}
+
+
+/*----------------------------------------------------------------------------
+       BlockDXT5
+----------------------------------------------------------------------------*/
+
+void AlphaBlockDXT5::evaluatePalette(unsigned char alpha[8]) const
+{
+       if (alpha0 > alpha1) {
+               evaluatePalette8(alpha);
+       }
+       else {
+               evaluatePalette6(alpha);
+       }
+}
+
+void AlphaBlockDXT5::evaluatePalette8(unsigned char alpha[8]) const
+{
+       // 8-alpha block:  derive the other six alphas.
+       // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+       alpha[0] = alpha0;
+       alpha[1] = alpha1;
+       alpha[2] = (6 * alpha0 + 1 * alpha1) / 7;       // bit code 010
+       alpha[3] = (5 * alpha0 + 2 * alpha1) / 7;       // bit code 011
+       alpha[4] = (4 * alpha0 + 3 * alpha1) / 7;       // bit code 100
+       alpha[5] = (3 * alpha0 + 4 * alpha1) / 7;       // bit code 101
+       alpha[6] = (2 * alpha0 + 5 * alpha1) / 7;       // bit code 110
+       alpha[7] = (1 * alpha0 + 6 * alpha1) / 7;       // bit code 111
+}
+
+void AlphaBlockDXT5::evaluatePalette6(unsigned char alpha[8]) const
+{
+       // 6-alpha block.
+       // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+       alpha[0] = alpha0;
+       alpha[1] = alpha1;
+       alpha[2] = (4 * alpha0 + 1 * alpha1) / 5;       // Bit code 010
+       alpha[3] = (3 * alpha0 + 2 * alpha1) / 5;       // Bit code 011
+       alpha[4] = (2 * alpha0 + 3 * alpha1) / 5;       // Bit code 100
+       alpha[5] = (1 * alpha0 + 4 * alpha1) / 5;       // Bit code 101
+       alpha[6] = 0x00;                                                        // Bit code 110
+       alpha[7] = 0xFF;                                                        // Bit code 111
+}
+
+void AlphaBlockDXT5::indices(unsigned char 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;
+}
+
+unsigned int AlphaBlockDXT5::index(unsigned int index) const
+{
+       int offset = (3 * index + 16);
+       return (this->u >> offset) & 0x7;
+}
+
+void AlphaBlockDXT5::setIndex(unsigned int index, unsigned int value)
+{
+       int offset = (3 * index + 16);
+       unsigned long long mask = ((unsigned long long)(0x7)) << offset;
+       this->u = (this->u & ~mask) | (((unsigned long long)(value)) << offset);
+}
+
+void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const
+{
+       unsigned char alpha_array[8];
+       evaluatePalette(alpha_array);
+       
+       unsigned char index_array[16];
+       indices(index_array);
+       
+       for(unsigned int i = 0; i < 16; i++) {
+               block->color(i).a = alpha_array[index_array[i]];
+       }
+}
+
+void AlphaBlockDXT5::flip4()
+{
+       unsigned long long * b = (unsigned long long *)this;
+       
+       // @@ The masks might have to be byte swapped.
+       unsigned long long tmp = (*b & (unsigned long long)(0x000000000000FFFFLL));
+       tmp |= (*b & (unsigned long long)(0x000000000FFF0000LL)) << 36;
+       tmp |= (*b & (unsigned long long)(0x000000FFF0000000LL)) << 12;
+       tmp |= (*b & (unsigned long long)(0x000FFF0000000000LL)) >> 12;
+       tmp |= (*b & (unsigned long long)(0xFFF0000000000000LL)) >> 36;
+       
+       *b = tmp;
+}
+
+void AlphaBlockDXT5::flip2()
+{
+       unsigned int * b = (unsigned int *)this;
+       
+       // @@ The masks might have to be byte swapped.
+       unsigned int tmp = (*b & 0xFF000000);
+       tmp |=  (*b & 0x00000FFF) << 12;
+       tmp |= (*b & 0x00FFF000) >> 12;
+       
+       *b = tmp;
+}
+
+void BlockDXT5::decodeBlock(ColorBlock * block) const
+{
+       // Decode color.
+       color.decodeBlock(block);
+       
+       // Decode alpha.
+       alpha.decodeBlock(block);
+}
+
+/// Flip DXT5 block vertically.
+void BlockDXT5::flip4()
+{
+       alpha.flip4();
+       color.flip4();
+}
+
+/// Flip half DXT5 block vertically.
+void BlockDXT5::flip2()
+{
+       alpha.flip2();
+       color.flip2();
+}
+
+
+/// Decode ATI1 block.
+void BlockATI1::decodeBlock(ColorBlock * block) const
+{
+       unsigned char alpha_array[8];
+       alpha.evaluatePalette(alpha_array);
+       
+       unsigned char index_array[16];
+       alpha.indices(index_array);
+       
+       for(unsigned int 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();
+}
+
+/// Flip half ATI1 block vertically.
+void BlockATI1::flip2()
+{
+       alpha.flip2();
+}
+
+
+/// Decode ATI2 block.
+void BlockATI2::decodeBlock(ColorBlock * block) const
+{
+       unsigned char alpha_array[8];
+       unsigned char index_array[16];
+       
+       x.evaluatePalette(alpha_array);
+       x.indices(index_array);
+       
+       for(unsigned int 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);
+       
+       for(unsigned int 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();
+}
+
+/// Flip half ATI2 block vertically.
+void BlockATI2::flip2()
+{
+       x.flip2();
+       y.flip2();
+}
+
+void mem_read(Stream & mem, BlockDXT1 & block)
+{
+       mem_read(mem, block.col0.u);
+       mem_read(mem, block.col1.u);
+       mem_read(mem, block.indices);
+}
+
+void mem_read(Stream & mem, AlphaBlockDXT3 & block)
+{
+       for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]);
+}
+
+void mem_read(Stream & mem, BlockDXT3 & block)
+{
+       mem_read(mem, block.alpha);
+       mem_read(mem, block.color);
+}
+
+void mem_read(Stream & mem, AlphaBlockDXT5 & block)
+{
+       mem_read(mem, block.u);
+}
+
+void mem_read(Stream & mem, BlockDXT5 & block)
+{
+       mem_read(mem, block.alpha);
+       mem_read(mem, block.color);
+}
+
+void mem_read(Stream & mem, BlockATI1 & block)
+{
+       mem_read(mem, block.alpha);
+}
+
+void mem_read(Stream & mem, BlockATI2 & block)
+{
+       mem_read(mem, block.x);
+       mem_read(mem, block.y);
+}
+
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
new file mode 100644 (file)
index 0000000..fde1bce
--- /dev/null
@@ -0,0 +1,227 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+// 
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef _DDS_BLOCKDXT_H
+#define _DDS_BLOCKDXT_H
+
+#include <Color.h>
+#include <ColorBlock.h>
+#include <Stream.h>
+
+/// DXT1 block.
+struct BlockDXT1
+{
+       Color16 col0;
+       Color16 col1;
+       union {
+               unsigned char row[4];
+               unsigned int indices;
+       };
+
+       bool isFourColorMode() const;
+
+       unsigned int evaluatePalette(Color32 color_array[4]) const;
+       unsigned int evaluatePaletteFast(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 setIndices(int * idx);
+
+       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;        // @@ > or >= ?
+}
+
+
+/// DXT3 alpha block with explicit alpha.
+struct AlphaBlockDXT3
+{
+       union {
+               struct {
+                       unsigned int alpha0 : 4;
+                       unsigned int alpha1 : 4;
+                       unsigned int alpha2 : 4;
+                       unsigned int alpha3 : 4;
+                       unsigned int alpha4 : 4;
+                       unsigned int alpha5 : 4;
+                       unsigned int alpha6 : 4;
+                       unsigned int alpha7 : 4;
+                       unsigned int alpha8 : 4;
+                       unsigned int alpha9 : 4;
+                       unsigned int alphaA : 4;
+                       unsigned int alphaB : 4;
+                       unsigned int alphaC : 4;
+                       unsigned int alphaD : 4;
+                       unsigned int alphaE : 4;
+                       unsigned int alphaF : 4;
+               };
+               unsigned short row[4];
+       };
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+
+/// DXT3 block.
+struct BlockDXT3
+{
+       AlphaBlockDXT3 alpha;
+       BlockDXT1 color;
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+
+/// DXT5 alpha block.
+struct AlphaBlockDXT5
+{
+       union {
+               struct {
+                       unsigned long long alpha0 : 8;  // 8
+                       unsigned long long alpha1 : 8;  // 16
+                       unsigned long long bits0 : 3;   // 3 - 19
+                       unsigned long long bits1 : 3;   // 6 - 22
+                       unsigned long long bits2 : 3;   // 9 - 25
+                       unsigned long long bits3 : 3;   // 12 - 28
+                       unsigned long long bits4 : 3;   // 15 - 31
+                       unsigned long long bits5 : 3;   // 18 - 34
+                       unsigned long long bits6 : 3;   // 21 - 37
+                       unsigned long long bits7 : 3;   // 24 - 40
+                       unsigned long long bits8 : 3;   // 27 - 43
+                       unsigned long long bits9 : 3;   // 30 - 46
+                       unsigned long long bitsA : 3;   // 33 - 49
+                       unsigned long long bitsB : 3;   // 36 - 52
+                       unsigned long long bitsC : 3;   // 39 - 55
+                       unsigned long long bitsD : 3;   // 42 - 58
+                       unsigned long long bitsE : 3;   // 45 - 61
+                       unsigned long long bitsF : 3;   // 48 - 64
+               };
+               unsigned long long u;
+       };
+       
+       void evaluatePalette(unsigned char alpha[8]) const;
+       void evaluatePalette8(unsigned char alpha[8]) const;
+       void evaluatePalette6(unsigned char alpha[8]) const;
+       void indices(unsigned char index_array[16]) const;
+
+       unsigned int index(unsigned int index) const;
+       void setIndex(unsigned int index, unsigned int value);
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+
+/// DXT5 block.
+struct BlockDXT5
+{
+       AlphaBlockDXT5 alpha;
+       BlockDXT1 color;
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+/// ATI1 block.
+struct BlockATI1
+{
+       AlphaBlockDXT5 alpha;
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+/// ATI2 block.
+struct BlockATI2
+{
+       AlphaBlockDXT5 x;
+       AlphaBlockDXT5 y;
+       
+       void decodeBlock(ColorBlock * block) const;
+       
+       void flip4();
+       void flip2();
+};
+
+void mem_read(Stream & mem, BlockDXT1 & block);
+void mem_read(Stream & mem, AlphaBlockDXT3 & block);
+void mem_read(Stream & mem, BlockDXT3 & block);
+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);
+
+#endif // _DDS_BLOCKDXT_H
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
new file mode 100644 (file)
index 0000000..f8055af
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_COLOR_H
+#define _DDS_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) { }
+
+       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;
+       }
+
+       operator unsigned int () const {
+               return 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) { }
+       
+       union {
+               struct {
+                       unsigned short b : 5;
+                       unsigned short g : 6;
+                       unsigned short r : 5;
+               };
+               unsigned short u;
+       };
+};
+
+#endif // _DDS_COLOR_H
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
new file mode 100644 (file)
index 0000000..63997f9
--- /dev/null
@@ -0,0 +1,310 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#include <ColorBlock.h>
+#include <Image.h>
+#include <Common.h>
+
+       // Get approximate luminance.
+       inline static unsigned int colorLuminance(Color32 c)
+       {
+               return c.r + c.g + c.b;
+       }
+       
+       // Get the euclidean distance between the given colors.
+       inline static unsigned int colorDistance(Color32 c0, Color32 c1)
+       {
+               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);
+       }
+       
+
+/// Default constructor.
+ColorBlock::ColorBlock()
+{
+}
+
+/// Init the color block with the contents of the given block.
+ColorBlock::ColorBlock(const ColorBlock & block)
+{
+       for(unsigned int i = 0; i < 16; i++) {
+               color(i) = block.color(i);
+       }
+}
+
+
+/// Initialize this color block.
+ColorBlock::ColorBlock(const Image * img, unsigned int x, unsigned int y)
+{
+       init(img, x, y);
+}
+
+void ColorBlock::init(const Image * img, unsigned int x, unsigned int y)
+{
+       const unsigned int bw = min(img->width() - x, 4U);
+       const unsigned int bh = min(img->height() - y, 4U);
+
+       static int remainder[] = {
+               0, 0, 0, 0,
+               0, 1, 0, 1,
+               0, 1, 2, 0,
+               0, 1, 2, 3,
+       };
+
+       // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+       // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+
+       for(unsigned int i = 0; i < 4; i++) {
+               //const int by = i % bh;
+               const int by = remainder[(bh - 1) * 4 + i];
+               for(unsigned int e = 0; e < 4; e++) {
+                       //const int bx = e % bw;
+                       const int bx = remainder[(bw - 1) * 4 + e];
+                       color(e, i) = img->pixel(x + bx, y + by);
+               }
+       }
+}
+
+
+void ColorBlock::swizzleDXT5n()
+{
+       for(int i = 0; i < 16; i++)
+       {
+               Color32 c = m_color[i];
+               m_color[i] = Color32(0, c.g, 0, c.r);
+       }
+}
+
+void ColorBlock::splatX()
+{
+       for(int i = 0; i < 16; i++)
+       {
+               unsigned char x = m_color[i].r;
+               m_color[i] = Color32(x, x, x, x);
+       }
+}
+
+void ColorBlock::splatY()
+{
+       for(int i = 0; i < 16; i++)
+       {
+               unsigned char y = m_color[i].g;
+               m_color[i] = Color32(y, y, y, y);
+       }
+}
+
+
+/// Count number of unique colors in this color block.
+unsigned int ColorBlock::countUniqueColors() const
+{
+       unsigned int 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;
+}
+
+/// Get average color of the block.
+Color32 ColorBlock::averageColor() const
+{
+       unsigned int r, g, b, a;
+       r = g = b = a = 0;
+
+       for(unsigned int i = 0; i < 16; i++) {
+               r += m_color[i].r;
+               g += m_color[i].g;
+               b += m_color[i].b;
+               a += m_color[i].a;
+       }
+       
+       return Color32((unsigned char)(r / 16), (unsigned char)(g / 16), (unsigned char)(b / 16), (unsigned char)(a / 16));
+}
+
+
+/// Get diameter color range.
+void ColorBlock::diameterRange(Color32 * start, Color32 * end) const
+{
+       Color32 c0, c1;
+       unsigned int best_dist = 0;
+       
+       for(int i = 0; i < 16; i++) {
+               for (int j = i+1; j < 16; j++) {
+                       unsigned int dist = colorDistance(m_color[i], m_color[j]);
+                       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;
+       unsigned int minLuminance, maxLuminance;
+       
+       maxLuminance = minLuminance = colorLuminance(m_color[0]);
+       
+       for(unsigned int i = 1; i < 16; i++)
+       {
+               unsigned int 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(unsigned int 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(unsigned int 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;
+}
+
+/// Sort colors by abosolute value in their 16 bit representation.
+void ColorBlock::sortColorsByAbsoluteValue()
+{
+       // Dummy selection sort.
+       for( unsigned int a = 0; a < 16; a++ ) {
+               unsigned int max = a;
+               Color16 cmax(m_color[a]);
+               
+               for( unsigned int b = a+1; b < 16; b++ ) {
+                       Color16 cb(m_color[b]);
+                       
+                       if( cb.u > cmax.u ) {
+                               max = b;
+                               cmax = cb;
+                       }
+               }
+               Color32 tmp;
+               swap( m_color[a], m_color[max], tmp );
+       }
+}
+
+
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
new file mode 100644 (file)
index 0000000..eba3727
--- /dev/null
@@ -0,0 +1,115 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_COLORBLOCK_H
+#define _DDS_COLORBLOCK_H
+
+#include <Color.h>
+#include <Image.h>
+
+/// Uncompressed 4x4 color block.
+struct ColorBlock
+{
+       ColorBlock();
+       ColorBlock(const ColorBlock & block);
+       ColorBlock(const Image * img, unsigned int x, unsigned int y);
+       
+       void init(const Image * img, unsigned int x, unsigned int y);
+       
+       void swizzleDXT5n();
+       void splatX();
+       void splatY();
+       
+       unsigned int countUniqueColors() const;
+       Color32 averageColor() const;
+       
+       void diameterRange(Color32 * start, Color32 * end) const;
+       void luminanceRange(Color32 * start, Color32 * end) const;
+       void boundsRange(Color32 * start, Color32 * end) const;
+       void boundsRangeAlpha(Color32 * start, Color32 * end) const;
+       void bestFitRange(Color32 * start, Color32 * end) const;
+       
+       void sortColorsByAbsoluteValue();
+
+       float volume() const;
+
+       // Accessors
+       const Color32 * colors() const;
+
+       Color32 color(unsigned int i) const;
+       Color32 & color(unsigned int i);
+       
+       Color32 color(unsigned int x, unsigned int y) const;
+       Color32 & color(unsigned int x, unsigned int y);
+       
+private:
+       
+       Color32 m_color[4*4];
+       
+};
+
+
+/// Get pointer to block colors.
+inline const Color32 * ColorBlock::colors() const
+{
+       return m_color;
+}
+
+/// Get block color.
+inline Color32 ColorBlock::color(unsigned int i) const
+{
+       return m_color[i];
+}
+
+/// Get block color.
+inline Color32 & ColorBlock::color(unsigned int i)
+{
+       return m_color[i];
+}
+
+/// Get block color.
+inline Color32 ColorBlock::color(unsigned int x, unsigned int y) const
+{
+       return m_color[y * 4 + x];
+}
+
+/// Get block color.
+inline Color32 & ColorBlock::color(unsigned int x, unsigned int y)
+{
+       return m_color[y * 4 + x];
+}
+
+#endif // _DDS_COLORBLOCK_H
diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h
new file mode 100644 (file)
index 0000000..5aa8972
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef _DDS_COMMON_H
+#define _DDS_COMMON_H
+
+#ifndef min
+#define min(a,b) ((a) <= (b) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) ((a) >= (b) ? (a) : (b))
+#endif
+#ifndef clamp
+#define clamp(x,a,b) min(max((x), (a)), (b))
+#endif
+#ifndef swap
+#define swap(a,b,tmp) tmp=a; a=b; b=tmp;
+#endif
+
+#endif
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
new file mode 100644 (file)
index 0000000..6937840
--- /dev/null
@@ -0,0 +1,828 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+// 
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#include <Common.h>
+#include <DirectDrawSurface.h>
+#include <BlockDXT.h>
+
+#include <stdio.h> // printf
+#include <math.h>  // sqrt
+
+/*** declarations ***/
+
+#if !defined(MAKEFOURCC)
+#      define MAKEFOURCC(ch0, ch1, ch2, ch3) \
+               ((unsigned int)((unsigned char)(ch0)) | \
+               ((unsigned int)((unsigned char)(ch1)) << 8) | \
+               ((unsigned int)((unsigned char)(ch2)) << 16) | \
+               ((unsigned int)((unsigned char)(ch3)) << 24 ))
+#endif
+
+static const unsigned int FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
+static const unsigned int FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
+static const unsigned int FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
+static const unsigned int FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
+static const unsigned int FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
+static const unsigned int FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
+static const unsigned int FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
+static const unsigned int FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1');
+static const unsigned int FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
+
+// RGB formats.
+static const unsigned int D3DFMT_R8G8B8 = 20;
+static const unsigned int D3DFMT_A8R8G8B8 = 21;
+static const unsigned int D3DFMT_X8R8G8B8 = 22;
+static const unsigned int D3DFMT_R5G6B5 = 23;
+static const unsigned int D3DFMT_X1R5G5B5 = 24;
+static const unsigned int D3DFMT_A1R5G5B5 = 25;
+static const unsigned int D3DFMT_A4R4G4B4 = 26;
+static const unsigned int D3DFMT_R3G3B2 = 27;
+static const unsigned int D3DFMT_A8 = 28;
+static const unsigned int D3DFMT_A8R3G3B2 = 29;
+static const unsigned int D3DFMT_X4R4G4B4 = 30;
+static const unsigned int D3DFMT_A2B10G10R10 = 31;
+static const unsigned int D3DFMT_A8B8G8R8 = 32;
+static const unsigned int D3DFMT_X8B8G8R8 = 33;
+static const unsigned int D3DFMT_G16R16 = 34;
+static const unsigned int D3DFMT_A2R10G10B10 = 35;
+static const unsigned int D3DFMT_A16B16G16R16 = 36;
+
+// Palette formats.
+static const unsigned int D3DFMT_A8P8 = 40;
+static const unsigned int D3DFMT_P8 = 41;
+       
+// Luminance formats.
+static const unsigned int D3DFMT_L8 = 50;
+static const unsigned int D3DFMT_A8L8 = 51;
+static const unsigned int D3DFMT_A4L4 = 52;
+
+// Floating point formats
+static const unsigned int D3DFMT_R16F = 111;
+static const unsigned int D3DFMT_G16R16F = 112;
+static const unsigned int D3DFMT_A16B16G16R16F = 113;
+static const unsigned int D3DFMT_R32F = 114;
+static const unsigned int D3DFMT_G32R32F = 115;
+static const unsigned int D3DFMT_A32B32G32R32F = 116;
+       
+static const unsigned int DDSD_CAPS = 0x00000001U;
+static const unsigned int DDSD_PIXELFORMAT = 0x00001000U;
+static const unsigned int DDSD_WIDTH = 0x00000004U;
+static const unsigned int DDSD_HEIGHT = 0x00000002U;
+static const unsigned int DDSD_PITCH = 0x00000008U;
+static const unsigned int DDSD_MIPMAPCOUNT = 0x00020000U;
+static const unsigned int DDSD_LINEARSIZE = 0x00080000U;
+static const unsigned int DDSD_DEPTH = 0x00800000U;
+       
+static const unsigned int DDSCAPS_COMPLEX = 0x00000008U;
+static const unsigned int DDSCAPS_TEXTURE = 0x00001000U;
+static const unsigned int DDSCAPS_MIPMAP = 0x00400000U;
+static const unsigned int DDSCAPS2_VOLUME = 0x00200000U;
+static const unsigned int DDSCAPS2_CUBEMAP = 0x00000200U;
+
+static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U;
+static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U;
+static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U;
+static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U;
+static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U;
+static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U;
+static const unsigned int DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U;
+
+static const unsigned int DDPF_ALPHAPIXELS = 0x00000001U;
+static const unsigned int DDPF_ALPHA = 0x00000002U;
+static const unsigned int DDPF_FOURCC = 0x00000004U;
+static const unsigned int DDPF_RGB = 0x00000040U;
+static const unsigned int DDPF_PALETTEINDEXED1 = 0x00000800U;
+static const unsigned int DDPF_PALETTEINDEXED2 = 0x00001000U;
+static const unsigned int DDPF_PALETTEINDEXED4 = 0x00000008U;
+static const unsigned int DDPF_PALETTEINDEXED8 = 0x00000020U;
+static const unsigned int DDPF_LUMINANCE = 0x00020000U;
+static const unsigned int DDPF_ALPHAPREMULT = 0x00008000U;
+static const unsigned int DDPF_NORMAL = 0x80000000U;   // @@ Custom nv flag.
+
+/*** implementation ***/
+
+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);
+}
+
+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);
+}
+
+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 (unsigned int 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);
+}
+
+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 (unsigned int i = 0; i < 11; i++) this->reserved[i] = 0;
+
+       // Store version information on the reserved header attributes.
+       this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T');
+       this->reserved[10] = (0 << 16) | (9 << 8) | (3);        // major.minor.revision
+
+       this->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;
+}
+
+void DDSHeader::setWidth(unsigned int w)
+{
+       this->flags |= DDSD_WIDTH;
+       this->width = w;
+}
+
+void DDSHeader::setHeight(unsigned int h)
+{
+       this->flags |= DDSD_HEIGHT;
+       this->height = h;
+}
+
+void DDSHeader::setDepth(unsigned int d)
+{
+       this->flags |= DDSD_DEPTH;
+       this->height = d;
+}
+
+void DDSHeader::setMipmapCount(unsigned int count)
+{
+       if (count == 0)
+       {
+               this->flags &= ~DDSD_MIPMAPCOUNT;
+               this->mipmapcount = 0;
+
+               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()
+{
+       // nothing to do here.
+}
+
+void DDSHeader::setTexture3D()
+{
+       this->caps.caps2 = DDSCAPS2_VOLUME;
+}
+
+void DDSHeader::setTextureCube()
+{
+       this->caps.caps1 |= DDSCAPS_COMPLEX;
+       this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES;
+}
+
+void DDSHeader::setLinearSize(unsigned int size)
+{
+       this->flags &= ~DDSD_PITCH;
+       this->flags |= DDSD_LINEARSIZE;
+       this->pitch = size;
+}
+
+void DDSHeader::setPitch(unsigned int pitch)
+{
+       this->flags &= ~DDSD_LINEARSIZE;
+       this->flags |= DDSD_PITCH;
+       this->pitch = pitch;
+}
+
+void DDSHeader::setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3)
+{
+       // set fourcc pixel format.
+       this->pf.flags = DDPF_FOURCC;
+       this->pf.fourcc = 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::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int 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;
+       }
+
+       this->pf.flags = DDPF_RGB;
+
+       if (amask != 0) {
+               this->pf.flags |= DDPF_ALPHAPIXELS;
+       }
+
+       if (bitcount == 0)
+       {
+               // Compute bit count from the masks.
+               unsigned int total = rmask | gmask | bmask | amask;
+               while(total != 0) {
+                       bitcount++;
+                       total >>= 1;
+               }
+               // @@ Align to 8?
+       }
+
+       this->pf.fourcc = 0;
+       this->pf.bitcount = bitcount;
+       this->pf.rmask = rmask;
+       this->pf.gmask = gmask;
+       this->pf.bmask = bmask;
+       this->pf.amask = amask;
+}
+
+void DDSHeader::setNormalFlag(bool b)
+{
+       if (b) this->pf.flags |= DDPF_NORMAL;
+       else this->pf.flags &= ~DDPF_NORMAL;
+}
+
+/*
+void DDSHeader::swapBytes()
+{
+       this->fourcc = POSH_LittleU32(this->fourcc);
+       this->size = POSH_LittleU32(this->size);
+       this->flags = POSH_LittleU32(this->flags);
+       this->height = POSH_LittleU32(this->height);
+       this->width = POSH_LittleU32(this->width);
+       this->pitch = POSH_LittleU32(this->pitch);
+       this->depth = POSH_LittleU32(this->depth);
+       this->mipmapcount = POSH_LittleU32(this->mipmapcount);
+       
+       for(int i = 0; i < 11; i++) {
+               this->reserved[i] = POSH_LittleU32(this->reserved[i]);
+       }
+
+       this->pf.size = POSH_LittleU32(this->pf.size);
+       this->pf.flags = POSH_LittleU32(this->pf.flags);
+       this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
+       this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
+       this->pf.rmask = POSH_LittleU32(this->pf.rmask);
+       this->pf.gmask = POSH_LittleU32(this->pf.gmask);
+       this->pf.bmask = POSH_LittleU32(this->pf.bmask);
+       this->pf.amask = POSH_LittleU32(this->pf.amask);
+       this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
+       this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
+       this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
+       this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
+       this->notused = POSH_LittleU32(this->notused);
+}
+*/
+
+
+DirectDrawSurface::DirectDrawSurface(unsigned char *mem, unsigned int size) : stream(mem, size), header()
+{
+       mem_read(stream, header);
+}
+
+DirectDrawSurface::~DirectDrawSurface()
+{
+}
+
+bool DirectDrawSurface::isValid() const
+{
+       if (header.fourcc != FOURCC_DDS || header.size != 124)
+       {
+               return false;
+       }
+       
+       const unsigned int required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT);
+       if( (header.flags & required) != required ) {
+               return false;
+       }
+       
+       if (header.pf.size != 32) {
+               return false;
+       }
+
+       /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
+       /*
+       if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
+               return false;
+       }
+       */
+
+       return true;
+}
+
+bool DirectDrawSurface::isSupported() const
+{
+       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)
+       {
+               if (header.pf.bitcount == 24)
+               {
+                       return false;
+               }
+               else if (header.pf.bitcount == 32)
+               {
+                       return false;
+               }
+               else
+               {
+                       // Unsupported pixel format.
+                       return false;
+               }
+       }
+       */
+       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;
+}
+
+
+unsigned int DirectDrawSurface::mipmapCount() const
+{
+       if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount;
+       else return 0;
+}
+
+
+unsigned int DirectDrawSurface::width() const
+{
+       if (header.flags & DDSD_WIDTH) return header.width;
+       else return 1;
+}
+
+unsigned int DirectDrawSurface::height() const
+{
+       if (header.flags & DDSD_HEIGHT) return header.height;
+       else return 1;
+}
+
+unsigned int DirectDrawSurface::depth() const
+{
+       if (header.flags & DDSD_DEPTH) return header.depth;
+       else return 1;
+}
+
+bool DirectDrawSurface::hasAlpha() const
+{
+       if (header.pf.fourcc == FOURCC_DXT1) return false;
+       else return true;
+}
+
+bool DirectDrawSurface::isTexture2D() const
+{
+       return !isTexture3D() && !isTextureCube();
+}
+
+bool DirectDrawSurface::isTexture3D() const
+{
+       return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
+}
+
+bool DirectDrawSurface::isTextureCube() const
+{
+       return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
+}
+
+void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipmap)
+{
+       stream.seek(offset(face, mipmap));
+       
+       unsigned int w = width();
+       unsigned int h = height();
+       
+       // Compute width and height.
+       for (unsigned int m = 0; m < mipmap; m++)
+       {
+               w = max(w/2, 1U);
+               h = max(h/2, 1U);
+       }
+       
+       img->allocate(w, h);
+       
+       if (header.pf.flags & DDPF_RGB) 
+       {
+               readLinearImage(img);
+       }
+       else if (header.pf.flags & DDPF_FOURCC)
+       {
+               readBlockImage(img);
+       }
+}
+
+void DirectDrawSurface::readLinearImage(Image * img)
+{
+       // @@ Read linear RGB images.
+       printf("DDS: linear RGB images not supported\n");
+}
+
+void DirectDrawSurface::readBlockImage(Image * img)
+{
+       const unsigned int w = img->width();
+       const unsigned int h = img->height();
+       
+       const unsigned int bw = (w + 3) / 4;
+       const unsigned int bh = (h + 3) / 4;
+       
+       for (unsigned int by = 0; by < bh; by++)
+       {
+               for (unsigned int bx = 0; bx < bw; bx++)
+               {
+                       ColorBlock block;
+                       
+                       // Read color block.
+                       readBlock(&block);
+                       
+                       // Write color block.
+                       for (unsigned int y = 0; y < min(4U, h-4*by); y++)
+                       {
+                               for (unsigned int x = 0; x < min(4U, w-4*bx); x++)
+                               {
+                                       img->pixel(4*bx+x, 4*by+y) = block.color(x, y);
+                               }
+                       }
+               }
+       }
+}
+
+static Color32 buildNormal(unsigned char x, unsigned char y)
+{
+       float nx = 2 * (x / 255) - 1;
+       float ny = 2 * (x / 255) - 1;
+       float nz = sqrt(1 - nx*nx - ny*ny);
+       unsigned char z = clamp(int(255 * (nz + 1) / 2), 0, 255);
+       
+       return Color32(x, y, z);
+}
+
+
+void DirectDrawSurface::readBlock(ColorBlock * rgba)
+{
+       if (header.pf.fourcc == FOURCC_DXT1)
+       {
+               BlockDXT1 block;
+               mem_read(stream, block);
+               block.decodeBlock(rgba);
+       }
+       else if (header.pf.fourcc == FOURCC_DXT2 ||
+           header.pf.fourcc == FOURCC_DXT3)
+       {
+               BlockDXT3 block;
+               mem_read(stream, block);
+               block.decodeBlock(rgba);
+       }
+       else if (header.pf.fourcc == FOURCC_DXT4 ||
+           header.pf.fourcc == FOURCC_DXT5 ||
+           header.pf.fourcc == FOURCC_RXGB)
+       {
+               BlockDXT5 block;
+               mem_read(stream, block);
+               block.decodeBlock(rgba);
+               
+               if (header.pf.fourcc == FOURCC_RXGB)
+               {
+                       // Swap R & A.
+                       for (int i = 0; i < 16; i++)
+                       {
+                               Color32 & c = rgba->color(i);
+                               unsigned int tmp = c.r;
+                               c.r = c.a;
+                               c.a = tmp;
+                       }
+               }
+       }
+       else if (header.pf.fourcc == FOURCC_ATI1)
+       {
+               BlockATI1 block;
+               mem_read(stream, block);
+               block.decodeBlock(rgba);
+       }
+       else if (header.pf.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 (header.pf.fourcc == FOURCC_ATI2)
+               {
+                       for (int i = 0; i < 16; i++)
+                       {
+                               Color32 & c = rgba->color(i);
+                               c = buildNormal(c.r, c.g);
+                       }
+               }
+               else if (header.pf.fourcc == FOURCC_DXT5)
+               {
+                       for (int i = 0; i < 16; i++)
+                       {
+                               Color32 & c = rgba->color(i);
+                               c = buildNormal(c.g, c.a);
+                       }
+               }
+       }
+}
+
+
+unsigned int 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;
+       };
+
+       // Not a block image.
+       return 0;
+}
+
+unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const
+{
+       unsigned int w = width();
+       unsigned int h = height();
+       unsigned int d = depth();
+       
+       for (unsigned int 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)
+       {
+               // Align pixels to bytes.
+               unsigned int byteCount = (header.pf.bitcount + 7) / 8;
+               
+               // Align pitch to 4 bytes.
+               unsigned int pitch = 4 * ((w * byteCount + 3) / 4);
+               
+               return pitch * h * d;
+       }
+       else {
+               printf("DDS: mipmap format not supported\n");
+               return(0);
+       };
+}
+
+unsigned int DirectDrawSurface::faceSize() const
+{
+       const unsigned int count = mipmapCount();
+       unsigned int size = 0;
+       
+       for (unsigned int m = 0; m < count; m++)
+       {
+               size += mipmapSize(m);
+       }
+       
+       return size;
+}
+
+unsigned int DirectDrawSurface::offset(const unsigned int face, const unsigned int mipmap)
+{
+       unsigned int size = sizeof(DDSHeader);
+       
+       if (face != 0)
+       {
+               size += face * faceSize();
+       }
+       
+       for (unsigned int m = 0; m < mipmap; m++)
+       {
+               size += mipmapSize(m);
+       }
+       
+       return size;
+}
+
+
+void DirectDrawSurface::printInfo() const
+{
+       /* printf("FOURCC: %c%c%c%c\n", ((unsigned char *)&header.fourcc)[0], ((unsigned char *)&header.fourcc)[1], ((unsigned char *)&header.fourcc)[2], ((unsigned char *)&header.fourcc)[3]); */
+       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: %d\n", header.height);
+       printf("Width: %d\n", header.width);
+       printf("Depth: %d\n", header.depth);
+       if (header.flags & DDSD_PITCH) printf("Pitch: %d\n", header.pitch);
+       else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %d\n", header.pitch);
+       printf("Mipmap count: %d\n", header.mipmapcount);
+       
+       printf("Pixel Format:\n");
+       /* printf("\tSize: %d\n", header.pf.size); */
+       printf("\tFlags: 0x%.8X\n", header.pf.flags);
+       if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\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");
+       
+       printf("\tFourCC: '%c%c%c%c'\n", ((header.pf.fourcc >> 0) & 0xFF), ((header.pf.fourcc >> 8) & 0xFF), ((header.pf.fourcc >> 16) & 0xFF), ((header.pf.fourcc >> 24) & 0xFF));
+       printf("\tBit count: %d\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.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T'))
+       {
+               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);
+       }
+}
+
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
new file mode 100644 (file)
index 0000000..2b3319d
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+// 
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef _DDS_DIRECTDRAWSURFACE_H
+#define _DDS_DIRECTDRAWSURFACE_H
+
+#include <Stream.h>
+#include <ColorBlock.h>
+#include <Image.h>
+
+struct DDSPixelFormat {
+       unsigned int size;
+       unsigned int flags;
+       unsigned int fourcc;
+       unsigned int bitcount;
+       unsigned int rmask;
+       unsigned int gmask;
+       unsigned int bmask;
+       unsigned int amask;
+};
+
+struct DDSCaps {
+       unsigned int caps1;
+       unsigned int caps2;
+       unsigned int caps3;
+       unsigned int caps4;
+};
+
+/// DDS file header.
+struct DDSHeader {
+       unsigned int fourcc;
+       unsigned int size;
+       unsigned int flags;
+       unsigned int height;
+       unsigned int width;
+       unsigned int pitch;
+       unsigned int depth;
+       unsigned int mipmapcount;
+       unsigned int reserved[11];
+       DDSPixelFormat pf;
+       DDSCaps caps;
+       unsigned int notused;
+       
+       // Helper methods.
+       DDSHeader();
+       
+       void setWidth(unsigned int w);
+       void setHeight(unsigned int h);
+       void setDepth(unsigned int d);
+       void setMipmapCount(unsigned int count);
+       void setTexture2D();
+       void setTexture3D();
+       void setTextureCube();
+       void setLinearSize(unsigned int size);
+       void setPitch(unsigned int pitch);
+       void setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3);
+       void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask);
+       void setNormalFlag(bool b);
+       
+       /* void swapBytes(); */
+};
+
+/// DirectDraw Surface. (DDS)
+class DirectDrawSurface
+{
+public:
+       DirectDrawSurface(unsigned char *mem, unsigned int size);
+       ~DirectDrawSurface();
+       
+       bool isValid() const;
+       bool isSupported() const;
+       
+       unsigned int mipmapCount() const;
+       unsigned int width() const;
+       unsigned int height() const;
+       unsigned int depth() const;
+       bool isTexture2D() const;
+       bool isTexture3D() const;
+       bool isTextureCube() const;
+       bool hasAlpha() const; /* false for DXT1, true for all others */
+       
+       void mipmap(Image * img, unsigned int f, unsigned int m);
+       
+       void printInfo() const;
+
+private:
+       
+       unsigned int blockSize() const;
+       unsigned int faceSize() const;
+       unsigned int mipmapSize(unsigned int m) const;
+       
+       unsigned int offset(unsigned int f, unsigned int 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);
+
+#endif // _DDS_DIRECTDRAWSURFACE_H
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
new file mode 100644 (file)
index 0000000..f3e6fa3
--- /dev/null
@@ -0,0 +1,132 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#include <Color.h>
+#include <Image.h>
+
+#include <stdio.h> // printf
+
+Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(0)
+{
+}
+
+Image::~Image()
+{
+       free();
+}
+
+void Image::allocate(unsigned int w, unsigned int 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 = 0;
+}
+
+
+unsigned int Image::width() const
+{
+       return m_width;
+}
+
+unsigned int Image::height() const
+{
+       return m_height;
+}
+
+const Color32 * Image::scanline(unsigned int h) const
+{
+       if (h >= m_height) {
+               printf("DDS: scanline beyond dimensions of image");
+               return m_data;
+       }
+       return m_data + h * m_width;
+}
+
+Color32 * Image::scanline(unsigned int h)
+{
+       if (h >= m_height) {
+               printf("DDS: scanline beyond dimensions of image");
+               return m_data;
+       }
+       return m_data + h * m_width;
+}
+
+const Color32 * Image::pixels() const
+{
+       return m_data;
+}
+
+Color32 * Image::pixels()
+{
+       return m_data;
+}
+
+const Color32 & Image::pixel(unsigned int idx) const
+{
+       if (idx >= m_width * m_height) {
+               printf("DDS: pixel beyond dimensions of image");
+               return m_data[0];
+       }
+       return m_data[idx];
+}
+
+Color32 & Image::pixel(unsigned int idx)
+{
+       if (idx >= m_width * m_height) {
+               printf("DDS: pixel beyond dimensions of image");
+               return m_data[0];
+       }
+       return m_data[idx];
+}
+
+
+Image::Format Image::format() const
+{
+       return m_format;
+}
+
+void Image::setFormat(Image::Format f)
+{
+       m_format = f;
+}
+
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
new file mode 100644 (file)
index 0000000..1035677
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_IMAGE_H
+#define _DDS_IMAGE_H
+
+#include <Color.h>
+
+/// 32 bit RGBA image.
+class Image
+{
+public:
+       
+       enum Format 
+       {
+               Format_RGB,
+               Format_ARGB,
+       };
+       
+       Image();
+       ~Image();
+       
+       void allocate(unsigned int w, unsigned int h);
+       /*
+       bool load(const char * name);
+       
+       void wrap(void * data, unsigned int w, unsigned int h);
+       void unwrap();
+       */
+       
+       unsigned int width() const;
+       unsigned int height() const;
+       
+       const Color32 * scanline(unsigned int h) const;
+       Color32 * scanline(unsigned int h);
+       
+       const Color32 * pixels() const;
+       Color32 * pixels();
+       
+       const Color32 & pixel(unsigned int idx) const;
+       Color32 & pixel(unsigned int idx);
+       
+       const Color32 & pixel(unsigned int x, unsigned int y) const;
+       Color32 & pixel(unsigned int x, unsigned int y);
+       
+       Format format() const;
+       void setFormat(Format f);
+       
+private:
+       void free();
+       
+private:
+       unsigned int m_width;
+       unsigned int m_height;
+       Format m_format;
+       Color32 * m_data;
+};
+
+
+inline const Color32 & Image::pixel(unsigned int x, unsigned int y) const
+{
+       return pixel(y * width() + x);
+}
+
+inline Color32 & Image::pixel(unsigned int x, unsigned int y)
+{
+       return pixel(y * width() + x);
+}
+
+#endif // _DDS_IMAGE_H
diff --git a/source/blender/imbuf/intern/dds/Makefile b/source/blender/imbuf/intern/dds/Makefile
new file mode 100644 (file)
index 0000000..2bab1de
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# $Id: Makefile 7037 2006-03-12 14:11:23Z ton $
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License.  See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = dds
+DIR = $(OCGDIR)/blender/imbuf/dds
+SOURCEDIR = source/blender/imbuf/intern/dds
+
+include nan_compile.mk
+include nan_definitions.mk
+
+ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+    CFLAGS += -funsigned-char
+endif
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I$(NAN_JPEG)/include
+CPPFLAGS += -I$(NAN_PNG)/include
+CPPFLAGS += -I$(NAN_ZLIB)/include
+CPPFLAGS += -I$(NAN_TIFF)/include
+CPPFLAGS += -I../../../include
+CPPFLAGS += -I../../../blenkernel
+CPPFLAGS += -I../../../blenlib
+CPPFLAGS += -I../../../avi
+CPPFLAGS += -I../../../quicktime
+# path to the guarded memory allocator
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_MEMUTIL)/include
+# This is not really needed, but until /include is cleaned, it must be
+# there for proper compilation.
+# - No, it is also needed in antialias, for listbase (nzc)
+CPPFLAGS += -I../../../makesdna
+# external interface of this module
+CPPFLAGS += -I../..
+CPPFLAGS += -I..
+CPPFLAGS += -I.
+CPPFLAGS += -DWITH_DDS
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
new file mode 100644 (file)
index 0000000..0618e32
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+Import ('env')
+
+source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp']
+
+incs = ['.',
+       '../../',
+       '..',
+       '../../../makesdna',
+       '../../../blenkernel',
+       '../../../blenlib',
+       'intern/include',
+       '#/intern/guardedalloc']
+
+
+defs = []
+                 
+env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
new file mode 100644 (file)
index 0000000..a181ec7
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <Stream.h>
+
+#include <stdio.h>  // printf
+#include <string.h> // memcpy
+
+unsigned int Stream::seek(unsigned int p)
+{
+       if (p > size) {
+               printf("DDS: trying to seek beyond end of stream (corrupt file?)");
+       }
+       else {
+               pos = p;
+       }
+
+       return pos;
+}
+
+unsigned int mem_read(Stream & mem, unsigned long long & i)
+{
+       if (mem.pos + 8 > mem.size) {
+               printf("DDS: trying to read beyond end of stream (corrupt file?)");
+               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)
+{
+       if (mem.pos + 4 > mem.size) {
+               printf("DDS: trying to read beyond end of stream (corrupt file?)");
+               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)
+{
+       if (mem.pos + 2 > mem.size) {
+               printf("DDS: trying to read beyond end of stream (corrupt file?)");
+               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)
+{
+       if (mem.pos + 1 > mem.size) {
+               printf("DDS: trying to read beyond end of stream (corrupt file?)");
+               return(0);
+       };
+       i = (mem.mem + mem.pos)[0];
+       mem.pos += 1;
+       return(1);
+}
+
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
new file mode 100644 (file)
index 0000000..1e7d3c6
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/* 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
+       Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0) {};
+       unsigned int seek(unsigned int p);
+};
+
+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);
+
+#endif // _STREAM_H
+
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
new file mode 100644 (file)
index 0000000..0e06fd3
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <dds_api.h>
+#include <Stream.h>
+#include <DirectDrawSurface.h>
+
+#include <stdio.h> // printf
+
+extern "C" {
+
+#include "imbuf.h"
+#include "imbuf_patch.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_allocimbuf.h"
+
+/* not supported yet
+short imb_save_dds(struct ImBuf * ibuf, char *name, int flags)
+{
+       return(0);
+}
+*/
+
+int imb_is_a_dds(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);
+}
+
+struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
+{
+       struct ImBuf * ibuf = 0;
+       DirectDrawSurface dds(mem, size); /* reads header */
+       unsigned char bytes_per_pixel;
+       unsigned int *rect;
+       Image img;
+       unsigned int numpixels = 0;
+       int col;
+       unsigned char *cp = (unsigned char *) &col;
+       Color32 pixel;
+       Color32 *pixels = 0;
+
+       /* check if DDS is valid and supported */
+       if (!dds.isValid()) {
+               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 */
+       if (dds.hasAlpha()) bytes_per_pixel = 32;
+       else bytes_per_pixel = 24;
+       ibuf = IMB_allocImBuf(dds.width(), dds.height(), bytes_per_pixel, 0, 0); 
+       if (ibuf == 0) return(0); /* memory allocation failed */
+
+       ibuf->ftype = DDS;
+
+       if ((flags & IB_test) == 0) {
+               if (!imb_addrectImBuf(ibuf)) return(ibuf);
+               if (ibuf->rect == 0) return(ibuf);
+
+               rect = ibuf->rect;
+               dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
+               pixels = img.pixels();
+               numpixels = dds.width() * dds.height();
+               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 (bytes_per_pixel == 32)
+                               cp[3] = pixel.a; /* set A component of col */
+                       rect[i] = col;
+               }
+               IMB_flipy(ibuf);
+       }
+
+       return(ibuf);
+}
+
+} // extern "C"
diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h
new file mode 100644 (file)
index 0000000..8a0f966
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef _DDS_API_H
+#define _DDS_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+short        imb_save_dds(struct ImBuf *ibuf, char *name, int flags);
+int           imb_is_a_dds(unsigned char *mem); /* use only first 32 bytes of mem */
+struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DDS_API_H */
index bfa6200d23beb37b19c34b6c405dbcc052742922..c5901ccad90db281248243a610cc9758ce16107d 100644 (file)
 #include "openexr/openexr_api.h"
 #endif
 
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
+
 #ifdef WITH_QUICKTIME
 #if defined(_WIN32) || defined (__APPLE__)
 #include "quicktime_import.h"
@@ -153,6 +157,11 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
                ibuf = imb_load_openexr((uchar *)mem, size, flags);
                if (ibuf) return (ibuf);
 #endif
+
+#ifdef WITH_DDS
+               ibuf = imb_load_dds((uchar *)mem, size, flags);
+               if (ibuf) return (ibuf);
+#endif
                
 #ifdef WITH_QUICKTIME
 #if defined(_WIN32) || defined (__APPLE__)
index 69390951a254534d6ef4896213d468066e0fbb8b..4c7b5fec2c4c89a50009da3b64a2dec888b9c015 100644 (file)
 
 #include "IMB_targa.h"
 #include "IMB_png.h"
+
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
+
 #include "IMB_bmp.h"
 #include "IMB_tiff.h"
 #include "IMB_radiance_hdr.h"
@@ -113,6 +118,9 @@ static int IMB_ispic_name(char *name)
 
                                }
                                if (imb_is_a_png(buf)) return(PNG);
+#ifdef WITH_DDS
+                               if (imb_is_a_dds((uchar *)buf)) return(DDS);
+#endif
                                if (imb_is_a_targa(buf)) return(TGA);
 #ifdef WITH_OPENEXR
                                if (imb_is_a_openexr((uchar *)buf)) return(OPENEXR);
@@ -162,6 +170,9 @@ int IMB_ispic(char *filename)
                                ||      BLI_testextensie(filename, ".rgb")
                                ||      BLI_testextensie(filename, ".bmp")
                                ||      BLI_testextensie(filename, ".png")
+#ifdef WITH_DDS
+                               ||      BLI_testextensie(filename, ".dds")
+#endif
                                ||      BLI_testextensie(filename, ".iff")
                                ||      BLI_testextensie(filename, ".lbm")
                                ||      BLI_testextensie(filename, ".gif")
@@ -188,6 +199,9 @@ int IMB_ispic(char *filename)
                                ||      BLI_testextensie(filename, ".bmp")
                                ||      BLI_testextensie(filename, ".png")
                                ||      BLI_testextensie(filename, ".cin")
+#ifdef WITH_DDS
+                               ||      BLI_testextensie(filename, ".dds")
+#endif
 #ifdef WITH_BF_OPENEXR
                                ||      BLI_testextensie(filename, ".exr")
 #endif
@@ -251,6 +265,7 @@ static int isffmpeg (char *filename) {
        if( BLI_testextensie(filename, ".swf") ||
                BLI_testextensie(filename, ".jpg") ||
                BLI_testextensie(filename, ".png") ||
+               BLI_testextensie(filename, ".dds") ||
                BLI_testextensie(filename, ".tga") ||
                BLI_testextensie(filename, ".bmp") ||
                BLI_testextensie(filename, ".exr") ||
index 2e922c65827ace551ed3eb3fdab6301eee371d52..ccca8e9f85916b4542e7369521570e183267aecb 100644 (file)
@@ -61,6 +61,9 @@
 #ifdef WITH_OPENEXR
 #include "openexr/openexr_api.h"
 #endif
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
 
 #include "IMB_iff.h"
 #include "IMB_bitplanes.h"
@@ -115,6 +118,13 @@ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags)
                return imb_save_openexr(ibuf, name, flags);
        }
 #endif
+/* not supported yet
+#ifdef WITH_DDS
+       if (IS_dds(ibuf)) {
+               return imb_save_dds(ibuf, name, flags);
+       }
+#endif
+*/
        if (IS_cineon(ibuf)) {
                return imb_savecineon(ibuf, name, flags);
                
index 4dc6403e60553f3531e5a08cc628333e86020e4f..5eaec3480cecadb6796eced80093b4c3936c4614 100644 (file)
@@ -551,6 +551,7 @@ typedef struct Scene {
 #define R_CINEON               26
 #define R_DPX                  27
 #define R_MULTILAYER   28
+#define R_DDS                  29
 
 /* subimtype, flag options for imtype */
 #define R_OPENEXR_HALF 1
index e9f4e807259f3e155cce7c9e96a3205b58921c09..ac3ee291e9d9c77c7af9cc2027a55d63d3c6ccd7 100644 (file)
@@ -125,6 +125,10 @@ ifeq ($(WITH_OPENEXR),true)
        CPPFLAGS += -DWITH_OPENEXR
 endif
 
+ifeq ($(WITH_DDS),true)
+       CPPFLAGS += -DWITH_DDS
+endif
+
 ifeq ($(INTERNATIONAL), true)
     CPPFLAGS += -DINTERNATIONAL
 endif
index 729e79dcb6f1a9151cafc5fe16e6417e9ab9b5bd..415e5ac4be48ebb12214932c33ad03e599f20a97 100644 (file)
@@ -35,6 +35,9 @@ if env['WITH_BF_INTERNATIONAL'] == 1:
 if env['WITH_BF_OPENEXR'] == 1:
     defs.append('WITH_OPENEXR')
 
+if env['WITH_BF_DDS'] == 1:
+    defs.append('WITH_DDS')
+
 if env['WITH_BF_QUICKTIME']==1:
     incs += ' ' + env['BF_QUICKTIME_INC']
     defs.append('WITH_QUICKTIME')
index 4f59e965371559db4a45ec5c8ea6909c12a67ea1..951a4ac25e4c989af4106951735e2022340081f4 100644 (file)
@@ -1041,6 +1041,11 @@ static char *imagetype_pup(void)
 #endif
 
        strcat(formatstring, "|%s %%x%d");      // add space for PNG
+/*  Commented out until implemented
+#ifdef WITH_DDS
+       strcat(formatstring, "|%s %%x%d");      // add space for DDS
+#endif
+*/
        strcat(formatstring, "|%s %%x%d");      // add space for BMP
        strcat(formatstring, "|%s %%x%d");      // add space for Radiance HDR
        strcat(formatstring, "|%s %%x%d");      // add space for Cineon
@@ -1077,6 +1082,11 @@ static char *imagetype_pup(void)
                        "Targa",          R_TARGA,
                        "Targa Raw",      R_RAWTGA,
                        "PNG",            R_PNG,
+/* commented out until implemented 
+#ifdef WITH_DDS
+                       "DDS",            R_DDS,
+#endif
+*/
                        "BMP",            R_BMP,
                        "Jpeg",           R_JPEG90,
                        "HamX",           R_HAMX,
@@ -1102,6 +1112,9 @@ static char *imagetype_pup(void)
                        "Targa",          R_TARGA,
                        "Targa Raw",      R_RAWTGA,
                        "PNG",            R_PNG,
+#ifdef WITH_DDS
+                       "DDS",            R_DDS,
+#endif
                        "BMP",            R_BMP,
                        "Jpeg",           R_JPEG90,
                        "HamX",           R_HAMX,
index 025ee86e563a39c6e9bcf9c69d4573cc03e9871c..59543861348fded8a0f7d11cce7754bd7c506a9e 100644 (file)
@@ -535,6 +535,9 @@ void test_flags_file(SpaceFile *sfile)
                                        ||      BLI_testextensie(file->relname, ".rgb")
                                        ||      BLI_testextensie(file->relname, ".bmp")
                                        ||      BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+                                       ||      BLI_testextensie(file->relname, ".dds")
+#endif
                                        ||      BLI_testextensie(file->relname, ".iff")
                                        ||      BLI_testextensie(file->relname, ".lbm")
                                        ||      BLI_testextensie(file->relname, ".gif")
@@ -566,6 +569,9 @@ void test_flags_file(SpaceFile *sfile)
                                        ||      BLI_testextensie(file->relname, ".rgb")
                                        ||      BLI_testextensie(file->relname, ".bmp")
                                        ||      BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+                                       ||      BLI_testextensie(file->relname, ".dds")
+#endif
                                        ||      BLI_testextensie(file->relname, ".iff")
                                        ||      BLI_testextensie(file->relname, ".lbm")
                                        ||  BLI_testextensie(file->relname, ".cin")
index ca3a312f98ba6bea7a46414aa24df5bfa8445268..cb3d4158ec1fd324719ed631e599cdab64444518 100644 (file)
@@ -151,6 +151,11 @@ void save_image_filesel_str(char *str)
                case R_PNG:
                        strcpy(str, "Save PNG");
                        break;
+#ifdef WITH_DDS
+               case R_DDS:
+                       strcpy(str, "Save DDS");
+                       break;
+#endif
                case R_BMP:
                        strcpy(str, "Save BMP");
                        break;
index efc3c05052780a7c4fa0122d6bdc55ae1db704da..851fd9e6ee775b6f046e034949e911cc4cf5d006 100644 (file)
@@ -111,7 +111,7 @@ endif
     endif
 
     export WITH_OPENEXR ?= true
-
+    export WITH_DDS ?= true
 
     ifeq ($(OS),windows)
        export NAN_WINTAB ?= $(LCGDIR)/wintab
index f3ad7983e74670587720962fdb1be280b816b8bf..0e1fc81dcff864c2fc25e5e09167df26f5607962 100755 (executable)
@@ -29,6 +29,7 @@ def validate_arguments(args, bc):
             'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
             'WITH_BF_FMOD',
             'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH',
+            'WITH_BF_DDS',
             'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB', 'BF_FFMPEG',  'BF_FFMPEG_INC',
             'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
             'WITH_BF_PNG', 'BF_PNG', 'BF_PNG_INC', 'BF_PNG_LIB', 'BF_PNG_LIBPATH',
@@ -162,6 +163,8 @@ def read_opts(cfg, args):
         ('BF_OPENEXR_LIB', 'OPENEXR library', ''),
         ('BF_OPENEXR_LIBPATH', 'OPENEXR library path', ''),
 
+        (BoolOption('WITH_BF_DDS', 'Use DDS if true', 'true')),
+
         (BoolOption('WITH_BF_FFMPEG', 'Use FFMPEG if true', 'false')),
         ('BF_FFMPEG', 'FFMPEG base path', ''),
         ('BF_FFMPEG_LIB', 'FFMPEG library', ''),