Browse Source
Merge pull request #11650 from german77/lle_album
Merge pull request #11650 from german77/lle_album
service: am: Add support for LLE Album Appletnce_cpp
committed by
GitHub
36 changed files with 12216 additions and 247 deletions
-
2externals/CMakeLists.txt
-
7529externals/stb/stb_image.cpp
-
772externals/stb/stb_image.h
-
2282externals/stb/stb_image_resize.cpp
-
426externals/stb/stb_image_resize.h
-
8src/core/CMakeLists.txt
-
106src/core/hle/service/am/am.cpp
-
20src/core/hle/service/am/am.h
-
20src/core/hle/service/am/applet_ae.cpp
-
5src/core/hle/service/am/applets/applet_error.cpp
-
21src/core/hle/service/caps/caps.cpp
-
81src/core/hle/service/caps/caps.h
-
239src/core/hle/service/caps/caps_a.cpp
-
21src/core/hle/service/caps/caps_a.h
-
50src/core/hle/service/caps/caps_c.cpp
-
10src/core/hle/service/caps/caps_c.h
-
342src/core/hle/service/caps/caps_manager.cpp
-
72src/core/hle/service/caps/caps_manager.h
-
35src/core/hle/service/caps/caps_result.h
-
5src/core/hle/service/caps/caps_sc.cpp
-
6src/core/hle/service/caps/caps_sc.h
-
5src/core/hle/service/caps/caps_ss.cpp
-
6src/core/hle/service/caps/caps_ss.h
-
9src/core/hle/service/caps/caps_su.cpp
-
6src/core/hle/service/caps/caps_su.h
-
184src/core/hle/service/caps/caps_types.h
-
104src/core/hle/service/caps/caps_u.cpp
-
12src/core/hle/service/caps/caps_u.h
-
12src/core/hle/service/nifm/nifm.cpp
-
1src/core/hle/service/nifm/nifm.h
-
27src/core/hle/service/ns/ns.cpp
-
4src/core/hle/service/ns/ns.h
-
9src/core/hle/service/pctl/pctl_module.cpp
-
25src/yuzu/main.cpp
-
1src/yuzu/main.h
-
6src/yuzu/main.ui
7529
externals/stb/stb_image.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,772 @@ |
|||
// SPDX-FileCopyrightText: stb http://nothings.org/stb |
|||
// SPDX-License-Identifier: MIT |
|||
|
|||
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb |
|||
no warranty implied; use at your own risk |
|||
|
|||
Do this: |
|||
#define STB_IMAGE_IMPLEMENTATION |
|||
before you include this file in *one* C or C++ file to create the implementation. |
|||
|
|||
// i.e. it should look like this: |
|||
#include ... |
|||
#include ... |
|||
#include ... |
|||
#define STB_IMAGE_IMPLEMENTATION |
|||
#include "stb_image.h" |
|||
|
|||
You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. |
|||
And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free |
|||
|
|||
|
|||
QUICK NOTES: |
|||
Primarily of interest to game developers and other people who can |
|||
avoid problematic images and only need the trivial interface |
|||
|
|||
JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) |
|||
PNG 1/2/4/8/16-bit-per-channel |
|||
|
|||
TGA (not sure what subset, if a subset) |
|||
BMP non-1bpp, non-RLE |
|||
PSD (composited view only, no extra channels, 8/16 bit-per-channel) |
|||
|
|||
GIF (*comp always reports as 4-channel) |
|||
HDR (radiance rgbE format) |
|||
PIC (Softimage PIC) |
|||
PNM (PPM and PGM binary only) |
|||
|
|||
Animated GIF still needs a proper API, but here's one way to do it: |
|||
http://gist.github.com/urraka/685d9a6340b26b830d49 |
|||
|
|||
- decode from memory or through FILE (define STBI_NO_STDIO to remove code) |
|||
- decode from arbitrary I/O callbacks |
|||
- SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) |
|||
|
|||
Full documentation under "DOCUMENTATION" below. |
|||
|
|||
|
|||
LICENSE |
|||
|
|||
See end of file for license information. |
|||
|
|||
RECENT REVISION HISTORY: |
|||
|
|||
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff |
|||
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes |
|||
2.26 (2020-07-13) many minor fixes |
|||
2.25 (2020-02-02) fix warnings |
|||
2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically |
|||
2.23 (2019-08-11) fix clang static analysis warning |
|||
2.22 (2019-03-04) gif fixes, fix warnings |
|||
2.21 (2019-02-25) fix typo in comment |
|||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs |
|||
2.19 (2018-02-11) fix warning |
|||
2.18 (2018-01-30) fix warnings |
|||
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings |
|||
2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes |
|||
2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC |
|||
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs |
|||
2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes |
|||
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes |
|||
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 |
|||
RGB-format JPEG; remove white matting in PSD; |
|||
allocate large structures on the stack; |
|||
correct channel count for PNG & BMP |
|||
2.10 (2016-01-22) avoid warning introduced in 2.09 |
|||
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED |
|||
|
|||
See end of file for full revision history. |
|||
|
|||
|
|||
============================ Contributors ========================= |
|||
|
|||
Image formats Extensions, features |
|||
Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) |
|||
Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) |
|||
Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) |
|||
Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) |
|||
Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) |
|||
Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) |
|||
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) |
|||
github:urraka (animated gif) Junggon Kim (PNM comments) |
|||
Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) |
|||
socks-the-fox (16-bit PNG) |
|||
Jeremy Sawicki (handle all ImageNet JPGs) |
|||
Optimizations & bugfixes Mikhail Morozov (1-bit BMP) |
|||
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) |
|||
Arseny Kapoulkine Simon Breuss (16-bit PNM) |
|||
John-Mark Allen |
|||
Carmelo J Fdez-Aguera |
|||
|
|||
Bug & warning fixes |
|||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko |
|||
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski |
|||
Phil Jordan Dave Moore Roy Eltham |
|||
Hayaki Saito Nathan Reed Won Chun |
|||
Luke Graham Johan Duparc Nick Verigakis the Horde3D community |
|||
Thomas Ruf Ronny Chevalier github:rlyeh |
|||
Janez Zemva John Bartholomew Michal Cichon github:romigrou |
|||
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk |
|||
Eugene Golushkov Laurent Gomila Cort Stratton github:snagar |
|||
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex |
|||
Cass Everitt Ryamond Barbiero github:grim210 |
|||
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw |
|||
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus |
|||
Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo |
|||
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji |
|||
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 |
|||
Brad Weinberger Matvey Cherevko github:mosra |
|||
Luca Sas Alexander Veselov Zack Middleton [reserved] |
|||
Ryan C. Gordon [reserved] [reserved] |
|||
DO NOT ADD YOUR NAME HERE |
|||
|
|||
Jacko Dirks |
|||
|
|||
To add your name to the credits, pick a random blank space in the middle and fill it. |
|||
80% of merge conflicts on stb PRs are due to people adding their name at the end |
|||
of the credits. |
|||
*/ |
|||
|
|||
#ifndef STBI_INCLUDE_STB_IMAGE_H |
|||
#define STBI_INCLUDE_STB_IMAGE_H |
|||
|
|||
// DOCUMENTATION |
|||
// |
|||
// Limitations: |
|||
// - no 12-bit-per-channel JPEG |
|||
// - no JPEGs with arithmetic coding |
|||
// - GIF always returns *comp=4 |
|||
// |
|||
// Basic usage (see HDR discussion below for HDR usage): |
|||
// int x,y,n; |
|||
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); |
|||
// // ... process data if not NULL ... |
|||
// // ... x = width, y = height, n = # 8-bit components per pixel ... |
|||
// // ... replace '0' with '1'..'4' to force that many components per pixel |
|||
// // ... but 'n' will always be the number that it would have been if you said 0 |
|||
// stbi_image_free(data); |
|||
// |
|||
// Standard parameters: |
|||
// int *x -- outputs image width in pixels |
|||
// int *y -- outputs image height in pixels |
|||
// int *channels_in_file -- outputs # of image components in image file |
|||
// int desired_channels -- if non-zero, # of image components requested in result |
|||
// |
|||
// The return value from an image loader is an 'unsigned char *' which points |
|||
// to the pixel data, or NULL on an allocation failure or if the image is |
|||
// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, |
|||
// with each pixel consisting of N interleaved 8-bit components; the first |
|||
// pixel pointed to is top-left-most in the image. There is no padding between |
|||
// image scanlines or between pixels, regardless of format. The number of |
|||
// components N is 'desired_channels' if desired_channels is non-zero, or |
|||
// *channels_in_file otherwise. If desired_channels is non-zero, |
|||
// *channels_in_file has the number of components that _would_ have been |
|||
// output otherwise. E.g. if you set desired_channels to 4, you will always |
|||
// get RGBA output, but you can check *channels_in_file to see if it's trivially |
|||
// opaque because e.g. there were only 3 channels in the source image. |
|||
// |
|||
// An output image with N components has the following components interleaved |
|||
// in this order in each pixel: |
|||
// |
|||
// N=#comp components |
|||
// 1 grey |
|||
// 2 grey, alpha |
|||
// 3 red, green, blue |
|||
// 4 red, green, blue, alpha |
|||
// |
|||
// If image loading fails for any reason, the return value will be NULL, |
|||
// and *x, *y, *channels_in_file will be unchanged. The function |
|||
// stbi_failure_reason() can be queried for an extremely brief, end-user |
|||
// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS |
|||
// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly |
|||
// more user-friendly ones. |
|||
// |
|||
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. |
|||
// |
|||
// To query the width, height and component count of an image without having to |
|||
// decode the full file, you can use the stbi_info family of functions: |
|||
// |
|||
// int x,y,n,ok; |
|||
// ok = stbi_info(filename, &x, &y, &n); |
|||
// // returns ok=1 and sets x, y, n if image is a supported format, |
|||
// // 0 otherwise. |
|||
// |
|||
// Note that stb_image pervasively uses ints in its public API for sizes, |
|||
// including sizes of memory buffers. This is now part of the API and thus |
|||
// hard to change without causing breakage. As a result, the various image |
|||
// loaders all have certain limits on image size; these differ somewhat |
|||
// by format but generally boil down to either just under 2GB or just under |
|||
// 1GB. When the decoded image would be larger than this, stb_image decoding |
|||
// will fail. |
|||
// |
|||
// Additionally, stb_image will reject image files that have any of their |
|||
// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, |
|||
// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, |
|||
// the only way to have an image with such dimensions load correctly |
|||
// is for it to have a rather extreme aspect ratio. Either way, the |
|||
// assumption here is that such larger images are likely to be malformed |
|||
// or malicious. If you do need to load an image with individual dimensions |
|||
// larger than that, and it still fits in the overall size limit, you can |
|||
// #define STBI_MAX_DIMENSIONS on your own to be something larger. |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// UNICODE: |
|||
// |
|||
// If compiling for Windows and you wish to use Unicode filenames, compile |
|||
// with |
|||
// #define STBI_WINDOWS_UTF8 |
|||
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert |
|||
// Windows wchar_t filenames to utf8. |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// Philosophy |
|||
// |
|||
// stb libraries are designed with the following priorities: |
|||
// |
|||
// 1. easy to use |
|||
// 2. easy to maintain |
|||
// 3. good performance |
|||
// |
|||
// Sometimes I let "good performance" creep up in priority over "easy to maintain", |
|||
// and for best performance I may provide less-easy-to-use APIs that give higher |
|||
// performance, in addition to the easy-to-use ones. Nevertheless, it's important |
|||
// to keep in mind that from the standpoint of you, a client of this library, |
|||
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. |
|||
// |
|||
// Some secondary priorities arise directly from the first two, some of which |
|||
// provide more explicit reasons why performance can't be emphasized. |
|||
// |
|||
// - Portable ("ease of use") |
|||
// - Small source code footprint ("easy to maintain") |
|||
// - No dependencies ("ease of use") |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// I/O callbacks |
|||
// |
|||
// I/O callbacks allow you to read from arbitrary sources, like packaged |
|||
// files or some other source. Data read from callbacks are processed |
|||
// through a small internal buffer (currently 128 bytes) to try to reduce |
|||
// overhead. |
|||
// |
|||
// The three functions you must define are "read" (reads some bytes of data), |
|||
// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// SIMD support |
|||
// |
|||
// The JPEG decoder will try to automatically use SIMD kernels on x86 when |
|||
// supported by the compiler. For ARM Neon support, you must explicitly |
|||
// request it. |
|||
// |
|||
// (The old do-it-yourself SIMD API is no longer supported in the current |
|||
// code.) |
|||
// |
|||
// On x86, SSE2 will automatically be used when available based on a run-time |
|||
// test; if not, the generic C versions are used as a fall-back. On ARM targets, |
|||
// the typical path is to have separate builds for NEON and non-NEON devices |
|||
// (at least this is true for iOS and Android). Therefore, the NEON support is |
|||
// toggled by a build flag: define STBI_NEON to get NEON loops. |
|||
// |
|||
// If for some reason you do not want to use any of SIMD code, or if |
|||
// you have issues compiling it, you can disable it entirely by |
|||
// defining STBI_NO_SIMD. |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// HDR image support (disable by defining STBI_NO_HDR) |
|||
// |
|||
// stb_image supports loading HDR images in general, and currently the Radiance |
|||
// .HDR file format specifically. You can still load any file through the existing |
|||
// interface; if you attempt to load an HDR file, it will be automatically remapped |
|||
// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; |
|||
// both of these constants can be reconfigured through this interface: |
|||
// |
|||
// stbi_hdr_to_ldr_gamma(2.2f); |
|||
// stbi_hdr_to_ldr_scale(1.0f); |
|||
// |
|||
// (note, do not use _inverse_ constants; stbi_image will invert them |
|||
// appropriately). |
|||
// |
|||
// Additionally, there is a new, parallel interface for loading files as |
|||
// (linear) floats to preserve the full dynamic range: |
|||
// |
|||
// float *data = stbi_loadf(filename, &x, &y, &n, 0); |
|||
// |
|||
// If you load LDR images through this interface, those images will |
|||
// be promoted to floating point values, run through the inverse of |
|||
// constants corresponding to the above: |
|||
// |
|||
// stbi_ldr_to_hdr_scale(1.0f); |
|||
// stbi_ldr_to_hdr_gamma(2.2f); |
|||
// |
|||
// Finally, given a filename (or an open file or memory block--see header |
|||
// file for details) containing image data, you can query for the "most |
|||
// appropriate" interface to use (that is, whether the image is HDR or |
|||
// not), using: |
|||
// |
|||
// stbi_is_hdr(char *filename); |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// iPhone PNG support: |
|||
// |
|||
// We optionally support converting iPhone-formatted PNGs (which store |
|||
// premultiplied BGRA) back to RGB, even though they're internally encoded |
|||
// differently. To enable this conversion, call |
|||
// stbi_convert_iphone_png_to_rgb(1). |
|||
// |
|||
// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per |
|||
// pixel to remove any premultiplied alpha *only* if the image file explicitly |
|||
// says there's premultiplied data (currently only happens in iPhone images, |
|||
// and only if iPhone convert-to-rgb processing is on). |
|||
// |
|||
// =========================================================================== |
|||
// |
|||
// ADDITIONAL CONFIGURATION |
|||
// |
|||
// - You can suppress implementation of any of the decoders to reduce |
|||
// your code footprint by #defining one or more of the following |
|||
// symbols before creating the implementation. |
|||
// |
|||
// STBI_NO_JPEG |
|||
// STBI_NO_PNG |
|||
// STBI_NO_BMP |
|||
// STBI_NO_PSD |
|||
// STBI_NO_TGA |
|||
// STBI_NO_GIF |
|||
// STBI_NO_HDR |
|||
// STBI_NO_PIC |
|||
// STBI_NO_PNM (.ppm and .pgm) |
|||
// |
|||
// - You can request *only* certain decoders and suppress all other ones |
|||
// (this will be more forward-compatible, as addition of new decoders |
|||
// doesn't require you to disable them explicitly): |
|||
// |
|||
// STBI_ONLY_JPEG |
|||
// STBI_ONLY_PNG |
|||
// STBI_ONLY_BMP |
|||
// STBI_ONLY_PSD |
|||
// STBI_ONLY_TGA |
|||
// STBI_ONLY_GIF |
|||
// STBI_ONLY_HDR |
|||
// STBI_ONLY_PIC |
|||
// STBI_ONLY_PNM (.ppm and .pgm) |
|||
// |
|||
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still |
|||
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB |
|||
// |
|||
// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater |
|||
// than that size (in either width or height) without further processing. |
|||
// This is to let programs in the wild set an upper bound to prevent |
|||
// denial-of-service attacks on untrusted data, as one could generate a |
|||
// valid image of gigantic dimensions and force stb_image to allocate a |
|||
// huge block of memory and spend disproportionate time decoding it. By |
|||
// default this is set to (1 << 24), which is 16777216, but that's still |
|||
// very big. |
|||
|
|||
#ifndef STBI_NO_STDIO |
|||
#include <stdio.h> |
|||
#endif // STBI_NO_STDIO |
|||
|
|||
#define STBI_VERSION 1 |
|||
|
|||
enum |
|||
{ |
|||
STBI_default = 0, // only used for desired_channels |
|||
|
|||
STBI_grey = 1, |
|||
STBI_grey_alpha = 2, |
|||
STBI_rgb = 3, |
|||
STBI_rgb_alpha = 4 |
|||
}; |
|||
|
|||
#include <stdlib.h> |
|||
typedef unsigned char stbi_uc; |
|||
typedef unsigned short stbi_us; |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
#ifndef STBIDEF |
|||
#ifdef STB_IMAGE_STATIC |
|||
#define STBIDEF static |
|||
#else |
|||
#define STBIDEF extern |
|||
#endif |
|||
#endif |
|||
|
|||
////////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// PRIMARY API - works on images of any type |
|||
// |
|||
|
|||
// |
|||
// load image by filename, open file, or memory buffer |
|||
// |
|||
|
|||
typedef struct |
|||
{ |
|||
int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read |
|||
void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative |
|||
int (*eof) (void *user); // returns nonzero if we are at end of file/data |
|||
} stbi_io_callbacks; |
|||
|
|||
//////////////////////////////////// |
|||
// |
|||
// 8-bits-per-channel interface |
|||
// |
|||
|
|||
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
|
|||
#ifndef STBI_NO_STDIO |
|||
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
// for stbi_load_from_file, file pointer is left pointing immediately after image |
|||
#endif |
|||
|
|||
#ifndef STBI_NO_GIF |
|||
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); |
|||
#endif |
|||
|
|||
#ifdef STBI_WINDOWS_UTF8 |
|||
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); |
|||
#endif |
|||
|
|||
//////////////////////////////////// |
|||
// |
|||
// 16-bits-per-channel interface |
|||
// |
|||
|
|||
STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
|
|||
#ifndef STBI_NO_STDIO |
|||
STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
#endif |
|||
|
|||
//////////////////////////////////// |
|||
// |
|||
// float-per-channel interface |
|||
// |
|||
#ifndef STBI_NO_LINEAR |
|||
STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
|
|||
#ifndef STBI_NO_STDIO |
|||
STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); |
|||
#endif |
|||
#endif |
|||
|
|||
#ifndef STBI_NO_HDR |
|||
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); |
|||
STBIDEF void stbi_hdr_to_ldr_scale(float scale); |
|||
#endif // STBI_NO_HDR |
|||
|
|||
#ifndef STBI_NO_LINEAR |
|||
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); |
|||
STBIDEF void stbi_ldr_to_hdr_scale(float scale); |
|||
#endif // STBI_NO_LINEAR |
|||
|
|||
// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR |
|||
STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); |
|||
STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); |
|||
#ifndef STBI_NO_STDIO |
|||
STBIDEF int stbi_is_hdr (char const *filename); |
|||
STBIDEF int stbi_is_hdr_from_file(FILE *f); |
|||
#endif // STBI_NO_STDIO |
|||
|
|||
|
|||
// get a VERY brief reason for failure |
|||
// on most compilers (and ALL modern mainstream compilers) this is threadsafe |
|||
STBIDEF const char *stbi_failure_reason (void); |
|||
|
|||
// free the loaded image -- this is just free() |
|||
STBIDEF void stbi_image_free (void *retval_from_stbi_load); |
|||
|
|||
// get image dimensions & components without fully decoding |
|||
STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); |
|||
STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); |
|||
STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); |
|||
STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); |
|||
|
|||
#ifndef STBI_NO_STDIO |
|||
STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); |
|||
STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); |
|||
STBIDEF int stbi_is_16_bit (char const *filename); |
|||
STBIDEF int stbi_is_16_bit_from_file(FILE *f); |
|||
#endif |
|||
|
|||
|
|||
|
|||
// for image formats that explicitly notate that they have premultiplied alpha, |
|||
// we just return the colors as stored in the file. set this flag to force |
|||
// unpremultiplication. results are undefined if the unpremultiply overflow. |
|||
STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); |
|||
|
|||
// indicate whether we should process iphone images back to canonical format, |
|||
// or just pass them through "as-is" |
|||
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); |
|||
|
|||
// flip the image vertically, so the first pixel in the output array is the bottom left |
|||
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); |
|||
|
|||
// as above, but only applies to images loaded on the thread that calls the function |
|||
// this function is only available if your compiler supports thread-local variables; |
|||
// calling it will fail to link if your compiler doesn't |
|||
STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); |
|||
STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); |
|||
STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); |
|||
|
|||
// ZLIB client - used by PNG, available for other purposes |
|||
|
|||
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); |
|||
STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); |
|||
STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); |
|||
STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); |
|||
|
|||
STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); |
|||
STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); |
|||
|
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
// |
|||
// |
|||
//// end header file ///////////////////////////////////////////////////// |
|||
#endif // STBI_INCLUDE_STB_IMAGE_H |
|||
|
|||
/* |
|||
revision history: |
|||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs |
|||
2.19 (2018-02-11) fix warning |
|||
2.18 (2018-01-30) fix warnings |
|||
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug |
|||
1-bit BMP |
|||
*_is_16_bit api |
|||
avoid warnings |
|||
2.16 (2017-07-23) all functions have 16-bit variants; |
|||
STBI_NO_STDIO works again; |
|||
compilation fixes; |
|||
fix rounding in unpremultiply; |
|||
optimize vertical flip; |
|||
disable raw_len validation; |
|||
documentation fixes |
|||
2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; |
|||
warning fixes; disable run-time SSE detection on gcc; |
|||
uniform handling of optional "return" values; |
|||
thread-safe initialization of zlib tables |
|||
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs |
|||
2.13 (2016-11-29) add 16-bit API, only supported for PNG right now |
|||
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes |
|||
2.11 (2016-04-02) allocate large structures on the stack |
|||
remove white matting for transparent PSD |
|||
fix reported channel count for PNG & BMP |
|||
re-enable SSE2 in non-gcc 64-bit |
|||
support RGB-formatted JPEG |
|||
read 16-bit PNGs (only as 8-bit) |
|||
2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED |
|||
2.09 (2016-01-16) allow comments in PNM files |
|||
16-bit-per-pixel TGA (not bit-per-component) |
|||
info() for TGA could break due to .hdr handling |
|||
info() for BMP to shares code instead of sloppy parse |
|||
can use STBI_REALLOC_SIZED if allocator doesn't support realloc |
|||
code cleanup |
|||
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA |
|||
2.07 (2015-09-13) fix compiler warnings |
|||
partial animated GIF support |
|||
limited 16-bpc PSD support |
|||
#ifdef unused functions |
|||
bug with < 92 byte PIC,PNM,HDR,TGA |
|||
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value |
|||
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning |
|||
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit |
|||
2.03 (2015-04-12) extra corruption checking (mmozeiko) |
|||
stbi_set_flip_vertically_on_load (nguillemot) |
|||
fix NEON support; fix mingw support |
|||
2.02 (2015-01-19) fix incorrect assert, fix warning |
|||
2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 |
|||
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG |
|||
2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) |
|||
progressive JPEG (stb) |
|||
PGM/PPM support (Ken Miller) |
|||
STBI_MALLOC,STBI_REALLOC,STBI_FREE |
|||
GIF bugfix -- seemingly never worked |
|||
STBI_NO_*, STBI_ONLY_* |
|||
1.48 (2014-12-14) fix incorrectly-named assert() |
|||
1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) |
|||
optimize PNG (ryg) |
|||
fix bug in interlaced PNG with user-specified channel count (stb) |
|||
1.46 (2014-08-26) |
|||
fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG |
|||
1.45 (2014-08-16) |
|||
fix MSVC-ARM internal compiler error by wrapping malloc |
|||
1.44 (2014-08-07) |
|||
various warning fixes from Ronny Chevalier |
|||
1.43 (2014-07-15) |
|||
fix MSVC-only compiler problem in code changed in 1.42 |
|||
1.42 (2014-07-09) |
|||
don't define _CRT_SECURE_NO_WARNINGS (affects user code) |
|||
fixes to stbi__cleanup_jpeg path |
|||
added STBI_ASSERT to avoid requiring assert.h |
|||
1.41 (2014-06-25) |
|||
fix search&replace from 1.36 that messed up comments/error messages |
|||
1.40 (2014-06-22) |
|||
fix gcc struct-initialization warning |
|||
1.39 (2014-06-15) |
|||
fix to TGA optimization when req_comp != number of components in TGA; |
|||
fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) |
|||
add support for BMP version 5 (more ignored fields) |
|||
1.38 (2014-06-06) |
|||
suppress MSVC warnings on integer casts truncating values |
|||
fix accidental rename of 'skip' field of I/O |
|||
1.37 (2014-06-04) |
|||
remove duplicate typedef |
|||
1.36 (2014-06-03) |
|||
convert to header file single-file library |
|||
if de-iphone isn't set, load iphone images color-swapped instead of returning NULL |
|||
1.35 (2014-05-27) |
|||
various warnings |
|||
fix broken STBI_SIMD path |
|||
fix bug where stbi_load_from_file no longer left file pointer in correct place |
|||
fix broken non-easy path for 32-bit BMP (possibly never used) |
|||
TGA optimization by Arseny Kapoulkine |
|||
1.34 (unknown) |
|||
use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case |
|||
1.33 (2011-07-14) |
|||
make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements |
|||
1.32 (2011-07-13) |
|||
support for "info" function for all supported filetypes (SpartanJ) |
|||
1.31 (2011-06-20) |
|||
a few more leak fixes, bug in PNG handling (SpartanJ) |
|||
1.30 (2011-06-11) |
|||
added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) |
|||
removed deprecated format-specific test/load functions |
|||
removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway |
|||
error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) |
|||
fix inefficiency in decoding 32-bit BMP (David Woo) |
|||
1.29 (2010-08-16) |
|||
various warning fixes from Aurelien Pocheville |
|||
1.28 (2010-08-01) |
|||
fix bug in GIF palette transparency (SpartanJ) |
|||
1.27 (2010-08-01) |
|||
cast-to-stbi_uc to fix warnings |
|||
1.26 (2010-07-24) |
|||
fix bug in file buffering for PNG reported by SpartanJ |
|||
1.25 (2010-07-17) |
|||
refix trans_data warning (Won Chun) |
|||
1.24 (2010-07-12) |
|||
perf improvements reading from files on platforms with lock-heavy fgetc() |
|||
minor perf improvements for jpeg |
|||
deprecated type-specific functions so we'll get feedback if they're needed |
|||
attempt to fix trans_data warning (Won Chun) |
|||
1.23 fixed bug in iPhone support |
|||
1.22 (2010-07-10) |
|||
removed image *writing* support |
|||
stbi_info support from Jetro Lauha |
|||
GIF support from Jean-Marc Lienher |
|||
iPhone PNG-extensions from James Brown |
|||
warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) |
|||
1.21 fix use of 'stbi_uc' in header (reported by jon blow) |
|||
1.20 added support for Softimage PIC, by Tom Seddon |
|||
1.19 bug in interlaced PNG corruption check (found by ryg) |
|||
1.18 (2008-08-02) |
|||
fix a threading bug (local mutable static) |
|||
1.17 support interlaced PNG |
|||
1.16 major bugfix - stbi__convert_format converted one too many pixels |
|||
1.15 initialize some fields for thread safety |
|||
1.14 fix threadsafe conversion bug |
|||
header-file-only version (#define STBI_HEADER_FILE_ONLY before including) |
|||
1.13 threadsafe |
|||
1.12 const qualifiers in the API |
|||
1.11 Support installable IDCT, colorspace conversion routines |
|||
1.10 Fixes for 64-bit (don't use "unsigned long") |
|||
optimized upsampling by Fabian "ryg" Giesen |
|||
1.09 Fix format-conversion for PSD code (bad global variables!) |
|||
1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz |
|||
1.07 attempt to fix C++ warning/errors again |
|||
1.06 attempt to fix C++ warning/errors again |
|||
1.05 fix TGA loading to return correct *comp and use good luminance calc |
|||
1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free |
|||
1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR |
|||
1.02 support for (subset of) HDR files, float interface for preferred access to them |
|||
1.01 fix bug: possible bug in handling right-side up bmps... not sure |
|||
fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all |
|||
1.00 interface to zlib that skips zlib header |
|||
0.99 correct handling of alpha in palette |
|||
0.98 TGA loader by lonesock; dynamically add loaders (untested) |
|||
0.97 jpeg errors on too large a file; also catch another malloc failure |
|||
0.96 fix detection of invalid v value - particleman@mollyrocket forum |
|||
0.95 during header scan, seek to markers in case of padding |
|||
0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same |
|||
0.93 handle jpegtran output; verbose errors |
|||
0.92 read 4,8,16,24,32-bit BMP files of several formats |
|||
0.91 output 24-bit Windows 3.0 BMP files |
|||
0.90 fix a few more warnings; bump version number to approach 1.0 |
|||
0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd |
|||
0.60 fix compiling as c++ |
|||
0.59 fix warnings: merge Dave Moore's -Wall fixes |
|||
0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian |
|||
0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available |
|||
0.56 fix bug: zlib uncompressed mode len vs. nlen |
|||
0.55 fix bug: restart_interval not initialized to 0 |
|||
0.54 allow NULL for 'int *comp' |
|||
0.53 fix bug in png 3->4; speedup png decoding |
|||
0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments |
|||
0.51 obey req_comp requests, 1-component jpegs return as 1-component, |
|||
on 'test' only check type, not whether we support this variant |
|||
0.50 (2006-11-19) |
|||
first released version |
|||
*/ |
|||
|
|||
|
|||
/* |
|||
------------------------------------------------------------------------------ |
|||
This software is available under 2 licenses -- choose whichever you prefer. |
|||
------------------------------------------------------------------------------ |
|||
ALTERNATIVE A - MIT License |
|||
Copyright (c) 2017 Sean Barrett |
|||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
|||
this software and associated documentation files (the "Software"), to deal in |
|||
the Software without restriction, including without limitation the rights to |
|||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
|||
of the Software, and to permit persons to whom the Software is furnished to do |
|||
so, subject to the following conditions: |
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
|||
------------------------------------------------------------------------------ |
|||
ALTERNATIVE B - Public Domain (www.unlicense.org) |
|||
This is free and unencumbered software released into the public domain. |
|||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this |
|||
software, either in source code form or as a compiled binary, for any purpose, |
|||
commercial or non-commercial, and by any means. |
|||
In jurisdictions that recognize copyright laws, the author or authors of this |
|||
software dedicate any and all copyright interest in the software to the public |
|||
domain. We make this dedication for the benefit of the public at large and to |
|||
the detriment of our heirs and successors. We intend this dedication to be an |
|||
overt act of relinquishment in perpetuity of all present and future rights to |
|||
this software under copyright law. |
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
------------------------------------------------------------------------------ |
|||
*/ |
|||
2282
externals/stb/stb_image_resize.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,426 @@ |
|||
// SPDX-FileCopyrightText: Jorge L Rodriguez |
|||
// SPDX-License-Identifier: MIT |
|||
|
|||
/* stb_image_resize - v0.97 - public domain image resizing |
|||
by Jorge L Rodriguez (@VinoBS) - 2014 |
|||
http://github.com/nothings/stb |
|||
|
|||
Written with emphasis on usability, portability, and efficiency. (No |
|||
SIMD or threads, so it be easily outperformed by libs that use those.) |
|||
Only scaling and translation is supported, no rotations or shears. |
|||
Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation. |
|||
|
|||
COMPILING & LINKING |
|||
In one C/C++ file that #includes this file, do this: |
|||
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|||
before the #include. That will create the implementation in that file. |
|||
|
|||
QUICKSTART |
|||
stbir_resize_uint8( input_pixels , in_w , in_h , 0, |
|||
output_pixels, out_w, out_h, 0, num_channels) |
|||
stbir_resize_float(...) |
|||
stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0, |
|||
output_pixels, out_w, out_h, 0, |
|||
num_channels , alpha_chan , 0) |
|||
stbir_resize_uint8_srgb_edgemode( |
|||
input_pixels , in_w , in_h , 0, |
|||
output_pixels, out_w, out_h, 0, |
|||
num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP) |
|||
// WRAP/REFLECT/ZERO |
|||
|
|||
FULL API |
|||
See the "header file" section of the source for API documentation. |
|||
|
|||
ADDITIONAL DOCUMENTATION |
|||
|
|||
SRGB & FLOATING POINT REPRESENTATION |
|||
The sRGB functions presume IEEE floating point. If you do not have |
|||
IEEE floating point, define STBIR_NON_IEEE_FLOAT. This will use |
|||
a slower implementation. |
|||
|
|||
MEMORY ALLOCATION |
|||
The resize functions here perform a single memory allocation using |
|||
malloc. To control the memory allocation, before the #include that |
|||
triggers the implementation, do: |
|||
|
|||
#define STBIR_MALLOC(size,context) ... |
|||
#define STBIR_FREE(ptr,context) ... |
|||
|
|||
Each resize function makes exactly one call to malloc/free, so to use |
|||
temp memory, store the temp memory in the context and return that. |
|||
|
|||
ASSERT |
|||
Define STBIR_ASSERT(boolval) to override assert() and not use assert.h |
|||
|
|||
OPTIMIZATION |
|||
Define STBIR_SATURATE_INT to compute clamp values in-range using |
|||
integer operations instead of float operations. This may be faster |
|||
on some platforms. |
|||
|
|||
DEFAULT FILTERS |
|||
For functions which don't provide explicit control over what filters |
|||
to use, you can change the compile-time defaults with |
|||
|
|||
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something |
|||
#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something |
|||
|
|||
See stbir_filter in the header-file section for the list of filters. |
|||
|
|||
NEW FILTERS |
|||
A number of 1D filter kernels are used. For a list of |
|||
supported filters see the stbir_filter enum. To add a new filter, |
|||
write a filter function and add it to stbir__filter_info_table. |
|||
|
|||
PROGRESS |
|||
For interactive use with slow resize operations, you can install |
|||
a progress-report callback: |
|||
|
|||
#define STBIR_PROGRESS_REPORT(val) some_func(val) |
|||
|
|||
The parameter val is a float which goes from 0 to 1 as progress is made. |
|||
|
|||
For example: |
|||
|
|||
static void my_progress_report(float progress); |
|||
#define STBIR_PROGRESS_REPORT(val) my_progress_report(val) |
|||
|
|||
#define STB_IMAGE_RESIZE_IMPLEMENTATION |
|||
#include "stb_image_resize.h" |
|||
|
|||
static void my_progress_report(float progress) |
|||
{ |
|||
printf("Progress: %f%%\n", progress*100); |
|||
} |
|||
|
|||
MAX CHANNELS |
|||
If your image has more than 64 channels, define STBIR_MAX_CHANNELS |
|||
to the max you'll have. |
|||
|
|||
ALPHA CHANNEL |
|||
Most of the resizing functions provide the ability to control how |
|||
the alpha channel of an image is processed. The important things |
|||
to know about this: |
|||
|
|||
1. The best mathematically-behaved version of alpha to use is |
|||
called "premultiplied alpha", in which the other color channels |
|||
have had the alpha value multiplied in. If you use premultiplied |
|||
alpha, linear filtering (such as image resampling done by this |
|||
library, or performed in texture units on GPUs) does the "right |
|||
thing". While premultiplied alpha is standard in the movie CGI |
|||
industry, it is still uncommon in the videogame/real-time world. |
|||
|
|||
If you linearly filter non-premultiplied alpha, strange effects |
|||
occur. (For example, the 50/50 average of 99% transparent bright green |
|||
and 1% transparent black produces 50% transparent dark green when |
|||
non-premultiplied, whereas premultiplied it produces 50% |
|||
transparent near-black. The former introduces green energy |
|||
that doesn't exist in the source image.) |
|||
|
|||
2. Artists should not edit premultiplied-alpha images; artists |
|||
want non-premultiplied alpha images. Thus, art tools generally output |
|||
non-premultiplied alpha images. |
|||
|
|||
3. You will get best results in most cases by converting images |
|||
to premultiplied alpha before processing them mathematically. |
|||
|
|||
4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the |
|||
resizer does not do anything special for the alpha channel; |
|||
it is resampled identically to other channels. This produces |
|||
the correct results for premultiplied-alpha images, but produces |
|||
less-than-ideal results for non-premultiplied-alpha images. |
|||
|
|||
5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, |
|||
then the resizer weights the contribution of input pixels |
|||
based on their alpha values, or, equivalently, it multiplies |
|||
the alpha value into the color channels, resamples, then divides |
|||
by the resultant alpha value. Input pixels which have alpha=0 do |
|||
not contribute at all to output pixels unless _all_ of the input |
|||
pixels affecting that output pixel have alpha=0, in which case |
|||
the result for that pixel is the same as it would be without |
|||
STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for |
|||
input images in integer formats. For input images in float format, |
|||
input pixels with alpha=0 have no effect, and output pixels |
|||
which have alpha=0 will be 0 in all channels. (For float images, |
|||
you can manually achieve the same result by adding a tiny epsilon |
|||
value to the alpha channel of every image, and then subtracting |
|||
or clamping it at the end.) |
|||
|
|||
6. You can suppress the behavior described in #5 and make |
|||
all-0-alpha pixels have 0 in all channels by #defining |
|||
STBIR_NO_ALPHA_EPSILON. |
|||
|
|||
7. You can separately control whether the alpha channel is |
|||
interpreted as linear or affected by the colorspace. By default |
|||
it is linear; you almost never want to apply the colorspace. |
|||
(For example, graphics hardware does not apply sRGB conversion |
|||
to the alpha channel.) |
|||
|
|||
CONTRIBUTORS |
|||
Jorge L Rodriguez: Implementation |
|||
Sean Barrett: API design, optimizations |
|||
Aras Pranckevicius: bugfix |
|||
Nathan Reed: warning fixes |
|||
|
|||
REVISIONS |
|||
0.97 (2020-02-02) fixed warning |
|||
0.96 (2019-03-04) fixed warnings |
|||
0.95 (2017-07-23) fixed warnings |
|||
0.94 (2017-03-18) fixed warnings |
|||
0.93 (2017-03-03) fixed bug with certain combinations of heights |
|||
0.92 (2017-01-02) fix integer overflow on large (>2GB) images |
|||
0.91 (2016-04-02) fix warnings; fix handling of subpixel regions |
|||
0.90 (2014-09-17) first released version |
|||
|
|||
LICENSE |
|||
See end of file for license information. |
|||
|
|||
TODO |
|||
Don't decode all of the image data when only processing a partial tile |
|||
Don't use full-width decode buffers when only processing a partial tile |
|||
When processing wide images, break processing into tiles so data fits in L1 cache |
|||
Installable filters? |
|||
Resize that respects alpha test coverage |
|||
(Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: |
|||
https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp ) |
|||
*/ |
|||
|
|||
#ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H |
|||
#define STBIR_INCLUDE_STB_IMAGE_RESIZE_H |
|||
|
|||
#ifdef _MSC_VER |
|||
typedef unsigned char stbir_uint8; |
|||
typedef unsigned short stbir_uint16; |
|||
typedef unsigned int stbir_uint32; |
|||
#else |
|||
#include <stdint.h> |
|||
typedef uint8_t stbir_uint8; |
|||
typedef uint16_t stbir_uint16; |
|||
typedef uint32_t stbir_uint32; |
|||
#endif |
|||
|
|||
#ifndef STBIRDEF |
|||
#ifdef STB_IMAGE_RESIZE_STATIC |
|||
#define STBIRDEF static |
|||
#else |
|||
#ifdef __cplusplus |
|||
#define STBIRDEF extern "C" |
|||
#else |
|||
#define STBIRDEF extern |
|||
#endif |
|||
#endif |
|||
#endif |
|||
|
|||
////////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Easy-to-use API: |
|||
// |
|||
// * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4) |
|||
// * input_w is input image width (x-axis), input_h is input image height (y-axis) |
|||
// * stride is the offset between successive rows of image data in memory, in bytes. you can |
|||
// specify 0 to mean packed continuously in memory |
|||
// * alpha channel is treated identically to other channels. |
|||
// * colorspace is linear or sRGB as specified by function name |
|||
// * returned result is 1 for success or 0 in case of an error. |
|||
// #define STBIR_ASSERT() to trigger an assert on parameter validation errors. |
|||
// * Memory required grows approximately linearly with input and output size, but with |
|||
// discontinuities at input_w == output_w and input_h == output_h. |
|||
// * These functions use a "default" resampling filter defined at compile time. To change the filter, |
|||
// you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE |
|||
// and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API. |
|||
|
|||
STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels); |
|||
|
|||
STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels); |
|||
|
|||
|
|||
// The following functions interpret image data as gamma-corrected sRGB. |
|||
// Specify STBIR_ALPHA_CHANNEL_NONE if you have no alpha channel, |
|||
// or otherwise provide the index of the alpha channel. Flags value |
|||
// of 0 will probably do the right thing if you're not sure what |
|||
// the flags mean. |
|||
|
|||
#define STBIR_ALPHA_CHANNEL_NONE -1 |
|||
|
|||
// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will |
|||
// use alpha-weighted resampling (effectively premultiplying, resampling, |
|||
// then unpremultiplying). |
|||
#define STBIR_FLAG_ALPHA_PREMULTIPLIED (1 << 0) |
|||
// The specified alpha channel should be handled as gamma-corrected value even |
|||
// when doing sRGB operations. |
|||
#define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1) |
|||
|
|||
STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels, int alpha_channel, int flags); |
|||
|
|||
|
|||
typedef enum |
|||
{ |
|||
STBIR_EDGE_CLAMP = 1, |
|||
STBIR_EDGE_REFLECT = 2, |
|||
STBIR_EDGE_WRAP = 3, |
|||
STBIR_EDGE_ZERO = 4, |
|||
} stbir_edge; |
|||
|
|||
// This function adds the ability to specify how requests to sample off the edge of the image are handled. |
|||
STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_wrap_mode); |
|||
|
|||
////////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Medium-complexity API |
|||
// |
|||
// This extends the easy-to-use API as follows: |
|||
// |
|||
// * Alpha-channel can be processed separately |
|||
// * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE |
|||
// * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT) |
|||
// * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED) |
|||
// * Filter can be selected explicitly |
|||
// * uint16 image type |
|||
// * sRGB colorspace available for all types |
|||
// * context parameter for passing to STBIR_MALLOC |
|||
|
|||
typedef enum |
|||
{ |
|||
STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses |
|||
STBIR_FILTER_BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios |
|||
STBIR_FILTER_TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering |
|||
STBIR_FILTER_CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque |
|||
STBIR_FILTER_CATMULLROM = 4, // An interpolating cubic spline |
|||
STBIR_FILTER_MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3 |
|||
} stbir_filter; |
|||
|
|||
typedef enum |
|||
{ |
|||
STBIR_COLORSPACE_LINEAR, |
|||
STBIR_COLORSPACE_SRGB, |
|||
|
|||
STBIR_MAX_COLORSPACES, |
|||
} stbir_colorspace; |
|||
|
|||
// The following functions are all identical except for the type of the image data |
|||
|
|||
STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, |
|||
void *alloc_context); |
|||
|
|||
STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, |
|||
void *alloc_context); |
|||
|
|||
STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, |
|||
void *alloc_context); |
|||
|
|||
|
|||
|
|||
////////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Full-complexity API |
|||
// |
|||
// This extends the medium API as follows: |
|||
// |
|||
// * uint32 image type |
|||
// * not typesafe |
|||
// * separate filter types for each axis |
|||
// * separate edge modes for each axis |
|||
// * can specify scale explicitly for subpixel correctness |
|||
// * can specify image source tile using texture coordinates |
|||
|
|||
typedef enum |
|||
{ |
|||
STBIR_TYPE_UINT8 , |
|||
STBIR_TYPE_UINT16, |
|||
STBIR_TYPE_UINT32, |
|||
STBIR_TYPE_FLOAT , |
|||
|
|||
STBIR_MAX_TYPES |
|||
} stbir_datatype; |
|||
|
|||
STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
stbir_datatype datatype, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, |
|||
stbir_filter filter_horizontal, stbir_filter filter_vertical, |
|||
stbir_colorspace space, void *alloc_context); |
|||
|
|||
STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
stbir_datatype datatype, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, |
|||
stbir_filter filter_horizontal, stbir_filter filter_vertical, |
|||
stbir_colorspace space, void *alloc_context, |
|||
float x_scale, float y_scale, |
|||
float x_offset, float y_offset); |
|||
|
|||
STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, |
|||
void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, |
|||
stbir_datatype datatype, |
|||
int num_channels, int alpha_channel, int flags, |
|||
stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, |
|||
stbir_filter filter_horizontal, stbir_filter filter_vertical, |
|||
stbir_colorspace space, void *alloc_context, |
|||
float s0, float t0, float s1, float t1); |
|||
// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use. |
|||
|
|||
// |
|||
// |
|||
//// end header file ///////////////////////////////////////////////////// |
|||
#endif // STBIR_INCLUDE_STB_IMAGE_RESIZE_H |
|||
|
|||
/* |
|||
------------------------------------------------------------------------------ |
|||
This software is available under 2 licenses -- choose whichever you prefer. |
|||
------------------------------------------------------------------------------ |
|||
ALTERNATIVE A - MIT License |
|||
Copyright (c) 2017 Sean Barrett |
|||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
|||
this software and associated documentation files (the "Software"), to deal in |
|||
the Software without restriction, including without limitation the rights to |
|||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
|||
of the Software, and to permit persons to whom the Software is furnished to do |
|||
so, subject to the following conditions: |
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
|||
------------------------------------------------------------------------------ |
|||
ALTERNATIVE B - Public Domain (www.unlicense.org) |
|||
This is free and unencumbered software released into the public domain. |
|||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this |
|||
software, either in source code form or as a compiled binary, for any purpose, |
|||
commercial or non-commercial, and by any means. |
|||
In jurisdictions that recognize copyright laws, the author or authors of this |
|||
software dedicate any and all copyright interest in the software to the public |
|||
domain. We make this dedication for the benefit of the public at large and to |
|||
the detriment of our heirs and successors. We intend this dedication to be an |
|||
overt act of relinquishment in perpetuity of all present and future rights to |
|||
this software under copyright law. |
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
------------------------------------------------------------------------------ |
|||
*/ |
|||
@ -0,0 +1,342 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <sstream>
|
|||
#include <stb_image.h>
|
|||
#include <stb_image_resize.h>
|
|||
|
|||
#include "common/fs/file.h"
|
|||
#include "common/fs/path_util.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "core/hle/service/caps/caps_manager.h"
|
|||
#include "core/hle/service/caps/caps_result.h"
|
|||
|
|||
namespace Service::Capture { |
|||
|
|||
AlbumManager::AlbumManager() {} |
|||
|
|||
AlbumManager::~AlbumManager() = default; |
|||
|
|||
Result AlbumManager::DeleteAlbumFile(const AlbumFileId& file_id) { |
|||
if (file_id.storage > AlbumStorage::Sd) { |
|||
return ResultInvalidStorage; |
|||
} |
|||
|
|||
if (!is_mounted) { |
|||
return ResultIsNotMounted; |
|||
} |
|||
|
|||
std::filesystem::path path; |
|||
const auto result = GetFile(path, file_id); |
|||
|
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
|
|||
if (!Common::FS::RemoveFile(path)) { |
|||
return ResultFileNotFound; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AlbumManager::IsAlbumMounted(AlbumStorage storage) { |
|||
if (storage > AlbumStorage::Sd) { |
|||
return ResultInvalidStorage; |
|||
} |
|||
|
|||
is_mounted = true; |
|||
|
|||
if (storage == AlbumStorage::Sd) { |
|||
FindScreenshots(); |
|||
} |
|||
|
|||
return is_mounted ? ResultSuccess : ResultIsNotMounted; |
|||
} |
|||
|
|||
Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, |
|||
u8 flags) const { |
|||
if (storage > AlbumStorage::Sd) { |
|||
return ResultInvalidStorage; |
|||
} |
|||
|
|||
if (!is_mounted) { |
|||
return ResultIsNotMounted; |
|||
} |
|||
|
|||
for (auto& [file_id, path] : album_files) { |
|||
if (file_id.storage != storage) { |
|||
continue; |
|||
} |
|||
if (out_entries.size() >= SdAlbumFileLimit) { |
|||
break; |
|||
} |
|||
|
|||
const auto entry_size = Common::FS::GetSize(path); |
|||
out_entries.push_back({ |
|||
.entry_size = entry_size, |
|||
.file_id = file_id, |
|||
}); |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, |
|||
ContentType contex_type, AlbumFileDateTime start_date, |
|||
AlbumFileDateTime end_date, u64 aruid) const { |
|||
if (!is_mounted) { |
|||
return ResultIsNotMounted; |
|||
} |
|||
|
|||
for (auto& [file_id, path] : album_files) { |
|||
if (file_id.type != contex_type) { |
|||
continue; |
|||
} |
|||
|
|||
if (file_id.date > start_date) { |
|||
continue; |
|||
} |
|||
|
|||
if (file_id.date < end_date) { |
|||
continue; |
|||
} |
|||
|
|||
if (out_entries.size() >= SdAlbumFileLimit) { |
|||
break; |
|||
} |
|||
|
|||
const auto entry_size = Common::FS::GetSize(path); |
|||
ApplicationAlbumFileEntry entry{.entry = |
|||
{ |
|||
.size = entry_size, |
|||
.hash{}, |
|||
.datetime = file_id.date, |
|||
.storage = file_id.storage, |
|||
.content = contex_type, |
|||
.unknown = 1, |
|||
}, |
|||
.datetime = file_id.date, |
|||
.unknown = {}}; |
|||
out_entries.push_back(entry); |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AlbumManager::GetAutoSavingStorage(bool& out_is_autosaving) const { |
|||
out_is_autosaving = false; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, |
|||
std::vector<u8>& out_image, |
|||
const AlbumFileId& file_id, |
|||
const ScreenShotDecodeOption& decoder_options) const { |
|||
if (file_id.storage > AlbumStorage::Sd) { |
|||
return ResultInvalidStorage; |
|||
} |
|||
|
|||
if (!is_mounted) { |
|||
return ResultIsNotMounted; |
|||
} |
|||
|
|||
out_image_output = { |
|||
.width = 1280, |
|||
.height = 720, |
|||
.attribute = |
|||
{ |
|||
.unknown_0{}, |
|||
.orientation = AlbumImageOrientation::None, |
|||
.unknown_1{}, |
|||
.unknown_2{}, |
|||
}, |
|||
}; |
|||
|
|||
std::filesystem::path path; |
|||
const auto result = GetFile(path, file_id); |
|||
|
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
|
|||
out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha); |
|||
|
|||
return LoadImage(out_image, path, static_cast<int>(out_image_output.width), |
|||
+static_cast<int>(out_image_output.height), decoder_options.flags); |
|||
} |
|||
|
|||
Result AlbumManager::LoadAlbumScreenShotThumbnail( |
|||
LoadAlbumScreenShotImageOutput& out_image_output, std::vector<u8>& out_image, |
|||
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const { |
|||
if (file_id.storage > AlbumStorage::Sd) { |
|||
return ResultInvalidStorage; |
|||
} |
|||
|
|||
if (!is_mounted) { |
|||
return ResultIsNotMounted; |
|||
} |
|||
|
|||
out_image_output = { |
|||
.width = 320, |
|||
.height = 180, |
|||
.attribute = |
|||
{ |
|||
.unknown_0{}, |
|||
.orientation = AlbumImageOrientation::None, |
|||
.unknown_1{}, |
|||
.unknown_2{}, |
|||
}, |
|||
}; |
|||
|
|||
std::filesystem::path path; |
|||
const auto result = GetFile(path, file_id); |
|||
|
|||
if (result.IsError()) { |
|||
return result; |
|||
} |
|||
|
|||
out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha); |
|||
|
|||
return LoadImage(out_image, path, static_cast<int>(out_image_output.width), |
|||
+static_cast<int>(out_image_output.height), decoder_options.flags); |
|||
} |
|||
|
|||
Result AlbumManager::GetFile(std::filesystem::path& out_path, const AlbumFileId& file_id) const { |
|||
const auto file = album_files.find(file_id); |
|||
|
|||
if (file == album_files.end()) { |
|||
return ResultFileNotFound; |
|||
} |
|||
|
|||
out_path = file->second; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
void AlbumManager::FindScreenshots() { |
|||
is_mounted = false; |
|||
album_files.clear(); |
|||
|
|||
// TODO: Swap this with a blocking operation.
|
|||
const auto screenshots_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ScreenshotsDir); |
|||
Common::FS::IterateDirEntries( |
|||
screenshots_dir, |
|||
[this](const std::filesystem::path& full_path) { |
|||
AlbumEntry entry; |
|||
if (GetAlbumEntry(entry, full_path).IsError()) { |
|||
return true; |
|||
} |
|||
while (album_files.contains(entry.file_id)) { |
|||
if (++entry.file_id.date.unique_id == 0) { |
|||
break; |
|||
} |
|||
} |
|||
album_files[entry.file_id] = full_path; |
|||
return true; |
|||
}, |
|||
Common::FS::DirEntryFilter::File); |
|||
|
|||
is_mounted = true; |
|||
} |
|||
|
|||
Result AlbumManager::GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem::path& path) const { |
|||
std::istringstream line_stream(path.filename().string()); |
|||
std::string date; |
|||
std::string application; |
|||
std::string time; |
|||
|
|||
// Parse filename to obtain entry properties
|
|||
std::getline(line_stream, application, '_'); |
|||
std::getline(line_stream, date, '_'); |
|||
std::getline(line_stream, time, '_'); |
|||
|
|||
std::istringstream date_stream(date); |
|||
std::istringstream time_stream(time); |
|||
std::string year; |
|||
std::string month; |
|||
std::string day; |
|||
std::string hour; |
|||
std::string minute; |
|||
std::string second; |
|||
|
|||
std::getline(date_stream, year, '-'); |
|||
std::getline(date_stream, month, '-'); |
|||
std::getline(date_stream, day, '-'); |
|||
|
|||
std::getline(time_stream, hour, '-'); |
|||
std::getline(time_stream, minute, '-'); |
|||
std::getline(time_stream, second, '-'); |
|||
|
|||
try { |
|||
out_entry = { |
|||
.entry_size = 1, |
|||
.file_id{ |
|||
.application_id = static_cast<u64>(std::stoll(application, 0, 16)), |
|||
.date = |
|||
{ |
|||
.year = static_cast<u16>(std::stoi(year)), |
|||
.month = static_cast<u8>(std::stoi(month)), |
|||
.day = static_cast<u8>(std::stoi(day)), |
|||
.hour = static_cast<u8>(std::stoi(hour)), |
|||
.minute = static_cast<u8>(std::stoi(minute)), |
|||
.second = static_cast<u8>(std::stoi(second)), |
|||
.unique_id = 0, |
|||
}, |
|||
.storage = AlbumStorage::Sd, |
|||
.type = ContentType::Screenshot, |
|||
.unknown = 1, |
|||
}, |
|||
}; |
|||
} catch (const std::invalid_argument&) { |
|||
return ResultUnknown; |
|||
} catch (const std::out_of_range&) { |
|||
return ResultUnknown; |
|||
} catch (const std::exception&) { |
|||
return ResultUnknown; |
|||
} |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
|
|||
Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::path& path, |
|||
int width, int height, ScreenShotDecoderFlag flag) const { |
|||
if (out_image.size() != static_cast<std::size_t>(width * height * STBI_rgb_alpha)) { |
|||
return ResultUnknown; |
|||
} |
|||
|
|||
const Common::FS::IOFile db_file{path, Common::FS::FileAccessMode::Read, |
|||
Common::FS::FileType::BinaryFile}; |
|||
|
|||
std::vector<u8> raw_file(db_file.GetSize()); |
|||
if (db_file.Read(raw_file) != raw_file.size()) { |
|||
return ResultUnknown; |
|||
} |
|||
|
|||
int filter_flag = STBIR_FILTER_DEFAULT; |
|||
int original_width, original_height, color_channels; |
|||
const auto dbi_image = |
|||
stbi_load_from_memory(raw_file.data(), static_cast<int>(raw_file.size()), &original_width, |
|||
&original_height, &color_channels, STBI_rgb_alpha); |
|||
|
|||
if (dbi_image == nullptr) { |
|||
return ResultUnknown; |
|||
} |
|||
|
|||
switch (flag) { |
|||
case ScreenShotDecoderFlag::EnableFancyUpsampling: |
|||
filter_flag = STBIR_FILTER_TRIANGLE; |
|||
break; |
|||
case ScreenShotDecoderFlag::EnableBlockSmoothing: |
|||
filter_flag = STBIR_FILTER_BOX; |
|||
break; |
|||
default: |
|||
filter_flag = STBIR_FILTER_DEFAULT; |
|||
break; |
|||
} |
|||
|
|||
stbir_resize_uint8_srgb(dbi_image, original_width, original_height, 0, out_image.data(), width, |
|||
height, 0, STBI_rgb_alpha, 3, filter_flag); |
|||
|
|||
return ResultSuccess; |
|||
} |
|||
} // namespace Service::Capture
|
|||
@ -0,0 +1,72 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <unordered_map> |
|||
|
|||
#include "common/fs/fs.h" |
|||
#include "core/hle/result.h" |
|||
#include "core/hle/service/caps/caps_types.h" |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
namespace std { |
|||
// Hash used to create lists from AlbumFileId data |
|||
template <> |
|||
struct hash<Service::Capture::AlbumFileId> { |
|||
size_t operator()(const Service::Capture::AlbumFileId& pad_id) const noexcept { |
|||
u64 hash_value = (static_cast<u64>(pad_id.date.year) << 8); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.month) << 7); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.day) << 6); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.hour) << 5); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.minute) << 4); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.second) << 3); |
|||
hash_value ^= (static_cast<u64>(pad_id.date.unique_id) << 2); |
|||
hash_value ^= (static_cast<u64>(pad_id.storage) << 1); |
|||
hash_value ^= static_cast<u64>(pad_id.type); |
|||
return static_cast<size_t>(hash_value); |
|||
} |
|||
}; |
|||
|
|||
} // namespace std |
|||
|
|||
namespace Service::Capture { |
|||
|
|||
class AlbumManager { |
|||
public: |
|||
explicit AlbumManager(); |
|||
~AlbumManager(); |
|||
|
|||
Result DeleteAlbumFile(const AlbumFileId& file_id); |
|||
Result IsAlbumMounted(AlbumStorage storage); |
|||
Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, |
|||
u8 flags) const; |
|||
Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, |
|||
ContentType contex_type, AlbumFileDateTime start_date, |
|||
AlbumFileDateTime end_date, u64 aruid) const; |
|||
Result GetAutoSavingStorage(bool& out_is_autosaving) const; |
|||
Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, |
|||
std::vector<u8>& out_image, const AlbumFileId& file_id, |
|||
const ScreenShotDecodeOption& decoder_options) const; |
|||
Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output, |
|||
std::vector<u8>& out_image, const AlbumFileId& file_id, |
|||
const ScreenShotDecodeOption& decoder_options) const; |
|||
|
|||
private: |
|||
static constexpr std::size_t NandAlbumFileLimit = 1000; |
|||
static constexpr std::size_t SdAlbumFileLimit = 10000; |
|||
|
|||
void FindScreenshots(); |
|||
Result GetFile(std::filesystem::path& out_path, const AlbumFileId& file_id) const; |
|||
Result GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem::path& path) const; |
|||
Result LoadImage(std::span<u8> out_image, const std::filesystem::path& path, int width, |
|||
int height, ScreenShotDecoderFlag flag) const; |
|||
|
|||
bool is_mounted{}; |
|||
std::unordered_map<AlbumFileId, std::filesystem::path> album_files; |
|||
}; |
|||
|
|||
} // namespace Service::Capture |
|||
@ -0,0 +1,35 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Service::Capture { |
|||
|
|||
constexpr Result ResultWorkMemoryError(ErrorModule::Capture, 3); |
|||
constexpr Result ResultUnknown5(ErrorModule::Capture, 5); |
|||
constexpr Result ResultUnknown6(ErrorModule::Capture, 6); |
|||
constexpr Result ResultUnknown7(ErrorModule::Capture, 7); |
|||
constexpr Result ResultOutOfRange(ErrorModule::Capture, 8); |
|||
constexpr Result ResulInvalidTimestamp(ErrorModule::Capture, 12); |
|||
constexpr Result ResultInvalidStorage(ErrorModule::Capture, 13); |
|||
constexpr Result ResultInvalidFileContents(ErrorModule::Capture, 14); |
|||
constexpr Result ResultIsNotMounted(ErrorModule::Capture, 21); |
|||
constexpr Result ResultUnknown22(ErrorModule::Capture, 22); |
|||
constexpr Result ResultFileNotFound(ErrorModule::Capture, 23); |
|||
constexpr Result ResultInvalidFileData(ErrorModule::Capture, 24); |
|||
constexpr Result ResultUnknown25(ErrorModule::Capture, 25); |
|||
constexpr Result ResultReadBufferShortage(ErrorModule::Capture, 30); |
|||
constexpr Result ResultUnknown810(ErrorModule::Capture, 810); |
|||
constexpr Result ResultUnknown1024(ErrorModule::Capture, 1024); |
|||
constexpr Result ResultUnknown1202(ErrorModule::Capture, 1202); |
|||
constexpr Result ResultUnknown1203(ErrorModule::Capture, 1203); |
|||
constexpr Result ResultFileCountLimit(ErrorModule::Capture, 1401); |
|||
constexpr Result ResultUnknown1701(ErrorModule::Capture, 1701); |
|||
constexpr Result ResultUnknown1801(ErrorModule::Capture, 1801); |
|||
constexpr Result ResultUnknown1802(ErrorModule::Capture, 1802); |
|||
constexpr Result ResultUnknown1803(ErrorModule::Capture, 1803); |
|||
constexpr Result ResultUnknown1804(ErrorModule::Capture, 1804); |
|||
|
|||
} // namespace Service::Capture |
|||
@ -0,0 +1,184 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Service::Capture { |
|||
|
|||
// This is nn::album::ImageOrientation |
|||
enum class AlbumImageOrientation { |
|||
None, |
|||
Rotate90, |
|||
Rotate180, |
|||
Rotate270, |
|||
}; |
|||
|
|||
// This is nn::album::AlbumReportOption |
|||
enum class AlbumReportOption : s32 { |
|||
Disable, |
|||
Enable, |
|||
}; |
|||
|
|||
enum class ContentType : u8 { |
|||
Screenshot = 0, |
|||
Movie = 1, |
|||
ExtraMovie = 3, |
|||
}; |
|||
|
|||
enum class AlbumStorage : u8 { |
|||
Nand, |
|||
Sd, |
|||
}; |
|||
|
|||
enum class ScreenShotDecoderFlag : u64 { |
|||
None = 0, |
|||
EnableFancyUpsampling = 1 << 0, |
|||
EnableBlockSmoothing = 1 << 1, |
|||
}; |
|||
|
|||
// This is nn::capsrv::AlbumFileDateTime |
|||
struct AlbumFileDateTime { |
|||
u16 year{}; |
|||
u8 month{}; |
|||
u8 day{}; |
|||
u8 hour{}; |
|||
u8 minute{}; |
|||
u8 second{}; |
|||
u8 unique_id{}; |
|||
|
|||
friend constexpr bool operator==(const AlbumFileDateTime&, const AlbumFileDateTime&) = default; |
|||
friend constexpr bool operator>(const AlbumFileDateTime& a, const AlbumFileDateTime& b) { |
|||
if (a.year > b.year) { |
|||
return true; |
|||
} |
|||
if (a.month > b.month) { |
|||
return true; |
|||
} |
|||
if (a.day > b.day) { |
|||
return true; |
|||
} |
|||
if (a.hour > b.hour) { |
|||
return true; |
|||
} |
|||
if (a.minute > b.minute) { |
|||
return true; |
|||
} |
|||
return a.second > b.second; |
|||
}; |
|||
friend constexpr bool operator<(const AlbumFileDateTime& a, const AlbumFileDateTime& b) { |
|||
if (a.year < b.year) { |
|||
return true; |
|||
} |
|||
if (a.month < b.month) { |
|||
return true; |
|||
} |
|||
if (a.day < b.day) { |
|||
return true; |
|||
} |
|||
if (a.hour < b.hour) { |
|||
return true; |
|||
} |
|||
if (a.minute < b.minute) { |
|||
return true; |
|||
} |
|||
return a.second < b.second; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(AlbumFileDateTime) == 0x8, "AlbumFileDateTime has incorrect size."); |
|||
|
|||
// This is nn::album::AlbumEntry |
|||
struct AlbumFileEntry { |
|||
u64 size{}; // Size of the entry |
|||
u64 hash{}; // AES256 with hardcoded key over AlbumEntry |
|||
AlbumFileDateTime datetime{}; |
|||
AlbumStorage storage{}; |
|||
ContentType content{}; |
|||
INSERT_PADDING_BYTES(5); |
|||
u8 unknown{}; // Set to 1 on official SW |
|||
}; |
|||
static_assert(sizeof(AlbumFileEntry) == 0x20, "AlbumFileEntry has incorrect size."); |
|||
|
|||
struct AlbumFileId { |
|||
u64 application_id{}; |
|||
AlbumFileDateTime date{}; |
|||
AlbumStorage storage{}; |
|||
ContentType type{}; |
|||
INSERT_PADDING_BYTES(0x5); |
|||
u8 unknown{}; |
|||
|
|||
friend constexpr bool operator==(const AlbumFileId&, const AlbumFileId&) = default; |
|||
}; |
|||
static_assert(sizeof(AlbumFileId) == 0x18, "AlbumFileId is an invalid size"); |
|||
|
|||
// This is nn::capsrv::AlbumEntry |
|||
struct AlbumEntry { |
|||
u64 entry_size{}; |
|||
AlbumFileId file_id{}; |
|||
}; |
|||
static_assert(sizeof(AlbumEntry) == 0x20, "AlbumEntry has incorrect size."); |
|||
|
|||
// This is nn::capsrv::ApplicationAlbumEntry |
|||
struct ApplicationAlbumEntry { |
|||
u64 size{}; // Size of the entry |
|||
u64 hash{}; // AES256 with hardcoded key over AlbumEntry |
|||
AlbumFileDateTime datetime{}; |
|||
AlbumStorage storage{}; |
|||
ContentType content{}; |
|||
INSERT_PADDING_BYTES(5); |
|||
u8 unknown{1}; // Set to 1 on official SW |
|||
}; |
|||
static_assert(sizeof(ApplicationAlbumEntry) == 0x20, "ApplicationAlbumEntry has incorrect size."); |
|||
|
|||
// This is nn::capsrv::ApplicationAlbumFileEntry |
|||
struct ApplicationAlbumFileEntry { |
|||
ApplicationAlbumEntry entry{}; |
|||
AlbumFileDateTime datetime{}; |
|||
u64 unknown{}; |
|||
}; |
|||
static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30, |
|||
"ApplicationAlbumFileEntry has incorrect size."); |
|||
|
|||
struct ApplicationData { |
|||
std::array<u8, 0x400> data{}; |
|||
u32 data_size{}; |
|||
}; |
|||
static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size"); |
|||
|
|||
struct ScreenShotAttribute { |
|||
u32 unknown_0{}; |
|||
AlbumImageOrientation orientation{}; |
|||
u32 unknown_1{}; |
|||
u32 unknown_2{}; |
|||
INSERT_PADDING_BYTES(0x30); |
|||
}; |
|||
static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size"); |
|||
|
|||
struct ScreenShotDecodeOption { |
|||
ScreenShotDecoderFlag flags{}; |
|||
INSERT_PADDING_BYTES(0x18); |
|||
}; |
|||
static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size"); |
|||
|
|||
struct LoadAlbumScreenShotImageOutput { |
|||
s64 width{}; |
|||
s64 height{}; |
|||
ScreenShotAttribute attribute{}; |
|||
INSERT_PADDING_BYTES(0x400); |
|||
}; |
|||
static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450, |
|||
"LoadAlbumScreenShotImageOutput is an invalid size"); |
|||
|
|||
struct LoadAlbumScreenShotImageOutputForApplication { |
|||
s64 width{}; |
|||
s64 height{}; |
|||
ScreenShotAttribute attribute{}; |
|||
ApplicationData data{}; |
|||
INSERT_PADDING_BYTES(0xAC); |
|||
}; |
|||
static_assert(sizeof(LoadAlbumScreenShotImageOutputForApplication) == 0x500, |
|||
"LoadAlbumScreenShotImageOutput is an invalid size"); |
|||
|
|||
} // namespace Service::Capture |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue