IMBUF: Improved Thumbnailing of WebP Images
Thumbnail WebP images quicker while using much less RAM. See D15908 for more details. Differential Revision: https://developer.blender.org/D15908 Reviewed by Brecht Van Lommel
This commit is contained in:
parent
ad245f1970
commit
8851790dd7
Notes:
blender-bot
2024-01-16 18:05:25 +01:00
Referenced by commit 28c9b33870
, IMBUF: Fix WebP Build Error and Warnings
|
@ -264,6 +264,12 @@ struct ImBuf *imb_loadwebp(const unsigned char *mem,
|
|||
size_t size,
|
||||
int flags,
|
||||
char colorspace[IM_MAX_SPACE]);
|
||||
struct ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath,
|
||||
const int flags,
|
||||
const size_t max_thumb_size,
|
||||
char colorspace[],
|
||||
size_t *r_width,
|
||||
size_t *r_height);
|
||||
bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags);
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -217,7 +217,7 @@ const ImFileType IMB_FILE_TYPES[] = {
|
|||
.is_a = imb_is_a_webp,
|
||||
.load = imb_loadwebp,
|
||||
.load_filepath = NULL,
|
||||
.load_filepath_thumbnail = NULL,
|
||||
.load_filepath_thumbnail = imb_load_filepath_thumbnail_webp,
|
||||
.save = imb_savewebp,
|
||||
.load_tile = NULL,
|
||||
.flag = 0,
|
||||
|
|
|
@ -4,14 +4,21 @@
|
|||
* \ingroup imbuf
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <webp/decode.h>
|
||||
#include <webp/encode.h>
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_mmap.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "IMB_allocimbuf.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_colormanagement_intern.h"
|
||||
#include "IMB_filetype.h"
|
||||
|
@ -67,6 +74,85 @@ ImBuf *imb_loadwebp(const unsigned char *mem,
|
|||
return ibuf;
|
||||
}
|
||||
|
||||
struct ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath,
|
||||
const int flags,
|
||||
const size_t max_thumb_size,
|
||||
char colorspace[],
|
||||
size_t *r_width,
|
||||
size_t *r_height)
|
||||
{
|
||||
const int file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
|
||||
if (file == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t data_size = BLI_file_descriptor_size(file);
|
||||
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_file *mmap_file = BLI_mmap_open(file);
|
||||
imb_mmap_unlock();
|
||||
close(file);
|
||||
if (mmap_file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char *data = BLI_mmap_get_pointer(mmap_file);
|
||||
|
||||
WebPDecoderConfig config;
|
||||
if (!data || !WebPInitDecoderConfig(&config) ||
|
||||
WebPGetFeatures(data, data_size, &config.input) != VP8_STATUS_OK) {
|
||||
fprintf(stderr, "WebP: Invalid file\n");
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_free(mmap_file);
|
||||
imb_mmap_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const float scale = (float)max_thumb_size / MAX2(config.input.width, config.input.height);
|
||||
const int dest_w = (int)(config.input.width * scale);
|
||||
const int dest_h = (int)(config.input.height * scale);
|
||||
|
||||
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
|
||||
struct ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rect);
|
||||
if (ibuf == NULL) {
|
||||
fprintf(stderr, "WebP: Failed to allocate image memory\n");
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_free(mmap_file);
|
||||
imb_mmap_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config.options.no_fancy_upsampling = 1;
|
||||
config.options.use_scaling = 1;
|
||||
config.options.scaled_width = dest_w;
|
||||
config.options.scaled_height = dest_h;
|
||||
config.options.bypass_filtering = 1;
|
||||
config.options.use_threads = 0;
|
||||
config.options.flip = 1;
|
||||
config.output.is_external_memory = 1;
|
||||
config.output.colorspace = MODE_RGBA;
|
||||
config.output.u.RGBA.rgba = (uint8_t *)ibuf->rect;
|
||||
config.output.u.RGBA.stride = 4 * ibuf->x;
|
||||
config.output.u.RGBA.size = (size_t)(config.output.u.RGBA.stride * ibuf->y);
|
||||
|
||||
if (WebPDecode(data, data_size, &config) != VP8_STATUS_OK) {
|
||||
fprintf(stderr, "WebP: Failed to decode image\n");
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_free(mmap_file);
|
||||
imb_mmap_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free the output buffer. */
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_free(mmap_file);
|
||||
imb_mmap_unlock();
|
||||
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
bool imb_savewebp(struct ImBuf *ibuf, const char *name, int UNUSED(flags))
|
||||
{
|
||||
const int bytesperpixel = (ibuf->planes + 7) >> 3;
|
||||
|
|
Loading…
Reference in New Issue