diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2009-09-19 02:25:49 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2009-09-19 02:25:49 +0400 |
commit | be50ce61be7fdc96943dbdac79aabd88ba29996f (patch) | |
tree | 4dfde72478458923a3b2ce8d22e1658d4508024c /source/blender/imbuf | |
parent | 0a4d70f4d0ddc5bc709b162d84ec334e66ed848d (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')
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(¶meters); + + + /* 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, ¶meters); + + /* 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(¶meters); + + /* 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, ¶meters); + + + { /* 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, ¶meters, 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); |