Compare commits

...

11 Commits

Author SHA1 Message Date
d8c0550227 Merge branch 'master' into KTX_support 2022-02-07 19:37:15 +01:00
b64d551f3b Fix basic loading and reading RGBA KTX images.
Blender can also show thumbnails properly now that all work is done on the CPU
2022-01-24 22:18:00 +01:00
173291bc6d building and running with ktx now works on windows. Loading/saving most likely still broken 2022-01-24 20:28:05 +01:00
1987c894e9 Merge branch 'master' into KTX_support 2022-01-24 18:15:06 +01:00
b54ab323aa merge with master. It should build with option off, but cmake support/libs are not yet plugged in 2022-01-19 01:01:56 +01:00
4afb1899d9 KTX file format:
Support flipped images.

Two issues here:

* We need to check the metadata for flipped flags
* We need to invert compressed images (they are stored
inverted on GPU).

Not sure if all combinations are correct here (missing reference
material to make the decision), so will assume all is OKish for now.
2015-08-14 18:54:24 +02:00
fdf24d8899 Merge branch 'master' into KTX_support
Conflicts:
	source/blender/blenkernel/BKE_image.h
	source/blender/blenkernel/intern/dynamicpaint.c
	source/blender/blenkernel/intern/image.c
	source/blender/blenkernel/intern/movieclip.c
	source/blender/blenkernel/intern/sequencer.c
	source/blender/editors/space_image/image_buttons.c
	source/blender/editors/space_image/image_ops.c
	source/blender/gpu/intern/gpu_draw.c
	source/blender/imbuf/IMB_imbuf_types.h
	source/blender/imbuf/intern/allocimbuf.c
	source/blender/imbuf/intern/cineon/cineon_dpx.c
	source/blender/imbuf/intern/jp2.c
	source/blender/imbuf/intern/jpeg.c
	source/blender/imbuf/intern/openexr/openexr_api.cpp
	source/blender/imbuf/intern/png.c
	source/blender/imbuf/intern/targa.c
	source/blender/imbuf/intern/tiff.c
	source/blender/makesrna/intern/rna_image.c
	source/gameengine/Ketsji/BL_Texture.cpp
2015-08-14 15:18:46 +02:00
e3c416e938 Revert conversion to long long for KTX branch 2015-06-08 12:30:06 +02:00
67a6934dcb Merge branch 'temp_imbuf_types_refactor' into KTX_support
Conflicts:
	source/blender/blenkernel/BKE_image.h
	source/blender/blenkernel/intern/image.c
	source/blender/imbuf/IMB_imbuf_types.h
2015-06-08 12:17:15 +02:00
6b2386fa2b Imbuf types refactor.
ImBuf types were getting stored as bitflags in a 32bit integer which had
already run out of space. Solved the problem by separating file type to
an ftype enum, and file specific options to foptions.

Now we have 2^32 image formats to support, hopefully won't run out any
time soon.

Patch is committed to branch for inclusion after release due to
increased volatility, which could result explosions, spikes, acid, lava
and signs with "bad" on them if included now.
2015-06-08 12:07:34 +02:00
5e060bed27 KTX file format support
This commit introduces support for the KTX format in blender.

Saving and loading of files is supported though saving compressed formats
is not yet supported.

Thumbnails are not generated because the API relies on OpenGL to load the textures,
which is not available during threaded thumbnail generation.

We hand compiled a KTX library from https://github.com/KhronosGroup/KTX
and placed KTX lib files in intern/KTX as follows:

libktx.a in intern/KTX/lib
ktx.h in intern/KTX/include

We may include the library in extern when we make sure it compiles in all platforms (Ubuntu 15.04 failed here)

Scons is not supported, only cmake for now.
2015-05-30 19:05:50 +02:00
14 changed files with 264 additions and 5 deletions

View File

@@ -302,6 +302,7 @@ option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON) option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
option(WITH_IMAGE_KTX "Enable KTX image support" OFF)
# Audio/Video format support # Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON) option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
@@ -2030,6 +2031,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_IMAGE_OPENJPEG) info_cfg_option(WITH_IMAGE_OPENJPEG)
info_cfg_option(WITH_IMAGE_TIFF) info_cfg_option(WITH_IMAGE_TIFF)
info_cfg_option(WITH_OPENIMAGEIO) info_cfg_option(WITH_OPENIMAGEIO)
info_cfg_option(WITH_IMAGE_KTX)
info_cfg_text("Audio:") info_cfg_text("Audio:")
info_cfg_option(WITH_CODEC_AVI) info_cfg_option(WITH_CODEC_AVI)

View File

@@ -454,6 +454,12 @@ if(WITH_IMAGE_TIFF)
endif() endif()
endif() endif()
if(WITH_IMAGE_KTX)
set(KTX_INCLUDE ${LIBDIR}/ktx2/include)
set(KTX_LIBRARY ${LIBDIR}/ktx2/lib/ktx.lib)
set(KTX_LIBRARY_DLL ${LIBDIR}/ktx2/lib/ktx.dll)
endif()
if(WITH_JACK) if(WITH_JACK)
set(JACK_INCLUDE_DIRS set(JACK_INCLUDE_DIRS
${LIBDIR}/jack/include/jack ${LIBDIR}/jack/include/jack

View File

@@ -611,6 +611,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()
if(WITH_IMAGE_KTX)
add_definitions(-DWITH_KTX)
endif()
if(WITH_CODEC_AVI) if(WITH_CODEC_AVI)
list(APPEND INC list(APPEND INC
../io/avi ../io/avi

View File

@@ -1459,7 +1459,6 @@ void BKE_image_all_free_anim_ibufs(Main *bmain, int cfra)
} }
/* *********** READ AND WRITE ************** */ /* *********** READ AND WRITE ************** */
int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
{ {
memset(r_options, 0, sizeof(*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; return R_IMF_IMTYPE_JP2;
} }
#endif #endif
#ifdef WITH_KTX
if (ftype == IMB_FTYPE_KTX) {
return R_IMF_IMTYPE_KTX;
}
#endif
return R_IMF_IMTYPE_JPEG90; 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_DDS:
case R_IMF_IMTYPE_JP2: case R_IMF_IMTYPE_JP2:
case R_IMF_IMTYPE_DPX: case R_IMF_IMTYPE_DPX:
case R_IMF_IMTYPE_KTX:
chan_flag |= IMA_CHAN_FLAG_ALPHA; chan_flag |= IMA_CHAN_FLAG_ALPHA;
break; break;
} }
@@ -1885,6 +1890,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 #endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc 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))) { if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", NULL))) {
@@ -2051,7 +2062,11 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
} }
} }
#endif #endif
#ifdef WITH_KTX
else if (ftype == IMB_FTYPE_KTX) {
im_format->imtype = R_IMF_IMTYPE_KTX;
}
#endif
else { else {
im_format->imtype = R_IMF_IMTYPE_JPEG90; im_format->imtype = R_IMF_IMTYPE_JPEG90;
im_format->quality = quality; im_format->quality = quality;
@@ -3115,6 +3130,11 @@ void BKE_imbuf_write_prepare(ImBuf *ibuf, const ImageFormatData *imf)
BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec"); BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
} }
} }
#endif
#ifdef WITH_KTX
else if (imtype == R_IMF_IMTYPE_KTX) {
ibuf->ftype = IMB_FTYPE_KTX;
}
#endif #endif
else { else {
/* R_IMF_IMTYPE_JPEG90, etc. default we save jpegs */ /* R_IMF_IMTYPE_JPEG90, etc. default we save jpegs */

View File

@@ -123,7 +123,6 @@ if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF) add_definitions(-DWITH_TIFF)
endif() endif()
if(WITH_OPENIMAGEIO) if(WITH_OPENIMAGEIO)
list(APPEND LIB list(APPEND LIB
bf_imbuf_openimageio bf_imbuf_openimageio
@@ -190,6 +189,20 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() 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 list(APPEND INC
../../../intern/opencolorio ../../../intern/opencolorio
) )

View File

@@ -96,6 +96,10 @@ enum eImbFileType {
#ifdef WITH_DDS #ifdef WITH_DDS
IMB_FTYPE_DDS = 13, IMB_FTYPE_DDS = 13,
#endif #endif
#ifdef WITH_KTX
IMB_FTYPE_KTX = 14,
#endif
}; };
/* Only for readability. */ /* Only for readability. */

View File

@@ -115,6 +115,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) /** \name Format: IRIS (#IMB_FTYPE_IMAGIC)
* \{ */ * \{ */

View File

@@ -210,6 +210,21 @@ const ImFileType IMB_FILE_TYPES[] = {
.filetype = IMB_FTYPE_PSD, .filetype = IMB_FTYPE_PSD,
.default_save_role = COLOR_ROLE_DEFAULT_FLOAT, .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 #endif
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
}; };

View File

@@ -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;
}

View File

@@ -80,7 +80,10 @@ const char *imb_ext_image[] = {
#ifdef WITH_OPENIMAGEIO #ifdef WITH_OPENIMAGEIO
".psd", ".pdd", ".psb", ".psd", ".pdd", ".psb",
#endif #endif
NULL, #ifdef WITH_KTX
".ktx",
#endif
NULL,
}; };
const char *imb_ext_image_filepath_only[] = { const char *imb_ext_image_filepath_only[] = {

View File

@@ -481,6 +481,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_XVID 32 #define R_IMF_IMTYPE_XVID 32
#define R_IMF_IMTYPE_THEORA 33 #define R_IMF_IMTYPE_THEORA 33
#define R_IMF_IMTYPE_PSD 34 #define R_IMF_IMTYPE_PSD 34
#define R_IMF_IMTYPE_KTX 35
#define R_IMF_IMTYPE_INVALID 255 #define R_IMF_IMTYPE_INVALID 255

View File

@@ -250,6 +250,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()
if(WITH_IMAGE_KTX)
add_definitions(-DWITH_KTX)
endif()
if(WITH_AUDASPACE) if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE)

View File

@@ -341,6 +341,13 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = {
# define R_IMF_ENUM_TIFF # define R_IMF_ENUM_TIFF
#endif #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 \ #define IMAGE_TYPE_ITEMS_IMAGE_ONLY \
R_IMF_ENUM_BMP \ R_IMF_ENUM_BMP \
/* DDS save not supported yet R_IMF_ENUM_DDS */ \ /* 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 \
R_IMF_ENUM_TAGA_RAW{0, "", 0, " ", NULL}, \ 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_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 #ifdef RNA_RUNTIME
static const EnumPropertyItem image_only_type_items[] = { static const EnumPropertyItem image_only_type_items[] = {

View File

@@ -734,6 +734,14 @@ elseif(WIN32)
) )
endif() endif()
if(WITH_IMAGE_KTX AND WIN32)
install(
FILES ${KTX_LIBRARY_DLL}
DESTINATION "."
)
endif()
if(WITH_FFTW3) if(WITH_FFTW3)
install( install(
FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll