Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c9
-rw-r--r--source/blender/imbuf/intern/anim_movie.c56
-rw-r--r--source/blender/imbuf/intern/cineon/CMakeLists.txt22
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c9
-rw-r--r--source/blender/imbuf/intern/cineon/cineonfile.h13
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c4
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.c2
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp79
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h8
-rw-r--r--source/blender/imbuf/intern/dds/CMakeLists.txt9
-rw-r--r--source/blender/imbuf/intern/dds/Color.h2
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp188
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h21
-rw-r--r--source/blender/imbuf/intern/dds/Common.h8
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp489
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h22
-rw-r--r--source/blender/imbuf/intern/dds/Image.cpp7
-rw-r--r--source/blender/imbuf/intern/dds/Image.h2
-rw-r--r--source/blender/imbuf/intern/dds/PixelFormat.h34
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp2
-rw-r--r--source/blender/imbuf/intern/dds/Stream.h2
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp24
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.h2
-rw-r--r--source/blender/imbuf/intern/divers.c149
-rw-r--r--source/blender/imbuf/intern/filter.c281
-rw-r--r--source/blender/imbuf/intern/imageprocess.c2
-rw-r--r--source/blender/imbuf/intern/md5.h2
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt13
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp24
-rw-r--r--source/blender/imbuf/intern/png.c18
-rw-r--r--source/blender/imbuf/intern/rectop.c17
-rw-r--r--source/blender/imbuf/intern/scaling.c11
-rw-r--r--source/blender/imbuf/intern/targa.c6
-rw-r--r--source/blender/imbuf/intern/tiff.c39
-rw-r--r--source/blender/imbuf/intern/util.c31
36 files changed, 1176 insertions, 433 deletions
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 4804d363628..fba0772dd93 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -107,7 +107,7 @@
#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff))
/* more endianness... should move to a separate file... */
-#if defined(__sgi) || defined (__sparc) || (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__BIG_ENDIAN__)
+#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__BIG_ENDIAN__)
#define GET_ID GET_BIG_LONG
#define LITTLE_LONG SWAP_LONG
#else
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index a8b9e21331d..59772771f3b 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -84,17 +84,13 @@ void imb_freerectfloatImBuf(ImBuf *ibuf)
void imb_freerectImBuf(ImBuf *ibuf)
{
if(ibuf==NULL) return;
-
- if(ibuf->crect)
- MEM_freeN(ibuf->crect);
if(ibuf->rect && (ibuf->mall & IB_rect))
MEM_freeN(ibuf->rect);
+ ibuf->rect= NULL;
imb_freemipmapImBuf(ibuf);
-
- ibuf->rect= NULL;
- ibuf->crect= NULL;
+
ibuf->mall &= ~IB_rect;
}
@@ -346,6 +342,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flag
ibuf->depth= d;
ibuf->ftype= TGA;
ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */
+ ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */
if(flags & IB_rect) {
if(imb_addrectImBuf(ibuf)==FALSE) {
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 4de96bb17bc..919b0eb0c29 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -97,16 +97,7 @@
#include <libavutil/rational.h>
#include <libswscale/swscale.h>
-#if LIBAVFORMAT_VERSION_INT < (49 << 16)
-#define FFMPEG_OLD_FRAME_RATE 1
-#else
-#define FFMPEG_CODEC_IS_POINTER 1
-#endif
-
-#if (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29) && \
- (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10)
-#define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
-#endif
+#include "ffmpeg_compat.h"
#endif //WITH_FFMPEG
@@ -520,18 +511,6 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
extern void do_init_ffmpeg(void);
-#ifdef FFMPEG_CODEC_IS_POINTER
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return stream->codec;
-}
-#else
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return &stream->codec;
-}
-#endif
-
static int startffmpeg(struct anim * anim) {
int i, videoStream;
@@ -559,14 +538,14 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
- dump_format(pFormatCtx, 0, anim->name, 0);
+ av_dump_format(pFormatCtx, 0, anim->name, 0);
/* Find the first video stream */
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
- if(get_codec_from_stream(pFormatCtx->streams[i])->codec_type
- == CODEC_TYPE_VIDEO) {
+ if(pFormatCtx->streams[i]->codec->codec_type
+ == AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
@@ -576,7 +555,7 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
- pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]);
+ pCodecCtx = pFormatCtx->streams[videoStream]->codec;
/* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
@@ -592,19 +571,10 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
-#ifdef FFMPEG_OLD_FRAME_RATE
- if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
- pCodecCtx->frame_rate_base=1000;
-
-
- anim->duration = pFormatCtx->duration * pCodecCtx->frame_rate
- / pCodecCtx->frame_rate_base / AV_TIME_BASE;
-#else
anim->duration = ceil(pFormatCtx->duration
* av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate)
/ AV_TIME_BASE);
-#endif
anim->params = 0;
anim->x = pCodecCtx->width;
@@ -830,10 +800,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
&& position - (anim->curposition + 1) < anim->preseek) {
while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
if (packet.stream_index == anim->videoStream) {
- avcodec_decode_video(
+ avcodec_decode_video2(
anim->pCodecCtx,
anim->pFrame, &frameFinished,
- packet.data, packet.size);
+ &packet);
if (frameFinished) {
anim->curposition++;
@@ -858,15 +828,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
#endif
if (position != anim->curposition + 1) {
-#ifdef FFMPEG_OLD_FRAME_RATE
- double frame_rate =
- (double) anim->pCodecCtx->frame_rate
- / (double) anim->pCodecCtx->frame_rate_base;
-#else
double frame_rate =
av_q2d(anim->pFormatCtx->streams[anim->videoStream]
->r_frame_rate);
-#endif
double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base);
long long pos;
long long st_time = anim->pFormatCtx->start_time;
@@ -915,9 +879,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
if(packet.stream_index == anim->videoStream) {
- avcodec_decode_video(anim->pCodecCtx,
- anim->pFrame, &frameFinished,
- packet.data, packet.size);
+ avcodec_decode_video2(anim->pCodecCtx,
+ anim->pFrame, &frameFinished,
+ &packet);
if (seek_by_bytes && preseek_count > 0) {
preseek_count--;
diff --git a/source/blender/imbuf/intern/cineon/CMakeLists.txt b/source/blender/imbuf/intern/cineon/CMakeLists.txt
index 92cba72c094..4f7f20beecf 100644
--- a/source/blender/imbuf/intern/cineon/CMakeLists.txt
+++ b/source/blender/imbuf/intern/cineon/CMakeLists.txt
@@ -25,14 +25,18 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
- ../..
- ../../../blenkernel
- ../../../blenloader
- ../../../blenlib
- ../../../makesdna
- ../../../../../intern/guardedalloc
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../blenloader
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
+)
+
+set(INC_SYS
+
)
set(SRC
@@ -44,4 +48,4 @@ set(SRC
logmemfile.c
)
-blender_add_lib(bf_imbuf_cineon "${SRC}" "${INC}")
+blender_add_lib(bf_imbuf_cineon "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 504817b263f..8df2a9f6985 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -44,6 +44,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "IMB_filetype.h"
#include "BKE_global.h"
@@ -192,7 +193,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon
return 1;
}
-short imb_savecineon(struct ImBuf *buf, const char *myfile, int flags)
+int imb_savecineon(struct ImBuf *buf, const char *myfile, int flags)
{
return imb_save_dpx_cineon(buf, myfile, 1, flags);
}
@@ -203,14 +204,14 @@ int imb_is_cineon(unsigned char *buf)
return cineonIsMemFileCineon(buf);
}
-ImBuf *imb_loadcineon(unsigned char *mem, int size, int flags)
+ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags)
{
if(imb_is_cineon(mem))
return imb_load_dpx_cineon(mem, 1, size, flags);
return NULL;
}
-short imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags)
+int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags)
{
return imb_save_dpx_cineon(buf, myfile, 0, flags);
}
@@ -220,7 +221,7 @@ int imb_is_dpx(unsigned char *buf)
return dpxIsMemFileCineon(buf);
}
-ImBuf *imb_loaddpx(unsigned char *mem, int size, int flags)
+ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags)
{
if(imb_is_dpx(mem))
return imb_load_dpx_cineon(mem, 0, size, flags);
diff --git a/source/blender/imbuf/intern/cineon/cineonfile.h b/source/blender/imbuf/intern/cineon/cineonfile.h
index 31aa56f560c..896e0af65b3 100644
--- a/source/blender/imbuf/intern/cineon/cineonfile.h
+++ b/source/blender/imbuf/intern/cineon/cineonfile.h
@@ -126,19 +126,6 @@ typedef struct {
ASCII reserved[740];
} CineonMPISpecificInformation;
-#if 0
-/* create CineonFile from data in header */
-/* return 0 for OK */
-int readCineonGenericHeader(CineonFile* cineon, CineonGenericHeader* header);
-
-/* create header from data in CineonFile */
-int initCineonGenericHeader(
- CineonFile* cineon, CineonGenericHeader* header, const char* imagename);
-
-/* Note: dump routine assumes network byte order */
-void dumpCineonGenericHeader(CineonGenericHeader* header);
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index fdcd3491af1..922cfcf9629 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -276,7 +276,7 @@ dumpCineonOriginationInfo(CineonOriginationInformation* originInfo) {
d_printf("Input device gamma %f\n", ntohf(originInfo->input_device_gamma));
}
-int
+static int
initCineonGenericHeader(CineonFile* cineon, CineonGenericHeader* header, const char* imagename) {
fillCineonFileInfo(cineon, &header->fileInfo, imagename);
@@ -287,7 +287,7 @@ initCineonGenericHeader(CineonFile* cineon, CineonGenericHeader* header, const c
return 0;
}
-void
+static void
dumpCineonGenericHeader(CineonGenericHeader* header) {
dumpCineonFileInfo(&header->fileInfo);
dumpCineonImageInfo(&header->imageInfo);
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c
index 6347eb5fdf9..d3a32774efd 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.c
+++ b/source/blender/imbuf/intern/cineon/logmemfile.c
@@ -27,6 +27,8 @@
#include "logImageCore.h"
+#include "logmemfile.h" /* own include */
+
int logimage_fseek(void* logfile, intptr_t offsett, int origin)
{
struct _Log_Image_File_t_ *file = (struct _Log_Image_File_t_*) logfile;
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index 2989361efe6..0d17f16532b 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -123,6 +123,53 @@ uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
}
}
+
+uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
+{
+ // Does bit expansion before interpolation.
+ color_array[0].b = (3 * col0.b * 22) / 8;
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (3 * col0.r * 22) / 8;
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = (3 * col1.r * 22) / 8;
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (3 * col1.b * 22) / 8;
+ color_array[1].a = 0xFF;
+
+ int gdiff = color_array[1].g - color_array[0].g;
+
+ if( col0.u > col1.u ) {
+ // Four-color block: derive the other two colors.
+ color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
+ color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
+ color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
+ color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
+ color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
+ color_array[3].a = 0xFF;
+
+ return 4;
+ }
+ else {
+ // Three-color block: derive the other color.
+ color_array[2].r = ((col0.r + col1.r) * 33) / 8;
+ color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
+ color_array[2].b = ((col0.b + col1.b) * 33) / 8;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
+ }
+}
+
// Evaluate palette assuming 3 color block.
void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
{
@@ -174,6 +221,7 @@ void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const
color_array[3].a = 0xFF;
}
+
void BlockDXT1::decodeBlock(ColorBlock * block) const
{
// Decode color block.
@@ -189,6 +237,21 @@ void BlockDXT1::decodeBlock(ColorBlock * block) const
}
}
+void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
+{
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePaletteNV5x(color_array);
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
+}
+
void BlockDXT1::setIndices(int * idx)
{
indices = 0;
@@ -225,6 +288,12 @@ void BlockDXT3::decodeBlock(ColorBlock * block) const
alpha.decodeBlock(block);
}
+void BlockDXT3::decodeBlockNV5x(ColorBlock * block) const
+{
+ color.decodeBlockNV5x(block);
+ alpha.decodeBlock(block);
+}
+
void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const
{
block->color(0x0).a = (alpha0 << 4) | alpha0;
@@ -394,7 +463,15 @@ void BlockDXT5::decodeBlock(ColorBlock * block) const
// Decode alpha.
alpha.decodeBlock(block);
+}
+void BlockDXT5::decodeBlockNV5x(ColorBlock * block) const
+{
+ // Decode color.
+ color.decodeBlockNV5x(block);
+
+ // Decode alpha.
+ alpha.decodeBlock(block);
}
/// Flip DXT5 block vertically.
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
index 7c5b9acffd2..aa0c1c509ca 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.h
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -78,11 +78,13 @@ struct BlockDXT1
bool isFourColorMode() const;
uint evaluatePalette(Color32 color_array[4]) const;
- uint evaluatePaletteFast(Color32 color_array[4]) const;
+ uint evaluatePaletteNV5x(Color32 color_array[4]) const;
+
void evaluatePalette3(Color32 color_array[4]) const;
void evaluatePalette4(Color32 color_array[4]) const;
void decodeBlock(ColorBlock * block) const;
+ void decodeBlockNV5x(ColorBlock * block) const;
void setIndices(int * idx);
@@ -136,6 +138,7 @@ struct BlockDXT3
BlockDXT1 color;
void decodeBlock(ColorBlock * block) const;
+ void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
@@ -213,6 +216,7 @@ struct BlockDXT5
BlockDXT1 color;
void decodeBlock(ColorBlock * block) const;
+ void decodeBlockNV5x(ColorBlock * block) const;
void flip4();
void flip2();
diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt
index 7564287ce4a..53822b830f7 100644
--- a/source/blender/imbuf/intern/dds/CMakeLists.txt
+++ b/source/blender/imbuf/intern/dds/CMakeLists.txt
@@ -28,13 +28,16 @@ set(INC
.
..
../..
- ./intern/include
- ../../../blenlib
../../../blenkernel
+ ../../../blenlib
../../../makesdna
../../../../../intern/guardedalloc
)
+set(INC_SYS
+
+)
+
set(SRC
BlockDXT.cpp
ColorBlock.cpp
@@ -48,4 +51,4 @@ if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
-blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}")
+blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
index 5efc259b795..42ed34daf76 100644
--- a/source/blender/imbuf/intern/dds/Color.h
+++ b/source/blender/imbuf/intern/dds/Color.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
index 711d1b54cfa..edb69934231 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.cpp
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -83,65 +83,90 @@ ColorBlock::ColorBlock(const Image * img, uint x, uint y)
void ColorBlock::init(const Image * img, uint x, uint y)
{
- const uint bw = min(img->width() - x, 4U);
- const uint bh = min(img->height() - y, 4U);
+ init(img->width(), img->height(), (const uint *)img->pixels(), x, y);
+}
- static int remainder[] = {
- 0, 0, 0, 0,
- 0, 1, 0, 1,
- 0, 1, 2, 0,
- 0, 1, 2, 3,
- };
+void ColorBlock::init(uint w, uint h, const uint * data, uint x, uint y)
+{
+ const uint bw = min(w - x, 4U);
+ const uint bh = min(h - y, 4U);
- // 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. :(
+ // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+ // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+ // @@ Ideally we should zero the weights of the pixels out of range.
- for(uint i = 0; i < 4; i++) {
- //const int by = i % bh;
- const int by = remainder[(bh - 1) * 4 + i];
- for(uint e = 0; e < 4; e++) {
- //const int bx = e % bw;
- const int bx = remainder[(bw - 1) * 4 + e];
- color(e, i) = img->pixel(x + bx, y + by);
- }
- }
-}
+ for (uint i = 0; i < 4; i++)
+ {
+ const int by = i % bh;
+
+ for (uint e = 0; e < 4; e++)
+ {
+ const int bx = e % bw;
+ const uint idx = (y + by) * w + x + bx;
+ color(e, i).u = data[idx];
+ }
+ }
+}
-void ColorBlock::swizzleDXT5n()
+void ColorBlock::init(uint w, uint h, const float * data, uint x, uint y)
{
- for(int i = 0; i < 16; i++)
+ const uint bw = min(w - x, 4U);
+ const uint bh = min(h - y, 4U);
+
+ // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+ // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+ // @@ Ideally we should zero the weights of the pixels out of range.
+
+ uint srcPlane = w * h;
+
+ for (uint i = 0; i < 4; i++)
{
- Color32 c = m_color[i];
- m_color[i] = Color32(0xFF, c.g, 0, c.r);
+ const uint by = i % bh;
+
+ for (uint e = 0; e < 4; e++)
+ {
+ const uint bx = e % bw;
+ const uint idx = ((y + by) * w + x + bx);
+
+ Color32 & c = color(e, i);
+ c.r = uint8(255 * clamp(data[idx + 0 * srcPlane], 0.0f, 1.0f)); // @@ Is this the right way to quantize floats to bytes?
+ c.g = uint8(255 * clamp(data[idx + 1 * srcPlane], 0.0f, 1.0f));
+ c.b = uint8(255 * clamp(data[idx + 2 * srcPlane], 0.0f, 1.0f));
+ c.a = uint8(255 * clamp(data[idx + 3 * srcPlane], 0.0f, 1.0f));
+ }
}
}
-void ColorBlock::splatX()
+static inline uint8 component(Color32 c, uint i)
{
- for(int i = 0; i < 16; i++)
- {
- uint8 x = m_color[i].r;
- m_color[i] = Color32(x, x, x, x);
- }
+ if (i == 0) return c.r;
+ if (i == 1) return c.g;
+ if (i == 2) return c.b;
+ if (i == 3) return c.a;
+ if (i == 4) return 0xFF;
+ return 0;
}
-void ColorBlock::splatY()
+void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
{
- for(int i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++)
{
- uint8 y = m_color[i].g;
- m_color[i] = Color32(y, y, y, y);
+ Color32 c = m_color[i];
+ m_color[i].r = component(c, x);
+ m_color[i].g = component(c, y);
+ m_color[i].b = component(c, z);
+ m_color[i].a = component(c, w);
}
}
+
/// Returns true if the block has a single color.
-bool ColorBlock::isSingleColor() const
+bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
{
- Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
uint u = m_color[0].u & mask.u;
- for(int i = 1; i < 16; i++)
+ for (int i = 1; i < 16; i++)
{
if (u != (m_color[i].u & mask.u))
{
@@ -152,6 +177,7 @@ bool ColorBlock::isSingleColor() const
return true;
}
+/*
/// Returns true if the block has a single color, ignoring transparent pixels.
bool ColorBlock::isSingleColorNoAlpha() const
{
@@ -159,7 +185,7 @@ bool ColorBlock::isSingleColorNoAlpha() const
int i;
for(i = 0; i < 16; i++)
{
- if (m_color[i].a != 0) c = m_color[i];
+ if (m_color[i].a != 0) c = m_color[i];
}
Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
@@ -175,9 +201,10 @@ bool ColorBlock::isSingleColorNoAlpha() const
return true;
}
+*/
/// Count number of unique colors in this color block.
-uint ColorBlock::countUniqueColors() const
+/*uint ColorBlock::countUniqueColors() const
{
uint count = 0;
@@ -197,9 +224,9 @@ uint ColorBlock::countUniqueColors() const
}
return count;
-}
+}*/
-/// Get average color of the block.
+/*/// Get average color of the block.
Color32 ColorBlock::averageColor() const
{
uint r, g, b, a;
@@ -213,7 +240,7 @@ Color32 ColorBlock::averageColor() const
}
return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16));
-}
+}*/
/// Return true if the block is not fully opaque.
bool ColorBlock::hasAlpha() const
@@ -225,6 +252,7 @@ bool ColorBlock::hasAlpha() const
return false;
}
+#if 0
/// Get diameter color range.
void ColorBlock::diameterRange(Color32 * start, Color32 * end) const
@@ -345,8 +373,9 @@ void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const
*start = minColor;
*end = maxColor;
}
+#endif
-/// Sort colors by abosolute value in their 16 bit representation.
+/*/// Sort colors by abosolute value in their 16 bit representation.
void ColorBlock::sortColorsByAbsoluteValue()
{
// Dummy selection sort.
@@ -364,4 +393,75 @@ void ColorBlock::sortColorsByAbsoluteValue()
}
swap( m_color[a], m_color[max] );
}
+}*/
+
+
+/*/// Find extreme colors in the given axis.
+void ColorBlock::computeRange(Vector3::Arg axis, Color32 * start, Color32 * end) const
+{
+
+ int mini, maxi;
+ mini = maxi = 0;
+
+ float min, max;
+ min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis);
+
+ for(uint i = 1; i < 16; i++)
+ {
+ const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+
+ float val = dot(vec, axis);
+ if( val < min ) {
+ mini = i;
+ min = val;
+ }
+ else if( val > max ) {
+ maxi = i;
+ max = val;
+ }
+ }
+
+ *start = m_color[mini];
+ *end = m_color[maxi];
+}*/
+
+
+/*/// Sort colors in the given axis.
+void ColorBlock::sortColors(const Vector3 & axis)
+{
+ float luma_array[16];
+
+ for(uint i = 0; i < 16; i++) {
+ const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+ luma_array[i] = dot(vec, axis);
+ }
+
+ // Dummy selection sort.
+ for( uint a = 0; a < 16; a++ ) {
+ uint min = a;
+ for( uint b = a+1; b < 16; b++ ) {
+ if( luma_array[b] < luma_array[min] ) {
+ min = b;
+ }
+ }
+ swap( luma_array[a], luma_array[min] );
+ swap( m_color[a], m_color[min] );
+ }
+}*/
+
+
+/*/// Get the volume of the color block.
+float ColorBlock::volume() const
+{
+ Box bounds;
+ bounds.clearBounds();
+
+ for(int i = 0; i < 16; i++) {
+ const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b);
+ bounds.addPointToBounds(point);
+ }
+
+ return bounds.volume();
}
+*/
+
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index dd40d21e8b3..d4e4e8a809f 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -51,26 +51,15 @@ struct ColorBlock
ColorBlock(const Image * img, uint x, uint y);
void init(const Image * img, uint x, uint y);
+ void init(uint w, uint h, const uint * data, uint x, uint y);
+ void init(uint w, uint h, const float * data, uint x, uint y);
- void swizzleDXT5n();
- void splatX();
- void splatY();
+ void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
- bool isSingleColor() const;
- bool isSingleColorNoAlpha() const;
- uint countUniqueColors() const;
- Color32 averageColor() const;
+ bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
bool hasAlpha() 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 sortColorsByAbsoluteValue();
-
- float volume() const;
-
// Accessors
const Color32 * colors() const;
diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h
index 25b743311d2..a6dcf69febf 100644
--- a/source/blender/imbuf/intern/dds/Common.h
+++ b/source/blender/imbuf/intern/dds/Common.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -55,4 +55,10 @@ typedef unsigned int uint;
typedef unsigned int uint32;
typedef unsigned long long uint64;
+// copied from nvtt src/nvimage/nvimage.h
+inline uint computePitch(uint w, uint bitsize, uint alignment)
+{
+ return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
+}
+
#endif
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index ede82896554..971658ff482 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -69,12 +69,11 @@
#if !defined(MAKEFOURCC)
# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
- ((uint)((unsigned char)(ch0)) | \
- ((uint)((unsigned char)(ch1)) << 8) | \
- ((uint)((unsigned char)(ch2)) << 16) | \
- ((uint)((unsigned char)(ch3)) << 24 ))
+ (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
+ (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif
+static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
@@ -89,6 +88,8 @@ static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y');
static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
+static const uint FOURCC_UVER = MAKEFOURCC('U', 'V', 'E', 'R');
+
// 32 bit RGB formats.
static const uint D3DFMT_R8G8B8 = 20;
static const uint D3DFMT_A8R8G8B8 = 21;
@@ -160,7 +161,10 @@ static const uint DDPF_PALETTEINDEXED4 = 0x00000008U;
static const uint DDPF_PALETTEINDEXED8 = 0x00000020U;
static const uint DDPF_LUMINANCE = 0x00020000U;
static const uint DDPF_ALPHAPREMULT = 0x00008000U;
-static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag.
+
+// Custom NVTT flags.
+static const uint DDPF_NORMAL = 0x80000000U;
+static const uint DDPF_SRGB = 0x40000000U;
// DX10 formats.
enum DXGI_FORMAT
@@ -277,6 +281,20 @@ static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag.
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+
+ DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+
+ DXGI_FORMAT_BC6H_TYPELESS = 94,
+ DXGI_FORMAT_BC6H_UF16 = 95,
+ DXGI_FORMAT_BC6H_SF16 = 96,
+
+ DXGI_FORMAT_BC7_TYPELESS = 97,
+ DXGI_FORMAT_BC7_UNORM = 98,
+ DXGI_FORMAT_BC7_UNORM_SRGB = 99,
};
enum D3D10_RESOURCE_DIMENSION
@@ -478,6 +496,63 @@ void mem_read(Stream & mem, DDSHeader & header)
}
}
+namespace
+{
+ struct FormatDescriptor
+ {
+ uint format;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
+ };
+
+ static const FormatDescriptor s_d3dFormats[] =
+ {
+ { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 },
+ { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM
+ { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM
+ { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM
+ { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 },
+ { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM
+ { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 },
+ { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 },
+ { D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM
+ { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 },
+ { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 },
+ { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2
+ { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM
+ { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 },
+ { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM
+ { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 },
+ { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 },
+
+ { D3DFMT_L8, 8, 8, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM
+ { D3DFMT_L16, 16, 16, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM
+ };
+
+ static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
+
+} // namespace
+
+uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
+{
+ for (int i = 0; i < s_d3dFormatCount; i++)
+ {
+ if (s_d3dFormats[i].bitcount == bitcount &&
+ s_d3dFormats[i].rmask == rmask &&
+ s_d3dFormats[i].gmask == gmask &&
+ s_d3dFormats[i].bmask == bmask &&
+ s_d3dFormats[i].amask == amask)
+ {
+ return s_d3dFormats[i].format;
+ }
+ }
+
+ return 0;
+ }
+
DDSHeader::DDSHeader()
@@ -493,8 +568,8 @@ DDSHeader::DDSHeader()
for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
// Store version information on the reserved header attributes.
- this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T');
- this->reserved[10] = (0 << 16) | (9 << 8) | (5); // major.minor.revision
+ this->reserved[9] = FOURCC_NVTT;
+ this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision
this->pf.size = 32;
this->pf.flags = 0;
@@ -532,7 +607,7 @@ void DDSHeader::setHeight(uint h)
void DDSHeader::setDepth(uint d)
{
this->flags |= DDSD_DEPTH;
- this->height = d;
+ this->depth = d;
}
void DDSHeader::setMipmapCount(uint count)
@@ -540,7 +615,7 @@ void DDSHeader::setMipmapCount(uint count)
if (count == 0 || count == 1)
{
this->flags &= ~DDSD_MIPMAPCOUNT;
- this->mipmapcount = 0;
+ this->mipmapcount = 1;
if (this->caps.caps2 == 0) {
this->caps.caps1 = DDSCAPS_TEXTURE;
@@ -561,6 +636,7 @@ void DDSHeader::setMipmapCount(uint count)
void DDSHeader::setTexture2D()
{
this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTexture3D()
@@ -568,6 +644,7 @@ void DDSHeader::setTexture3D()
this->caps.caps2 = DDSCAPS2_VOLUME;
this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTextureCube()
@@ -599,21 +676,32 @@ void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
this->pf.flags = DDPF_FOURCC;
this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
- if (this->pf.fourcc == FOURCC_ATI2)
- {
- this->pf.bitcount = FOURCC_A2XY;
- }
- else
- {
- this->pf.bitcount = 0;
- }
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
+}
+
+void DDSHeader::setFormatCode(uint32 code)
+{
+ // set fourcc pixel format.
+ this->pf.flags = DDPF_FOURCC;
+ this->pf.fourcc = code;
+ this->pf.bitcount = 0;
this->pf.rmask = 0;
this->pf.gmask = 0;
this->pf.bmask = 0;
this->pf.amask = 0;
}
+void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
+{
+ this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
+}
+
+
void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
{
// Make sure the masks are correct.
@@ -627,10 +715,24 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask
return;
}
- this->pf.flags = DDPF_RGB;
-
- if (amask != 0) {
- this->pf.flags |= DDPF_ALPHAPIXELS;
+ if (rmask != 0 || gmask != 0 || bmask != 0)
+ {
+ if (gmask == 0 && bmask == 0)
+ {
+ this->pf.flags = DDPF_LUMINANCE;
+ }
+ else
+ {
+ this->pf.flags = DDPF_RGB;
+ }
+
+ if (amask != 0) {
+ this->pf.flags |= DDPF_ALPHAPIXELS;
+ }
+ }
+ else if (amask != 0)
+ {
+ this->pf.flags |= DDPF_ALPHA;
}
if (bitcount == 0)
@@ -643,18 +745,16 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask
}
}
+ // D3DX functions do not like this:
+ this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
+ /*if (this->pf.fourcc) {
+ this->pf.flags |= DDPF_FOURCC;
+ }*/
+
if (!(bitcount > 0 && bitcount <= 32)) {
printf("DDS: bad bit count, pixel format not set\n");
return;
}
-
- // Align to 8.
- if (bitcount <= 8) bitcount = 8;
- else if (bitcount <= 16) bitcount = 16;
- else if (bitcount <= 24) bitcount = 24;
- else bitcount = 32;
-
- this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
this->pf.bitcount = bitcount;
this->pf.rmask = rmask;
this->pf.gmask = gmask;
@@ -675,10 +775,108 @@ void DDSHeader::setNormalFlag(bool b)
else this->pf.flags &= ~DDPF_NORMAL;
}
+void DDSHeader::setSrgbFlag(bool b)
+{
+ if (b) this->pf.flags |= DDPF_SRGB;
+ else this->pf.flags &= ~DDPF_SRGB;
+}
+
+void DDSHeader::setHasAlphaFlag(bool b)
+{
+ if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
+ else this->pf.flags &= ~DDPF_ALPHAPIXELS;
+}
+
+void DDSHeader::setUserVersion(int version)
+{
+ this->reserved[7] = FOURCC_UVER;
+ this->reserved[8] = version;
+}
+
+/*
+void DDSHeader::swapBytes()
+{
+ this->fourcc = POSH_LittleU32(this->fourcc);
+ this->size = POSH_LittleU32(this->size);
+ this->flags = POSH_LittleU32(this->flags);
+ this->height = POSH_LittleU32(this->height);
+ this->width = POSH_LittleU32(this->width);
+ this->pitch = POSH_LittleU32(this->pitch);
+ this->depth = POSH_LittleU32(this->depth);
+ this->mipmapcount = POSH_LittleU32(this->mipmapcount);
+
+ for(int i = 0; i < 11; i++) {
+ this->reserved[i] = POSH_LittleU32(this->reserved[i]);
+ }
+
+ this->pf.size = POSH_LittleU32(this->pf.size);
+ this->pf.flags = POSH_LittleU32(this->pf.flags);
+ this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
+ this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
+ this->pf.rmask = POSH_LittleU32(this->pf.rmask);
+ this->pf.gmask = POSH_LittleU32(this->pf.gmask);
+ this->pf.bmask = POSH_LittleU32(this->pf.bmask);
+ this->pf.amask = POSH_LittleU32(this->pf.amask);
+ this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
+ this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
+ this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
+ this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
+ this->notused = POSH_LittleU32(this->notused);
+
+ this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
+ this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
+ this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
+ this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
+ this->header10.reserved = POSH_LittleU32(this->header10.reserved);
+}
+*/
+
bool DDSHeader::hasDX10Header() const
{
- return this->pf.fourcc == FOURCC_DX10; // @@ This is according to AMD
- //return this->pf.flags == 0; // @@ This is according to MS
+ return this->pf.fourcc == FOURCC_DX10;
+}
+
+uint DDSHeader::signature() const
+{
+ return this->reserved[9];
+}
+
+uint DDSHeader::toolVersion() const
+{
+ return this->reserved[10];
+}
+
+uint DDSHeader::userVersion() const
+{
+ if (this->reserved[7] == FOURCC_UVER) {
+ return this->reserved[8];
+ }
+ return 0;
+}
+
+bool DDSHeader::isNormalMap() const
+{
+ return (pf.flags & DDPF_NORMAL) != 0;
+}
+
+bool DDSHeader::isSrgb() const
+{
+ return (pf.flags & DDPF_SRGB) != 0;
+}
+
+bool DDSHeader::hasAlpha() const
+{
+ return (pf.flags & DDPF_ALPHAPIXELS) != 0;
+}
+
+uint DDSHeader::d3d9Format() const
+{
+ if (pf.flags & DDPF_FOURCC) {
+ return pf.fourcc;
+ }
+ else {
+ return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
+ }
}
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
@@ -725,6 +923,16 @@ bool DirectDrawSurface::isSupported() const
{
if (header.hasDX10Header())
{
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
+ {
+ return true;
+ }
+
+ return false;
}
else
{
@@ -743,9 +951,9 @@ bool DirectDrawSurface::isSupported() const
return false;
}
}
- else if (header.pf.flags & DDPF_RGB)
- {
- // All RGB formats are supported now.
+ else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE))
+ {
+ // All RGB and luminance formats are supported now.
}
else
{
@@ -768,6 +976,41 @@ bool DirectDrawSurface::isSupported() const
return true;
}
+bool DirectDrawSurface::hasAlpha() const
+{
+ if (header.hasDX10Header())
+ {
+ /* TODO: Update hasAlpha to handle all DX10 formats. */
+ return
+ header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
+ }
+ else
+ {
+ if (header.pf.flags & DDPF_RGB)
+ {
+ return header.pf.amask != 0;
+ }
+ else if (header.pf.flags & DDPF_FOURCC)
+ {
+ if (header.pf.fourcc == FOURCC_RXGB ||
+ header.pf.fourcc == FOURCC_ATI1 ||
+ header.pf.fourcc == FOURCC_ATI2 ||
+ header.pf.flags & DDPF_NORMAL)
+ {
+ return false;
+ }
+ else
+ {
+ // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
uint DirectDrawSurface::mipmapCount() const
{
@@ -794,22 +1037,6 @@ uint DirectDrawSurface::depth() const
else return 1;
}
-bool DirectDrawSurface::hasAlpha() const
-{
- if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
- {
- return false;
- }
- else if (header.pf.fourcc == FOURCC_DXT1)
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
bool DirectDrawSurface::isTexture1D() const
{
if (header.hasDX10Header())
@@ -853,6 +1080,16 @@ void DirectDrawSurface::setNormalFlag(bool b)
header.setNormalFlag(b);
}
+void DirectDrawSurface::setHasAlphaFlag(bool b)
+{
+ header.setHasAlphaFlag(b);
+}
+
+void DirectDrawSurface::setUserVersion(int version)
+{
+ header.setUserVersion(version);
+}
+
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
{
stream.seek(offset(face, mipmap));
@@ -869,14 +1106,31 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
img->allocate(w, h);
- if (header.pf.flags & DDPF_RGB)
+ if (hasAlpha())
+ {
+ img->setFormat(Image::Format_ARGB);
+ }
+ else
{
- readLinearImage(img);
+ img->setFormat(Image::Format_RGB);
}
- else if (header.pf.flags & DDPF_FOURCC)
+
+ if (header.hasDX10Header())
{
+ // So far only block formats supported.
readBlockImage(img);
}
+ else
+ {
+ if (header.pf.flags & DDPF_RGB)
+ {
+ readLinearImage(img);
+ }
+ else if (header.pf.flags & DDPF_FOURCC)
+ {
+ readBlockImage(img);
+ }
+ }
}
void DirectDrawSurface::readLinearImage(Image * img)
@@ -906,17 +1160,6 @@ void DirectDrawSurface::readLinearImage(Image * img)
return;
}
- // set image format: RGB or ARGB
- // alpha channel exists if and only if the alpha mask is non-zero
- if (header.pf.amask == 0)
- {
- img->setFormat(Image::Format_RGB);
- }
- else
- {
- img->setFormat(Image::Format_ARGB);
- }
-
// Read linear RGB images.
for (uint y = 0; y < h; y++)
{
@@ -926,10 +1169,10 @@ void DirectDrawSurface::readLinearImage(Image * img)
mem_read(stream, (unsigned char *)(&c), byteCount);
Color32 pixel(0, 0, 0, 0xFF);
- pixel.r = PixelFormat::convert(c >> rshift, rsize, 8);
- pixel.g = PixelFormat::convert(c >> gshift, gsize, 8);
- pixel.b = PixelFormat::convert(c >> bshift, bsize, 8);
- pixel.a = PixelFormat::convert(c >> ashift, asize, 8);
+ pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
+ pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
+ pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
+ pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
img->pixel(x, y) = pixel;
}
@@ -939,19 +1182,6 @@ void DirectDrawSurface::readLinearImage(Image * img)
void DirectDrawSurface::readBlockImage(Image * img)
{
- // set image format: RGB or ARGB
- if (header.pf.fourcc == FOURCC_RXGB ||
- header.pf.fourcc == FOURCC_ATI1 ||
- header.pf.fourcc == FOURCC_ATI2 ||
- header.pf.flags & DDPF_NORMAL)
- {
- img->setFormat(Image::Format_RGB);
- }
- else
- {
- img->setFormat(Image::Format_ARGB);
- }
-
const uint w = img->width();
const uint h = img->height();
@@ -993,20 +1223,33 @@ static Color32 buildNormal(uint8 x, uint8 y)
void DirectDrawSurface::readBlock(ColorBlock * rgba)
{
- if (header.pf.fourcc == FOURCC_DXT1)
+ uint fourcc = header.pf.fourcc;
+
+ // Map DX10 block formats to fourcc codes.
+ if (header.hasDX10Header())
+ {
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
+ }
+
+
+ if (fourcc == FOURCC_DXT1)
{
BlockDXT1 block;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_DXT2 ||
+ else if (fourcc == FOURCC_DXT2 ||
header.pf.fourcc == FOURCC_DXT3)
{
BlockDXT3 block;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_DXT4 ||
+ else if (fourcc == FOURCC_DXT4 ||
header.pf.fourcc == FOURCC_DXT5 ||
header.pf.fourcc == FOURCC_RXGB)
{
@@ -1014,7 +1257,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
mem_read(stream, block);
block.decodeBlock(rgba);
- if (header.pf.fourcc == FOURCC_RXGB)
+ if (fourcc == FOURCC_RXGB)
{
// Swap R & A.
for (int i = 0; i < 16; i++)
@@ -1026,13 +1269,13 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
}
}
}
- else if (header.pf.fourcc == FOURCC_ATI1)
+ else if (fourcc == FOURCC_ATI1)
{
BlockATI1 block;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_ATI2)
+ else if (fourcc == FOURCC_ATI2)
{
BlockATI2 block;
mem_read(stream, block);
@@ -1042,7 +1285,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
// If normal flag set, convert to normal.
if (header.pf.flags & DDPF_NORMAL)
{
- if (header.pf.fourcc == FOURCC_ATI2)
+ if (fourcc == FOURCC_ATI2)
{
for (int i = 0; i < 16; i++)
{
@@ -1050,7 +1293,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
c = buildNormal(c.r, c.g);
}
}
- else if (header.pf.fourcc == FOURCC_DXT5)
+ else if (fourcc == FOURCC_DXT5)
{
for (int i = 0; i < 16; i++)
{
@@ -1076,6 +1319,27 @@ uint DirectDrawSurface::blockSize() const
case FOURCC_RXGB:
case FOURCC_ATI2:
return 16;
+ case FOURCC_DX10:
+ switch(header.header10.dxgiFormat)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return 8;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ return 16;
+ };
};
// Not a block image.
@@ -1102,14 +1366,10 @@ uint DirectDrawSurface::mipmapSize(uint mipmap) const
h = (h + 3) / 4;
return blockSize() * w * h;
}
- else if (header.pf.flags & DDPF_RGB)
+ else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE))
{
- // Align pixels to bytes.
- uint byteCount = (header.pf.bitcount + 7) / 8;
-
- // Align pitch to 4 bytes.
- uint pitch = 4 * ((w * byteCount + 3) / 4);
-
+ uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects.
+
return pitch * h * d;
}
else {
@@ -1133,7 +1393,7 @@ uint DirectDrawSurface::faceSize() const
uint DirectDrawSurface::offset(const uint face, const uint mipmap)
{
- uint size = 128; //sizeof(DDSHeader);
+ uint size = 128; // sizeof(DDSHeader);
if (header.hasDX10Header())
{
@@ -1156,7 +1416,6 @@ uint DirectDrawSurface::offset(const uint face, const uint mipmap)
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");
@@ -1175,9 +1434,9 @@ void DirectDrawSurface::printInfo() const
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_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
@@ -1188,23 +1447,30 @@ void DirectDrawSurface::printInfo() const
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));
- if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0))
+ if (header.pf.fourcc != 0) {
+ // Display fourcc code even when DDPF_FOURCC flag not set.
+ printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
+ ((header.pf.fourcc >> 0) & 0xFF),
+ ((header.pf.fourcc >> 8) & 0xFF),
+ ((header.pf.fourcc >> 16) & 0xFF),
+ ((header.pf.fourcc >> 24) & 0xFF),
+ header.pf.fourcc);
+ }
+
+ if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
{
- printf("\tSwizzle: '%c%c%c%c'\n",
+ printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
(header.pf.bitcount >> 0) & 0xFF,
(header.pf.bitcount >> 8) & 0xFF,
(header.pf.bitcount >> 16) & 0xFF,
- (header.pf.bitcount >> 24) & 0xFF);
+ (header.pf.bitcount >> 24) & 0xFF,
+ header.pf.bitcount);
}
else
{
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);
@@ -1244,7 +1510,7 @@ void DirectDrawSurface::printInfo() const
printf("\tArray size: %u\n", header.header10.arraySize);
}
- if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T'))
+ if (header.reserved[9] == FOURCC_NVTT)
{
int major = (header.reserved[10] >> 16) & 0xFF;
int minor = (header.reserved[10] >> 8) & 0xFF;
@@ -1253,5 +1519,10 @@ void DirectDrawSurface::printInfo() const
printf("Version:\n");
printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
}
+
+ if (header.reserved[7] == FOURCC_UVER)
+ {
+ printf("User Version: %d\n", header.reserved[8]);
+ }
}
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index cc04c50e795..5978e780991 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -126,11 +126,25 @@ struct DDSHeader
void setLinearSize(uint size);
void setPitch(uint pitch);
void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
+ void setFormatCode(uint code);
+ void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
void setDX10Format(uint format);
void setNormalFlag(bool b);
+ void setSrgbFlag(bool b);
+ void setHasAlphaFlag(bool b);
+ void setUserVersion(int version);
+
+ /*void swapBytes();*/
bool hasDX10Header() const;
+ uint signature() const;
+ uint toolVersion() const;
+ uint userVersion() const;
+ bool isNormalMap() const;
+ bool isSrgb() const;
+ bool hasAlpha() const;
+ uint d3d9Format() const;
};
/// DirectDraw Surface. (DDS)
@@ -142,6 +156,8 @@ public:
bool isValid() const;
bool isSupported() const;
+
+ bool hasAlpha() const;
uint mipmapCount() const;
uint width() const;
@@ -153,8 +169,8 @@ public:
bool isTextureCube() const;
void setNormalFlag(bool b);
-
- bool hasAlpha() const; /* false for DXT1, true for all other DXTs */
+ void setHasAlphaFlag(bool b);
+ void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
// void mipmap(FloatImage * img, uint f, uint m);
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
index a775a9125d2..b9ec1c0c3aa 100644
--- a/source/blender/imbuf/intern/dds/Image.cpp
+++ b/source/blender/imbuf/intern/dds/Image.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -41,7 +41,7 @@
#include <stdio.h> // printf
-Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(0)
+Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL)
{
}
@@ -61,7 +61,7 @@ void Image::allocate(uint w, uint h)
void Image::free()
{
if (m_data) delete [] m_data;
- m_data = 0;
+ m_data = NULL;
}
@@ -132,3 +132,4 @@ void Image::setFormat(Image::Format f)
m_format = f;
}
+
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
index 88051410056..96e455fc75b 100644
--- a/source/blender/imbuf/intern/dds/Image.h
+++ b/source/blender/imbuf/intern/dds/Image.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h
index c483c525570..35c6eacb972 100644
--- a/source/blender/imbuf/intern/dds/PixelFormat.h
+++ b/source/blender/imbuf/intern/dds/PixelFormat.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -107,6 +107,38 @@
}
}
+ inline float quantizeCeil(float f, int inbits, int outbits)
+ {
+ //uint i = f * (float(1 << inbits) - 1);
+ //i = convert(i, inbits, outbits);
+ //float result = float(i) / (float(1 << outbits) - 1);
+ //nvCheck(result >= f);
+ float result;
+ int offset = 0;
+ do {
+ uint i = offset + uint(f * (float(1 << inbits) - 1));
+ i = convert(i, inbits, outbits);
+ result = float(i) / (float(1 << outbits) - 1);
+ offset++;
+ } while (result < f);
+
+ return result;
+ }
+
+ /*
+ inline float quantizeRound(float f, int bits)
+ {
+ float scale = float(1 << bits);
+ return fround(f * scale) / scale;
+ }
+
+ inline float quantizeFloor(float f, int bits)
+ {
+ float scale = float(1 << bits);
+ return floor(f * scale) / scale;
+ }
+ */
+
} // PixelFormat namespace
#endif // _DDS_IMAGE_PIXELFORMAT_H
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 88c5277e097..497109efd25 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
index acc2c8bb176..ca081d331fe 100644
--- a/source/blender/imbuf/intern/dds/Stream.h
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index a7b2934cafa..73ee3a2cb9c 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -106,10 +106,21 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
}
/* convert DDS into ImBuf */
- // TODO use the image RGB or RGBA tag to determine the bits per pixel
- if (dds.hasAlpha()) bits_per_pixel = 32;
- else bits_per_pixel = 24;
- ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
+ dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
+ pixels = img.pixels();
+ numpixels = dds.width() * dds.height();
+ bits_per_pixel = 24;
+ if (img.format() == Image::Format_ARGB) {
+ /* check that there is effectively an alpha channel */
+ for (unsigned int i = 0; i < numpixels; i++) {
+ pixel = pixels[i];
+ if (pixel.a != 255) {
+ bits_per_pixel = 32;
+ break;
+ };
+ };
+ };
+ ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
if (ibuf == 0) return(0); /* memory allocation failed */
ibuf->ftype = DDS;
@@ -120,9 +131,6 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
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++) {
diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h
index cfc6910e71d..d78e4f31474 100644
--- a/source/blender/imbuf/intern/dds/dds_api.h
+++ b/source/blender/imbuf/intern/dds/dds_api.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 6b35d7df397..7fc7669601d 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -197,6 +197,135 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
ibuf->userflags &= ~IB_RECT_INVALID;
}
+
+
+/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
+{
+ /* indices to source and destination image pixels */
+ float *srcFloatPxl;
+ unsigned char *dstBytePxl;
+ /* buffer index will fill buffer */
+ float *bufferIndex;
+
+ /* convenience pointers to start of image buffers */
+ float *init_srcFloatPxl = (float *)ibuf->rect_float;
+ unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
+
+ /* Dithering factor */
+ float dither= ibuf->dither / 255.0f;
+ /* respective attributes of image */
+ short profile= ibuf->profile;
+ int channels= ibuf->channels;
+
+ int i, j;
+
+ /*
+ if called -only- from GPU_paint_update_image this test will never fail
+ but leaving it here for better or worse
+ */
+ if(init_srcFloatPxl==NULL || (buffer == NULL)){
+ return;
+ }
+ if(init_dstBytePxl==NULL) {
+ imb_addrectImBuf(ibuf);
+ init_dstBytePxl = (unsigned char *) ibuf->rect;
+ }
+ if(channels==1) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x);
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) {
+ dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
+ bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
+ }
+ }
+ }
+ else if (profile == IB_PROFILE_LINEAR_RGB) {
+ if(channels == 3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3]= 1.0;
+ }
+ }
+ }
+ else if (channels == 4) {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3] = srcFloatPxl[3];
+ add_v4_fl(bufferIndex, d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3]= srcFloatPxl[3];
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
+ if(channels==3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) {
+ copy_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3] = 1.0;
+ }
+ }
+ }
+ else {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ add_v4_fl(bufferIndex,d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ /* ensure user flag is reset */
+ ibuf->userflags &= ~IB_RECT_INVALID;
+}
+
static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
{
float *tof = fbuf;
@@ -361,3 +490,23 @@ float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
return fbuf;
}
}
+
+
+/* no profile conversion */
+void IMB_color_to_bw(struct ImBuf *ibuf)
+{
+ float *rctf= ibuf->rect_float;
+ unsigned char *rct= (unsigned char *)ibuf->rect;
+ int i;
+ if(rctf) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
+ rctf[0]= rctf[1]= rctf[2]= rgb_to_grayscale(rctf);
+ }
+ }
+
+ if(rct) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
+ rct[0]= rct[1]= rct[2]= rgb_to_grayscale_byte(rct);
+ }
+ }
+}
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 2821ba2a361..1644e653df4 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -21,7 +21,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Morten Mikkelsen.
*
* ***** END GPL LICENSE BLOCK *****
* filter.c
@@ -262,121 +262,196 @@ void IMB_filter(struct ImBuf *ibuf)
imb_filterx(ibuf);
}
-#define EXTEND_PIXEL(color, w) if((color)[3]) {r+= w*(color)[0]; g+= w*(color)[1]; b+= w*(color)[2]; a+= w*(color)[3]; tot+=w;}
-
-/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
- *
- * When a mask is given, only effect pixels with a mask value of 1, defined as BAKE_MASK_MARGIN in rendercore.c
- * */
-void IMB_filter_extend(struct ImBuf *ibuf, char *mask)
+void IMB_mask_filter_extend(char *mask, int width, int height)
{
- register char *row1, *row2, *row3;
- register char *cp;
+ char *row1, *row2, *row3;
int rowlen, x, y;
-
- rowlen= ibuf->x;
-
-
+ char *temprect;
+
+ rowlen= width;
+
+ /* make a copy, to prevent flooding */
+ temprect= MEM_dupallocN(mask);
+
+ for(y=1; y<=height; y++) {
+ /* setup rows */
+ row1= (char *)(temprect + (y-2)*rowlen);
+ row2= row1 + rowlen;
+ row3= row2 + rowlen;
+ if(y==1)
+ row1= row2;
+ else if(y==height)
+ row3= row2;
+
+ for(x=0; x<rowlen; x++) {
+ if (mask[((y-1)*rowlen)+x]==0) {
+ if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
+ mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+ } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
+ mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+ }
+ }
+
+ if(x!=0) {
+ row1++; row2++; row3++;
+ }
+ }
+ }
+
+ MEM_freeN(temprect);
+}
+
+void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
+{
+ int x,y;
if (ibuf->rect_float) {
- float *temprect;
- float *row1f, *row2f, *row3f;
- float *fp;
- temprect= MEM_dupallocN(ibuf->rect_float);
-
- for(y=1; y<=ibuf->y; y++) {
- /* setup rows */
- row1f= (float *)(temprect + (y-2)*rowlen*4);
- row2f= row1f + 4*rowlen;
- row3f= row2f + 4*rowlen;
- if(y==1)
- row1f= row2f;
- else if(y==ibuf->y)
- row3f= row2f;
-
- fp= (float *)(ibuf->rect_float + (y-1)*rowlen*4);
-
- for(x=0; x<rowlen; x++) {
- if((mask==NULL && fp[3]==0.0f) || (mask && mask[((y-1)*rowlen)+x]==1)) {
- int tot= 0;
- float r=0.0f, g=0.0f, b=0.0f, a=0.0f;
-
- EXTEND_PIXEL(row1f, 1);
- EXTEND_PIXEL(row2f, 2);
- EXTEND_PIXEL(row3f, 1);
- EXTEND_PIXEL(row1f+4, 2);
- EXTEND_PIXEL(row3f+4, 2);
- if(x!=rowlen-1) {
- EXTEND_PIXEL(row1f+8, 1);
- EXTEND_PIXEL(row2f+8, 2);
- EXTEND_PIXEL(row3f+8, 1);
- }
- if(tot) {
- fp[0]= r/tot;
- fp[1]= g/tot;
- fp[2]= b/tot;
- fp[3]= a/tot;
- }
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0.0f;
}
- fp+=4;
-
- if(x!=0) {
- row1f+=4; row2f+=4; row3f+=4;
+ }
+ }
+ } else {
+ /* char buffer */
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ char *col= (char *)(ibuf->rect + ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0;
}
}
}
+ }
+}
+
+static int filter_make_index(const int x, const int y, const int w, const int h)
+{
+ if(x<0 || x>=w || y<0 || y>=h) return -1; /* return bad index */
+ else return y*w+x;
+}
+
+static int check_pixel_assigned(const void *buffer, const char *mask, const int index, const int depth, const int is_float)
+{
+ int res = 0;
+
+ if(index>=0) {
+ const int alpha_index = depth*index+(depth-1);
- MEM_freeN(temprect);
+ if(mask!=NULL) {
+ res = mask[index]!=0 ? 1 : 0;
+ }
+ else if( (is_float && ((const float *) buffer)[alpha_index]!=0.0f) ||
+ (!is_float && ((const unsigned char *) buffer)[alpha_index]!=0) ) {
+ res=1;
+ }
}
- else if(ibuf->rect) {
- int *temprect;
-
- /* make a copy, to prevent flooding */
- temprect= MEM_dupallocN(ibuf->rect);
-
- for(y=1; y<=ibuf->y; y++) {
- /* setup rows */
- row1= (char *)(temprect + (y-2)*rowlen);
- row2= row1 + 4*rowlen;
- row3= row2 + 4*rowlen;
- if(y==1)
- row1= row2;
- else if(y==ibuf->y)
- row3= row2;
-
- cp= (char *)(ibuf->rect + (y-1)*rowlen);
-
- for(x=0; x<rowlen; x++) {
- /*if(cp[3]==0) {*/
- if((mask==NULL && cp[3]==0) || (mask && mask[((y-1)*rowlen)+x]==1)) {
- int tot= 0, r=0, g=0, b=0, a=0;
-
- EXTEND_PIXEL(row1, 1);
- EXTEND_PIXEL(row2, 2);
- EXTEND_PIXEL(row3, 1);
- EXTEND_PIXEL(row1+4, 2);
- EXTEND_PIXEL(row3+4, 2);
- if(x!=rowlen-1) {
- EXTEND_PIXEL(row1+8, 1);
- EXTEND_PIXEL(row2+8, 2);
- EXTEND_PIXEL(row3+8, 1);
- }
- if(tot) {
- cp[0]= r/tot;
- cp[1]= g/tot;
- cp[2]= b/tot;
- cp[3]= a/tot;
+
+ return res;
+}
+
+/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
+ *
+ * When a mask is given, only effect pixels with a mask value of 1, defined as BAKE_MASK_MARGIN in rendercore.c
+ * */
+void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
+{
+ const int width= ibuf->x;
+ const int height= ibuf->y;
+ const int depth= 4; /* always 4 channels */
+ const int chsize= ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
+ const int bsize= width*height*depth*chsize;
+ const int is_float= ibuf->rect_float!=NULL;
+ void *dstbuf= (void *) MEM_dupallocN(ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect);
+ char *dstmask= mask==NULL ? NULL : (char *) MEM_dupallocN(mask);
+ void *srcbuf= ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect;
+ char *srcmask= mask;
+ int cannot_early_out= 1, r, n, k, i, j, c;
+ float weight[25];
+
+ /* build a weights buffer */
+ n= 2;
+ k= 0;
+ for(i = -n; i <= n; i++)
+ for(j = -n; j <= n; j++)
+ weight[k++] = sqrt((float) i * i + j * j);
+
+ /* run passes */
+ for(r = 0; cannot_early_out == 1 && r < filter; r++) {
+ int x, y;
+ cannot_early_out = 0;
+
+ for(y= 0; y<height; y++) {
+ for(x= 0; x<width; x++) {
+ const int index= filter_make_index(x, y, width, height);
+
+ /* only update unassigned pixels */
+ if(!check_pixel_assigned(srcbuf, srcmask, index, depth, is_float)) {
+ float tmp[4];
+ float wsum=0;
+ float acc[4]={0,0,0,0};
+ k = 0;
+
+ if (check_pixel_assigned(srcbuf, srcmask, filter_make_index(x-1, y, width, height), depth, is_float) ||
+ check_pixel_assigned(srcbuf, srcmask, filter_make_index(x+1, y, width, height), depth, is_float) ||
+ check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y-1, width, height), depth, is_float) ||
+ check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y+1, width, height), depth, is_float)) {
+ for(i= -n; i<=n; i++) {
+ for(j=-n; j<=n; j++) {
+ if(i != 0 || j != 0) {
+ const int tmpindex= filter_make_index(x+i, y+j, width, height);
+
+ if(check_pixel_assigned(srcbuf, srcmask, tmpindex, depth, is_float)) {
+ if(is_float) {
+ for(c=0; c<depth; c++)
+ tmp[c] = ((const float *) srcbuf)[depth*tmpindex+c];
+ }
+ else {
+ for(c=0; c<depth; c++)
+ tmp[c] = (float) ((const unsigned char *) srcbuf)[depth*tmpindex+c];
+ }
+
+ wsum+= weight[k];
+
+ for(c=0; c<depth; c++)
+ acc[c]+= weight[k] * tmp[c];
+ }
+ }
+ k++;
+ }
+ }
+
+ if(wsum!=0) {
+ for(c=0; c<depth; c++)
+ acc[c]/= wsum;
+
+ if(is_float) {
+ for(c=0; c<depth; c++)
+ ((float *) dstbuf)[depth*index+c] = acc[c];
+ }
+ else {
+ for(c=0; c<depth; c++) {
+ ((unsigned char *) dstbuf)[depth*index+c]= acc[c] > 255 ? 255 : (acc[c] < 0 ? 0 : ((unsigned char) (acc[c]+0.5f)));
+ }
+ }
+
+ if(dstmask!=NULL) dstmask[index]=FILTER_MASK_MARGIN; /* assigned */
+ cannot_early_out = 1;
+ }
}
}
- cp+=4;
-
- if(x!=0) {
- row1+=4; row2+=4; row3+=4;
- }
}
}
-
- MEM_freeN(temprect);
+
+ /* keep the original buffer up to date. */
+ memcpy(srcbuf, dstbuf, bsize);
+ if(dstmask!=NULL) memcpy(srcmask, dstmask, width*height);
}
+
+ /* free memory */
+ MEM_freeN(dstbuf);
+ if(dstmask!=NULL) MEM_freeN(dstmask);
}
/* threadsafe version, only recreates existing maps */
@@ -437,7 +512,7 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
hbuf= ibuf->mipmap[curmap];
hbuf->miplevel= curmap+1;
- if(!hbuf || (hbuf->x == 1 && hbuf->y == 1))
+ if(!hbuf || (hbuf->x <= 2 && hbuf->y <= 2))
break;
curmap++;
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index fa5e951067d..1ac4e4e06cb 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -315,7 +315,7 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float *
/* Note about wrapping, the u/v still needs to be within the image bounds,
* just the interpolation is wrapped.
- * This the same as bilinear_interpolation_color except it wraps rather then using empty and emptyI */
+ * This the same as bilinear_interpolation_color except it wraps rather than using empty and emptyI */
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
float *row1, *row2, *row3, *row4, a, b;
diff --git a/source/blender/imbuf/intern/md5.h b/source/blender/imbuf/intern/md5.h
index 5fc1f80216f..79c480d8152 100644
--- a/source/blender/imbuf/intern/md5.h
+++ b/source/blender/imbuf/intern/md5.h
@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <stdio.h>
-#if defined HAVE_LIMITS_H || _LIBC
+#if defined HAVE_LIMITS_H || defined _LIBC
# include <limits.h>
#endif
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index ace4f4f9a65..3be5219ae44 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -30,10 +30,12 @@ set(INC
../..
../../../blenkernel
../../../blenlib
- intern/include
- ../../../../../intern/guardedalloc
../../../makesdna
- ${OPENEXR_INC}
+ ../../../../../intern/guardedalloc
+)
+
+set(INC_SYS
+
)
set(SRC
@@ -41,7 +43,10 @@ set(SRC
)
if(WITH_IMAGE_OPENEXR)
+ list(APPEND INC_SYS
+ ${OPENEXR_INCLUDE_DIRS}
+ )
add_definitions(-DWITH_OPENEXR)
endif()
-blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}")
+blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 9fd6cd1c3fa..7b528ed9624 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -76,18 +76,18 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <IlmImf/ImfStringAttribute.h>
#include <Imath/ImathBox.h>
#else
-#include <OpenEXR/half.h>
-#include <OpenEXR/ImfVersion.h>
-#include <OpenEXR/ImathBox.h>
-#include <OpenEXR/ImfArray.h>
-#include <OpenEXR/ImfIO.h>
-#include <OpenEXR/ImfChannelList.h>
-#include <OpenEXR/ImfPixelType.h>
-#include <OpenEXR/ImfInputFile.h>
-#include <OpenEXR/ImfOutputFile.h>
-#include <OpenEXR/ImfCompression.h>
-#include <OpenEXR/ImfCompressionAttribute.h>
-#include <OpenEXR/ImfStringAttribute.h>
+#include <half.h>
+#include <ImfVersion.h>
+#include <ImathBox.h>
+#include <ImfArray.h>
+#include <ImfIO.h>
+#include <ImfChannelList.h>
+#include <ImfPixelType.h>
+#include <ImfInputFile.h>
+#include <ImfOutputFile.h>
+#include <ImfCompression.h>
+#include <ImfCompressionAttribute.h>
+#include <ImfStringAttribute.h>
#endif
using namespace Imf;
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 200ff0af9af..f0c06ec0ae7 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -257,6 +257,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
}
+ if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+ png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER);
+ }
+
// write the file header information
png_write_info(png_ptr, info_ptr);
@@ -384,7 +388,19 @@ struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
if (ibuf) {
ibuf->ftype = PNG;
ibuf->profile = IB_PROFILE_SRGB;
- } else {
+
+ if (png_get_valid (png_ptr, info_ptr, PNG_INFO_pHYs)) {
+ int unit_type;
+ png_uint_32 xres, yres;
+
+ if(png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type))
+ if(unit_type == PNG_RESOLUTION_METER) {
+ ibuf->ppm[0]= xres;
+ ibuf->ppm[1]= yres;
+ }
+ }
+ }
+ else {
printf("Couldn't allocate memory for PNG image\n");
}
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 44af7ffdb3f..844478e03cb 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -450,7 +450,7 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
/* fill */
-void IMB_rectfill(struct ImBuf *drect, float col[4])
+void IMB_rectfill(struct ImBuf *drect, const float col[4])
{
int num;
@@ -561,3 +561,18 @@ void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, i
if (!ibuf) return;
buf_rectfill_area((unsigned char *) ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, x1, y1, x2, y2);
}
+
+
+void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
+{
+ int i;
+ if (ibuf->rect_float) {
+ float *fbuf= ibuf->rect_float + 3;
+ for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf+= 4) { *fbuf = value; }
+ }
+ else {
+ const unsigned char cvalue= value * 255;
+ unsigned char *cbuf= ((unsigned char *)ibuf->rect) + 3;
+ for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf+= 4) { *cbuf = cvalue; }
+ }
+}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index f6a6a644977..5389d90867e 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -300,17 +300,18 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
uchar *p1, *p2 = NULL, *dest;
float *p1f, *destf, *p2f = NULL;
int x,y;
- int do_rect, do_float;
+ const short do_rect= (ibuf1->rect != NULL);
+ const short do_float= (ibuf1->rect_float != NULL) && (ibuf2->rect_float != NULL);
+
+ if(do_rect && (ibuf2->rect == NULL)) {
+ imb_addrectImBuf(ibuf2);
+ }
- do_rect= (ibuf1->rect != NULL);
-
p1f = ibuf1->rect_float;
destf=ibuf2->rect_float;
p1 = (uchar *) ibuf1->rect;
dest=(uchar *) ibuf2->rect;
- do_float= (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
-
for(y=ibuf2->y;y>0;y--){
if (do_rect) p2 = p1 + (ibuf1->x << 2);
if (do_float) p2f = p1f + (ibuf1->x << 2);
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index f334409133f..ec00b15c079 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -532,7 +532,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
TARGA tga;
struct ImBuf * ibuf;
int col, count, size;
- unsigned int *rect, *cmap= NULL, mincol= 0, maxcol= 0;
+ unsigned int *rect, *cmap= NULL /*, mincol= 0*/, maxcol= 0;
uchar * cp = (uchar *) &col;
if (checktarga(&tga,mem) == 0) return(NULL);
@@ -550,7 +550,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
if (tga.mapsize){
/* load color map */
- mincol = tga.maporig;
+ /*mincol = tga.maporig;*/ /*UNUSED*/
maxcol = tga.mapsize;
cmap = MEM_callocN(sizeof(unsigned int)*maxcol, "targa cmap");
@@ -586,7 +586,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
ibuf->depth = size;
if (tga.mapbits != 32) { /* set alpha bits */
- cmap[0] &= BIG_LONG(0x00ffffff);
+ cmap[0] &= BIG_LONG(0x00ffffffl);
}
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 67d20d56466..36130aa0dbf 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -354,6 +354,25 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i
rectf[i*4 + chan] = fbuf[i];
}
+static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
+{
+ uint16 unit;
+ float xres;
+ float yres;
+
+ TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit);
+ TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres);
+ TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres);
+
+ if(unit == RESUNIT_CENTIMETER) {
+ ibuf->ppm[0]= (double)xres * 100.0;
+ ibuf->ppm[1]= (double)yres * 100.0;
+ }
+ else {
+ ibuf->ppm[0]= (double)xres / 0.0254;
+ ibuf->ppm[1]= (double)yres / 0.0254;
+ }
+}
/*
* Use the libTIFF scanline API to read a TIFF image.
@@ -369,10 +388,13 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
int ib_flag=0, row, chan;
float *fbuf=NULL;
unsigned short *sbuf=NULL;
-
+
TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */
TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
+
+ imb_read_tiff_resolution(ibuf, image);
+
scanline = TIFFScanlineSize(image);
if (bitspersample == 32) {
@@ -658,6 +680,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
unsigned char *from = NULL, *to = NULL;
unsigned short *pixels16 = NULL, *to16 = NULL;
float *fromf = NULL;
+ float xres, yres;
int x, y, from_i, to_i, i;
int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
@@ -783,8 +806,18 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0);
- TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0);
+
+
+ if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+ xres= (float)(ibuf->ppm[0] * 0.0254);
+ yres= (float)(ibuf->ppm[1] * 0.0254);
+ }
+ else {
+ xres= yres= 150.0f;
+ }
+
+ TIFFSetField(image, TIFFTAG_XRESOLUTION, xres);
+ TIFFSetField(image, TIFFTAG_YRESOLUTION, yres);
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
if(TIFFWriteEncodedStrip(image, 0,
(bitspersample == 16)? (unsigned char*)pixels16: pixels,
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 3e4136cbef9..6db8dcc06cf 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -63,11 +63,7 @@
#include <libavdevice/avdevice.h>
#include <libavutil/log.h>
-#if LIBAVFORMAT_VERSION_INT < (49 << 16)
-#define FFMPEG_OLD_FRAME_RATE 1
-#else
-#define FFMPEG_CODEC_IS_POINTER 1
-#endif
+#include "ffmpeg_compat.h"
#endif
@@ -117,6 +113,7 @@ const char *imb_ext_movie[] = {
".m4v",
".m2v",
".m2t",
+ ".m2ts",
".mts",
".mv",
".avs",
@@ -146,6 +143,9 @@ const char *imb_ext_audio[] = {
".flac",
".wma",
".eac3",
+ ".aif",
+ ".aiff",
+ ".m4a",
NULL};
static int IMB_ispic_name(const char *name)
@@ -241,19 +241,6 @@ void do_init_ffmpeg(void)
}
}
-#ifdef FFMPEG_CODEC_IS_POINTER
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return stream->codec;
-}
-#else
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return &stream->codec;
-}
-#endif
-
-
static int isffmpeg (const char *filename) {
AVFormatContext *pFormatCtx;
unsigned int i;
@@ -284,15 +271,15 @@ static int isffmpeg (const char *filename) {
return 0;
}
- if(UTIL_DEBUG) dump_format(pFormatCtx, 0, filename, 0);
+ if(UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
/* Find the first video stream */
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i] &&
- get_codec_from_stream(pFormatCtx->streams[i]) &&
- (get_codec_from_stream(pFormatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO))
+ pFormatCtx->streams[i]->codec &&
+ (pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO))
{
videoStream=i;
break;
@@ -303,7 +290,7 @@ static int isffmpeg (const char *filename) {
return 0;
}
- pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]);
+ pCodecCtx = pFormatCtx->streams[videoStream]->codec;
/* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);