diff --git a/nx/include/switch/services/capsdc.h b/nx/include/switch/services/capsdc.h index cdf50745..184c0509 100644 --- a/nx/include/switch/services/capsdc.h +++ b/nx/include/switch/services/capsdc.h @@ -33,5 +33,31 @@ Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption /** * @brief Shrinks a jpeg's dimensions by 2. + * @note Tries to compress with jpeg quality in this order: 98, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0. + * @note Only available on [17.0.0+]. + * @param[in] width Input image width. + * @param[in] height Input image width. + * @param[in] opts \ref CapsScreenShotDecodeOption. + * @param[in] jpeg Jpeg image input buffer. + * @param[in] jpeg_size Input image buffer size. + * @param[out] out_jpeg Jpeg image output buffer + * @param[in] out_jpeg_size Output image buffer size. + * @param[out] out_result_size size of the resulting JPEG. */ Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size); + +/** + * @brief Shrinks a jpeg. + * @note Fails if the scaled size is larger than the original or the output buffer isn't large enough. + * @note Only available on [19.0.0+]. + * @param[in] scaled_width Wanted image width. + * @param[in] scaled_height Wanted image width. + * @param[in] jpeg_quality has to be in range 0-100. + * @param[in] opts \ref CapsScreenShotDecodeOption. + * @param[in] jpeg Jpeg image input buffer. + * @param[in] jpeg_size Input image buffer size. + * @param[out] out_jpeg Jpeg image output buffer + * @param[in] out_jpeg_size Output image buffer size. + * @param[out] out_result_size size of the resulting jpeg. + */ +Result capsdcShrinkJpegEx(u32 scaled_width, u32 scaled_height, u32 jpeg_quality, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size); diff --git a/nx/source/services/capsdc.c b/nx/source/services/capsdc.c index 6566dc33..10d43b86 100644 --- a/nx/source/services/capsdc.c +++ b/nx/source/services/capsdc.c @@ -41,6 +41,9 @@ Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption } Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size) { + if (hosversionBefore(17,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + const struct { u32 width; u32 height; @@ -57,3 +60,26 @@ Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption } ); } + +Result capsdcShrinkJpegEx(u32 scaled_width, u32 scaled_height, u32 jpeg_quality, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size) { + if (hosversionBefore(18,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + u32 scaled_width; + u32 scaled_height; + u32 jpeg_quality; + u8 pad[4]; + CapsScreenShotDecodeOption opts; + } in = { scaled_width, scaled_height, jpeg_quality, {}, *opts }; + return serviceDispatchInOut(&g_capsdcSrv, 4002, in, *out_result_size, + .buffer_attrs = { + SfBufferAttr_In | SfBufferAttr_HipcMapAlias, + SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_HipcMapTransferAllowsNonSecure, + }, + .buffers = { + { jpeg, jpeg_size }, + { out_jpeg, out_jpeg_size }, + } + ); +}