mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 19:28:43 +12:00
349 lines
7.5 KiB
C++
349 lines
7.5 KiB
C++
#pragma once
|
|
|
|
#include "Emu/Memory/vm_ptr.h"
|
|
|
|
#include "png.h"
|
|
|
|
enum : u32
|
|
{
|
|
PNGDEC_CODEC_VERSION = 0x00420000,
|
|
};
|
|
|
|
// Return Codes
|
|
enum CellPngDecError
|
|
{
|
|
CELL_PNGDEC_ERROR_HEADER = 0x80611201,
|
|
CELL_PNGDEC_ERROR_STREAM_FORMAT = 0x80611202,
|
|
CELL_PNGDEC_ERROR_ARG = 0x80611203,
|
|
CELL_PNGDEC_ERROR_SEQ = 0x80611204,
|
|
CELL_PNGDEC_ERROR_BUSY = 0x80611205,
|
|
CELL_PNGDEC_ERROR_FATAL = 0x80611206,
|
|
CELL_PNGDEC_ERROR_OPEN_FILE = 0x80611207,
|
|
CELL_PNGDEC_ERROR_SPU_UNSUPPORT = 0x80611208,
|
|
CELL_PNGDEC_ERROR_SPU_ERROR = 0x80611209,
|
|
CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a,
|
|
};
|
|
|
|
// Consts
|
|
enum CellPngDecColorSpace : s32
|
|
{
|
|
CELL_PNGDEC_GRAYSCALE = 1,
|
|
CELL_PNGDEC_RGB = 2,
|
|
CELL_PNGDEC_PALETTE = 4,
|
|
CELL_PNGDEC_GRAYSCALE_ALPHA = 9,
|
|
CELL_PNGDEC_RGBA = 10,
|
|
CELL_PNGDEC_ARGB = 20,
|
|
};
|
|
|
|
enum CellPngDecSpuThreadEna : s32
|
|
{
|
|
CELL_PNGDEC_SPU_THREAD_DISABLE = 0,
|
|
CELL_PNGDEC_SPU_THREAD_ENABLE = 1,
|
|
};
|
|
|
|
enum CellPngDecStreamSrcSel : s32
|
|
{
|
|
CELL_PNGDEC_FILE = 0,
|
|
CELL_PNGDEC_BUFFER = 1,
|
|
};
|
|
|
|
enum CellPngDecInterlaceMode : s32
|
|
{
|
|
CELL_PNGDEC_NO_INTERLACE = 0,
|
|
CELL_PNGDEC_ADAM7_INTERLACE = 1,
|
|
};
|
|
|
|
enum CellPngDecOutputMode : s32
|
|
{
|
|
CELL_PNGDEC_TOP_TO_BOTTOM = 0,
|
|
CELL_PNGDEC_BOTTOM_TO_TOP = 1,
|
|
};
|
|
|
|
enum CellPngDecPackFlag : s32
|
|
{
|
|
CELL_PNGDEC_1BYTE_PER_NPIXEL = 0,
|
|
CELL_PNGDEC_1BYTE_PER_1PIXEL = 1,
|
|
};
|
|
|
|
enum CellPngDecAlphaSelect : s32
|
|
{
|
|
CELL_PNGDEC_STREAM_ALPHA = 0,
|
|
CELL_PNGDEC_FIX_ALPHA = 1,
|
|
};
|
|
|
|
enum CellPngDecCommand : s32
|
|
{
|
|
CELL_PNGDEC_CONTINUE = 0,
|
|
CELL_PNGDEC_STOP = 1,
|
|
};
|
|
|
|
enum CellPngDecDecodeStatus : s32
|
|
{
|
|
CELL_PNGDEC_DEC_STATUS_FINISH = 0,
|
|
CELL_PNGDEC_DEC_STATUS_STOP = 1,
|
|
};
|
|
|
|
enum CellPngDecBufferMode : s32
|
|
{
|
|
CELL_PNGDEC_LINE_MODE = 1,
|
|
};
|
|
|
|
enum CellPngDecSpuMode : s32
|
|
{
|
|
CELL_PNGDEC_RECEIVE_EVENT = 0,
|
|
CELL_PNGDEC_TRYRECEIVE_EVENT = 1,
|
|
};
|
|
|
|
// Callbacks for memory management
|
|
using CellPngDecCbControlMalloc = vm::ptr<void>(u32 size, vm::ptr<void> cbCtrlMallocArg);
|
|
using CellPngDecCbControlFree = s32(vm::ptr<void> ptr, vm::ptr<void> cbCtrlFreeArg);
|
|
|
|
// Structs
|
|
struct CellPngDecThreadInParam
|
|
{
|
|
be_t<s32> spuThreadEnable; // CellPngDecSpuThreadEna
|
|
be_t<u32> ppuThreadPriority;
|
|
be_t<u32> spuThreadPriority;
|
|
vm::bptr<CellPngDecCbControlMalloc> cbCtrlMallocFunc;
|
|
vm::bptr<void> cbCtrlMallocArg;
|
|
vm::bptr<CellPngDecCbControlFree> cbCtrlFreeFunc;
|
|
vm::bptr<void> cbCtrlFreeArg;
|
|
};
|
|
|
|
struct CellPngDecExtThreadInParam
|
|
{
|
|
vm::bptr<struct CellSpurs> spurs;
|
|
u8 priority[8];
|
|
be_t<u32> maxContention;
|
|
};
|
|
|
|
struct CellPngDecThreadOutParam
|
|
{
|
|
be_t<u32> pngCodecVersion;
|
|
};
|
|
|
|
struct CellPngDecExtThreadOutParam
|
|
{
|
|
be_t<u32> reserved;
|
|
};
|
|
|
|
struct CellPngDecSrc
|
|
{
|
|
be_t<s32> srcSelect; // CellPngDecStreamSrcSel
|
|
vm::bcptr<char> fileName;
|
|
be_t<s64> fileOffset;
|
|
be_t<u32> fileSize;
|
|
vm::bptr<void> streamPtr;
|
|
be_t<u32> streamSize;
|
|
be_t<s32> spuThreadEnable; // CellGifDecSpuThreadEna
|
|
};
|
|
|
|
struct CellPngDecOpnInfo
|
|
{
|
|
be_t<u32> initSpaceAllocated;
|
|
};
|
|
|
|
struct CellPngDecInfo
|
|
{
|
|
be_t<u32> imageWidth;
|
|
be_t<u32> imageHeight;
|
|
be_t<u32> numComponents;
|
|
be_t<s32> colorSpace; // CellPngDecColorSpace
|
|
be_t<u32> bitDepth;
|
|
be_t<s32> interlaceMethod; // CellPngDecInterlaceMode
|
|
be_t<u32> chunkInformation;
|
|
};
|
|
|
|
struct CellPngDecInParam
|
|
{
|
|
vm::bptr<volatile s32> commandPtr; // CellPngDecCommand
|
|
be_t<s32> outputMode; // CellPngDecOutputMode
|
|
be_t<s32> outputColorSpace; // CellPngDecColorSpace
|
|
be_t<u32> outputBitDepth;
|
|
be_t<s32> outputPackFlag; // CellPngDecPackFlag
|
|
be_t<s32> outputAlphaSelect; // CellPngDecAlphaSelect
|
|
be_t<u32> outputColorAlpha;
|
|
};
|
|
|
|
struct CellPngDecOutParam
|
|
{
|
|
be_t<u64> outputWidthByte;
|
|
be_t<u32> outputWidth;
|
|
be_t<u32> outputHeight;
|
|
be_t<u32> outputComponents;
|
|
be_t<u32> outputBitDepth;
|
|
be_t<s32> outputMode; // CellPngDecOutputMode
|
|
be_t<s32> outputColorSpace; // CellPngDecOutputMode
|
|
be_t<u32> useMemorySpace;
|
|
};
|
|
|
|
struct CellPngDecDataCtrlParam
|
|
{
|
|
be_t<u64> outputBytesPerLine;
|
|
};
|
|
|
|
struct CellPngDecDataOutInfo
|
|
{
|
|
be_t<u32> chunkInformation;
|
|
be_t<u32> numText;
|
|
be_t<u32> numUnknownChunk;
|
|
be_t<s32> status; // CellPngDecDecodeStatus
|
|
};
|
|
|
|
// Structs for decoding partial streams
|
|
struct CellPngDecStrmInfo
|
|
{
|
|
be_t<u32> decodedStrmSize;
|
|
};
|
|
|
|
struct CellPngDecStrmParam
|
|
{
|
|
vm::bptr<void> strmPtr;
|
|
be_t<u32> strmSize;
|
|
};
|
|
|
|
struct CellPngDecDispInfo
|
|
{
|
|
be_t<u64> outputFrameWidthByte;
|
|
be_t<u32> outputFrameHeight;
|
|
be_t<u64> outputStartXByte;
|
|
be_t<u32> outputStartY;
|
|
be_t<u64> outputWidthByte;
|
|
be_t<u32> outputHeight;
|
|
be_t<u32> outputBitDepth;
|
|
be_t<u32> outputComponents;
|
|
be_t<u32> nextOutputStartY;
|
|
be_t<u32> scanPassCount;
|
|
vm::bptr<void> outputImage;
|
|
};
|
|
|
|
struct CellPngDecDispParam
|
|
{
|
|
vm::bptr<void> nextOutputImage;
|
|
};
|
|
|
|
struct CellPngDecOpnParam
|
|
{
|
|
be_t<u32> selectChunk;
|
|
};
|
|
|
|
struct CellPngDecExtInfo
|
|
{
|
|
be_t<u64> reserved;
|
|
};
|
|
|
|
struct CellPngDecExtInParam
|
|
{
|
|
be_t<s32> bufferMode; // CellPngDecBufferMode
|
|
be_t<u32> outputCounts;
|
|
be_t<s32> spuMode; // CellPngDecSpuMode
|
|
};
|
|
|
|
struct CellPngDecExtOutParam
|
|
{
|
|
be_t<u64> outputWidthByte;
|
|
be_t<u32> outputHeight;
|
|
};
|
|
|
|
// Callbacks for decoding partial streams
|
|
using CellPngDecCbControlStream = s32(vm::ptr<CellPngDecStrmInfo> strmInfo, vm::ptr<CellPngDecStrmParam> strmParam, vm::ptr<void> cbCtrlStrmArg);
|
|
using CellPngDecCbControlDisp = s32(vm::ptr<CellPngDecDispInfo> dispInfo, vm::ptr<CellPngDecDispParam> dispParam, vm::ptr<void> cbCtrlDispArg);
|
|
|
|
struct CellPngDecCbCtrlStrm
|
|
{
|
|
vm::bptr<CellPngDecCbControlStream> cbCtrlStrmFunc;
|
|
vm::bptr<void> cbCtrlStrmArg;
|
|
};
|
|
|
|
struct CellPngDecCbCtrlDisp
|
|
{
|
|
vm::bptr<CellPngDecCbControlDisp> cbCtrlDispFunc;
|
|
vm::bptr<void> cbCtrlDispArg;
|
|
};
|
|
|
|
// Custom structs
|
|
struct PngHandle
|
|
{
|
|
vm::ptr<CellPngDecCbControlMalloc> malloc_;
|
|
vm::ptr<void> malloc_arg;
|
|
vm::ptr<CellPngDecCbControlFree> free_;
|
|
vm::ptr<void> free_arg;
|
|
};
|
|
|
|
// For reading from a buffer using libpng
|
|
struct PngBuffer
|
|
{
|
|
// The cursor location and data pointer for reading from a buffer
|
|
usz cursor;
|
|
usz length;
|
|
vm::bptr<void> data;
|
|
|
|
// The file descriptor, and whether we need to read from a file descriptor
|
|
bool file;
|
|
u32 fd;
|
|
};
|
|
|
|
struct PngStream
|
|
{
|
|
// PNG decoding structures
|
|
CellPngDecInfo info;
|
|
CellPngDecOutParam out_param;
|
|
CellPngDecSrc source;
|
|
|
|
// Partial decoding
|
|
CellPngDecCbCtrlStrm cbCtrlStream;
|
|
CellPngDecCbCtrlDisp cbCtrlDisp;
|
|
vm::ptr<CellPngDecDispInfo> cbDispInfo;
|
|
vm::ptr<CellPngDecDispParam> cbDispParam;
|
|
ppu_thread* ppuContext;
|
|
|
|
u32 outputCounts = 0;
|
|
u32 nextRow = 0;
|
|
bool endOfFile = false;
|
|
|
|
// Pixel packing value
|
|
be_t<s32> packing;
|
|
u32 passes;
|
|
|
|
// PNG custom read function structure, for decoding from a buffer
|
|
vm::ptr<PngBuffer> buffer;
|
|
|
|
// libpng structures for reading and decoding the PNG file
|
|
png_structp png_ptr;
|
|
png_infop info_ptr;
|
|
};
|
|
|
|
// Converts libpng colour type to cellPngDec colour type
|
|
static s32 getPngDecColourType(u8 type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case PNG_COLOR_TYPE_RGB: return CELL_PNGDEC_RGB;
|
|
case PNG_COLOR_TYPE_RGBA: return CELL_PNGDEC_RGBA; // We can't diffrentiate between ARGB and RGBA. Doesn't seem to be exactly important.
|
|
case PNG_COLOR_TYPE_PALETTE: return CELL_PNGDEC_PALETTE;
|
|
case PNG_COLOR_TYPE_GRAY: return CELL_PNGDEC_GRAYSCALE;
|
|
case PNG_COLOR_TYPE_GRAY_ALPHA: return CELL_PNGDEC_GRAYSCALE_ALPHA;
|
|
default: fmt::throw_exception("Unknown colour type: %d", type);
|
|
}
|
|
}
|
|
|
|
static bool cellPngColorSpaceHasAlpha(u32 colorspace)
|
|
{
|
|
switch (colorspace)
|
|
{
|
|
case CELL_PNGDEC_RGBA:
|
|
case CELL_PNGDEC_ARGB:
|
|
case CELL_PNGDEC_GRAYSCALE_ALPHA:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Custom exception for libPng errors
|
|
|
|
class LibPngCustomException : public std::runtime_error
|
|
{
|
|
public:
|
|
LibPngCustomException(char const* const message) : runtime_error(message) {}
|
|
};
|