mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
Add support to webp encoded dragged images
This commit is contained in:
parent
16f3e53ce9
commit
b1d1265450
@ -105,6 +105,13 @@ else()
|
||||
target_sources(app-lib PRIVATE font_path_unix.cpp)
|
||||
endif()
|
||||
|
||||
# This defines a specific webp decoding utility function for using
|
||||
# in Windows when dragging and dropping images that are stored as
|
||||
# webp files (like Chrome does).
|
||||
if(WIN32 AND ENABLE_WEBP)
|
||||
target_sources(app-lib PRIVATE util/decode_webp.cpp)
|
||||
endif()
|
||||
|
||||
# Trial-version vs Full version (enable save command)
|
||||
if(ENABLE_TRIAL_MODE)
|
||||
target_compile_definitions(app-lib PUBLIC -DENABLE_TRIAL_MODE)
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "doc/layer_list.h"
|
||||
#include "render/dithering.h"
|
||||
|
||||
#if ENABLE_WEBP && LAF_WINDOWS
|
||||
#include "app/util/decode_webp.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace app {
|
||||
|
81
src/app/util/decode_webp.cpp
Normal file
81
src/app/util/decode_webp.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#include "app/util/decode_webp.h"
|
||||
|
||||
#include <webp/demux.h>
|
||||
#include <webp/mux.h>
|
||||
|
||||
namespace app {
|
||||
namespace util {
|
||||
|
||||
os::SurfaceRef decode_webp(const uint8_t* buf, uint32_t len)
|
||||
{
|
||||
// I've considered using the FileFormatsManager here but we don't have a file
|
||||
// in this case just the bytes. At some point maye we should refactor this or
|
||||
// the WepFormat class to avoid duplicated logic.
|
||||
WebPData webp_data;
|
||||
WebPDataInit(&webp_data);
|
||||
webp_data.bytes = &buf[0];
|
||||
webp_data.size = len;
|
||||
|
||||
WebPAnimDecoderOptions dec_options;
|
||||
WebPAnimDecoderOptionsInit(&dec_options);
|
||||
dec_options.color_mode = MODE_RGBA;
|
||||
|
||||
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
|
||||
if (dec == nullptr) {
|
||||
// Error parsing WebP image
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebPAnimInfo anim_info;
|
||||
if (!WebPAnimDecoderGetInfo(dec, &anim_info)) {
|
||||
// Error getting global info about the WebP animation
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebPDecoderConfig config;
|
||||
WebPInitDecoderConfig(&config);
|
||||
if (WebPGetFeatures(webp_data.bytes, webp_data.size, &config.input)) {
|
||||
|
||||
}
|
||||
else {
|
||||
config.input.has_alpha = false;
|
||||
}
|
||||
|
||||
const int w = anim_info.canvas_width;
|
||||
const int h = anim_info.canvas_height;
|
||||
|
||||
if (anim_info.frame_count <= 0)
|
||||
return nullptr;
|
||||
|
||||
auto surface = os::instance()->makeSurface(w, h);
|
||||
|
||||
// We just want the first frame, so we don't iterate.
|
||||
WebPAnimDecoderHasMoreFrames(dec);
|
||||
|
||||
uint8_t* frame_rgba;
|
||||
int frame_timestamp = 0;
|
||||
if (!WebPAnimDecoderGetNext(dec, &frame_rgba, &frame_timestamp)) {
|
||||
// Error loading WebP frame
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint32_t* src = (const uint32_t*)frame_rgba;
|
||||
for (int y = 0; y < h; ++y, src += w) {
|
||||
memcpy(surface->getData(0, y), src, w * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
WebPAnimDecoderReset(dec);
|
||||
|
||||
WebPAnimDecoderDelete(dec);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace app
|
31
src/app/util/decode_webp.h
Normal file
31
src/app/util/decode_webp.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_UTIL_DECODE_WEBP_H_INCLUDED
|
||||
#define APP_UTIL_DECODE_WEBP_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "os/surface.h"
|
||||
#include "os/system.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
namespace util {
|
||||
|
||||
// Decodes webp content passed in buf and returns a surface with just the first
|
||||
// frame.
|
||||
os::SurfaceRef decode_webp(const uint8_t* buf, uint32_t len);
|
||||
|
||||
static void* once = []() {
|
||||
os::set_decode_webp(decode_webp);
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user