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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/intern/image_format.cc36
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt3
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt3
-rw-r--r--source/blender/imbuf/CMakeLists.txt13
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h3
-rw-r--r--source/blender/imbuf/intern/IMB_filetype.h13
-rw-r--r--source/blender/imbuf/intern/filetype.c14
-rw-r--r--source/blender/imbuf/intern/util.c13
-rw-r--r--source/blender/imbuf/intern/webp.c129
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c9
-rw-r--r--source/blender/python/intern/CMakeLists.txt4
14 files changed, 243 insertions, 6 deletions
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 268239ed7b5..bb91b2f63f6 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -607,6 +607,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
+
if(WITH_CODEC_AVI)
list(APPEND INC
../io/avi
diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc
index 2b5712a1597..3ff0b3da963 100644
--- a/source/blender/blenkernel/intern/image_format.cc
+++ b/source/blender/blenkernel/intern/image_format.cc
@@ -120,6 +120,12 @@ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
return IMB_FTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (imtype == R_IMF_IMTYPE_WEBP) {
+ r_options->quality = 90;
+ return IMB_FTYPE_WEBP;
+ }
+#endif
r_options->quality = 90;
return IMB_FTYPE_JPG;
@@ -177,6 +183,11 @@ char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
return R_IMF_IMTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (ftype == IMB_FTYPE_WEBP) {
+ return R_IMF_IMTYPE_WEBP;
+ }
+#endif
return R_IMF_IMTYPE_JPEG90;
}
@@ -220,6 +231,7 @@ bool BKE_imtype_supports_quality(const char imtype)
case R_IMF_IMTYPE_JPEG90:
case R_IMF_IMTYPE_JP2:
case R_IMF_IMTYPE_AVIJPEG:
+ case R_IMF_IMTYPE_WEBP:
return true;
}
return false;
@@ -259,6 +271,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_WEBP:
chan_flag |= IMA_CHAN_FLAG_ALPHA;
break;
}
@@ -379,6 +392,11 @@ char BKE_imtype_from_arg(const char *imtype_arg)
return R_IMF_IMTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (STREQ(imtype_arg, "WEBP")) {
+ return R_IMF_IMTYPE_WEBP;
+ }
+#endif
return R_IMF_IMTYPE_INVALID;
}
@@ -494,6 +512,12 @@ static bool do_add_image_extension(char *string,
}
}
#endif
+#ifdef WITH_WEBP
+ else if (imtype == R_IMF_IMTYPE_WEBP) {
+ if (!BLI_path_extension_check(string, extension_test = ".webp"))
+ 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", nullptr))) {
extension = extension_test;
@@ -732,6 +756,12 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
}
}
#endif
+#ifdef WITH_WEBP
+ else if (imtype == R_IMF_IMTYPE_WEBP) {
+ ibuf->ftype = IMB_FTYPE_WEBP;
+ ibuf->foptions.quality = quality;
+ }
+#endif
else {
/* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */
if (quality < 10) {
@@ -864,6 +894,12 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
}
}
#endif
+#ifdef WITH_WEBP
+ else if (ftype == IMB_FTYPE_WEBP) {
+ im_format->imtype = R_IMF_IMTYPE_WEBP;
+ im_format->quality = quality;
+ }
+#endif
else {
im_format->imtype = R_IMF_IMTYPE_JPEG90;
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index c4c6fa01025..b8c28e354da 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -79,6 +79,9 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index f5cc6083b25..c385420b18e 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -60,6 +60,9 @@ if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
blender_add_lib(bf_editor_space_image "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 25961e6e1d5..e46326467cc 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -174,6 +174,19 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ list(APPEND SRC
+ intern/webp.c
+ )
+ list(APPEND INC_SYS
+ ${WEBP_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${WEBP_LIBRARIES}
+ )
+ add_definitions(-DWITH_WEBP)
+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 98b7cc6e87f..934163846e4 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -80,6 +80,9 @@ enum eImbFileType {
#ifdef WITH_DDS
IMB_FTYPE_DDS = 13,
#endif
+#ifdef WITH_WEBP
+ IMB_FTYPE_WEBP = 14,
+#endif
};
/* Only for readability. */
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index 035c5b10c60..31f8b3a9505 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -238,3 +238,16 @@ void imb_loadtiletiff(
bool imb_savetiff(struct ImBuf *ibuf, const char *filepath, int flags);
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Format: TIFF (#IMB_FTYPE_WEBP)
+ * \{ */
+
+bool imb_is_a_webp(const unsigned char *buf, size_t size);
+struct ImBuf *imb_loadwebp(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
+bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags);
+
+/** \} */
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index 60442f97885..548bc9e120c 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -197,6 +197,20 @@ const ImFileType IMB_FILE_TYPES[] = {
.default_save_role = COLOR_ROLE_DEFAULT_FLOAT,
},
#endif
+#ifdef WITH_WEBP
+ {
+ .init = NULL,
+ .exit = NULL,
+ .is_a = imb_is_a_webp,
+ .load = imb_loadwebp,
+ .load_filepath = NULL,
+ .save = imb_savewebp,
+ .load_tile = NULL,
+ .flag = 0,
+ .filetype = IMB_FTYPE_WEBP,
+ .default_save_role = COLOR_ROLE_DEFAULT_BYTE,
+ },
+#endif
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
};
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 241f1a736f4..45b50c866fe 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -41,12 +41,12 @@
#define UTIL_DEBUG 0
const char *imb_ext_image[] = {
- ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
+ ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
#ifdef WITH_TIFF
- ".tif", ".tiff", ".tx",
+ ".tif", ".tiff", ".tx",
#endif
#ifdef WITH_OPENJPEG
- ".jp2", ".j2c",
+ ".jp2", ".j2c",
#endif
#ifdef WITH_HDR
".hdr",
@@ -55,13 +55,16 @@ const char *imb_ext_image[] = {
".dds",
#endif
#ifdef WITH_CINEON
- ".dpx", ".cin",
+ ".dpx", ".cin",
#endif
#ifdef WITH_OPENEXR
".exr",
#endif
#ifdef WITH_OPENIMAGEIO
- ".psd", ".pdd", ".psb",
+ ".psd", ".pdd", ".psb",
+#endif
+#ifdef WITH_WEBP
+ ".webp",
#endif
NULL,
};
diff --git a/source/blender/imbuf/intern/webp.c b/source/blender/imbuf/intern/webp.c
new file mode 100644
index 00000000000..1070920e458
--- /dev/null
+++ b/source/blender/imbuf/intern/webp.c
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file blender/imbuf/intern/webp.c
+ * \ingroup imbuf
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <webp/decode.h>
+#include <webp/encode.h>
+
+#include "BLI_fileops.h"
+#include "BLI_utildefines.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+#include "IMB_filetype.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "MEM_guardedalloc.h"
+
+bool imb_is_a_webp(const unsigned char *buf, size_t size)
+{
+ if (WebPGetInfo(buf, size, NULL, NULL)) {
+ return true;
+ }
+ return false;
+}
+
+ImBuf *imb_loadwebp(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
+{
+ if (!imb_is_a_webp(mem, size)) {
+ return NULL;
+ }
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ WebPBitstreamFeatures features;
+ if (WebPGetFeatures(mem, size, &features) != VP8_STATUS_OK) {
+ fprintf(stderr, "WebP: Failed to parse features\n");
+ return NULL;
+ }
+
+ const int planes = features.has_alpha ? 32 : 24;
+ ImBuf *ibuf = IMB_allocImBuf(features.width, features.height, planes, 0);
+
+ if (ibuf == NULL) {
+ fprintf(stderr, "WebP: Failed to allocate image memory\n");
+ return NULL;
+ }
+
+ if ((flags & IB_test) == 0) {
+ ibuf->ftype = IMB_FTYPE_WEBP;
+ imb_addrectImBuf(ibuf);
+ /* Flip the image during decoding to match Blender. */
+ unsigned char *last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
+ if (WebPDecodeRGBAInto(mem, size, last_row, (size_t)(ibuf->x) * ibuf->y * 4, -4 * ibuf->x) ==
+ NULL) {
+ fprintf(stderr, "WebP: Failed to decode image\n");
+ }
+ }
+
+ return ibuf;
+}
+
+bool imb_savewebp(struct ImBuf *ibuf, const char *name, int UNUSED(flags))
+{
+ const int bytesperpixel = (ibuf->planes + 7) >> 3;
+ unsigned char *encoded_data, *last_row;
+ size_t encoded_data_size;
+
+ if (bytesperpixel == 3) {
+ /* We must convert the ImBuf RGBA buffer to RGB as WebP expects a RGB buffer. */
+ const size_t num_pixels = ibuf->x * ibuf->y;
+ const uint8_t *rgba_rect = (uint8_t *)ibuf->rect;
+ uint8_t *rgb_rect = MEM_mallocN(sizeof(uint8_t) * num_pixels * 3, "webp rgb_rect");
+ for (int i = 0; i < num_pixels; i++) {
+ rgb_rect[i * 3 + 0] = rgba_rect[i * 4 + 0];
+ rgb_rect[i * 3 + 1] = rgba_rect[i * 4 + 1];
+ rgb_rect[i * 3 + 2] = rgba_rect[i * 4 + 2];
+ }
+
+ last_row = (unsigned char *)(rgb_rect + (ibuf->y - 1) * ibuf->x * 3);
+ MEM_freeN(rgb_rect);
+
+ if (ibuf->foptions.quality == 100.0f) {
+ encoded_data_size = WebPEncodeLosslessRGB(
+ last_row, ibuf->x, ibuf->y, -3 * ibuf->x, &encoded_data);
+ }
+ else {
+ encoded_data_size = WebPEncodeRGB(
+ last_row, ibuf->x, ibuf->y, -3 * ibuf->x, ibuf->foptions.quality, &encoded_data);
+ }
+ }
+ else if (bytesperpixel == 4) {
+ last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
+
+ if (ibuf->foptions.quality == 100.0f) {
+ encoded_data_size = WebPEncodeLosslessRGBA(
+ last_row, ibuf->x, ibuf->y, -4 * ibuf->x, &encoded_data);
+ }
+ else {
+ encoded_data_size = WebPEncodeRGBA(
+ last_row, ibuf->x, ibuf->y, -4 * ibuf->x, ibuf->foptions.quality, &encoded_data);
+ }
+ }
+ else {
+ fprintf(stderr, "WebP: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ return false;
+ }
+
+ if (encoded_data != NULL) {
+ FILE *fp = BLI_fopen(name, "wb");
+ if (!fp) {
+ free(encoded_data);
+ fprintf(stderr, "WebP: Cannot open file for writing: '%s'\n", name);
+ return false;
+ }
+ fwrite(encoded_data, encoded_data_size, 1, fp);
+ free(encoded_data);
+ fclose(fp);
+ }
+
+ return true;
+}
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 24c120ae860..e6b2f2769b8 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -465,6 +465,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_WEBP 35
#define R_IMF_IMTYPE_INVALID 255
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 4e3a4aae727..9980545c19d 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -236,6 +236,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+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 8172a511eb0..6be2c361ba9 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -330,6 +330,13 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = {
# define R_IMF_ENUM_TIFF
#endif
+#ifdef WITH_WEBP
+# define R_IMF_ENUM_WEBP \
+ {R_IMF_IMTYPE_WEBP, "WEBP", ICON_FILE_IMAGE, "WebP", "Output image in WebP format"},
+#else
+# define R_IMF_ENUM_WEBP
+#endif
+
#define IMAGE_TYPE_ITEMS_IMAGE_ONLY \
R_IMF_ENUM_BMP \
/* DDS save not supported yet R_IMF_ENUM_DDS */ \
@@ -340,7 +347,7 @@ 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_WEBP
#ifdef RNA_RUNTIME
static const EnumPropertyItem image_only_type_items[] = {
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index a35f03f9872..f813a006c7e 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -224,6 +224,10 @@ if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
+if(WITH_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
+
if(WITH_INPUT_NDOF)
add_definitions(-DWITH_INPUT_NDOF)
endif()