forked from bartvdbraak/blender
This commit is a modified version of patch #6860
It adds read only dds support. (Writing will come later) Kent
This commit is contained in:
parent
ddc68225c2
commit
613646b33e
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
|
@ -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'])
|
||||
|
||||
|
@ -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']
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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']
|
||||
|
@ -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
|
||||
|
||||
|
523
source/blender/imbuf/intern/dds/BlockDXT.cpp
Normal file
523
source/blender/imbuf/intern/dds/BlockDXT.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
227
source/blender/imbuf/intern/dds/BlockDXT.h
Normal file
227
source/blender/imbuf/intern/dds/BlockDXT.h
Normal file
@ -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
|
99
source/blender/imbuf/intern/dds/Color.h
Normal file
99
source/blender/imbuf/intern/dds/Color.h
Normal file
@ -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
|
310
source/blender/imbuf/intern/dds/ColorBlock.cpp
Normal file
310
source/blender/imbuf/intern/dds/ColorBlock.cpp
Normal file
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
115
source/blender/imbuf/intern/dds/ColorBlock.h
Normal file
115
source/blender/imbuf/intern/dds/ColorBlock.h
Normal file
@ -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
|
44
source/blender/imbuf/intern/dds/Common.h
Normal file
44
source/blender/imbuf/intern/dds/Common.h
Normal file
@ -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
|
828
source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
Normal file
828
source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
162
source/blender/imbuf/intern/dds/DirectDrawSurface.h
Normal file
162
source/blender/imbuf/intern/dds/DirectDrawSurface.h
Normal file
@ -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
|
132
source/blender/imbuf/intern/dds/Image.cpp
Normal file
132
source/blender/imbuf/intern/dds/Image.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
103
source/blender/imbuf/intern/dds/Image.h
Normal file
103
source/blender/imbuf/intern/dds/Image.h
Normal file
@ -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
|
67
source/blender/imbuf/intern/dds/Makefile
Normal file
67
source/blender/imbuf/intern/dds/Makefile
Normal file
@ -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
|
18
source/blender/imbuf/intern/dds/SConscript
Normal file
18
source/blender/imbuf/intern/dds/SConscript
Normal file
@ -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])
|
88
source/blender/imbuf/intern/dds/Stream.cpp
Normal file
88
source/blender/imbuf/intern/dds/Stream.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
48
source/blender/imbuf/intern/dds/Stream.h
Normal file
48
source/blender/imbuf/intern/dds/Stream.h
Normal file
@ -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
|
||||
|
120
source/blender/imbuf/intern/dds/dds_api.cpp
Normal file
120
source/blender/imbuf/intern/dds/dds_api.cpp
Normal file
@ -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"
|
43
source/blender/imbuf/intern/dds/dds_api.h
Normal file
43
source/blender/imbuf/intern/dds/dds_api.h
Normal file
@ -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 */
|
@ -59,6 +59,10 @@
|
||||
#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__)
|
||||
|
@ -44,6 +44,11 @@
|
||||
|
||||
#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") ||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
|
@ -111,7 +111,7 @@ endif
|
||||
endif
|
||||
|
||||
export WITH_OPENEXR ?= true
|
||||
|
||||
export WITH_DDS ?= true
|
||||
|
||||
ifeq ($(OS),windows)
|
||||
export NAN_WINTAB ?= $(LCGDIR)/wintab
|
||||
|
@ -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', ''),
|
||||
|
Loading…
Reference in New Issue
Block a user