mirror of https://github.com/RPCS3/rpcs3.git
Fixed memory exception on cellJpgDec & cellGifDec
* Added support for CELL_JPGDEC_BUFFER and CELL_GIFDEC_BUFFER.
This commit is contained in:
parent
6651795f6d
commit
fe46a45915
|
@ -29,39 +29,21 @@ int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_ptr_t<CellGifDec
|
||||||
{
|
{
|
||||||
if (!subHandle.IsGood() || !src.IsGood())
|
if (!subHandle.IsGood() || !src.IsGood())
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
return CELL_GIFDEC_ERROR_ARG;
|
||||||
/*
|
|
||||||
vfsStream* stream;
|
|
||||||
|
|
||||||
switch(src->srcSelect)
|
|
||||||
{
|
|
||||||
case CELL_GIFDEC_FILE:
|
|
||||||
stream = Emu.GetVFS().Open(src->fileName.GetString(), vfsRead);
|
|
||||||
stream->Seek(src->fileOffset);
|
|
||||||
src->fileSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GIFDEC_BUFFER:
|
|
||||||
if(src->streamSize < 5)
|
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
|
||||||
|
|
||||||
stream = new vfsStreamMemory(src->streamPtr.GetAddr(), src->streamSize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!stream->IsOpened())
|
|
||||||
{
|
|
||||||
return CELL_GIFDEC_ERROR_OPEN_FILE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
||||||
|
current_subHandle->fd = 0;
|
||||||
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
switch(src->srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
|
current_subHandle->fileSize = src->streamSize.ToLE();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_GIFDEC_FILE):
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
MemoryAllocator<be_t<u32>> fd;
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(src->fileName, 0, fd, 0, 0);
|
int ret = cellFsOpen(src->fileName, 0, fd.GetAddr(), 0, 0);
|
||||||
current_subHandle->fd = fd->ToLE();
|
current_subHandle->fd = fd->ToLE();
|
||||||
if (ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
if (ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
||||||
|
|
||||||
|
@ -70,8 +52,10 @@ int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_ptr_t<CellGifDec
|
||||||
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
||||||
if (ret != CELL_OK) return ret;
|
if (ret != CELL_OK) return ret;
|
||||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellGifDecSubHandle struct.
|
||||||
subHandle = cellGifDec->GetNewId(current_subHandle);
|
subHandle = cellGifDec->GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -94,8 +78,20 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellGifDecInfo
|
||||||
MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header
|
MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header
|
||||||
MemoryAllocator<be_t<u64>> pos, nread;
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
|
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize())) {
|
||||||
|
cellGifDec->Error("cellGifDecReadHeader() failed ()");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_GIFDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
|
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
|
||||||
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
|
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
|
||||||
|
@ -166,8 +162,21 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
//Copy the GIF file to a buffer
|
//Copy the GIF file to a buffer
|
||||||
MemoryAllocator<unsigned char> gif(fileSize);
|
MemoryAllocator<unsigned char> gif(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
|
||||||
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(gif.GetAddr(), subHandle_data->src.streamPtr.ToLE(), gif.GetSize())) {
|
||||||
|
cellGifDec->Error("cellGifDecDecodeData() failed (I)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_GIFDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread);
|
cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
|
|
|
@ -105,10 +105,12 @@ struct CellGifDecDataCtrlParam
|
||||||
be_t<u64> outputBytesPerLine;
|
be_t<u64> outputBytesPerLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecSubHandle //Custom struct
|
//Custom structs
|
||||||
|
struct CellGifDecSubHandle
|
||||||
{
|
{
|
||||||
u32 fd;
|
u32 fd;
|
||||||
u64 fileSize;
|
u64 fileSize;
|
||||||
CellGifDecInfo info;
|
CellGifDecInfo info;
|
||||||
CellGifDecOutParam outParam;
|
CellGifDecOutParam outParam;
|
||||||
|
CellGifDecSrc src;
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,14 +33,24 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellJpgDecSrc> s
|
||||||
cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)",
|
cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)",
|
||||||
mainHandle, subHandle.GetAddr(), src.GetAddr(), openInfo);
|
mainHandle, subHandle.GetAddr(), src.GetAddr(), openInfo);
|
||||||
|
|
||||||
if (!subHandle.IsGood() || !src.IsGood() || !openInfo.IsGood())
|
if (!subHandle.IsGood() || !src.IsGood())
|
||||||
return CELL_JPGDEC_ERROR_ARG;
|
return CELL_JPGDEC_ERROR_ARG;
|
||||||
|
|
||||||
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
||||||
|
|
||||||
|
current_subHandle->fd = 0;
|
||||||
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
switch(src->srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
|
current_subHandle->fileSize = src->streamSize.ToLE();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_JPGDEC_FILE):
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
MemoryAllocator<be_t<u32>> fd;
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(src->fileName, 0, fd, 0, 0);
|
int ret = cellFsOpen(src->fileName, 0, fd.GetAddr(), 0, 0);
|
||||||
current_subHandle->fd = fd->ToLE();
|
current_subHandle->fd = fd->ToLE();
|
||||||
if (ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
if (ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
||||||
|
|
||||||
|
@ -49,8 +59,10 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellJpgDecSrc> s
|
||||||
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
||||||
if (ret != CELL_OK) return ret;
|
if (ret != CELL_OK) return ret;
|
||||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellJpgDecSubHandle struct.
|
||||||
subHandle = cellJpgDec->GetNewId(current_subHandle);
|
subHandle = cellJpgDec->GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -83,12 +95,24 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellJpgDecInfo
|
||||||
const u64& fileSize = subHandle_data->fileSize;
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||||
|
|
||||||
//Copy the JPG file to a buffer
|
//Write the header to buffer
|
||||||
MemoryAllocator<u8> buffer(fileSize);
|
MemoryAllocator<u8> buffer(fileSize);
|
||||||
MemoryAllocator<be_t<u64>> pos, nread;
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
|
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize())) {
|
||||||
|
cellJpgDec->Error("cellJpgDecReadHeader() failed ()");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_JPGDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
||||||
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
|
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
|
||||||
|
@ -146,8 +170,21 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
//Copy the JPG file to a buffer
|
//Copy the JPG file to a buffer
|
||||||
MemoryAllocator<unsigned char> jpg(fileSize);
|
MemoryAllocator<unsigned char> jpg(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
|
||||||
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(jpg.GetAddr(), subHandle_data->src.streamPtr.ToLE(), jpg.GetSize())) {
|
||||||
|
cellJpgDec->Error("cellJpgDecDecodeData() failed (I)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_JPGDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread);
|
cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
|
|
|
@ -27,6 +27,12 @@ enum CellJpgDecColorSpace
|
||||||
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellJpgDecStreamSrcSel
|
||||||
|
{
|
||||||
|
CELL_JPGDEC_FILE = 0,
|
||||||
|
CELL_JPGDEC_BUFFER = 1,
|
||||||
|
};
|
||||||
|
|
||||||
enum CellJpgDecDecodeStatus
|
enum CellJpgDecDecodeStatus
|
||||||
{
|
{
|
||||||
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||||
|
@ -92,10 +98,12 @@ struct CellJpgDecDataOutInfo
|
||||||
be_t<u32> status;
|
be_t<u32> status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecSubHandle //Custom struct
|
// Custom structs
|
||||||
|
struct CellJpgDecSubHandle
|
||||||
{
|
{
|
||||||
u32 fd;
|
u32 fd;
|
||||||
u64 fileSize;
|
u64 fileSize;
|
||||||
CellJpgDecInfo info;
|
CellJpgDecInfo info;
|
||||||
CellJpgDecOutParam outParam;
|
CellJpgDecOutParam outParam;
|
||||||
|
CellJpgDecSrc src;
|
||||||
};
|
};
|
|
@ -60,7 +60,6 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellPngDecSrc> s
|
||||||
return CELL_PNGDEC_ERROR_ARG;
|
return CELL_PNGDEC_ERROR_ARG;
|
||||||
|
|
||||||
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
||||||
|
|
||||||
current_subHandle->fd = 0;
|
current_subHandle->fd = 0;
|
||||||
current_subHandle->src = *src;
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
@ -212,16 +211,16 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
MemoryAllocator<unsigned char> png(fileSize);
|
MemoryAllocator<unsigned char> png(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
|
|
||||||
switch(subHandle_data->src.srcSelect.ToLE())
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
{
|
|
||||||
case CELL_PNGDEC_BUFFER:
|
|
||||||
if (!Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize()))
|
|
||||||
{
|
{
|
||||||
|
case se32(CELL_PNGDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize())) {
|
||||||
cellPngDec->Error("cellPngDecDecodeData() failed (I)");
|
cellPngDec->Error("cellPngDecDecodeData() failed (I)");
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CELL_PNGDEC_FILE:
|
|
||||||
|
case se32(CELL_PNGDEC_FILE):
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, png.GetAddr(), png.GetSize(), nread.GetAddr());
|
cellFsRead(fd, png.GetAddr(), png.GetSize(), nread.GetAddr());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,6 +49,7 @@ enum CellPngDecOutputMode
|
||||||
CELL_PNGDEC_BOTTOM_TO_TOP = 1,
|
CELL_PNGDEC_BOTTOM_TO_TOP = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Structs
|
// Structs
|
||||||
struct CellPngDecDataOutInfo
|
struct CellPngDecDataOutInfo
|
||||||
{
|
{
|
||||||
|
@ -108,23 +109,6 @@ struct CellPngDecOutParam
|
||||||
be_t<u32> useMemorySpace;
|
be_t<u32> useMemorySpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Custom structs
|
|
||||||
struct CellPngDecSubHandle
|
|
||||||
{
|
|
||||||
be_t<u32> fd;
|
|
||||||
be_t<u64> fileSize;
|
|
||||||
CellPngDecInfo info;
|
|
||||||
CellPngDecOutParam outParam;
|
|
||||||
CellPngDecSrc src;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellPngDecMainHandle
|
|
||||||
{
|
|
||||||
be_t<u32> mainHandle;
|
|
||||||
be_t<u32> threadInParam;
|
|
||||||
be_t<u32> threadOutParam;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellPngDecStrmInfo
|
struct CellPngDecStrmInfo
|
||||||
{
|
{
|
||||||
be_t<u32> decodedStrmSize;
|
be_t<u32> decodedStrmSize;
|
||||||
|
@ -175,3 +159,21 @@ struct CellPngDecOpnParam
|
||||||
{
|
{
|
||||||
be_t<u32> selectChunk;
|
be_t<u32> selectChunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Custom structs
|
||||||
|
struct CellPngDecSubHandle
|
||||||
|
{
|
||||||
|
be_t<u32> fd;
|
||||||
|
be_t<u64> fileSize;
|
||||||
|
CellPngDecInfo info;
|
||||||
|
CellPngDecOutParam outParam;
|
||||||
|
CellPngDecSrc src;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellPngDecMainHandle
|
||||||
|
{
|
||||||
|
be_t<u32> mainHandle;
|
||||||
|
be_t<u32> threadInParam;
|
||||||
|
be_t<u32> threadOutParam;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue