#pragma once #include "cellPng.h" enum : u32 { PNGDEC_CODEC_VERSION = 0x00420000, }; // Return Codes enum { 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(u32 size, vm::ptr cbCtrlMallocArg); using CellPngDecCbControlFree = s32(vm::ptr ptr, vm::ptr cbCtrlFreeArg); // Structs struct CellPngDecThreadInParam { be_t spuThreadEnable; // CellPngDecSpuThreadEna be_t ppuThreadPriority; be_t spuThreadPriority; vm::bptr cbCtrlMallocFunc; vm::bptr cbCtrlMallocArg; vm::bptr cbCtrlFreeFunc; vm::bptr cbCtrlFreeArg; }; struct CellPngDecExtThreadInParam { vm::bptr spurs; u8 priority[8]; be_t maxContention; }; struct CellPngDecThreadOutParam { be_t pngCodecVersion; }; struct CellPngDecExtThreadOutParam { be_t reserved; }; struct CellPngDecSrc { be_t srcSelect; // CellPngDecStreamSrcSel vm::bcptr fileName; be_t fileOffset; be_t fileSize; vm::bptr streamPtr; be_t streamSize; be_t spuThreadEnable; // CellGifDecSpuThreadEna }; struct CellPngDecOpnInfo { be_t initSpaceAllocated; }; struct CellPngDecInfo { be_t imageWidth; be_t imageHeight; be_t numComponents; be_t colorSpace; // CellPngDecColorSpace be_t bitDepth; be_t interlaceMethod; // CellPngDecInterlaceMode be_t chunkInformation; }; struct CellPngDecInParam { vm::bptr commandPtr; // CellPngDecCommand be_t outputMode; // CellPngDecOutputMode be_t outputColorSpace; // CellPngDecColorSpace be_t outputBitDepth; be_t outputPackFlag; // CellPngDecPackFlag be_t outputAlphaSelect; // CellPngDecAlphaSelect be_t outputColorAlpha; }; struct CellPngDecOutParam { be_t outputWidthByte; be_t outputWidth; be_t outputHeight; be_t outputComponents; be_t outputBitDepth; be_t outputMode; // CellPngDecOutputMode be_t outputColorSpace; // CellPngDecOutputMode be_t useMemorySpace; }; struct CellPngDecDataCtrlParam { be_t outputBytesPerLine; }; struct CellPngDecDataOutInfo { be_t chunkInformation; be_t numText; be_t numUnknownChunk; be_t status; // CellPngDecDecodeStatus }; // Structs for decoding partial streams struct CellPngDecStrmInfo { be_t decodedStrmSize; }; struct CellPngDecStrmParam { vm::bptr strmPtr; be_t strmSize; }; struct CellPngDecDispInfo { be_t outputFrameWidthByte; be_t outputFrameHeight; be_t outputStartXByte; be_t outputStartY; be_t outputWidthByte; be_t outputHeight; be_t outputBitDepth; be_t outputComponents; be_t nextOutputStartY; be_t scanPassCount; vm::bptr outputImage; }; struct CellPngDecDispParam { vm::bptr nextOutputImage; }; struct CellPngDecOpnParam { be_t selectChunk; }; struct CellPngDecExtInfo { be_t reserved; }; struct CellPngDecExtInParam { be_t bufferMode; // CellPngDecBufferMode be_t outputCounts; be_t spuMode; // CellPngDecSpuMode }; struct CellPngDecExtOutParam { be_t outputWidthByte; be_t outputHeight; }; // Callbacks for decoding partial streams using CellPngDecCbControlStream = s32(vm::ptr strmInfo, vm::ptr strmParam, vm::ptr cbCtrlStrmArg); using CellPngDecCbControlDisp = s32(vm::ptr dispInfo, vm::ptr dispParam, vm::ptr cbCtrlDispArg); struct CellPngDecCbCtrlStrm { vm::bptr cbCtrlStrmFunc; vm::bptr cbCtrlStrmArg; }; struct CellPngDecCbCtrlDisp { vm::bptr cbCtrlDispFunc; vm::bptr cbCtrlDispArg; }; // Custom structs struct PngHandle { vm::ptr malloc_; vm::ptr malloc_arg; vm::ptr free_; vm::ptr free_arg; }; // For reading from a buffer using libpng struct PngBuffer { // The cursor location and data pointer for reading from a buffer size_t cursor; size_t length; vm::bptr 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 cbDispInfo; vm::ptr cbDispParam; ppu_thread* ppuContext; u32 outputCounts = 0; u32 nextRow = 0; bool endOfFile = false; // Pixel packing value be_t packing; u32 passes; // PNG custom read function structure, for decoding from a buffer vm::ptr 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" HERE, 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) {} };