diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 24 | ||||
-rw-r--r-- | source/blender/imbuf/CMakeLists.txt | 15 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf_types.h | 4 | ||||
-rw-r--r-- | source/blender/imbuf/intern/IMB_filetype.h | 10 | ||||
-rw-r--r-- | source/blender/imbuf/intern/filetype.c | 15 | ||||
-rw-r--r-- | source/blender/imbuf/intern/ktx.c | 161 | ||||
-rw-r--r-- | source/blender/imbuf/intern/util.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 10 | ||||
-rw-r--r-- | source/creator/CMakeLists.txt | 8 |
12 files changed, 256 insertions, 5 deletions
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index efc9cd6e99f..11dab0ecaad 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -611,6 +611,10 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_KTX) + add_definitions(-DWITH_KTX) +endif() + if(WITH_CODEC_AVI) list(APPEND INC ../io/avi diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 040257fe976..130691dc7ff 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1459,7 +1459,6 @@ void BKE_image_all_free_anim_ibufs(Main *bmain, int cfra) } /* *********** READ AND WRITE ************** */ - int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) { memset(r_options, 0, sizeof(*r_options)); @@ -1571,6 +1570,11 @@ char BKE_image_ftype_to_imtype(const int ftype, const ImbFormatOptions *options) return R_IMF_IMTYPE_JP2; } #endif +#ifdef WITH_KTX + if (ftype == IMB_FTYPE_KTX) { + return R_IMF_IMTYPE_KTX; + } +#endif return R_IMF_IMTYPE_JPEG90; } @@ -1653,6 +1657,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file) case R_IMF_IMTYPE_DDS: case R_IMF_IMTYPE_JP2: case R_IMF_IMTYPE_DPX: + case R_IMF_IMTYPE_KTX: chan_flag |= IMA_CHAN_FLAG_ALPHA; break; } @@ -1886,6 +1891,12 @@ static bool do_add_image_extension(char *string, } } #endif +#ifdef WITH_KTX + else if (imtype == R_IMF_IMTYPE_KTX) { + if (!BLI_path_extension_check(string, extension_test = ".ktx")) + extension = extension_test; + } +#endif else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", NULL))) { extension = extension_test; @@ -2051,7 +2062,11 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i } } #endif - +#ifdef WITH_KTX + else if (ftype == IMB_FTYPE_KTX) { + im_format->imtype = R_IMF_IMTYPE_KTX; + } +#endif else { im_format->imtype = R_IMF_IMTYPE_JPEG90; im_format->quality = quality; @@ -3116,6 +3131,11 @@ void BKE_imbuf_write_prepare(ImBuf *ibuf, const ImageFormatData *imf) } } #endif +#ifdef WITH_KTX + else if (imtype == R_IMF_IMTYPE_KTX) { + ibuf->ftype = IMB_FTYPE_KTX; + } +#endif else { /* R_IMF_IMTYPE_JPEG90, etc. default we save jpegs */ if (quality < 10) { diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 479f4f7e82f..a14e91179d6 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -123,7 +123,6 @@ if(WITH_IMAGE_TIFF) add_definitions(-DWITH_TIFF) endif() - if(WITH_OPENIMAGEIO) list(APPEND LIB bf_imbuf_openimageio @@ -190,6 +189,20 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_KTX) + list(APPEND INC + ${KTX_INCLUDE} + ) + list(APPEND SRC + intern/ktx.c + ) + list(APPEND LIB + ${KTX_LIBRARY} + ) + + add_definitions(-DWITH_KTX) +endif() + list(APPEND INC ../../../intern/opencolorio ) diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 58148743b7e..952497eb57e 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -96,6 +96,10 @@ enum eImbFileType { #ifdef WITH_DDS IMB_FTYPE_DDS = 13, #endif + +#ifdef WITH_KTX + IMB_FTYPE_KTX = 14, +#endif }; /* Only for readability. */ diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index bf6aef3ecd3..06bb88dd2b3 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -116,6 +116,16 @@ bool imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ /* -------------------------------------------------------------------- */ +/** \name Format: KTX (#IMB_FTYPE_KTX) + * \{ */ + +bool check_ktx(const unsigned char *mem, size_t size); +struct ImBuf *imb_loadktx(const unsigned char *mem, size_t size, int flags, char *colorspace); +bool imb_savektx(struct ImBuf *ibuf, const char *name, int flags); + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Format: IRIS (#IMB_FTYPE_IMAGIC) * \{ */ diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index b1fe557a9bf..17e38312094 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -211,6 +211,21 @@ const ImFileType IMB_FILE_TYPES[] = { .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, }, #endif +#ifdef WITH_KTX + { + .init = NULL, + .exit = NULL, + .is_a = check_ktx, + .load = imb_loadktx, + .load_filepath = NULL, + .save = imb_savektx, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_KTX, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, + //{imb_initktx, NULL, check_ktx, imb_is_a_ktx, imb_ftype_default, imb_loadktx, NULL, imb_savektx, NULL, 0, IMB_FTYPE_KTX, COLOR_ROLE_DEFAULT_BYTE}, +#endif {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}, }; diff --git a/source/blender/imbuf/intern/ktx.c b/source/blender/imbuf/intern/ktx.c new file mode 100644 index 00000000000..e5647a396ca --- /dev/null +++ b/source/blender/imbuf/intern/ktx.c @@ -0,0 +1,161 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 blender/imbuf/intern/ktx.c + * \ingroup imbuf + */ + +#include "ktx.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "IMB_filetype.h" + +#include "BLI_utildefines.h" +#include "BLI_path_util.h" +#include "BLI_sys_types.h" + +#include <string.h> +#include <stdlib.h> + +static char KTX_HEAD[] = {0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A}; + + +bool check_ktx(const unsigned char *mem, size_t size) +{ + return memcmp(KTX_HEAD, mem, sizeof(KTX_HEAD)) == 0; +} + +struct ImBuf *imb_loadktx(const unsigned char *mem, size_t size, int flags, char * UNUSED(colorspace)) +{ + ktxTexture *tex; + KTX_error_code ktx_error = ktxTexture_CreateFromMemory( + mem, size, KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tex); + + if (ktx_error != KTX_SUCCESS) { + return NULL; + } + + ktx_size_t offset; + ktx_error = ktxTexture_GetImageOffset(tex, 0, 0, 0, &offset); + + if (ktx_error != KTX_SUCCESS) { + ktxTexture_Destroy(tex); + return NULL; + } + + const ktx_uint8_t *image = ktxTexture_GetData(tex) + offset; + + ktx_uint32_t x_size = tex->baseWidth; + ktx_uint32_t y_size = tex->baseHeight; + + ImBuf *ibuf = IMB_allocImBuf(x_size, y_size, 32, (int)IB_rect); + + bool flip_x = false, flip_y = false; + + size_t num_pixels = (size_t)x_size * (size_t)y_size; + for (size_t i = 0; i < num_pixels; ++i) { + ktx_uint8_t *c_out = (ktx_uint8_t *)(ibuf->rect + i); + const ktx_uint8_t *c_in = image + i * 4; + + for (size_t c = 0; c < 4; ++c) { + c_out[c] = c_in[c]; + } + } + + const char *pValue; + uint32_t valueLen; + ktx_error = ktxHashList_FindValue(&tex->kvDataHead, KTX_ORIENTATION_KEY, &valueLen, (void **)&pValue); + if (ktx_error == KTX_SUCCESS) { + char cx, cy; + if (sscanf(pValue, KTX_ORIENTATION2_FMT, &cx, &cy) == 2) { + flip_x = (cx == 'd'); + flip_y = (cy == 'd'); + } + } + + if (flip_x && flip_y) { + for (size_t i = 0; i < num_pixels / 2; i++) { + SWAP(unsigned int, ibuf->rect[i], ibuf->rect[num_pixels - i - 1]); + } + } + else if (flip_y) { + size_t i, j; + for (j = 0; j < ibuf->y / 2; j++) { + for (i = 0; i < ibuf->x; i++) { + SWAP(unsigned int, + ibuf->rect[i + j * ibuf->x], + ibuf->rect[i + (ibuf->y - j - 1) * ibuf->x]); + } + } + } + + ktxTexture_Destroy(tex); + + return ibuf; +} + + +bool imb_savektx(struct ImBuf *ibuf, const char *name, int UNUSED(flags)) +{ + ktxTextureCreateInfo create_info; + create_info.glInternalformat = 0x8058; // GL_RGBA8 + create_info.baseWidth = ibuf->x; + create_info.baseHeight = ibuf->y; + create_info.baseDepth = 1; + create_info.numDimensions = 2; + // Note: it is not necessary to provide a full mipmap pyramid. + create_info.numLevels = 1; + create_info.numLayers = 1; + create_info.numFaces = 1; + create_info.isArray = KTX_FALSE; + create_info.generateMipmaps = KTX_TRUE; + KTX_error_code result; + ktxTexture1 *tex; + result = ktxTexture1_Create(&create_info, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &tex); + if (KTX_SUCCESS != result) { + return false; + } + + ktxTexture *texture = ktxTexture(tex); + + ktx_uint32_t level, layer, face_slice; + level = 0; + layer = 0; + face_slice = 0; + result = ktxTexture_SetImageFromMemory( + texture, level, layer, face_slice, (ktx_uint8_t*)ibuf->rect, (size_t)ibuf->x * (size_t)ibuf->y * (size_t) 4); + + if (KTX_SUCCESS != result) { + ktxTexture_Destroy(texture); + return false; + } + result = ktxTexture_WriteToNamedFile(texture, name); + ktxTexture_Destroy(texture); + + return KTX_SUCCESS == result; +} diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 18ed4710e78..7c371d11d1b 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -80,7 +80,10 @@ const char *imb_ext_image[] = { #ifdef WITH_OPENIMAGEIO ".psd", ".pdd", ".psb", #endif - NULL, +#ifdef WITH_KTX + ".ktx", +#endif + NULL, }; const char *imb_ext_image_filepath_only[] = { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 864358e040c..c45f69cde8f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -481,6 +481,7 @@ typedef struct ImageFormatData { #define R_IMF_IMTYPE_XVID 32 #define R_IMF_IMTYPE_THEORA 33 #define R_IMF_IMTYPE_PSD 34 +#define R_IMF_IMTYPE_KTX 35 #define R_IMF_IMTYPE_INVALID 255 diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 91d7c5a1394..71ada76fb76 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -250,6 +250,10 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_IMAGE_KTX) + add_definitions(-DWITH_KTX) +endif() + if(WITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 201ea5469cc..3802f5ceaed 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -341,6 +341,13 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { # define R_IMF_ENUM_TIFF #endif +#if WITH_KTX +# define R_IMF_ENUM_KTX \ + {R_IMF_IMTYPE_KTX, "KTX", ICON_FILE_IMAGE, "KTX", "Output image in KTX format"}, +#else +# define R_IMF_ENUM_KTX +#endif + #define IMAGE_TYPE_ITEMS_IMAGE_ONLY \ R_IMF_ENUM_BMP \ /* DDS save not supported yet R_IMF_ENUM_DDS */ \ @@ -351,7 +358,8 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { R_IMF_ENUM_TAGA \ R_IMF_ENUM_TAGA_RAW{0, "", 0, " ", NULL}, \ R_IMF_ENUM_CINEON R_IMF_ENUM_DPX R_IMF_ENUM_EXR_MULTILAYER R_IMF_ENUM_EXR R_IMF_ENUM_HDR \ - R_IMF_ENUM_TIFF + R_IMF_ENUM_TIFF \ + R_IMF_ENUM_KTX #ifdef RNA_RUNTIME static const EnumPropertyItem image_only_type_items[] = { diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index b86b8999fd0..61809b1719d 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -734,6 +734,14 @@ elseif(WIN32) ) endif() + if(WITH_IMAGE_KTX AND WIN32) + install( + FILES ${KTX_LIBRARY_DLL} + DESTINATION "." + ) + endif() + + if(WITH_FFTW3) install( FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll |