18#include <webp/decode.h>
19#include <webp/encode.h>
39 if (WebPGetInfo(mem,
size,
nullptr,
nullptr)) {
51 WebPBitstreamFeatures features;
52 if (WebPGetFeatures(mem,
size, &features) != VP8_STATUS_OK) {
57 const int planes = features.has_alpha ? 32 : 24;
60 if (ibuf ==
nullptr) {
66 ibuf->
ftype = IMB_FTYPE_WEBP;
70 if (WebPDecodeRGBAInto(mem,
size, last_row,
size_t(ibuf->
x) * ibuf->
y * 4, -4 * ibuf->
x) ==
82 const size_t max_thumb_size,
94 if (mmap_file ==
nullptr) {
101 WebPDecoderConfig config;
102 if (!
data || !WebPInitDecoderConfig(&config) ||
103 WebPGetFeatures(
data, data_size, &config.input) != VP8_STATUS_OK ||
112 *r_width = size_t(config.input.width);
113 *r_height = size_t(config.input.height);
115 const float scale =
float(max_thumb_size) / std::max(config.input.width, config.input.height);
116 const int dest_w = std::max(
int(config.input.width * scale), 1);
117 const int dest_h = std::max(
int(config.input.height * scale), 1);
120 if (ibuf ==
nullptr) {
126 config.options.no_fancy_upsampling = 1;
127 config.options.use_scaling = 1;
128 config.options.scaled_width = dest_w;
129 config.options.scaled_height = dest_h;
130 config.options.bypass_filtering = 1;
131 config.options.use_threads = 0;
132 config.options.flip = 1;
133 config.output.is_external_memory = 1;
134 config.output.colorspace = MODE_RGBA;
136 config.output.u.RGBA.stride = 4 * ibuf->
x;
137 config.output.u.RGBA.size = size_t(config.output.u.RGBA.stride) * size_t(ibuf->
y);
147 WebPFreeDecBuffer(&config.output);
156 const uint limit = 16383;
157 if (ibuf->
x > limit || ibuf->
y > limit) {
162 const int bytesperpixel = (ibuf->
planes + 7) >> 3;
163 uchar *encoded_data, *last_row;
164 size_t encoded_data_size;
166 if (bytesperpixel == 3) {
171 for (
size_t i = 0;
i < num_pixels;
i++) {
172 rgb_rect[
i * 3 + 0] = rgba_rect[
i * 4 + 0];
173 rgb_rect[
i * 3 + 1] = rgba_rect[
i * 4 + 1];
174 rgb_rect[
i * 3 + 2] = rgba_rect[
i * 4 + 2];
177 last_row = (
uchar *)(rgb_rect + (
size_t(ibuf->
y - 1) *
size_t(ibuf->
x) * 3));
180 encoded_data_size = WebPEncodeLosslessRGB(
181 last_row, ibuf->
x, ibuf->
y, -3 * ibuf->
x, &encoded_data);
184 encoded_data_size = WebPEncodeRGB(
189 else if (bytesperpixel == 4) {
193 encoded_data_size = WebPEncodeLosslessRGBA(
194 last_row, ibuf->
x, ibuf->
y, -4 * ibuf->
x, &encoded_data);
197 encoded_data_size = WebPEncodeRGBA(
202 CLOG_ERROR(&
LOG,
"Unsupported bytes per pixel: %d for file: '%s'", bytesperpixel, filepath);
206 if (encoded_data ==
nullptr) {
210 WebPMux *mux = WebPMuxNew();
211 WebPData image_data = {encoded_data, encoded_data_size};
212 WebPMuxSetImage(mux, &image_data,
false );
219 WebPData icc_chunk = {
reinterpret_cast<const uint8_t *
>(icc_profile.
data()),
220 size_t(icc_profile.
size())};
221 WebPMuxSetChunk(mux,
"ICCP", &icc_chunk,
true );
226 WebPData output_data;
227 if (WebPMuxAssemble(mux, &output_data) != WEBP_MUX_OK) {
228 CLOG_ERROR(&
LOG,
"Error in mux assemble writing file: '%s'", filepath);
230 WebPFree(encoded_data);
238 if (fwrite(output_data.bytes, output_data.size, 1, fp) != 1) {
239 CLOG_ERROR(&
LOG,
"Unknown error writing file: '%s'", filepath);
247 CLOG_ERROR(&
LOG,
"Cannot open file for writing: '%s'", filepath);
251 WebPFree(encoded_data);
252 WebPDataClear(&output_data);
blender::ocio::ColorSpace ColorSpace
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
bool BLI_mmap_any_io_error(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
size_t BLI_mmap_get_length(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
#define CLOG_ERROR(clg_ref,...)
blender::Vector< char > IMB_colormanagement_space_to_icc_profile(const ColorSpace *colorspace)
bool IMB_alloc_byte_pixels(ImBuf *ibuf, bool initialize_pixels=true)
void IMB_freeImBuf(ImBuf *ibuf)
size_t IMB_get_pixel_count(const ImBuf *ibuf)
Get the length of the data of the given image buffer in pixels.
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Read Guarded memory(de)allocation.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
const ColorSpace * colorspace
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer