1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-24 19:52:37 +01:00

cellPngDec Module Added

Implemented 'cellPngDec', using 'sys_fs' to access the files and the
'lodepng' library to decode PNG buffers to Raw-pixel buffers that can be
used as textures.
This commit is contained in:
Alexandro Sánchez Bach 2013-09-08 10:45:10 +02:00
parent 43e0c84f64
commit 3123432dcc
6 changed files with 8217 additions and 2 deletions

6267
lodepng/lodepng.cpp Normal file

File diff suppressed because it is too large Load Diff

1705
lodepng/lodepng.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
ProjectSection(ProjectDependencies) = postProject
{3111D679-7796-23C4-BA0C-271F1145DA24} = {3111D679-7796-23C4-BA0C-271F1145DA24}
@ -57,6 +57,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "wxWidgets\build\msw\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\wx_xrc.vcxproj", "{8BECCA95-C7D7-CFF8-FDB1-4950E9F8E8E6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lodepng", "lodepng", "{48675C2D-D949-400D-8758-E22FB6DF3D58}"
ProjectSection(SolutionItems) = preProject
lodepng\lodepng.cpp = lodepng\lodepng.cpp
lodepng\lodepng.h = lodepng\lodepng.h
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32

View File

@ -0,0 +1,233 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
#include "lodepng/lodepng.h"
#include "lodepng/lodepng.cpp"
void cellPngDec_init();
Module cellPngDec(0x0018, cellPngDec_init);
//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,
};
struct CellPngDecInfo
{
u32 imageWidth;
u32 imageHeight;
u32 numComponents;
u32 colorSpace; // CellPngDecColorSpace
u32 bitDepth;
u32 interlaceMethod; // CellPngDecInterlaceMode
u32 chunkInformation;
};
struct CellPngDecSrc
{
u32 srcSelect; // CellPngDecStreamSrcSel
u32 fileName_addr; // const char*
u64 fileOffset; // int64_t
u32 fileSize;
u32 streamPtr;
u32 streamSize;
u32 spuThreadEnable; // CellPngDecSpuThreadEna
};
CellPngDecInfo current_info;
CellPngDecSrc current_src;
int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
{
UNIMPLEMENTED_FUNC(cellPngDec);
return CELL_OK;
}
int cellPngDecDestroy(u32 mainHandle)
{
UNIMPLEMENTED_FUNC(cellPngDec);
return CELL_OK;
}
int cellPngDecOpen(u32 mainHandle, u32 subHandle_addr, u32 src_addr, u32 openInfo)
{
//current_src.srcSelect = Memory.Read32(src_addr);
current_src.fileName_addr = Memory.Read32(src_addr+4);
//current_src.fileOffset = Memory.Read32(src_addr+8);
//current_src.fileSize = Memory.Read32(src_addr+12);
//current_src.streamPtr = Memory.Read32(src_addr+16);
//current_src.streamSize = Memory.Read32(src_addr+20);
//current_src.spuThreadEnable = Memory.Read32(src_addr+24);
u32& fd_addr = subHandle_addr; // Set file descriptor as sub handler of the decoder
int ret = cellFsOpen(current_src.fileName_addr, 0, fd_addr, NULL, 0);
if(ret != 0) return CELL_PNGDEC_ERROR_OPEN_FILE;
return CELL_OK;
}
int cellPngDecClose(u32 mainHandle, u32 subHandle)
{
u32& fd = subHandle;
cellFsClose(fd);
return CELL_OK;
}
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, u32 info_addr)
{
u32& fd = subHandle;
//Check size of file
u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct
cellFsFstat(fd, sb_addr);
u64 fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size
if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header
//Write the header to buffer
u32 buffer = Memory.Alloc(34,1); // Alloc buffer for PNG header
u32 pos_addr = Memory.Alloc(8,1);
cellFsLseek(fd, 0, 0, pos_addr);
cellFsRead(fd, buffer, 34, NULL);
if (Memory.Read32(buffer) != 0x89504E47 || Memory.Read32(buffer+4) != 0x0D0A1A0A)
return CELL_PNGDEC_ERROR_HEADER; // Error: The first 8 bytes are not a valid PNG signature
if (Memory.Read32(buffer+12) != 0x49484452)
return CELL_PNGDEC_ERROR_HEADER; // Error: The PNG file does not start with an IHDR chunk
current_info.imageWidth = Memory.Read32(buffer+16);
current_info.imageHeight = Memory.Read32(buffer+20);
current_info.numComponents = 0; // Unimplemented
current_info.colorSpace = Memory.Read8(buffer+25);
current_info.bitDepth = Memory.Read8(buffer+24);
current_info.interlaceMethod = Memory.Read8(buffer+28);
current_info.chunkInformation = 0; // Unimplemented
mem_class_t info(info_addr);
info += current_info.imageWidth;
info += current_info.imageHeight;
info += current_info.numComponents;
info += current_info.colorSpace;
info += current_info.bitDepth;
info += current_info.interlaceMethod;
info += current_info.chunkInformation;
Memory.Free(sb_addr);
Memory.Free(pos_addr);
Memory.Free(buffer);
return CELL_OK;
}
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, u32 data_addr, u32 dataCtrlParam_addr, u32 dataOutInfo_addr)
{
u32& fd = subHandle;
//Check size of file
u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct
cellFsFstat(fd, sb_addr);
u64 fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size
if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header
//Write the header to buffer
u32 buffer = Memory.Alloc(34,1); // Alloc buffer for PNG header
u32 pos_addr = Memory.Alloc(8,1);
cellFsLseek(fd, 0, 0, pos_addr);
cellFsRead(fd, buffer, 34, NULL);
if (Memory.Read32(buffer) != 0x89504E47 || Memory.Read32(buffer+4) != 0x0D0A1A0A)
return CELL_PNGDEC_ERROR_HEADER; // Error: The first 8 bytes are not a valid PNG signature
if (Memory.Read32(buffer+12) != 0x49484452)
return CELL_PNGDEC_ERROR_HEADER; // Error: The PNG file does not start with an IHDR chunk
current_info.imageWidth = Memory.Read32(buffer+16);
current_info.imageHeight = Memory.Read32(buffer+20);
Memory.Free(buffer);
//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
buffer = Memory.Alloc(fileSize,1);
cellFsLseek(fd,0,0,pos_addr);
cellFsRead(fd, buffer, fileSize, NULL);
std::vector<unsigned char> png; // PNG buffer
std::vector<unsigned char> image; // Raw buffer
//Load contents in png buffer
png.resize(size_t(fileSize));
for(u32 i = 0; i < fileSize; i++){
png[i] = Memory.Read8(buffer+i);
}
//Decode
lodepng::decode(image, current_info.imageWidth, current_info.imageHeight, png);
u32 image_size = image.size();
for(u32 i = 0; i < image_size; i+=4){
Memory.Write8(data_addr+i+0, image[i+3]);
Memory.Write8(data_addr+i+1, image[i+0]);
Memory.Write8(data_addr+i+2, image[i+1]);
Memory.Write8(data_addr+i+3, image[i+2]);
}
Memory.Free(sb_addr);
Memory.Free(pos_addr);
Memory.Free(buffer);
return CELL_OK;
}
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, u32 inParam, u32 outParam)
{
UNIMPLEMENTED_FUNC(cellPngDec);
return CELL_OK;
}
void cellPngDec_init()
{
cellPngDec.AddFunc(0x157d30c5, cellPngDecCreate);
cellPngDec.AddFunc(0x820dae1a, cellPngDecDestroy);
cellPngDec.AddFunc(0xd2bc5bfd, cellPngDecOpen);
cellPngDec.AddFunc(0x5b3d1ff1, cellPngDecClose);
cellPngDec.AddFunc(0x9ccdcc95, cellPngDecReadHeader);
cellPngDec.AddFunc(0x2310f155, cellPngDecDecodeData);
cellPngDec.AddFunc(0xe97c9bd4, cellPngDecSetParameter);
/*cellPngDec.AddFunc(0x48436b2d, cellPngDecExtCreate);
cellPngDec.AddFunc(0x0c515302, cellPngDecExtOpen);
cellPngDec.AddFunc(0x8b33f863, cellPngDecExtReadHeader);
cellPngDec.AddFunc(0x726fc1d0, cellPngDecExtDecodeData);
cellPngDec.AddFunc(0x9e9d7d42, cellPngDecExtSetParameter);
cellPngDec.AddFunc(0x7585a275, cellPngDecGetbKGD);
cellPngDec.AddFunc(0x7a062d26, cellPngDecGetcHRM);
cellPngDec.AddFunc(0xb153629c, cellPngDecGetgAMA);
cellPngDec.AddFunc(0xb905ebb7, cellPngDecGethIST);
cellPngDec.AddFunc(0xf44b6c30, cellPngDecGetiCCP);
cellPngDec.AddFunc(0x27c921b5, cellPngDecGetoFFs);
cellPngDec.AddFunc(0xb4fe75e1, cellPngDecGetpCAL);
cellPngDec.AddFunc(0x3d50016a, cellPngDecGetpHYs);
cellPngDec.AddFunc(0x30cb334a, cellPngDecGetsBIT);
cellPngDec.AddFunc(0xc41e1198, cellPngDecGetsCAL);
cellPngDec.AddFunc(0xa5cdf57e, cellPngDecGetsPLT);
cellPngDec.AddFunc(0xe4416e82, cellPngDecGetsRGB);
cellPngDec.AddFunc(0x35a6846c, cellPngDecGettIME);
cellPngDec.AddFunc(0xb96fb26e, cellPngDecGettRNS);
cellPngDec.AddFunc(0xe163977f, cellPngDecGetPLTE);
cellPngDec.AddFunc(0x609ec7d5, cellPngDecUnknownChunks);
cellPngDec.AddFunc(0xb40ca175, cellPngDecGetTextChunk);*/
}

View File

@ -245,6 +245,7 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellGcmSys.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSysutil.cpp" />

View File

@ -286,6 +286,9 @@
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />