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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2009-09-19 02:25:49 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2009-09-19 02:25:49 +0400
commitbe50ce61be7fdc96943dbdac79aabd88ba29996f (patch)
tree4dfde72478458923a3b2ce8d22e1658d4508024c /source/blender/imbuf
parent0a4d70f4d0ddc5bc709b162d84ec334e66ed848d (diff)
Merged
https://svn.blender.org/svnroot/bf-blender/branches/soc-2008-mxcurioni (r22789) and https://svn.blender.org/svnroot/bf-blender/trunk/blender (r23338) with the "Ignore ancestry" and "Ignore line endings" options enabled (using TortoiseSVN on Windows). After the merge operation, all changes (i.e., deletion) in source/blender/freestyle/ were reverted in order to keep the primary source tree of the Freestyle renderer.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/CMakeLists.txt34
-rw-r--r--source/blender/imbuf/IMB_imbuf.h10
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h29
-rw-r--r--source/blender/imbuf/IMB_thumbs.h3
-rw-r--r--source/blender/imbuf/SConscript10
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h12
-rw-r--r--source/blender/imbuf/intern/IMB_jp2.h49
-rw-r--r--source/blender/imbuf/intern/IMB_targa.h2
-rw-r--r--source/blender/imbuf/intern/Makefile4
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c5
-rw-r--r--source/blender/imbuf/intern/amiga.c8
-rw-r--r--source/blender/imbuf/intern/anim.c60
-rw-r--r--source/blender/imbuf/intern/anim5.c18
-rw-r--r--source/blender/imbuf/intern/cineon/CMakeLists.txt16
-rw-r--r--source/blender/imbuf/intern/cineon/SConscript4
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c29
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c6
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c40
-rw-r--r--source/blender/imbuf/intern/dds/CMakeLists.txt18
-rw-r--r--source/blender/imbuf/intern/dds/Makefile2
-rw-r--r--source/blender/imbuf/intern/dds/SConscript2
-rw-r--r--source/blender/imbuf/intern/divers.c54
-rw-r--r--source/blender/imbuf/intern/filter.c88
-rw-r--r--source/blender/imbuf/intern/hamx.c10
-rw-r--r--source/blender/imbuf/intern/iff.c7
-rw-r--r--source/blender/imbuf/intern/imageprocess.c283
-rw-r--r--source/blender/imbuf/intern/imbuf.h2
-rw-r--r--source/blender/imbuf/intern/iris.c312
-rw-r--r--source/blender/imbuf/intern/jp2.c736
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt22
-rw-r--r--source/blender/imbuf/intern/openexr/Makefile3
-rw-r--r--source/blender/imbuf/intern/openexr/SConscript6
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp21
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c20
-rw-r--r--source/blender/imbuf/intern/readimage.c41
-rw-r--r--source/blender/imbuf/intern/rotate.c6
-rw-r--r--source/blender/imbuf/intern/scaling.c70
-rw-r--r--source/blender/imbuf/intern/targa.c71
-rw-r--r--source/blender/imbuf/intern/thumbs.c35
-rw-r--r--source/blender/imbuf/intern/tiff.c2
-rw-r--r--source/blender/imbuf/intern/util.c54
-rw-r--r--source/blender/imbuf/intern/writeimage.c16
42 files changed, 1815 insertions, 405 deletions
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 2d41a6d73e6..5eb98151c14 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -27,35 +27,35 @@
FILE(GLOB SRC intern/*.c)
SET(INC
- . ../makesdna ../../../intern/guardedalloc ../../../intern/memutil ../blenlib
- ../avi ../quicktime ../blenkernel
- ${JPEG_INC}
- ${PNG_INC}
- ${TIFF_INC}
- ${ZLIB_INC}
+ . ../makesdna ../../../intern/guardedalloc ../../../intern/memutil ../blenlib
+ ../avi ../blenkernel
+ ${JPEG_INC}
+ ${PNG_INC}
+ ${TIFF_INC}
+ ${ZLIB_INC}
+ ${OPENJPEG_INC}
)
-IF(WITH_VERSE)
- ADD_DEFINITIONS(-DWITH_VERSE)
- SET(INC ${INC} VERSE_INC)
-ENDIF(WITH_VERSE)
-
IF(WITH_OPENEXR)
- ADD_DEFINITIONS(-DWITH_OPENEXR)
+ ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
+IF(WITH_OPENJPEG)
+ ADD_DEFINITIONS(-DWITH_OPENJPEG)
+ENDIF(WITH_OPENJPEG)
+
IF(WITH_QUICKTIME)
- SET(INC ${INC} ${QUICKTIME_INC})
- ADD_DEFINITIONS(-DWITH_QUICKTIME)
+ SET(INC ${INC} ../quicktime ${QUICKTIME_INC})
+ ADD_DEFINITIONS(-DWITH_QUICKTIME)
ENDIF(WITH_QUICKTIME)
IF(WITH_FFMPEG)
- SET(INC ${INC} ${FFMPEG_INC})
- ADD_DEFINITIONS(-DWITH_FFMPEG)
+ SET(INC ${INC} ${FFMPEG_INC})
+ ADD_DEFINITIONS(-DWITH_FFMPEG)
ENDIF(WITH_FFMPEG)
if(WITH_DDS)
- ADD_DEFINITIONS(-DWITH_DDS)
+ ADD_DEFINITIONS(-DWITH_DDS)
ENDIF(WITH_DDS)
BLENDERLIB(bf_imbuf "${SRC}" "${INC}")
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d4d8030bf10..d2f561438b9 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -319,7 +319,7 @@ void IMB_antialias(struct ImBuf * ibuf);
void IMB_filter(struct ImBuf *ibuf);
void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
void IMB_filter_extend(struct ImBuf *ibuf, char *mask);
-void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
+void IMB_makemipmap(struct ImBuf *ibuf, int use_filter, int SAT);
/**
*
@@ -403,9 +403,15 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
*
* @attention defined in imageprocess.c
*/
-void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float x, float y, int xout, int yout);
+void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+
+void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+
/**
* Change the ordering of the color bytes pointed to by rect from
* rgba to abgr. size * 4 color bytes are reordered.
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 73ef83393b0..91a7b136fa5 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -83,6 +83,7 @@ typedef struct ImBuf {
int ftype; /**< File type we are going to save as */
unsigned int *cmap; /**< Color map data. */
unsigned int *rect; /**< pixel values stored here */
+ unsigned int *crect; /**< color corrected pixel values stored here */
unsigned int **planes; /**< bitplanes */
int flags; /**< Controls which components should exist. */
int mall; /**< what is malloced internal, and can be freed */
@@ -97,9 +98,13 @@ typedef struct ImBuf {
unsigned int encodedsize; /**< Size of data written to encodedbuffer */
unsigned int encodedbuffersize; /**< Size of encodedbuffer */
- float *rect_float; /**< floating point Rect equivilant */
+ float *rect_float; /**< floating point Rect equivalent
+ Linear RGB color space - may need gamma correction to
+ sRGB when generating 8bit representations */
int channels; /**< amount of channels in rect_float (0 = 4 channel default) */
float dither; /**< random dither value, for conversion from float -> byte rect */
+ short profile; /** color space/profile preset that the byte rect buffer represents */
+ char profile_filename[256]; /** to be implemented properly, specific filename for custom profiles */
struct MEM_CacheLimiterHandle_s * c_handle; /**< handle for cache limiter */
struct ImgInfo * img_info;
@@ -181,6 +186,15 @@ typedef enum {
#define DDS (1 << 19)
#endif
+#ifdef WITH_OPENJPEG
+#define JP2 (1 << 18)
+#define JP2_12BIT (1 << 17)
+#define JP2_16BIT (1 << 16)
+#define JP2_YCC (1 << 15)
+#define JP2_CINE (1 << 14)
+#define JP2_CINE_48FPS (1 << 13)
+#endif
+
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
@@ -203,6 +217,18 @@ typedef enum {
#define AN_tanx (Anim | TANX)
/**@}*/
+/**
+ * \name Imbuf preset profile tags
+ * \brief Some predefined color space profiles that 8 bit imbufs can represent
+ */
+/**@{*/
+#define IB_PROFILE_NONE 0
+#define IB_PROFILE_LINEAR_RGB 1
+#define IB_PROFILE_SRGB 2
+#define IB_PROFILE_CUSTOM 3
+/**@}*/
+
+
/** \name Imbuf File Type Tests
* \brief These macros test if an ImBuf struct is the corresponding file type.
*/
@@ -217,6 +243,7 @@ typedef enum {
#define IS_tga(x) (x->ftype & TGA)
#define IS_png(x) (x->ftype & PNG)
#define IS_openexr(x) (x->ftype & OPENEXR)
+#define IS_jp2(x) (x->ftype & JP2)
#define IS_cineon(x) (x->ftype & CINEON)
#define IS_dpx(x) (x->ftype & DPX)
#define IS_bmp(x) (x->ftype & BMP)
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index 4f4b77ff000..53b63b4d304 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -67,7 +67,8 @@ void IMB_thumb_delete(const char* dir, const char* file, ThumbSize size);
/* return the state of the thumb, needed to determine how to manage the thumb */
ImBuf* IMB_thumb_manage(const char* dir, const char* file, ThumbSize size, ThumbSource source);
-
+/* create the necessary dirs to store the thumbnails */
+void IMB_thumb_makedirs();
#endif /* _IMB_THUMBS_H */
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 4eba4a843b2..6052b344da7 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
incs = '. ../makesdna #/intern/guardedalloc #/intern/memutil ../blenlib'
-incs += ' ../avi ../quicktime ../blenkernel'
+incs += ' ../avi ../blenkernel'
incs += ' ' + env['BF_JPEG_INC']
incs += ' ' + env['BF_PNG_INC']
@@ -13,10 +13,6 @@ incs += ' ' + env['BF_ZLIB_INC']
defs = []
-if env['WITH_BF_VERSE']:
- defs.append('WITH_VERSE')
- incs += ' ' + env['BF_VERSE_INCLUDE']
-
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
@@ -36,7 +32,7 @@ if env['WITH_BF_REDCODE']:
incs += ' ' + env['BF_REDCODE_INC']
if env['WITH_BF_QUICKTIME']:
- incs += ' ' + env['BF_QUICKTIME_INC']
+ incs += ' ../quicktime ' + env['BF_QUICKTIME_INC']
defs.append('WITH_QUICKTIME')
-env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [80, 40] )
+env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [185,115] )
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 7dc1f966b71..7e99df8237a 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -76,13 +76,17 @@
#endif /* WITH_QUICKTIME */
#ifdef WITH_FFMPEG
-#include <ffmpeg/avformat.h>
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/swscale.h>
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libswscale/swscale.h>
#endif
#ifdef WITH_REDCODE
-#include <redcode/format.h>
+#ifdef _WIN32 /* on windows we use the one in extern instead */
+#include "libredcode/format.h"
+#else
+#include "libredcode/format.h"
+#endif
#endif
#include "IMB_imbuf_types.h"
diff --git a/source/blender/imbuf/intern/IMB_jp2.h b/source/blender/imbuf/intern/IMB_jp2.h
new file mode 100644
index 00000000000..abc6b78357c
--- /dev/null
+++ b/source/blender/imbuf/intern/IMB_jp2.h
@@ -0,0 +1,49 @@
+/*
+ * IMB_jp2.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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 LICENSE BLOCK *****
+ */
+/**
+ * \file IMB_jp2.h
+ * \ingroup imbuf
+ * \brief Function declarations for jp2.c
+ */
+
+#ifndef IMB_JP2_H
+#define IMB_JP2_H
+
+#ifdef WITH_OPENJPEG
+struct ImBuf;
+
+int imb_is_a_jp2(void *buf);
+struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags);
+short imb_savejp2(struct ImBuf *ibuf, char *name, int flags);
+#endif /* WITH_OPENJPEG */
+
+#endif
+
diff --git a/source/blender/imbuf/intern/IMB_targa.h b/source/blender/imbuf/intern/IMB_targa.h
index 956bc512b97..7759e4bc772 100644
--- a/source/blender/imbuf/intern/IMB_targa.h
+++ b/source/blender/imbuf/intern/IMB_targa.h
@@ -41,7 +41,7 @@ struct ImBuf;
int imb_is_a_targa(void *buf);
-struct ImBuf *imb_loadtarga(unsigned char *mem, int flags);
+struct ImBuf *imb_loadtarga(unsigned char *mem, int size, int flags);
short imb_savetarga(struct ImBuf * ibuf, char *name, int flags);
#endif
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index 8294931b60f..427052cbdc3 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -48,6 +48,10 @@ ifeq ($(WITH_DDS), true)
CPPFLAGS += -DWITH_DDS
endif
+ifeq ($(WITH_OPENJPEG), true)
+ CFLAGS += -DWITH_OPENJPEG -I../../../../extern/libopenjpeg
+endif
+
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_JPEG)/include
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index ad7b1dce2e0..b561f0a583d 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -93,6 +93,10 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
{
if (ibuf==NULL) return;
+ if (ibuf->crect && ibuf->crect != ibuf->rect) {
+ MEM_freeN(ibuf->crect);
+ }
+
if (ibuf->rect) {
if (ibuf->mall & IB_rect) {
MEM_freeN(ibuf->rect);
@@ -102,6 +106,7 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
imb_freemipmapImBuf(ibuf);
ibuf->rect= NULL;
+ ibuf->crect= NULL;
ibuf->mall &= ~IB_rect;
}
diff --git a/source/blender/imbuf/intern/amiga.c b/source/blender/imbuf/intern/amiga.c
index 3d52a287a31..f84740826ae 100644
--- a/source/blender/imbuf/intern/amiga.c
+++ b/source/blender/imbuf/intern/amiga.c
@@ -29,8 +29,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifdef WIN32
+#ifdef _WIN32
#include <io.h>
+#define open _open
+#define read _read
+#define close _close
+#define write _write
#endif
#include "imbuf.h"
#include "imbuf_patch.h"
@@ -528,7 +532,7 @@ struct ImBuf *imb_loadamiga(int *iffmem,int flags)
if (ibuf) {
if (ibuf->rect)
- if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+ if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
}
return (ibuf);
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index c0e84b73e47..1aaba620f3a 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -83,10 +83,10 @@
#include "IMB_anim5.h"
#ifdef WITH_FFMPEG
-#include <ffmpeg/avformat.h>
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/rational.h>
-#include <ffmpeg/swscale.h>
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/rational.h>
+#include <libswscale/swscale.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
@@ -97,8 +97,13 @@
#endif
#ifdef WITH_REDCODE
-#include <redcode/format.h>
-#include <redcode/codec.h>
+#ifdef _WIN32 /* on windows we use the ones in extern instead */
+#include "libredcode/format.h"
+#include "libredcode/codec.h"
+#else
+#include "libredcode/format.h"
+#include "libredcode/codec.h"
+#endif
#endif
/****/
@@ -603,7 +608,7 @@ static int startffmpeg(struct anim * anim) {
anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
- if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
+ if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y)
!= anim->x * anim->y * 4) {
fprintf (stderr,
"ffmpeg has changed alloc scheme ... ARGHHH!\n");
@@ -637,7 +642,7 @@ static int startffmpeg(struct anim * anim) {
anim->pCodecCtx->pix_fmt,
anim->pCodecCtx->width,
anim->pCodecCtx->height,
- PIX_FMT_BGR32,
+ PIX_FMT_RGBA,
SWS_FAST_BILINEAR | SWS_PRINT_INFO,
NULL, NULL, NULL);
@@ -666,11 +671,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
if (anim == 0) return (0);
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect, 0);
avpicture_fill((AVPicture*) anim->pFrameRGB,
(unsigned char*) ibuf->rect,
- PIX_FMT_BGR32, anim->x, anim->y);
+ PIX_FMT_RGBA, anim->x, anim->y);
if (position != anim->curposition + 1) {
if (position > anim->curposition + 1
@@ -743,6 +748,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
if (frameFinished && !pos_found) {
if (packet.dts >= pts_to_search) {
pos_found = 1;
+ anim->curposition = position;
}
}
@@ -773,7 +779,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
}
}
- if (G.order == B_ENDIAN) {
+ if (ENDIAN_ORDER == B_ENDIAN) {
int * dstStride
= anim->pFrameRGB->linesize;
uint8_t** dst = anim->pFrameRGB->data;
@@ -806,21 +812,21 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
for (y = 0; y < h; y++) {
unsigned char tmp[4];
- unsigned long * tmp_l =
- (unsigned long*) tmp;
+ unsigned int * tmp_l =
+ (unsigned int*) tmp;
tmp[3] = 0xff;
for (x = 0; x < w; x++) {
- tmp[0] = bottom[3];
- tmp[1] = bottom[2];
- tmp[2] = bottom[1];
+ tmp[0] = bottom[0];
+ tmp[1] = bottom[1];
+ tmp[2] = bottom[2];
- bottom[0] = top[3];
- bottom[1] = top[2];
- bottom[2] = top[1];
+ bottom[0] = top[0];
+ bottom[1] = top[1];
+ bottom[2] = top[2];
bottom[3] = 0xff;
- *(unsigned long*) top
+ *(unsigned int*) top
= *tmp_l;
bottom +=4;
@@ -843,8 +849,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
0, 0, 0 };
int i;
unsigned char* r;
-
-
+
sws_scale(anim->img_convert_ctx,
input->data,
input->linesize,
@@ -852,8 +857,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
anim->pCodecCtx->height,
dst2,
dstStride2);
-
- /* workaround: sws_scale
+
+ /* workaround: sws_scale
sets alpha = 0... */
r = (unsigned char*) ibuf->rect;
@@ -862,7 +867,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
r[3] = 0xff;
r+=4;
}
-
+
av_free_packet(&packet);
break;
}
@@ -1041,10 +1046,11 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
char head[256], tail[256];
unsigned short digits;
int pic;
- int filter_y = (anim->ib_flags & IB_animdeinterlace);
-
+ int filter_y;
if (anim == NULL) return(0);
+ filter_y = (anim->ib_flags & IB_animdeinterlace);
+
if (anim->curtype == 0) {
ibuf = anim_getnew(anim);
if (ibuf == NULL) {
diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c
index ab203fe80de..43a6b0d2c5d 100644
--- a/source/blender/imbuf/intern/anim5.c
+++ b/source/blender/imbuf/intern/anim5.c
@@ -31,6 +31,7 @@
#include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
BLI_countlist BLI_stringdec */
+
#include "imbuf.h"
#include "imbuf_patch.h"
@@ -46,6 +47,11 @@
#include "IMB_anim5.h"
+#ifdef _WIN32
+#include <io.h>
+#include "BLI_winstuff.h"
+#endif
+
typedef struct Anhd{
unsigned char type, mask;
unsigned short w, h;
@@ -204,12 +210,12 @@ static void anim5decode(struct ImBuf * ibuf, uchar * dlta) {
int *ofspoint;
uchar **planes;
- /* samenstelling delta:
- lijst met ofsets voor delta's per bitplane (ofspoint)
- per kolom in delta (point)
- aantal handelingen (noops)
+ /* composition delta:
+ list with ofsets for delta' s by bitplane (ofspoint)
+ by column in delta (point)
+ number of operations (noops)
code
- bijbehorende data
+ associated data
...
...
*/
@@ -425,7 +431,7 @@ int startanim5(struct anim * anim) {
/* de hele file wordt in het geheugen gemapped */
totlen = BLI_filesize(file);
- if (totlen && file>=0) {
+ if (totlen>0 && file>=0) {
lseek(file, 0L, SEEK_SET);
mem= MEM_mallocN(totlen, "mmap");
diff --git a/source/blender/imbuf/intern/cineon/CMakeLists.txt b/source/blender/imbuf/intern/cineon/CMakeLists.txt
index 53cd161634b..8b28086016b 100644
--- a/source/blender/imbuf/intern/cineon/CMakeLists.txt
+++ b/source/blender/imbuf/intern/cineon/CMakeLists.txt
@@ -27,14 +27,14 @@
FILE(GLOB SRC *.c)
SET(INC
- .
- ../../../blenkernel
- ../../
- ..
- ../../../blenlib
- intern/include
- ../../../../../intern/guardedalloc
- ../../../makesdna
+ .
+ ../../../blenkernel
+ ../../
+ ..
+ ../../../blenlib
+ intern/include
+ ../../../../../intern/guardedalloc
+ ../../../makesdna
)
BLENDERLIB(bf_cineon "${SRC}" "${INC}")
diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript
index 7bfaa8dbdf2..d9c8ab14d35 100644
--- a/source/blender/imbuf/intern/cineon/SConscript
+++ b/source/blender/imbuf/intern/cineon/SConscript
@@ -13,5 +13,5 @@ incs = ['.',
'../../../makesdna']
defs = []
-
-env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
+
+env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core','player'], priority = [220,175])
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 514d6b5522b..45f23d34405 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -40,23 +40,26 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "MEM_guardedalloc.h"
-
-/* ugly bad level, should be fixed */
-#include "DNA_scene_types.h"
#include "BKE_global.h"
+#include "MEM_guardedalloc.h"
+
static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
{
- params->blackPoint = G.scene?G.scene->r.cineonblack:95;
- params->whitePoint = G.scene?G.scene->r.cineonwhite:685;
- params->gamma = G.scene?G.scene->r.cineongamma:1.7f;
- params->doLogarithm = G.scene?G.scene->r.subimtype & R_CINEON_LOG:0;
+// params->blackPoint = scene?scene->r.cineonblack:95;
+// params->whitePoint = scene?scene->r.cineonwhite:685;
+// params->gamma = scene?scene->r.cineongamma:1.7f;
+// params->doLogarithm = scene?scene->r.subimtype & R_CINEON_LOG:0;
+
+ params->blackPoint = 95;
+ params->whitePoint = 685;
+ params->gamma = 1.7f;
+ params->doLogarithm = 0;
+
}
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
{
- LogImageByteConversionParameters conversion;
ImBuf *ibuf;
LogImageFile *image;
int x, y;
@@ -64,7 +67,7 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
int width, height, depth;
float *frow;
- cineon_conversion_parameters(&conversion);
+ logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
image = logImageOpenFromMem(mem, size, use_cineon);
@@ -85,15 +88,13 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
return NULL;
}
- logImageSetByteConversion(image, &conversion);
-
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags, 0);
row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
frow = ibuf->rect_float+width*height*4;
for (y = 0; y < height; y++) {
- logImageGetRowBytes(image, row, y);
+ logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */
upix = row;
frow -= width*4;
@@ -143,7 +144,7 @@ static int imb_save_dpx_cineon(ImBuf *buf, char *filename, int use_cineon, int f
}
}
- logImageSetVerbose(0);
+ logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
logImage = logImageCreate(filename, use_cineon, width, height, depth);
if (!logImage) return 0;
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 75516bbf3ae..85b7ef0d5e9 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -558,7 +558,7 @@ cineonOpen(const char* filename) {
cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
if (cineon->pixelBuffer == 0) {
if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * sizeof(unsigned short));
+ (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
cineonClose(cineon);
return 0;
}
@@ -658,7 +658,7 @@ cineonOpenFromMem(unsigned char *mem, unsigned int size) {
cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
if (cineon->pixelBuffer == 0) {
if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * sizeof(unsigned short));
+ (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
cineonClose(cineon);
return 0;
}
@@ -744,7 +744,7 @@ cineonCreate(const char* filename, int width, int height, int depth) {
cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
if (cineon->pixelBuffer == 0) {
if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * sizeof(unsigned short));
+ (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
cineonClose(cineon);
return 0;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 8a9adc73cdc..8459eb0f989 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -240,7 +240,7 @@ dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) {
/* read enough longwords */
readLongs = pixelsToLongs(numPixels - dpx->pixelBufferUsed);
if (logimage_fread(dpx->lineBuffer, 4, readLongs, dpx) != readLongs) {
- if (verbose) d_printf("Couldn't read line %d length %d\n", y, readLongs * 4);
+ if (verbose) d_printf("Couldn't read line %d length %d\n", y, (int)readLongs * 4);
return 1;
}
++dpx->fileYPos;
@@ -352,7 +352,7 @@ dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y) {
/* write them */
if (fwrite(dpx->lineBuffer, 4, writeLongs, dpx->file) != writeLongs) {
- if (verbose) d_printf("Couldn't write line %d length %d\n", y, writeLongs * 4);
+ if (verbose) d_printf("Couldn't write line %d length %d\n", y, (int)writeLongs * 4);
return 1;
}
++dpx->fileYPos;
@@ -462,7 +462,7 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) {
dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short));
if (dpx->pixelBuffer == 0) {
if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (dpx->width * dpx->depth + 2 + 2) * sizeof(unsigned short));
+ (dpx->width * dpx->depth + 2 + 2) * (int)sizeof(unsigned short));
dpxClose(dpx);
return 0;
}
@@ -477,19 +477,49 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) {
logImageGetByteConversionDefaults(&dpx->params);
/* The SMPTE define this code:
+ * 0 - User-defined
+ * 1 - Printing density
* 2 - Linear
* 3 - Logarithmic
+ * 4 - Unspecified video
+ * 5 - SMPTE 240M
+ * 6 - CCIR 709-1
+ * 7 - CCIR 601-2 system B or G
+ * 8 - CCIR 601-2 system M
+ * 9 - NTSC composite video
+ * 10 - PAL composite video
+ * 11 - Z linear
+ * 12 - homogeneous
*
* Note that transfer_characteristics is U8, don't need
* check the byte order.
*/
+
switch (header.imageInfo.channel[0].transfer_characteristics) {
- case 2:
+ case 1:
+ case 2: /* linear */
dpx->params.doLogarithm= 0;
break;
+
case 3:
dpx->params.doLogarithm= 1;
break;
+
+ /* TODO - Unsupported, but for now just load them,
+ * colors may look wrong, but can solve color conversion later
+ */
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ if (verbose) d_printf("Un-supported Transfer Characteristics: %d using linear color conversion\n", header.imageInfo.channel[0].transfer_characteristics);
+ dpx->params.doLogarithm= 0;
+ break;
default:
if (verbose) d_printf("Un-supported Transfer Characteristics: %d\n", header.imageInfo.channel[0].transfer_characteristics);
dpxClose(dpx);
@@ -574,7 +604,7 @@ dpxCreate(const char* filename, int width, int height, int depth) {
dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short));
if (dpx->pixelBuffer == 0) {
if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (dpx->width * dpx->depth + 2 + 2) * sizeof(unsigned short));
+ (dpx->width * dpx->depth + 2 + 2) * (int)sizeof(unsigned short));
dpxClose(dpx);
return 0;
}
diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt
index 842f53bd88b..dc45afb9f5b 100644
--- a/source/blender/imbuf/intern/dds/CMakeLists.txt
+++ b/source/blender/imbuf/intern/dds/CMakeLists.txt
@@ -27,18 +27,18 @@
FILE (GLOB SRC *.cpp)
SET(INC
- .
- ../../../blenkernel
- ../../../makesdna
- ../../
- ..
- ../../../blenlib
- intern/include
- ../../../../../intern/guardedalloc
+ .
+ ../../../blenkernel
+ ../../../makesdna
+ ../../
+ ..
+ ../../../blenlib
+ intern/include
+ ../../../../../intern/guardedalloc
)
if(WITH_DDS)
- ADD_DEFINITIONS(-DWITH_DDS)
+ ADD_DEFINITIONS(-DWITH_DDS)
ENDIF(WITH_DDS)
BLENDERLIB(bf_dds "${SRC}" "${INC}")
diff --git a/source/blender/imbuf/intern/dds/Makefile b/source/blender/imbuf/intern/dds/Makefile
index 28f9e24c947..e14f9320d19 100644
--- a/source/blender/imbuf/intern/dds/Makefile
+++ b/source/blender/imbuf/intern/dds/Makefile
@@ -1,5 +1,5 @@
#
-# $Id: Makefile 7037 2006-03-12 14:11:23Z ton $
+# $Id$
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
index d005bae02be..0b7fd50e317 100644
--- a/source/blender/imbuf/intern/dds/SConscript
+++ b/source/blender/imbuf/intern/dds/SConscript
@@ -16,4 +16,4 @@ incs = ['.',
defs = ['WITH_DDS']
-env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
+env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [230,190])
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 8043e594454..6e1a176a5d2 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -39,6 +39,7 @@
#include "IMB_allocimbuf.h"
#include "IMB_divers.h"
#include "BKE_utildefines.h"
+#include "BKE_colortools.h"
void imb_checkncols(struct ImBuf *ibuf)
{
@@ -176,9 +177,11 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
void IMB_rect_from_float(struct ImBuf *ibuf)
{
/* quick method to convert floatbuf to byte */
- float *tof = ibuf->rect_float;
+ float *tof = (float *)ibuf->rect_float;
float dither= ibuf->dither;
+ float srgb[3];
int i, channels= ibuf->channels;
+ short profile= ibuf->profile;
unsigned char *to = (unsigned char *) ibuf->rect;
if(tof==NULL) return;
@@ -187,7 +190,24 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
to = (unsigned char *) ibuf->rect;
}
- if(dither==0.0f || channels!=4) {
+ if (profile == IB_PROFILE_SRGB && (channels == 3 || channels == 4)) {
+ if(channels == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
+ srgb[0]= linearrgb_to_srgb(tof[0]);
+ srgb[1]= linearrgb_to_srgb(tof[1]);
+ srgb[2]= linearrgb_to_srgb(tof[2]);
+
+ to[0] = FTOCHAR(srgb[0]);
+ to[1] = FTOCHAR(srgb[1]);
+ to[2] = FTOCHAR(srgb[2]);
+ to[3] = 255;
+ }
+ }
+ else if (channels == 4) {
+ floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x);
+ }
+ }
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_LINEAR_RGB) && (dither==0.0f || channels!=4)) {
if(channels==1) {
for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
@@ -242,14 +262,28 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
tof = ibuf->rect_float;
}
- for (i = ibuf->x * ibuf->y; i > 0; i--)
- {
- tof[0] = ((float)to[0])*(1.0f/255.0f);
- tof[1] = ((float)to[1])*(1.0f/255.0f);
- tof[2] = ((float)to[2])*(1.0f/255.0f);
- tof[3] = ((float)to[3])*(1.0f/255.0f);
- to += 4;
- tof += 4;
+ if (ibuf->profile == IB_PROFILE_SRGB) {
+ /* convert from srgb to linear rgb */
+
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
+ tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
+ tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
+ tof[3] = ((float)to[3])*(1.0f/255.0f);
+ to += 4;
+ tof += 4;
+ }
+ } else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ tof[0] = ((float)to[0])*(1.0f/255.0f);
+ tof[1] = ((float)to[1])*(1.0f/255.0f);
+ tof[2] = ((float)to[2])*(1.0f/255.0f);
+ tof[3] = ((float)to[3])*(1.0f/255.0f);
+ to += 4;
+ tof += 4;
+ }
}
}
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 9802405fd8d..cc3315c7696 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -371,6 +371,7 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask)
}
}
+#if 0
void IMB_makemipmap(ImBuf *ibuf, int use_filter)
{
ImBuf *hbuf= ibuf;
@@ -394,5 +395,90 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
minsize= hbuf->x<hbuf->y?hbuf->x:hbuf->y;
}
}
+#endif
-
+void IMB_makemipmap(ImBuf *ibuf, int use_filter, int SAT)
+{
+ if (SAT) {
+ // to maximize precision subtract image average, use intermediate double SAT,
+ // only convert to float at the end
+ const double dv = 1.0/255.0;
+ double avg[4] = {0, 0, 0, 0};
+ const int x4 = ibuf->x << 2;
+ int x, y, i;
+ ImBuf* sbuf = IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rectfloat, 0);
+ double *satp, *satbuf = MEM_callocN(sizeof(double)*ibuf->x*ibuf->y*4, "tmp SAT buf");
+ const double mf = ibuf->x*ibuf->y;
+ float* fp;
+ ibuf->mipmap[0] = sbuf;
+ if (ibuf->rect_float) {
+ fp = ibuf->rect_float;
+ for (y=0; y<ibuf->y; ++y)
+ for (x=0; x<ibuf->x; ++x) {
+ avg[0] += *fp++;
+ avg[1] += *fp++;
+ avg[2] += *fp++;
+ avg[3] += *fp++;
+ }
+ }
+ else {
+ char* cp = (char*)ibuf->rect;
+ for (y=0; y<ibuf->y; ++y)
+ for (x=0; x<ibuf->x; ++x) {
+ avg[0] += *cp++ * dv;
+ avg[1] += *cp++ * dv;
+ avg[2] += *cp++ * dv;
+ avg[3] += *cp++ * dv;
+ }
+ }
+ avg[0] /= mf;
+ avg[1] /= mf;
+ avg[2] /= mf;
+ avg[3] /= mf;
+ for (y=0; y<ibuf->y; ++y)
+ for (x=0; x<ibuf->x; ++x) {
+ const unsigned int p = (x + y*ibuf->x) << 2;
+ char* cp = (char*)ibuf->rect + p;
+ fp = ibuf->rect_float + p;
+ satp = satbuf + p;
+ for (i=0; i<4; ++i, ++cp, ++fp, ++satp) {
+ double sv = (ibuf->rect_float ? (double)*fp : (double)(*cp)*dv) - avg[i];
+ if (x > 0) sv += satp[-4];
+ if (y > 0) sv += satp[-x4];
+ if (x > 0 && y > 0) sv -= satp[-x4 - 4];
+ *satp = sv;
+ }
+ }
+ fp = sbuf->rect_float;
+ satp = satbuf;
+ for (y=0; y<ibuf->y; ++y)
+ for (x=0; x<ibuf->x; ++x) {
+ *fp++ = (float)*satp++;
+ *fp++ = (float)*satp++;
+ *fp++ = (float)*satp++;
+ *fp++ = (float)*satp++;
+ }
+ MEM_freeN(satbuf);
+ fp = &sbuf->rect_float[(sbuf->x - 1 + (sbuf->y - 1)*sbuf->x) << 2];
+ fp[0] = avg[0];
+ fp[1] = avg[1];
+ fp[2] = avg[2];
+ fp[3] = avg[3];
+ }
+ else {
+ ImBuf *hbuf = ibuf;
+ int curmap = 0;
+ while (curmap < IB_MIPMAP_LEVELS) {
+ if (use_filter) {
+ ImBuf *nbuf= IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect, 0);
+ IMB_filterN(nbuf, hbuf);
+ ibuf->mipmap[curmap] = IMB_onehalf(nbuf);
+ IMB_freeImBuf(nbuf);
+ }
+ else ibuf->mipmap[curmap] = IMB_onehalf(hbuf);
+ hbuf = ibuf->mipmap[curmap];
+ if (hbuf->x == 1 && hbuf->y == 1) break;
+ curmap++;
+ }
+ }
+}
diff --git a/source/blender/imbuf/intern/hamx.c b/source/blender/imbuf/intern/hamx.c
index 2f32d155407..258c196fcdf 100644
--- a/source/blender/imbuf/intern/hamx.c
+++ b/source/blender/imbuf/intern/hamx.c
@@ -31,11 +31,6 @@
#include "BLI_blenlib.h"
-#ifdef WIN32
-#include <io.h>
-#endif
-
-
#include "imbuf.h"
#include "imbuf_patch.h"
#include "IMB_imbuf_types.h"
@@ -46,6 +41,11 @@
#include "IMB_ham.h"
#include "IMB_hamx.h"
+#ifdef WIN32
+#include <io.h>
+#include "BLI_winstuff.h"
+#endif
+
/* actually hard coded endianness */
#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3])
#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0])
diff --git a/source/blender/imbuf/intern/iff.c b/source/blender/imbuf/intern/iff.c
index c3695173068..5fd823e78c1 100644
--- a/source/blender/imbuf/intern/iff.c
+++ b/source/blender/imbuf/intern/iff.c
@@ -29,14 +29,15 @@
* $Id$
*/
-#ifdef WIN32
-#include <io.h>
-#endif
#include "BLI_blenlib.h"
#include "imbuf.h"
#include "imbuf_patch.h"
#include "IMB_imbuf_types.h"
#include "IMB_iff.h"
+#ifdef WIN32
+#include <io.h>
+#include "BLI_winstuff.h"
+#endif
unsigned short imb_start_iff(struct ImBuf *ibuf, int file)
{
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 30e688ebe29..e4977c77155 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -80,6 +80,17 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
}
}
}
+static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y)
+
+{
+ int offset = ibuf->x * y * 4 + 4*x;
+
+ if (ibuf->rect)
+ *outI= (unsigned char *)ibuf->rect + offset;
+
+ if (ibuf->rect_float)
+ *outF= (float *)ibuf->rect_float + offset;
+}
/**************************************************************************
* INTERPOLATIONS
@@ -92,34 +103,82 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
/* More info: http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation
*/
/* function assumes out to be zero'ed, only does RGBA */
+
static float P(float k){
- float aux;
- aux=(float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
- return aux ;
+ float p1, p2, p3, p4;
+ p1 = MAX2(k+2.0f,0);
+ p2 = MAX2(k+1.0f,0);
+ p3 = MAX2(k,0);
+ p4 = MAX2(k-1.0f,0);
+ return (float)(1.0f/6.0f)*( p1*p1*p1 - 4.0f * p2*p2*p2 + 6.0f * p3*p3*p3 - 4.0f * p4*p4*p4);
}
-void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+
+#if 0
+/* older, slower function, works the same as above */
+static float P(float k){
+ return (float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
+}
+#endif
+
+void bicubic_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
int i,j,n,m,x1,y1;
- unsigned char *dataI,*outI;
- float a,b, outR,outG,outB,outA,*dataF,*outF;
- int do_rect, do_float;
+ unsigned char *dataI;
+ float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF;
- if (in == NULL) return;
- if (in->rect == NULL && in->rect_float == NULL) return;
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+ i= (int)floor(u);
+ j= (int)floor(v);
+ a= u - i;
+ b= v - j;
- i= (int)floor(x);
- j= (int)floor(y);
- a= x - i;
- b= y - j;
+ outR = outG = outB = outA = 0.0f;
+
+/* Optimized and not so easy to read */
+
+ /* avoid calling multiple times */
+ wy[0] = P(b-(-1));
+ wy[1] = P(b- 0);
+ wy[2] = P(b- 1);
+ wy[3] = P(b- 2);
+
+ for(n= -1; n<= 2; n++){
+ x1= i+n;
+ if (x1>0 && x1 < in->x) {
+ wx = P(n-a);
+ for(m= -1; m<= 2; m++){
+ y1= j+m;
+ if (y1>0 && y1<in->y) {
+ /* normally we could do this */
+ /* w = P(n-a) * P(b-m); */
+ /* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
+ w = wx * wy[m+1];
+
+ if (outF) {
+ dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
+ outR+= dataF[0] * w;
+ outG+= dataF[1] * w;
+ outB+= dataF[2] * w;
+ outA+= dataF[3] * w;
+ }
+ if (outI) {
+ dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
+ outR+= dataI[0] * w;
+ outG+= dataI[1] * w;
+ outB+= dataI[2] * w;
+ outA+= dataI[3] * w;
+ }
+ }
+ }
+ }
+ }
- outR= 0.0f;
- outG= 0.0f;
- outB= 0.0f;
- outA= 0.0f;
+/* Done with optimized part */
+
+#if 0
+ /* older, slower function, works the same as above */
for(n= -1; n<= 2; n++){
for(m= -1; m<= 2; m++){
x1= i+n;
@@ -142,15 +201,15 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
}
}
}
- if (do_rect) {
- outI= (unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
+#endif
+
+ if (outI) {
outI[0]= (int)outR;
outI[1]= (int)outG;
outI[2]= (int)outB;
outI[3]= (int)outA;
}
- if (do_float) {
- outF= (float *)out->rect_float + out->x * yout * 4 + 4*xout;
+ if (outF) {
outF[0]= outR;
outF[1]= outG;
outF[2]= outB;
@@ -158,23 +217,33 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
}
}
+
+void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ bicubic_interpolation_color(in, outI, outF, u, v);
+}
+
/* function assumes out to be zero'ed, only does RGBA */
/* BILINEAR INTERPOLATION */
-void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
- float *row1, *row2, *row3, *row4, a, b, *outF;
- unsigned char *row1I, *row2I, *row3I, *row4I, *outI;
+ float *row1, *row2, *row3, *row4, a, b;
+ unsigned char *row1I, *row2I, *row3I, *row4I;
float a_b, ma_b, a_mb, ma_mb;
float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f};
unsigned char emptyI[4]= {0, 0, 0, 0};
int y1, y2, x1, x2;
- int do_rect, do_float;
-
- if (in==NULL) return;
- if (in->rect==NULL && in->rect_float==NULL) return;
-
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
x1= (int)floor(u);
x2= (int)ceil(u);
@@ -184,16 +253,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
// sample area entirely outside image?
if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return;
- if (do_rect)
- outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
- else
- outI= NULL;
- if (do_float)
- outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
- else
- outF= NULL;
-
- if (do_float) {
+ if (outF) {
// sample including outside of edges of image
if (x1<0 || y1<0) row1= empty;
else row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1;
@@ -216,7 +276,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
}
- if (do_rect) {
+ if (outI) {
// sample including outside of edges of image
if (x1<0 || y1<0) row1I= emptyI;
else row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
@@ -234,52 +294,120 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
b= v-floor(v);
a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
- outI[0]= ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0];
- outI[1]= ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1];
- outI[2]= ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2];
- outI[3]= ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3];
+ /* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
+ * tested with white images and this should not wrap back to zero */
+ outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f;
+ outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f;
+ outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f;
+ outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f;
}
}
/* function assumes out to be zero'ed, only does RGBA */
-/* NEAREST INTERPOLATION */
-void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, int yout)
+/* BILINEAR INTERPOLATION */
+
+/* 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 */
+void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
- float *outF,*dataF;
- unsigned char *dataI,*outI;
- int y1, x1;
- int do_rect, do_float;
+ float *row1, *row2, *row3, *row4, a, b;
+ unsigned char *row1I, *row2I, *row3I, *row4I;
+ float a_b, ma_b, a_mb, ma_mb;
+ int y1, y2, x1, x2;
+
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
+
+ x1= (int)floor(u);
+ x2= (int)ceil(u);
+ y1= (int)floor(v);
+ y2= (int)ceil(v);
+
+ // sample area entirely outside image?
+ if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return;
+
+ /* wrap interpolation pixels - main difference from bilinear_interpolation_color */
+ if(x1<0)x1= in->x+x1;
+ if(y1<0)y1= in->y+y1;
+
+ if(x2>=in->x)x2= x2-in->x;
+ if(y2>=in->y)y2= y2-in->y;
+
+ if (outF) {
+ // sample including outside of edges of image
+ row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1;
+ row2= (float *)in->rect_float + in->x * y2 * 4 + 4*x1;
+ row3= (float *)in->rect_float + in->x * y1 * 4 + 4*x2;
+ row4= (float *)in->rect_float + in->x * y2 * 4 + 4*x2;
+
+ a= u-floor(u);
+ b= v-floor(v);
+ a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+
+ outF[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0];
+ outF[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1];
+ outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
+ outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
+ }
+ if (outI) {
+ // sample including outside of edges of image
+ row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
+ row2I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x1;
+ row3I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x2;
+ row4I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x2;
+
+ a= u-floor(u);
+ b= v-floor(v);
+ a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+
+ /* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
+ * tested with white images and this should not wrap back to zero */
+ outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f;
+ outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f;
+ outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f;
+ outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f;
+ }
+}
- if (in==NULL) return;
- if (in->rect==NULL && in->rect_float==NULL) return;
+void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ bilinear_interpolation_color(in, outI, outF, u, v);
+}
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+/* function assumes out to be zero'ed, only does RGBA */
+/* NEAREST INTERPOLATION */
+void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
+{
+ float *dataF;
+ unsigned char *dataI;
+ int y1, x1;
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
+
x1= (int)(u);
y1= (int)(v);
- if (do_rect)
- outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
- else
- outI= NULL;
- if (do_float)
- outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
- else
- outF= NULL;
-
// sample area entirely outside image?
if (x1<0 || x1>in->x-1 || y1<0 || y1>in->y-1) return;
// sample including outside of edges of image
if (x1<0 || y1<0) {
- if (do_rect) {
+ if (outI) {
outI[0]= 0;
outI[1]= 0;
outI[2]= 0;
outI[3]= 0;
}
- if (do_float) {
+ if (outF) {
outF[0]= 0.0f;
outF[1]= 0.0f;
outF[2]= 0.0f;
@@ -287,14 +415,14 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in
}
} else {
dataI= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
- if (do_rect) {
+ if (outI) {
outI[0]= dataI[0];
outI[1]= dataI[1];
outI[2]= dataI[2];
outI[3]= dataI[3];
}
dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
- if (do_float) {
+ if (outF) {
outF[0]= dataF[0];
outF[1]= dataF[1];
outF[2]= dataF[2];
@@ -302,3 +430,16 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in
}
}
}
+
+void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ neareast_interpolation_color(in, outI, outF, x, y);
+}
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index bd2a0d3082f..7b5d668ce2b 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -51,7 +51,7 @@
#include <sys/mman.h>
#endif
-#if !defined(WIN32) && !defined(__BeOS)
+#if !defined(WIN32)
#define O_BINARY 0
#endif
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index aa3015812fc..7b8c383ddb9 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -104,7 +104,9 @@ static int writetab(FILE *outf, unsigned int *tab, int len);
static void readtab(FILE *inf, unsigned int *tab, int len);
static void expandrow(unsigned char *optr, unsigned char *iptr, int z);
+static void expandrow2(float *optr, unsigned char *iptr, int z);
static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n);
+static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n);
static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt);
static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n);
@@ -233,6 +235,7 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
{
unsigned int *base, *lptr = NULL;
+ float *fbase, *fptr = NULL;
unsigned int *zbase, *zptr;
unsigned char *rledat;
unsigned int *starttab, *lengthtab;
@@ -242,7 +245,6 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
int xsize, ysize, zsize;
int bpp, rle, cur, badorder;
ImBuf * ibuf;
- uchar * rect;
/*printf("new iris\n");*/
@@ -257,8 +259,8 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
rle = ISRLE(image.type);
bpp = BPP(image.type);
- if(bpp != 1 ) {
- fprintf(stderr,"longimagedata: image must have 1 byte per pix chan\n");
+ if(bpp != 1 && bpp != 2) {
+ fprintf(stderr,"longimagedata: image must have 1 or 2 byte per pix chan\n");
return(0);
}
@@ -273,6 +275,7 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
}
if (rle) {
+
tablen = ysize*zsize*sizeof(int);
starttab = (unsigned int *)malloc(tablen);
lengthtab = (unsigned int *)malloc(tablen);
@@ -280,7 +283,7 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
readtab(inf,starttab,tablen);
readtab(inf,lengthtab,tablen);
-
+
/* check data order */
cur = 0;
badorder = 0;
@@ -295,99 +298,201 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
if(badorder)
break;
}
-
- ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
- if (ibuf->depth > 32) ibuf->depth = 32;
- base = ibuf->rect;
- zbase = (unsigned int *)ibuf->zbuf;
-
- if (badorder) {
- for(z=0; z<zsize; z++) {
+
+ if (bpp == 1) {
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
+ if (ibuf->depth > 32) ibuf->depth = 32;
+ base = ibuf->rect;
+ zbase = (unsigned int *)ibuf->zbuf;
+
+ if (badorder) {
+ for(z=0; z<zsize; z++) {
+ lptr = base;
+ for(y=0; y<ysize; y++) {
+ file_offset = starttab[y+z*ysize];
+
+ rledat = file_data + file_offset;
+ file_offset += lengthtab[y+z*ysize];
+
+ expandrow((uchar *)lptr, rledat, 3-z);
+ lptr += xsize;
+ }
+ }
+ } else {
lptr = base;
+ zptr = zbase;
for(y=0; y<ysize; y++) {
- file_offset = starttab[y+z*ysize];
-
- rledat = file_data + file_offset;
- file_offset += lengthtab[y+z*ysize];
-
- expandrow((uchar *)lptr, rledat, 3-z);
+
+ for(z=0; z<zsize; z++) {
+
+ file_offset = starttab[y+z*ysize];
+
+ rledat = file_data + file_offset;
+ file_offset += lengthtab[y+z*ysize];
+
+ if(z<4) expandrow((uchar *)lptr, rledat, 3-z);
+ else if(z<8) expandrow((uchar *)zptr, rledat, 7-z);
+ }
lptr += xsize;
+ zptr += xsize;
}
}
- }
- else {
- lptr = base;
- zptr = zbase;
- for(y=0; y<ysize; y++) {
+
+ } else { /* bpp == 2 */
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat, 0);
+
+ fbase = ibuf->rect_float;
+
+ if (badorder) {
for(z=0; z<zsize; z++) {
-
- file_offset = starttab[y+z*ysize];
+ fptr = fbase;
+ for(y=0; y<ysize; y++) {
+ file_offset = starttab[y+z*ysize];
+
+ rledat = file_data + file_offset;
+ file_offset += lengthtab[y+z*ysize];
+
+ expandrow2(fptr, rledat, 3-z);
+ fptr += xsize * 4;
+ }
+ }
+ } else {
+ fptr = fbase;
- rledat = file_data + file_offset;
- file_offset += lengthtab[y+z*ysize];
-
- if(z<4) expandrow((uchar *)lptr, rledat, 3-z);
- else if(z<8) expandrow((uchar *)zptr, rledat, 7-z);
+ for(y=0; y<ysize; y++) {
+
+ for(z=0; z<zsize; z++) {
+
+ file_offset = starttab[y+z*ysize];
+
+ rledat = file_data + file_offset;
+ file_offset += lengthtab[y+z*ysize];
+
+ expandrow2(fptr, rledat, 3-z);
+
+ }
+ fptr += xsize * 4;
}
- lptr += xsize;
- zptr += xsize;
}
}
free(starttab);
- free(lengthtab);
- }
- else {
-
- ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
- if (ibuf->depth > 32) ibuf->depth = 32;
+ free(lengthtab);
- base = ibuf->rect;
- zbase = (unsigned int *)ibuf->zbuf;
-
- file_offset = 512;
- rledat = file_data + file_offset;
-
- for(z = 0; z < zsize; z++) {
+ } else {
+ if (bpp == 1) {
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
+ if (ibuf->depth > 32) ibuf->depth = 32;
+
+ base = ibuf->rect;
+ zbase = (unsigned int *)ibuf->zbuf;
- if(z<4) lptr = base;
- else if(z<8) lptr= zbase;
+ file_offset = 512;
+ rledat = file_data + file_offset;
- for(y = 0; y < ysize; y++) {
+ for(z = 0; z < zsize; z++) {
+
+ if(z<4) lptr = base;
+ else if(z<8) lptr= zbase;
+
+ for(y = 0; y < ysize; y++) {
- interleaverow((uchar *)lptr, rledat, 3-z, xsize);
- rledat += xsize;
+ interleaverow((uchar *)lptr, rledat, 3-z, xsize);
+ rledat += xsize;
+
+ lptr += xsize;
+ }
+ }
+
+ } else { /* bpp == 2 */
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat, 0);
+
+ fbase = ibuf->rect_float;
+
+ file_offset = 512;
+ rledat = file_data + file_offset;
+
+ for(z = 0; z < zsize; z++) {
+
+ fptr = fbase;
- lptr += xsize;
+ for(y = 0; y < ysize; y++) {
+
+ interleaverow2(fptr, rledat, 3-z, xsize);
+ rledat += xsize * 2;
+
+ fptr += xsize * 4;
+ }
}
+
}
}
- if (image.zsize == 1){
- rect = (uchar *) ibuf->rect;
- for (x = ibuf->x * ibuf->y; x > 0; x--) {
- rect[0] = 255;
- rect[1] = rect[2] = rect[3];
- rect += 4;
+
+ if (bpp == 1) {
+ uchar * rect;
+
+ if (image.zsize == 1){
+ rect = (uchar *) ibuf->rect;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ rect[0] = 255;
+ rect[1] = rect[2] = rect[3];
+ rect += 4;
+ }
+ } else if (image.zsize == 2){
+ /* grayscale with alpha */
+ rect = (uchar *) ibuf->rect;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ rect[0] = rect[2];
+ rect[1] = rect[2] = rect[3];
+ rect += 4;
+ }
+ } else if (image.zsize == 3){
+ /* add alpha */
+ rect = (uchar *) ibuf->rect;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ rect[0] = 255;
+ rect += 4;
+ }
}
- } else if (image.zsize == 2){
- /* grayscale with alpha */
- rect = (uchar *) ibuf->rect;
- for (x = ibuf->x * ibuf->y; x > 0; x--) {
- rect[0] = rect[2];
- rect[1] = rect[2] = rect[3];
- rect += 4;
+
+ } else { /* bpp == 2 */
+
+ if (image.zsize == 1){
+ fbase = ibuf->rect_float;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ fbase[0] = 1;
+ fbase[1] = fbase[2] = fbase[3];
+ fbase += 4;
+ }
+ } else if (image.zsize == 2){
+ /* grayscale with alpha */
+ fbase = ibuf->rect_float;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ fbase[0] = fbase[2];
+ fbase[1] = fbase[2] = fbase[3];
+ fbase += 4;
+ }
+ } else if (image.zsize == 3){
+ /* add alpha */
+ fbase = ibuf->rect_float;
+ for (x = ibuf->x * ibuf->y; x > 0; x--) {
+ fbase[0] = 1;
+ fbase += 4;
+ }
}
- } else if (image.zsize == 3){
- /* add alpha */
- rect = (uchar *) ibuf->rect;
- for (x = ibuf->x * ibuf->y; x > 0; x--) {
- rect[0] = 255;
- rect += 4;
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
}
+
}
-
+
ibuf->ftype = IMAGIC;
if (flags & IB_ttob) IMB_flipy(ibuf);
@@ -412,6 +517,71 @@ static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n
}
}
+static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n)
+{
+ lptr += z;
+ while(n--) {
+ *lptr = ((cptr[0]<<8) | (cptr[1]<<0)) / (float)0xFFFF;
+ cptr += 2;
+ lptr += 4;
+ }
+}
+
+static void expandrow2(float *optr, unsigned char *iptr, int z)
+{
+ unsigned short pixel, count;
+ float pixel_f;
+
+ optr += z;
+ while(1) {
+ pixel = (iptr[0]<<8) | (iptr[1]<<0);
+ iptr += 2;
+
+ if ( !(count = (pixel & 0x7f)) )
+ return;
+ if(pixel & 0x80) {
+ while(count>=8) {
+ optr[0*4] = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+ optr[1*4] = ((iptr[2]<<8) | (iptr[3]<<0))/(float)0xFFFF;
+ optr[2*4] = ((iptr[4]<<8) | (iptr[5]<<0))/(float)0xFFFF;
+ optr[3*4] = ((iptr[6]<<8) | (iptr[7]<<0))/(float)0xFFFF;
+ optr[4*4] = ((iptr[8]<<8) | (iptr[9]<<0))/(float)0xFFFF;
+ optr[5*4] = ((iptr[10]<<8) | (iptr[11]<<0))/(float)0xFFFF;
+ optr[6*4] = ((iptr[12]<<8) | (iptr[13]<<0))/(float)0xFFFF;
+ optr[7*4] = ((iptr[14]<<8) | (iptr[15]<<0))/(float)0xFFFF;
+ optr += 8*4;
+ iptr += 8*2;
+ count -= 8;
+ }
+ while(count--) {
+ *optr = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+ iptr+=2;
+ optr+=4;
+ }
+ } else {
+ pixel_f = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+ iptr += 2;
+
+ while(count>=8) {
+ optr[0*4] = pixel_f;
+ optr[1*4] = pixel_f;
+ optr[2*4] = pixel_f;
+ optr[3*4] = pixel_f;
+ optr[4*4] = pixel_f;
+ optr[5*4] = pixel_f;
+ optr[6*4] = pixel_f;
+ optr[7*4] = pixel_f;
+ optr += 8*4;
+ count -= 8;
+ }
+ while(count--) {
+ *optr = pixel_f;
+ optr+=4;
+ }
+ }
+ }
+}
+
static void expandrow(unsigned char *optr, unsigned char *iptr, int z)
{
unsigned char pixel, count;
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
new file mode 100644
index 00000000000..2583a155d6a
--- /dev/null
+++ b/source/blender/imbuf/intern/jp2.c
@@ -0,0 +1,736 @@
+/**
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifdef WITH_OPENJPEG
+
+#include "BLI_blenlib.h"
+
+#include "imbuf.h"
+#include "imbuf_patch.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_allocimbuf.h"
+#include "IMB_jp2.h"
+
+#include "openjpeg.h"
+
+#define JP2_FILEHEADER_SIZE 14
+
+static char JP2_HEAD[]= {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
+
+/* We only need this because of how the presets are set */
+typedef struct img_folder{
+ /** The directory path of the folder containing input images*/
+ char *imgdirpath;
+ /** Output format*/
+ char *out_format;
+ /** Enable option*/
+ char set_imgdir;
+ /** Enable Cod Format for output*/
+ char set_out_format;
+ /** User specified rate stored in case of cinema option*/
+ float *rates;
+}img_fol_t;
+
+static int checkj2p(unsigned char *mem) /* J2K_CFMT */
+{
+ return memcmp(JP2_HEAD, mem, 12) ? 0 : 1;
+}
+
+int imb_is_a_jp2(void *buf)
+{
+ return checkj2p(buf);
+}
+
+
+/**
+sample error callback expecting a FILE* client object
+*/
+void error_callback(const char *msg, void *client_data) {
+ FILE *stream = (FILE*)client_data;
+ fprintf(stream, "[ERROR] %s", msg);
+}
+/**
+sample warning callback expecting a FILE* client object
+*/
+void warning_callback(const char *msg, void *client_data) {
+ FILE *stream = (FILE*)client_data;
+ fprintf(stream, "[WARNING] %s", msg);
+}
+/**
+sample debug callback expecting no client object
+*/
+void info_callback(const char *msg, void *client_data) {
+ (void)client_data;
+ fprintf(stdout, "[INFO] %s", msg);
+}
+
+
+
+struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags)
+{
+ struct ImBuf *ibuf = 0;
+ int use_float = 0; /* for precissions higher then 8 use float */
+ unsigned char *rect= NULL;
+ float *rect_float= NULL;
+
+ long signed_offsets[4] = {0,0,0,0};
+ int float_divs[4];
+
+ int index;
+
+ int w, h, depth;
+
+ opj_dparameters_t parameters; /* decompression parameters */
+
+ opj_event_mgr_t event_mgr; /* event manager */
+ opj_image_t *image = NULL;
+
+ int i;
+
+ opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
+ opj_cio_t *cio = NULL;
+
+ if (checkj2p(mem) == 0) return(0);
+
+ /* configure the event callbacks (not required) */
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+ event_mgr.error_handler = error_callback;
+ event_mgr.warning_handler = warning_callback;
+ event_mgr.info_handler = info_callback;
+
+
+ /* set decoding parameters to default values */
+ opj_set_default_decoder_parameters(&parameters);
+
+
+ /* JPEG 2000 compressed image data */
+
+ /* get a decoder handle */
+ dinfo = opj_create_decompress(CODEC_JP2);
+
+ /* catch events using our callbacks and give a local context */
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
+
+ /* setup the decoder decoding parameters using the current image and user parameters */
+ opj_setup_decoder(dinfo, &parameters);
+
+ /* open a byte stream */
+ cio = opj_cio_open((opj_common_ptr)dinfo, mem, size);
+
+ /* decode the stream and fill the image structure */
+ image = opj_decode(dinfo, cio);
+
+ if(!image) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
+ opj_destroy_decompress(dinfo);
+ opj_cio_close(cio);
+ return NULL;
+ }
+
+ /* close the byte stream */
+ opj_cio_close(cio);
+
+
+ if((image->numcomps * image->x1 * image->y1) == 0)
+ {
+ fprintf(stderr,"\nError: invalid raw image parameters\n");
+ return NULL;
+ }
+
+ w = image->comps[0].w;
+ h = image->comps[0].h;
+
+ switch (image->numcomps) {
+ case 1: /* Greyscale */
+ case 3: /* Color */
+ depth= 24;
+ break;
+ default: /* 2 or 4 - Greyscale or Color + alpha */
+ depth= 32; /* greyscale + alpha */
+ break;
+ }
+
+
+ i = image->numcomps;
+ if (i>4) i= 4;
+
+ while (i) {
+ i--;
+
+ if (image->comps[i].prec > 8)
+ use_float = 1;
+
+ if (image->comps[i].sgnd)
+ signed_offsets[i]= 1 << (image->comps[i].prec - 1);
+
+ /* only needed for float images but dosnt hurt to calc this */
+ float_divs[i]= (1<<image->comps[i].prec)-1;
+ }
+
+ if (use_float) {
+ ibuf= IMB_allocImBuf(w, h, depth, IB_rectfloat, 0);
+ rect_float = ibuf->rect_float;
+ } else {
+ ibuf= IMB_allocImBuf(w, h, depth, IB_rect, 0);
+ rect = (unsigned char *) ibuf->rect;
+ }
+
+ if (ibuf==NULL) {
+ if(dinfo)
+ opj_destroy_decompress(dinfo);
+ return NULL;
+ }
+
+ ibuf->ftype = JP2;
+
+ if (use_float) {
+ rect_float = ibuf->rect_float;
+
+ if (image->numcomps < 3) {
+ /* greyscale 12bits+ */
+ for (i = 0; i < w * h; i++, rect_float+=4) {
+ index = w * h - ((i) / (w) + 1) * w + (i) % (w);
+
+ rect_float[0]= rect_float[1]= rect_float[2]= (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
+
+ if (image->numcomps == 2)
+ rect_float[3]= (image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
+ else
+ rect_float[3]= 1.0f;
+ }
+ } else {
+ /* rgb or rgba 12bits+ */
+ for (i = 0; i < w * h; i++, rect_float+=4) {
+ index = w * h - ((i) / (w) + 1) * w + (i) % (w);
+
+ rect_float[0]= (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
+ rect_float[1]= (float)(image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
+ rect_float[2]= (float)(image->comps[2].data[index] + signed_offsets[2]) / float_divs[2];
+
+ if (image->numcomps >= 4)
+ rect_float[3]= (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3];
+ else
+ rect_float[3]= 1.0f;
+ }
+ }
+
+ } else {
+
+ if (image->numcomps < 3) {
+ /* greyscale */
+ for (i = 0; i < w * h; i++, rect+=4) {
+ index = w * h - ((i) / (w) + 1) * w + (i) % (w);
+
+ rect_float[0]= rect_float[1]= rect_float[2]= (image->comps[0].data[index] + signed_offsets[0]);
+
+ if (image->numcomps == 2)
+ rect[3]= image->comps[1].data[index] + signed_offsets[1];
+ else
+ rect[3]= 255;
+ }
+ } else {
+ /* 8bit rgb or rgba */
+ for (i = 0; i < w * h; i++, rect+=4) {
+ int index = w * h - ((i) / (w) + 1) * w + (i) % (w);
+
+ rect[0]= image->comps[0].data[index] + signed_offsets[0];
+ rect[1]= image->comps[1].data[index] + signed_offsets[1];
+ rect[2]= image->comps[2].data[index] + signed_offsets[2];
+
+ if (image->numcomps >= 4)
+ rect[3]= image->comps[3].data[index] + signed_offsets[3];
+ else
+ rect[3]= 255;
+ }
+ }
+ }
+
+ /* free remaining structures */
+ if(dinfo) {
+ opj_destroy_decompress(dinfo);
+ }
+
+ /* free image data structure */
+ opj_image_destroy(image);
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ return(ibuf);
+}
+
+//static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
+/* prec can be 8, 12, 16 */
+
+#define UPSAMPLE_8_TO_12(_val) ((_val<<4) | (_val & ((1<<4)-1)))
+#define UPSAMPLE_8_TO_16(_val) ((_val<<8)+_val)
+
+#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val)<=0.0f?0: ((_val)>=1.0f?255: (int)(255.0f*(_val)))
+#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val)<=0.0f?0: ((_val)>=1.0f?4095: (int)(4095.0f*(_val)))
+#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val)<=0.0f?0: ((_val)>=1.0f?65535: (int)(65535.0f*(_val)))
+
+
+/*
+2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3×12 bits per pixel, XYZ color space
+
+ * In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
+ * In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
+*/
+
+/* ****************************** COPIED FROM image_to_j2k.c */
+
+/* ----------------------------------------------------------------------- */
+#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
+#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
+#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
+#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
+
+
+static int initialise_4K_poc(opj_poc_t *POC, int numres){
+ POC[0].tile = 1;
+ POC[0].resno0 = 0;
+ POC[0].compno0 = 0;
+ POC[0].layno1 = 1;
+ POC[0].resno1 = numres-1;
+ POC[0].compno1 = 3;
+ POC[0].prg1 = CPRL;
+ POC[1].tile = 1;
+ POC[1].resno0 = numres-1;
+ POC[1].compno0 = 0;
+ POC[1].layno1 = 1;
+ POC[1].resno1 = numres;
+ POC[1].compno1 = 3;
+ POC[1].prg1 = CPRL;
+ return 2;
+}
+
+void cinema_parameters(opj_cparameters_t *parameters){
+ parameters->tile_size_on = false;
+ parameters->cp_tdx=1;
+ parameters->cp_tdy=1;
+
+ /*Tile part*/
+ parameters->tp_flag = 'C';
+ parameters->tp_on = 1;
+
+ /*Tile and Image shall be at (0,0)*/
+ parameters->cp_tx0 = 0;
+ parameters->cp_ty0 = 0;
+ parameters->image_offset_x0 = 0;
+ parameters->image_offset_y0 = 0;
+
+ /*Codeblock size= 32*32*/
+ parameters->cblockw_init = 32;
+ parameters->cblockh_init = 32;
+ parameters->csty |= 0x01;
+
+ /*The progression order shall be CPRL*/
+ parameters->prog_order = CPRL;
+
+ /* No ROI */
+ parameters->roi_compno = -1;
+
+ parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
+
+ /* 9-7 transform */
+ parameters->irreversible = 1;
+
+}
+
+void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
+ int i;
+ float temp_rate;
+
+ switch (parameters->cp_cinema){
+ case CINEMA2K_24:
+ case CINEMA2K_48:
+ if(parameters->numresolution > 6){
+ parameters->numresolution = 6;
+ }
+ if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))){
+ fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
+ "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
+ image->comps[0].w,image->comps[0].h);
+ parameters->cp_rsiz = STD_RSIZ;
+ }
+ break;
+
+ case CINEMA4K_24:
+ if(parameters->numresolution < 1){
+ parameters->numresolution = 1;
+ }else if(parameters->numresolution > 7){
+ parameters->numresolution = 7;
+ }
+ if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))){
+ fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
+ "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
+ image->comps[0].w,image->comps[0].h);
+ parameters->cp_rsiz = STD_RSIZ;
+ }
+ parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
+ break;
+ case OFF:
+ /* do nothing */
+ break;
+ }
+
+ switch (parameters->cp_cinema){
+ case CINEMA2K_24:
+ case CINEMA4K_24:
+ for(i=0 ; i<parameters->tcp_numlayers ; i++){
+ temp_rate = 0 ;
+ if (img_fol->rates[i]== 0){
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }else{
+ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_24_CS ){
+ parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }else{
+ parameters->tcp_rates[i]= img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_24_CS;
+ break;
+
+ case CINEMA2K_48:
+ for(i=0 ; i<parameters->tcp_numlayers ; i++){
+ temp_rate = 0 ;
+ if (img_fol->rates[i]== 0){
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }else{
+ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_48_CS ){
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }else{
+ parameters->tcp_rates[i]= img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_48_CS;
+ break;
+ case OFF:
+ /* do nothing */
+ break;
+ }
+ parameters->cp_disto_alloc = 1;
+}
+
+
+static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) {
+
+ unsigned char *rect;
+ float *rect_float;
+
+ int subsampling_dx = parameters->subsampling_dx;
+ int subsampling_dy = parameters->subsampling_dy;
+
+
+ int i, numcomps, w, h, prec;
+ int x,y, y_row;
+ OPJ_COLOR_SPACE color_space;
+ opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
+ opj_image_t * image = NULL;
+
+ img_fol_t img_fol; /* only needed for cinema presets */
+ memset(&img_fol,0,sizeof(img_fol_t));
+
+ if (ibuf->ftype & JP2_CINE) {
+
+ if (ibuf->x==4096 || ibuf->y==2160)
+ parameters->cp_cinema= CINEMA4K_24;
+ else {
+ if (ibuf->ftype & JP2_CINE_48FPS) {
+ parameters->cp_cinema= CINEMA2K_48;
+ }
+ else {
+ parameters->cp_cinema= CINEMA2K_24;
+ }
+ }
+ if (parameters->cp_cinema){
+ img_fol.rates = (float*)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates");
+ for(i=0; i< parameters->tcp_numlayers; i++){
+ img_fol.rates[i] = parameters->tcp_rates[i];
+ }
+ cinema_parameters(parameters);
+ }
+
+ color_space= CLRSPC_SYCC;
+ prec= 12;
+ numcomps= 3;
+ }
+ else {
+ /* Get settings from the imbuf */
+ color_space = (ibuf->ftype & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB;
+
+ if (ibuf->ftype & JP2_16BIT) prec= 16;
+ else if (ibuf->ftype & JP2_12BIT) prec= 12;
+ else prec= 8;
+
+ /* 32bit images == alpha channel */
+ /* grayscale not supported yet */
+ numcomps= (ibuf->depth==32) ? 4 : 3;
+ }
+
+ w= ibuf->x;
+ h= ibuf->y;
+
+
+ /* initialize image components */
+ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+ for(i = 0; i < numcomps; i++) {
+ cmptparm[i].prec = prec;
+ cmptparm[i].bpp = prec;
+ cmptparm[i].sgnd = 0;
+ cmptparm[i].dx = subsampling_dx;
+ cmptparm[i].dy = subsampling_dy;
+ cmptparm[i].w = w;
+ cmptparm[i].h = h;
+ }
+ /* create the image */
+ image = opj_image_create(numcomps, &cmptparm[0], color_space);
+ if(!image) {
+ printf("Error: opj_image_create() failed\n");
+ return NULL;
+ }
+
+ /* set image offset and reference grid */
+ image->x0 = parameters->image_offset_x0;
+ image->y0 = parameters->image_offset_y0;
+ image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
+ image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
+
+ /* set image data */
+ rect = (unsigned char*) ibuf->rect;
+ rect_float= ibuf->rect_float;
+
+ if (rect_float && rect && prec==8) {
+ /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
+ rect_float= NULL;
+ }
+
+
+ if (rect_float) {
+ switch (prec) {
+ case 8: /* Convert blenders float color channels to 8,12 or 16bit ints */
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect_float+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]);
+ image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]);
+ image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]);
+ if (numcomps>3)
+ image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
+ }
+ }
+ break;
+
+ case 12:
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect_float+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]);
+ image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]);
+ image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]);
+ if (numcomps>3)
+ image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
+ }
+ }
+ break;
+ case 16:
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect_float+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]);
+ image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]);
+ image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]);
+ if (numcomps>3)
+ image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
+ }
+ }
+ break;
+ }
+ } else {
+ /* just use rect*/
+ switch (prec) {
+ case 8:
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i] = rect[0];
+ image->comps[1].data[i] = rect[1];
+ image->comps[2].data[i] = rect[2];
+ if (numcomps>3)
+ image->comps[3].data[i] = rect[3];
+ }
+ }
+ break;
+
+ case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i]= UPSAMPLE_8_TO_12(rect[0]);
+ image->comps[1].data[i]= UPSAMPLE_8_TO_12(rect[1]);
+ image->comps[2].data[i]= UPSAMPLE_8_TO_12(rect[2]);
+ if (numcomps>3)
+ image->comps[3].data[i]= UPSAMPLE_8_TO_12(rect[3]);
+ }
+ }
+ break;
+ case 16:
+ for(y=h-1; y>=0; y--) {
+ y_row = y*w;
+ for(x=0; x<w; x++, rect+=4) {
+ i = y_row + x;
+
+ image->comps[0].data[i]= UPSAMPLE_8_TO_16(rect[0]);
+ image->comps[1].data[i]= UPSAMPLE_8_TO_16(rect[1]);
+ image->comps[2].data[i]= UPSAMPLE_8_TO_16(rect[2]);
+ if (numcomps>3)
+ image->comps[3].data[i]= UPSAMPLE_8_TO_16(rect[3]);
+ }
+ }
+ break;
+ }
+ }
+
+ /* Decide if MCT should be used */
+ parameters->tcp_mct = image->numcomps == 3 ? 1 : 0;
+
+ if(parameters->cp_cinema){
+ cinema_setup_encoder(parameters,image,&img_fol);
+ }
+
+ if (img_fol.rates)
+ MEM_freeN(img_fol.rates);
+
+ return image;
+}
+
+
+/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
+short imb_savejp2(struct ImBuf *ibuf, char *name, int flags) {
+
+ int quality = ibuf->ftype & 0xff;
+
+ int bSuccess;
+ opj_cparameters_t parameters; /* compression parameters */
+ opj_event_mgr_t event_mgr; /* event manager */
+ opj_image_t *image = NULL;
+
+ /*
+ configure the event callbacks (not required)
+ setting of each callback is optionnal
+ */
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+ event_mgr.error_handler = error_callback;
+ event_mgr.warning_handler = warning_callback;
+ event_mgr.info_handler = info_callback;
+
+ /* set encoding parameters to default values */
+ opj_set_default_encoder_parameters(&parameters);
+
+ /* compression ratio */
+ /* invert range, from 10-100, 100-1
+ * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
+ parameters.tcp_rates[0]= ((100-quality)/90.0f*99.0f) + 1;
+
+
+ parameters.tcp_numlayers = 1; // only one resolution
+ parameters.cp_disto_alloc = 1;
+
+ image= ibuftoimage(ibuf, &parameters);
+
+
+ { /* JP2 format output */
+ int codestream_length;
+ opj_cio_t *cio = NULL;
+ FILE *f = NULL;
+
+ /* get a JP2 compressor handle */
+ opj_cinfo_t* cinfo = opj_create_compress(CODEC_JP2);
+
+ /* catch events using our callbacks and give a local context */
+ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
+
+ /* setup the encoder parameters using the current image and using user parameters */
+ opj_setup_encoder(cinfo, &parameters, image);
+
+ /* open a byte stream for writing */
+ /* allocate memory for all tiles */
+ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
+
+ /* encode the image */
+ bSuccess = opj_encode(cinfo, cio, image, NULL); /* last arg used to be parameters.index but this deprecated */
+
+ if (!bSuccess) {
+ opj_cio_close(cio);
+ fprintf(stderr, "failed to encode image\n");
+ return 0;
+ }
+ codestream_length = cio_tell(cio);
+
+ /* write the buffer to disk */
+ f = fopen(name, "wb");
+
+ if (!f) {
+ fprintf(stderr, "failed to open %s for writing\n", name);
+ return 1;
+ }
+ fwrite(cio->buffer, 1, codestream_length, f);
+ fclose(f);
+ fprintf(stderr,"Generated outfile %s\n",name);
+ /* close and free the byte stream */
+ opj_cio_close(cio);
+
+ /* free remaining compression structures */
+ opj_destroy_compress(cinfo);
+ }
+
+ /* free image data */
+ opj_image_destroy(image);
+
+ return 1;
+}
+
+#endif /* WITH_OPENJPEG */
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index bb1dad087f3..33681da55af 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -27,16 +27,20 @@
SET(SRC openexr_api.cpp)
SET(INC
- .
- ../../../blenkernel
- ../../
- ..
- ../../../blenlib
- intern/include
- ../../../../../intern/guardedalloc
- ../../../makesdna
- ${OPENEXR_INC}
+ .
+ ../../../blenkernel
+ ../../
+ ..
+ ../../../blenlib
+ intern/include
+ ../../../../../intern/guardedalloc
+ ../../../makesdna
+ ${OPENEXR_INC}
)
+IF(WITH_OPENEXR)
+ ADD_DEFINITIONS(-DWITH_OPENEXR)
+ENDIF(WITH_OPENEXR)
+
BLENDERLIB(bf_openexr "${SRC}" "${INC}")
#env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
diff --git a/source/blender/imbuf/intern/openexr/Makefile b/source/blender/imbuf/intern/openexr/Makefile
index f77e3723e8a..083089b11d5 100644
--- a/source/blender/imbuf/intern/openexr/Makefile
+++ b/source/blender/imbuf/intern/openexr/Makefile
@@ -35,6 +35,9 @@ include nan_compile.mk
CFLAGS += $(LEVEL_1_C_WARNINGS)
+# If compiling the API, WITH_OPENEXR must be set.
+CPPFLAGS += -DWITH_OPENEXR
+
CPPFLAGS += -I../../../makesdna
CPPFLAGS += -I../../../blenkernel
CPPFLAGS += -I../../../blenlib
diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript
index 1b0a0ed6110..f504c503109 100644
--- a/source/blender/imbuf/intern/openexr/SConscript
+++ b/source/blender/imbuf/intern/openexr/SConscript
@@ -13,6 +13,6 @@ incs = ['.',
'../../../makesdna']
incs += Split(env['BF_OPENEXR_INC'])
-defs = []
-
-env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
+defs = ['WITH_OPENEXR']
+
+env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core','player'], priority = [225,180])
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 3e618a483e3..a780727b1a2 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -51,7 +51,6 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
-#define WITH_OPENEXR
#include "openexr_multi.h"
}
@@ -570,13 +569,17 @@ void IMB_exr_write_channels(void *handle)
FrameBuffer frameBuffer;
ExrChannel *echan;
- for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
- frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect,
- echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
-
- data->ofile->setFrameBuffer (frameBuffer);
- data->ofile->writePixels (data->height);
-
+ if(data->channels.first) {
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
+ frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect,
+ echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
+
+ data->ofile->setFrameBuffer (frameBuffer);
+ data->ofile->writePixels (data->height);
+ }
+ else {
+ printf("Error: attempt to save MultiLayer without layers.\n");
+ }
}
void IMB_exr_read_channels(void *handle)
@@ -861,7 +864,7 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan)
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
{
- const Channel &channel = i.channel();
+ /* const Channel &channel = i.channel(); */ /* Not used yet */
const char *str= i.name();
int len= strlen(str);
if(len) {
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index b4e384ada72..69c4970df38 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -180,7 +180,6 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
int width=0, height=0;
int x, y;
unsigned char* ptr;
- unsigned char* rect;
char oriY[80], oriX[80];
if (imb_is_a_hdr((void*)mem))
@@ -192,7 +191,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
break;
}
}
- if (found) {
+ if (found && (x<(size + 2))) {
if (sscanf((char *)&mem[x+1], "%79s %d %79s %d", (char*)&oriY, &height,
(char*)&oriX, &width) != 4) return NULL;
@@ -201,7 +200,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
ptr++;
if (flags & IB_test) ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
- else ibuf = IMB_allocImBuf(width, height, 32, IB_rect|IB_rectfloat, 0);
+ else ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect)|IB_rectfloat, 0);
if (ibuf==NULL) return NULL;
ibuf->ftype = RADHDR;
@@ -211,7 +210,6 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
/* read in and decode the actual data */
sline = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_read_tmpscan");
- rect = (unsigned char*)ibuf->rect;
rect_float = (float *)ibuf->rect_float;
for (y=0;y<height;y++) {
@@ -228,19 +226,15 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
*rect_float++ = fcol[GRN];
*rect_float++ = fcol[BLU];
*rect_float++ = 1.0f;
- /* Also old oldstyle for the rest of blender which is not using floats yet */
- // e: changed to simpler tonemapping, previous code was rather slow (is this actually still relevant at all?)
- fcol[RED] = fcol[RED]/(1.f + fcol[RED]);
- fcol[GRN] = fcol[GRN]/(1.f + fcol[GRN]);
- fcol[BLU] = fcol[BLU]/(1.f + fcol[BLU]);
- *rect++ = (unsigned char)((fcol[RED] < 0.f) ? 0 : ((fcol[RED] > 1.f) ? 255 : (255.f*fcol[RED])));
- *rect++ = (unsigned char)((fcol[GRN] < 0.f) ? 0 : ((fcol[GRN] > 1.f) ? 255 : (255.f*fcol[GRN])));
- *rect++ = (unsigned char)((fcol[BLU] < 0.f) ? 0 : ((fcol[BLU] > 1.f) ? 255 : (255.f*fcol[BLU])));
- *rect++ = 255;
}
}
MEM_freeN(sline);
if (oriY[0]=='-') IMB_flipy(ibuf);
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
return ibuf;
}
//else printf("Data not found!\n");
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 566df53a25e..4104a8db65c 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -29,11 +29,14 @@
* $Id$
*/
-#ifdef WIN32
+#ifdef _WIN32
#include <io.h>
#include <stddef.h>
#include <sys/types.h>
#include "mmap_win.h"
+#define open _open
+#define read _read
+#define close _close
#endif
#include "BLI_blenlib.h"
@@ -55,6 +58,10 @@
#include "IMB_dpxcineon.h"
#include "BKE_global.h"
+#ifdef WITH_OPENJPEG
+#include "IMB_jp2.h"
+#endif
+
#ifdef WITH_OPENEXR
#include "openexr/openexr_api.h"
#endif
@@ -136,7 +143,7 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
ibuf = imb_bmp_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
- ibuf = imb_loadtarga((uchar *)mem, flags);
+ ibuf = imb_loadtarga((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
ibuf = imb_loaddpx((uchar *)mem, size, flags);
@@ -158,11 +165,16 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
if (ibuf) return (ibuf);
#endif
+#ifdef WITH_OPENJPEG
+ ibuf = imb_jp2_decode((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__)
if(G.have_quicktime) {
@@ -217,7 +229,7 @@ struct ImBuf *IMB_loadiffmem(int *mem, int flags) {
}
}
- ibuf = imb_loadtarga((uchar *) mem,flags);
+ ibuf = imb_loadtarga((uchar *) mem,maxlen,flags);
if (ibuf) return(ibuf);
if (IB_verbose) fprintf(stderr,"Unknown fileformat\n");
@@ -232,26 +244,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
size = BLI_filesize(file);
-#if defined(AMIGA) || defined(__BeOS)
- mem= (int *)malloc(size);
- if (mem==0) {
- printf("Out of mem\n");
- return (0);
- }
-
- if (read(file, mem, size)!=size){
- printf("Read Error\n");
- free(mem);
- return (0);
- }
-
- ibuf = IMB_ibImageFromMemory(mem, size, flags);
- free(mem);
-
- /* for jpeg read */
- lseek(file, 0L, SEEK_SET);
-
-#else
mem= (int *)mmap(0,size,PROT_READ,MAP_SHARED,file,0);
if (mem==(int *)-1){
printf("Couldn't get mapping\n");
@@ -263,7 +255,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
if (munmap( (void *) mem, size)){
printf("Couldn't unmap file.\n");
}
-#endif
return(ibuf);
}
diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c
index c04987b3e71..732c06907df 100644
--- a/source/blender/imbuf/intern/rotate.c
+++ b/source/blender/imbuf/intern/rotate.c
@@ -30,6 +30,7 @@
*/
#include "BLI_blenlib.h"
+#include "BKE_utildefines.h"
#include "imbuf.h"
#include "imbuf_patch.h"
@@ -94,7 +95,6 @@ void IMB_flipy(struct ImBuf * ibuf)
void IMB_flipx(struct ImBuf * ibuf)
{
short x, y, xr, xl, yi;
- unsigned int px;
float px_f[4];
if (ibuf == NULL) return;
@@ -105,9 +105,7 @@ void IMB_flipx(struct ImBuf * ibuf)
if (ibuf->rect) {
for(yi=y-1;yi>=0;yi--) {
for(xr=x-1, xl=0; xr>=xl; xr--, xl++) {
- px = ibuf->rect[(x*yi)+xr];
- ibuf->rect[(x*yi)+xr] = ibuf->rect[(x*yi)+xl];
- ibuf->rect[(x*yi)+xl] = px;
+ SWAP(unsigned int, ibuf->rect[(x*yi)+xr], ibuf->rect[(x*yi)+xl]);
}
}
}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 8257eb4643e..1ccdad05deb 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -299,7 +299,6 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0);
do_rect= (ibuf1->rect != NULL);
- do_float= (ibuf1->rect_float != NULL);
if (ibuf1->x <= 1) return(IMB_half_y(ibuf1));
if (ibuf1->y <= 1) return(IMB_half_x(ibuf1));
@@ -312,6 +311,8 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
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);
@@ -595,12 +596,12 @@ static void shrink_picture_byte(
y_counter = 65536;
for (y_src = 0; y_src < src_height; y_src++) {
unsigned char* line = src + y_src * 4 * src_width;
- uintptr_t weight1y = 65536 - (y_dst & 0xffff);
- uintptr_t weight2y = 65536 - weight1y;
+ uintptr_t weight1y = 65535 - (y_dst & 0xffff);
+ uintptr_t weight2y = 65535 - weight1y;
x_dst = 0;
for (x_src = 0; x_src < src_width; x_src++) {
- uintptr_t weight1x = 65536 - (x_dst & 0xffff);
- uintptr_t weight2x = 65536 - weight1x;
+ uintptr_t weight1x = 65535 - (x_dst & 0xffff);
+ uintptr_t weight2x = 65535 - weight1x;
uintptr_t x = x_dst >> 16;
@@ -608,34 +609,35 @@ static void shrink_picture_byte(
w = (weight1y * weight1x) >> 16;
- dst_line1[x].r += (line[0] * w) >> 16;
- dst_line1[x].g += (line[1] * w) >> 16;
- dst_line1[x].b += (line[2] * w) >> 16;
- dst_line1[x].a += (line[3] * w) >> 16;
+ /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */
+ dst_line1[x].r += (line[0] * w + 32767) >> 16;
+ dst_line1[x].g += (line[1] * w + 32767) >> 16;
+ dst_line1[x].b += (line[2] * w + 32767) >> 16;
+ dst_line1[x].a += (line[3] * w + 32767) >> 16;
dst_line1[x].weight += w;
w = (weight2y * weight1x) >> 16;
- dst_line2[x].r += (line[0] * w) >> 16;
- dst_line2[x].g += (line[1] * w) >> 16;
- dst_line2[x].b += (line[2] * w) >> 16;
- dst_line2[x].a += (line[3] * w) >> 16;
+ dst_line2[x].r += (line[0] * w + 32767) >> 16;
+ dst_line2[x].g += (line[1] * w + 32767) >> 16;
+ dst_line2[x].b += (line[2] * w + 32767) >> 16;
+ dst_line2[x].a += (line[3] * w + 32767) >> 16;
dst_line2[x].weight += w;
w = (weight1y * weight2x) >> 16;
- dst_line1[x+1].r += (line[0] * w) >> 16;
- dst_line1[x+1].g += (line[1] * w) >> 16;
- dst_line1[x+1].b += (line[2] * w) >> 16;
- dst_line1[x+1].a += (line[3] * w) >> 16;
+ dst_line1[x+1].r += (line[0] * w + 32767) >> 16;
+ dst_line1[x+1].g += (line[1] * w + 32767) >> 16;
+ dst_line1[x+1].b += (line[2] * w + 32767) >> 16;
+ dst_line1[x+1].a += (line[3] * w + 32767) >> 16;
dst_line1[x+1].weight += w;
w = (weight2y * weight2x) >> 16;
- dst_line2[x+1].r += (line[0] * w) >> 16;
- dst_line2[x+1].g += (line[1] * w) >> 16;
- dst_line2[x+1].b += (line[2] * w) >> 16;
- dst_line2[x+1].a += (line[3] * w) >> 16;
+ dst_line2[x+1].r += (line[0] * w + 32767) >> 16;
+ dst_line2[x+1].g += (line[1] * w + 32767) >> 16;
+ dst_line2[x+1].b += (line[2] * w + 32767) >> 16;
+ dst_line2[x+1].a += (line[3] * w + 32767) >> 16;
dst_line2[x+1].weight += w;
x_dst += dx_dst;
@@ -645,18 +647,18 @@ static void shrink_picture_byte(
y_dst += dy_dst;
y_counter -= dy_dst;
if (y_counter < 0) {
+ int val;
uintptr_t x;
struct scale_outpix_byte * temp;
y_counter += 65536;
for (x=0; x < dst_width; x++) {
- uintptr_t f = 0x80000000UL
- / dst_line1[x].weight;
- *dst++ = (dst_line1[x].r * f) >> 15;
- *dst++ = (dst_line1[x].g * f) >> 15;
- *dst++ = (dst_line1[x].b * f) >> 15;
- *dst++ = (dst_line1[x].a * f) >> 15;
+ uintptr_t f = 0x80000000UL / dst_line1[x].weight;
+ *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
}
memset(dst_line1, 0, dst_width *
sizeof(struct scale_outpix_byte));
@@ -666,13 +668,14 @@ static void shrink_picture_byte(
}
}
if (dst - dst_begin < dst_width * dst_height * 4) {
+ int val;
uintptr_t x;
for (x = 0; x < dst_width; x++) {
uintptr_t f = 0x80000000UL / dst_line1[x].weight;
- *dst++ = (dst_line1[x].r * f) >> 15;
- *dst++ = (dst_line1[x].g * f) >> 15;
- *dst++ = (dst_line1[x].b * f) >> 15;
- *dst++ = (dst_line1[x].a * f) >> 15;
+ *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
+ *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
}
}
MEM_freeN(dst_line1);
@@ -910,6 +913,8 @@ static void q_scale_float(float* in, float* out, int in_width,
Should be comparable in speed to the ImBuf ..._fast functions at least
for byte-buffers.
+ NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton)
+
*/
static int q_scale_linear_interpolation(
struct ImBuf *ibuf, int newx, int newy)
@@ -1582,7 +1587,8 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy)
scalefast_Z_ImBuf(ibuf, newx, newy);
/* try to scale common cases in a fast way */
- if (q_scale_linear_interpolation(ibuf, newx, newy)) {
+ /* disabled, quality loss is inacceptable, see report #18609 (ton) */
+ if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
return ibuf;
}
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index 303e5685503..c89bc6a632f 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -289,7 +289,10 @@ short imb_savetarga(struct ImBuf * ibuf, char *name, int flags)
fildes = fopen(name,"wb");
if (!fildes) return 0;
- if (fwrite(buf, 1, 18,fildes) != 18) return (0);
+ if (fwrite(buf, 1, 18,fildes) != 18) {
+ fclose(fildes);
+ return (0);
+ }
if (ibuf->cmap){
for (i = 0 ; i<ibuf->maxcol ; i++){
@@ -365,8 +368,24 @@ int imb_is_a_targa(void *buf) {
return checktarga(&tga, buf);
}
-static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int psize)
+static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect)
{
+ int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect);
+ if(size) {
+ printf("decodetarga: incomplete file, %.1f%% missing\n", 100*((float)size / (ibuf->x * ibuf->y)));
+
+ /* not essential but makes displaying partially rendered TGA's less ugly */
+ memset(rect, 0, size);
+ }
+ else {
+ /* shouldnt happen */
+ printf("decodetarga: incomplete file, all pixels written\n");
+ }
+}
+
+static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int mem_size, int psize)
+{
+ unsigned char *mem_end = mem+mem_size;
int count, col, size;
unsigned int *rect;
uchar * cp = (uchar *) &col;
@@ -380,9 +399,13 @@ static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int psize)
/* set alpha */
cp[0] = 0xff;
cp[1] = cp[2] = 0;
-
+
while(size > 0){
count = *mem++;
+
+ if(mem>mem_end)
+ goto partial_load;
+
if (count >= 128) {
/*if (count == 128) printf("TARGA: 128 in file !\n");*/
count -= 127;
@@ -452,15 +475,28 @@ static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int psize)
}
*rect++ = col;
count --;
+
+ if(mem>mem_end)
+ goto partial_load;
}
+
+ if(mem>mem_end)
+ goto partial_load;
}
}
}
- if (size) printf("decodetarga: count would overwrite %d pixels\n", -size);
+ if (size) {
+ printf("decodetarga: count would overwrite %d pixels\n", -size);
+ }
+ return;
+
+partial_load:
+ complete_partial_load(ibuf, rect);
}
-static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int psize)
+static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int mem_size, int psize)
{
+ unsigned char *mem_end = mem+mem_size;
int col,size;
unsigned int *rect;
uchar * cp = (uchar *) &col;
@@ -476,6 +512,9 @@ static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int psize)
cp[1] = cp[2] = 0;
while(size > 0){
+ if(mem>mem_end)
+ goto partial_load;
+
if (psize & 2){
if (psize & 1){
/* order = bgra */
@@ -505,10 +544,14 @@ static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int psize)
*rect++ = col;
size--;
}
+ return;
+
+partial_load:
+ complete_partial_load(ibuf, rect);
}
-struct ImBuf *imb_loadtarga(unsigned char *mem, int flags)
+struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
{
TARGA tga;
struct ImBuf * ibuf;
@@ -579,18 +622,18 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int flags)
case 1:
case 2:
case 3:
- if (tga.pixsize <= 8) ldtarga(ibuf,mem,0);
- else if (tga.pixsize <= 16) ldtarga(ibuf,mem,1);
- else if (tga.pixsize <= 24) ldtarga(ibuf,mem,2);
- else if (tga.pixsize <= 32) ldtarga(ibuf,mem,3);
+ if (tga.pixsize <= 8) ldtarga(ibuf,mem,mem_size,0);
+ else if (tga.pixsize <= 16) ldtarga(ibuf,mem,mem_size,1);
+ else if (tga.pixsize <= 24) ldtarga(ibuf,mem,mem_size,2);
+ else if (tga.pixsize <= 32) ldtarga(ibuf,mem,mem_size,3);
break;
case 9:
case 10:
case 11:
- if (tga.pixsize <= 8) decodetarga(ibuf,mem,0);
- else if (tga.pixsize <= 16) decodetarga(ibuf,mem,1);
- else if (tga.pixsize <= 24) decodetarga(ibuf,mem,2);
- else if (tga.pixsize <= 32) decodetarga(ibuf,mem,3);
+ if (tga.pixsize <= 8) decodetarga(ibuf,mem,mem_size,0);
+ else if (tga.pixsize <= 16) decodetarga(ibuf,mem,mem_size,1);
+ else if (tga.pixsize <= 24) decodetarga(ibuf,mem,mem_size,2);
+ else if (tga.pixsize <= 32) decodetarga(ibuf,mem,mem_size,3);
break;
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 718b0537b48..6053c5556f1 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -27,9 +27,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/* also defined in BKE_utildefines, repeated here to avoid dependency */
-#define FILE_MAX 240
+#include <stdio.h>
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "MEM_guardedalloc.h"
@@ -38,31 +39,29 @@
#include "IMB_thumbs.h"
#include "IMB_imginfo.h"
-
#include "md5.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
#ifdef WIN32
#include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
#endif
#include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
-#include "BLI_winstuff.h"
#include <process.h> /* getpid */
#include <direct.h> /* chdir */
+#include "BLI_winstuff.h"
#else
#include <unistd.h>
#endif
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
#define URI_MAX FILE_MAX*3 + 8
static int get_thumb_dir( char* dir , ThumbSize size)
@@ -231,6 +230,16 @@ static int thumbpath_from_uri(const char* uri, char* path, ThumbSize size)
return rv;
}
+void IMB_thumb_makedirs()
+{
+ char tpath[FILE_MAX];
+ if (get_thumb_dir(tpath, THB_NORMAL)) {
+ BLI_recurdir_fileops(tpath);
+ }
+ if (get_thumb_dir(tpath, THB_FAIL)) {
+ BLI_recurdir_fileops(tpath);
+ }
+}
/* create thumbnail for file and returns new imbuf for thumbnail */
ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, ThumbSource source)
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 194082d3e19..b2465d6cc2f 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -410,7 +410,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
/* close the client layer interface to the in-memory file */
libtiff_TIFFClose(image);
- if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+ if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
/* return successfully */
return (ibuf);
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 4f6730db1f1..26434583118 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -29,6 +29,13 @@
* $Id$
*/
+#ifdef _WIN32
+#include <io.h>
+#define open _open
+#define read _read
+#define close _close
+#endif
+
#include "BLI_blenlib.h"
#include "DNA_userdef_types.h"
@@ -61,9 +68,15 @@
#include "quicktime_import.h"
#endif
+#ifdef WITH_OPENJPEG
+#include "IMB_jp2.h"
+#endif
+
#ifdef WITH_FFMPEG
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavdevice/avdevice.h>
+#include <libavutil/log.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
@@ -131,7 +144,11 @@ static int IMB_ispic_name(char *name)
/*
if (imb_is_a_bmp(buf)) return(BMP);
*/
-
+
+#ifdef WITH_OPENJPEG
+ if (imb_is_a_jp2(buf)) return(JP2);
+#endif
+
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
if(G.have_quicktime) {
@@ -182,6 +199,9 @@ int IMB_ispic(char *filename)
#ifdef WITH_BF_OPENEXR
|| BLI_testextensie(filename, ".exr")
#endif
+#ifdef WITH_BF_OPENJPEG
+ || BLI_testextensie(filename, ".jp2")
+#endif
|| BLI_testextensie(filename, ".sgi")) {
return IMB_ispic_name(filename);
} else {
@@ -202,6 +222,9 @@ int IMB_ispic(char *filename)
#ifdef WITH_BF_OPENEXR
|| BLI_testextensie(filename, ".exr")
#endif
+#ifdef WITH_BF_OPENJPEG
+ || BLI_testextensie(filename, ".jp2")
+#endif
|| BLI_testextensie(filename, ".iff")
|| BLI_testextensie(filename, ".lbm")
|| BLI_testextensie(filename, ".sgi")) {
@@ -229,6 +252,19 @@ static int isqtime (char *name) {
#endif
#ifdef WITH_FFMPEG
+
+void silence_log_ffmpeg(int quiet)
+{
+ if (quiet)
+ {
+ av_log_set_level(AV_LOG_QUIET);
+ }
+ else
+ {
+ av_log_set_level(AV_LOG_INFO);
+ }
+}
+
extern void do_init_ffmpeg();
void do_init_ffmpeg()
{
@@ -236,6 +272,12 @@ void do_init_ffmpeg()
if (!ffmpeg_init) {
ffmpeg_init = 1;
av_register_all();
+ avdevice_register_all();
+
+ if ((G.f & G_DEBUG) == 0)
+ {
+ silence_log_ffmpeg(1);
+ }
}
}
@@ -254,7 +296,8 @@ static AVCodecContext* get_codec_from_stream(AVStream* stream)
static int isffmpeg (char *filename) {
AVFormatContext *pFormatCtx;
- int i, videoStream;
+ unsigned int i;
+ int videoStream;
AVCodec *pCodec;
AVCodecContext *pCodecCtx;
@@ -358,8 +401,6 @@ int imb_get_anim_type(char * name) {
if (ib_stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
- if (isavi(name)) return (ANIM_AVI);
-
if (ismovie(name)) return (ANIM_MOVIE);
# ifdef WITH_QUICKTIME
if (isqtime(name)) return (ANIM_QTIME);
@@ -367,6 +408,7 @@ int imb_get_anim_type(char * name) {
# ifdef WITH_FFMPEG
if (isffmpeg(name)) return (ANIM_FFMPEG);
# endif
+ if (isavi(name)) return (ANIM_AVI);
#endif
#ifdef WITH_REDCODE
if (isredcode(name)) return (ANIM_REDCODE);
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index 5a4f83a473b..b3af727190a 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -29,9 +29,7 @@
* $Id$
*/
-#ifdef WIN32
-#include <io.h>
-#endif
+#include <stdio.h>
#include "BKE_global.h"
#include "BLI_blenlib.h"
@@ -55,6 +53,9 @@
#include "IMB_bmp.h"
#include "IMB_tiff.h"
#include "IMB_radiance_hdr.h"
+#ifdef WITH_OPENJPEG
+#include "IMB_jp2.h"
+#endif
#ifdef WITH_OPENEXR
#include "openexr/openexr_api.h"
#endif
@@ -66,6 +67,10 @@
#include "IMB_bitplanes.h"
#include "IMB_divers.h"
+#ifdef WIN32
+#include <io.h>
+#include "BLI_winstuff.h"
+#endif
/* added facility to copy with saving non-float rects */
short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags)
@@ -129,6 +134,11 @@ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags)
if (IS_dpx(ibuf)) {
return imb_save_dpx(ibuf, name, flags);
}
+#ifdef WITH_OPENJPEG
+ if (IS_jp2(ibuf)) {
+ return imb_savejp2(ibuf, name, flags);
+ }
+#endif
file = open(name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
if (file < 0) return (FALSE);