mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-03 08:08:39 -04:00
jpegdec: update to reflect 17.0.0 changes
This commit is contained in:
parent
7f61dfdb8d
commit
a84f725e21
6 changed files with 354 additions and 3 deletions
|
@ -16,11 +16,16 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include "decodersrv_decoder_server_object.hpp"
|
||||
#include "../jpeg/decodersrv_software_jpeg_decoder.hpp"
|
||||
#include "../jpeg/decodersrv_software_jpeg_shrinker.hpp"
|
||||
|
||||
namespace ams::capsrv::server {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const int JpegShrinkQualities[] = {
|
||||
98, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0
|
||||
};
|
||||
|
||||
Result DecodeJpegImpl(void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) {
|
||||
/* Clear the work memory. */
|
||||
std::memset(work, 0, work_size);
|
||||
|
@ -67,6 +72,61 @@ namespace ams::capsrv::server {
|
|||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ShrinkJpegImpl(u64 *out_size, void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) {
|
||||
/* Validate parameters. */
|
||||
R_UNLESS(util::IsAligned(width, 0x10), capsrv::ResultAlbumOutOfRange());
|
||||
R_UNLESS(util::IsAligned(height, 0x4), capsrv::ResultAlbumOutOfRange());
|
||||
|
||||
R_UNLESS(dst != nullptr, capsrv::ResultInternalJpegOutBufferShortage());
|
||||
R_UNLESS(dst_size != 0, capsrv::ResultAlbumReadBufferShortage());
|
||||
|
||||
R_UNLESS(src_jpeg != nullptr, capsrv::ResultAlbumInvalidFileData());
|
||||
R_UNLESS(src_jpeg_size != 0, capsrv::ResultAlbumInvalidFileData());
|
||||
|
||||
/* Create the input. */
|
||||
const jpeg::SoftwareJpegShrinkerInput shrink_input = {
|
||||
.jpeg = src_jpeg,
|
||||
.jpeg_size = src_jpeg_size,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.fancy_upsampling = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableFancyUpsampling),
|
||||
.block_smoothing = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableBlockSmoothing),
|
||||
};
|
||||
|
||||
/* Create the output. */
|
||||
u64 shrunk_size = 0;
|
||||
s32 shrunk_width = 0, shrunk_height = 0;
|
||||
jpeg::SoftwareJpegShrinkerOutput shrink_output = {
|
||||
.out_size = std::addressof(shrunk_size),
|
||||
.out_width = std::addressof(shrunk_width),
|
||||
.out_height = std::addressof(shrunk_height),
|
||||
.dst = dst,
|
||||
.dst_size = dst_size,
|
||||
};
|
||||
|
||||
/* Try to shrink the jpeg at various quality levels. */
|
||||
for (auto quality : JpegShrinkQualities) {
|
||||
/* Shrink at the current quality. */
|
||||
R_TRY_CATCH(jpeg::SoftwareJpegShrinker::ShrinkRgba8(shrink_output, shrink_input, quality, work, work_size)) {
|
||||
/* If the output buffer isn't large enough to fit the output, we should try at a lower quality. */
|
||||
R_CATCH(capsrv::ResultInternalJpegOutBufferShortage) {
|
||||
continue;
|
||||
}
|
||||
/* Nintendo doesn't catch this result, but our lack of work buffer use makes me think this may be necessary. */
|
||||
R_CATCH(capsrv::ResultInternalJpegWorkMemoryShortage) {
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* Write the output size. */
|
||||
*out_size = shrunk_size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Nintendo aborts if no quality succeeds. */
|
||||
AMS_ABORT("ShrinkJpeg should succeed before this point\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result DecoderControlService::DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option) {
|
||||
|
@ -78,4 +138,13 @@ namespace ams::capsrv::server {
|
|||
R_RETURN(DecodeJpegImpl(out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size));
|
||||
}
|
||||
|
||||
Result DecoderControlService::ShrinkJpeg(ams::sf::Out<u64> out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option) {
|
||||
/* Get the work buffer. */
|
||||
void *work = g_work_memory.jpeg_decoder_memory;
|
||||
size_t work_size = sizeof(g_work_memory.jpeg_decoder_memory);
|
||||
|
||||
/* Call the shrink implementation. */
|
||||
R_RETURN(ShrinkJpegImpl(out_size.GetPointer(), out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size));
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,8 @@
|
|||
#include <stratosphere.hpp>
|
||||
|
||||
#define AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option))
|
||||
AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4001, Result, ShrinkJpeg, (ams::sf::Out<u64> out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out_size, out, in, width, height, option))
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::capsrv::sf, IDecoderControlService, AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO, 0xD168E90B)
|
||||
|
||||
|
@ -26,6 +27,7 @@ namespace ams::capsrv::server {
|
|||
class DecoderControlService final {
|
||||
public:
|
||||
Result DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option);
|
||||
Result ShrinkJpeg(ams::sf::Out<u64> out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option);
|
||||
};
|
||||
static_assert(capsrv::sf::IsIDecoderControlService<DecoderControlService>);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue