mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Implement sceJpegDecodeMJpeg & sceJpegDecodeMJpegSuccessively
This commit is contained in:
parent
82df6af4c6
commit
0cdd55f450
1 changed files with 74 additions and 42 deletions
|
@ -50,6 +50,10 @@ void __JpegDoState(PointerWrap &p) {
|
||||||
p.Do(mjpegHeight);
|
p.Do(mjpegHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getWidthHeight(int width, int height) {
|
||||||
|
return (width << 16) | height;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 convertYCbCrToABGR (int y, int cb, int cr) {
|
static u32 convertYCbCrToABGR (int y, int cb, int cr) {
|
||||||
//see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information.
|
//see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information.
|
||||||
cb = cb - 128;
|
cb = cb - 128;
|
||||||
|
@ -104,34 +108,76 @@ static void __JpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferW
|
||||||
imageBuffer += skipEndOfLine;
|
imageBuffer += skipEndOfLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth)
|
|
||||||
{
|
static int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth) {
|
||||||
__JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth);
|
__JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth);
|
||||||
|
|
||||||
DEBUG_LOG(ME, "sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth);
|
DEBUG_LOG(ME, "sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode)
|
static u32 convertARGBtoABGR(u32 argb) {
|
||||||
{
|
return ((argb & 0xFF00FF00)) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
|
||||||
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
|
}
|
||||||
|
|
||||||
|
static int __DecodeJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr) {
|
||||||
|
u8 *buf = Memory::GetPointer(jpegAddr);
|
||||||
|
int width, height, actual_components;
|
||||||
|
unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &width, &height, &actual_components, 3);
|
||||||
|
|
||||||
|
if (actual_components != 3) {
|
||||||
|
// The assumption that the image was RGB was wrong...
|
||||||
|
// Try again.
|
||||||
|
int components = actual_components;
|
||||||
|
jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &width, &height, &actual_components, components);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jpegBuf == NULL) {
|
||||||
|
return getWidthHeight(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actual_components == 3) {
|
||||||
|
u24_be *imageBuffer = (u24_be*)jpegBuf;
|
||||||
|
u32 *abgr = (u32*)Memory::GetPointer(imageAddr);
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
abgr[x] = convertARGBtoABGR(imageBuffer[x]);
|
||||||
|
}
|
||||||
|
imageBuffer += width;
|
||||||
|
abgr += width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(jpegBuf);
|
||||||
|
return getWidthHeight(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) {
|
||||||
|
if (!Memory::IsValidAddress(jpegAddr)) {
|
||||||
|
ERROR_LOG(ME, "sceJpegDecodeMJpeg: Bad JPEG address 0x%08x", jpegAddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDeleteMJpeg()
|
DEBUG_LOG(ME, "sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
|
||||||
{
|
return __DecodeJpeg(jpegAddr, jpegSize, imageAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sceJpegDeleteMJpeg() {
|
||||||
WARN_LOG(ME, "sceJpegDeleteMJpeg()");
|
WARN_LOG(ME, "sceJpegDeleteMJpeg()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode)
|
static int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) {
|
||||||
{
|
if (!Memory::IsValidAddress(jpegAddr)) {
|
||||||
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
|
ERROR_LOG(ME, "sceJpegDecodeMJpegSuccessively: Bad JPEG address 0x%08x", jpegAddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo)
|
DEBUG_LOG(ME, "sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
|
||||||
{
|
return __DecodeJpeg(jpegAddr, jpegSize, imageAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo) {
|
||||||
if (bufferWidth < 0 || widthHeight < 0){
|
if (bufferWidth < 0 || widthHeight < 0){
|
||||||
WARN_LOG(ME, "sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo);
|
WARN_LOG(ME, "sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo);
|
||||||
return ERROR_JPEG_INVALID_VALUE;
|
return ERROR_JPEG_INVALID_VALUE;
|
||||||
|
@ -143,8 +189,7 @@ static int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferW
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegFinishMJpeg()
|
static int sceJpegFinishMJpeg() {
|
||||||
{
|
|
||||||
WARN_LOG(ME, "sceJpegFinishMJpeg()");
|
WARN_LOG(ME, "sceJpegFinishMJpeg()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -184,23 +229,22 @@ static int __JpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr) {
|
||||||
|
|
||||||
#ifdef JPEG_DEBUG
|
#ifdef JPEG_DEBUG
|
||||||
char jpeg_fname[256];
|
char jpeg_fname[256];
|
||||||
u8 *jpegBuf = Memory::GetPointer(jpegAddr);
|
u8 *jpegDumpBuf = Memory::GetPointer(jpegAddr);
|
||||||
uint32 jpeg_xxhash = XXH32((const char *)jpegBuf, jpegSize, 0xC0108888);
|
u32 jpeg_xxhash = XXH32((const char *)jpegBuf, jpegSize, 0xC0108888);
|
||||||
sprintf(jpeg_fname, "Jpeg\\%X.jpg", jpeg_xxhash);
|
sprintf(jpeg_fname, "Jpeg\\%X.jpg", jpeg_xxhash);
|
||||||
FILE *wfp = fopen(jpeg_fname, "wb");
|
FILE *wfp = fopen(jpeg_fname, "wb");
|
||||||
if (!wfp) {
|
if (!wfp) {
|
||||||
_wmkdir(L"Jpeg\\");
|
_wmkdir(L"Jpeg\\");
|
||||||
wfp = fopen(jpeg_fname, "wb");
|
wfp = fopen(jpeg_fname, "wb");
|
||||||
}
|
}
|
||||||
fwrite(jpegBuf, 1, jpegSize, wfp);
|
fwrite(jpegDumpBuf, 1, jpegSize, wfp);
|
||||||
fclose(wfp);
|
fclose(wfp);
|
||||||
#endif //JPEG_DEBUG
|
#endif //JPEG_DEBUG
|
||||||
|
|
||||||
return getYCbCrBufferSize(width, height);
|
return getYCbCrBufferSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr, int dhtMode)
|
static int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr, int dhtMode) {
|
||||||
{
|
|
||||||
if (!Memory::IsValidAddress(jpegAddr)) {
|
if (!Memory::IsValidAddress(jpegAddr)) {
|
||||||
ERROR_LOG(ME, "sceJpegGetOutputInfo: Bad JPEG address 0x%08x", jpegAddr);
|
ERROR_LOG(ME, "sceJpegGetOutputInfo: Bad JPEG address 0x%08x", jpegAddr);
|
||||||
return getYCbCrBufferSize(0, 0);
|
return getYCbCrBufferSize(0, 0);
|
||||||
|
@ -210,10 +254,6 @@ static int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr,
|
||||||
return __JpegGetOutputInfo(jpegAddr, jpegSize, colourInfoAddr);
|
return __JpegGetOutputInfo(jpegAddr, jpegSize, colourInfoAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getWidthHeight(int width, int height) {
|
|
||||||
return (width << 16) | height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 convertRGBToYCbCr(u32 rgb) {
|
static u32 convertRGBToYCbCr(u32 rgb) {
|
||||||
//see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information.
|
//see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information.
|
||||||
u8 r = (rgb >> 16) & 0xFF;
|
u8 r = (rgb >> 16) & 0xFF;
|
||||||
|
@ -262,7 +302,7 @@ static int __JpegConvertRGBToYCbCr (const void *data, u32 bufferOutputAddr, int
|
||||||
imageBuffer += width;
|
imageBuffer += width;
|
||||||
Y += width ;
|
Y += width ;
|
||||||
}
|
}
|
||||||
return (width << 16) | height;
|
return getWidthHeight(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __JpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr) {
|
static int __JpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr) {
|
||||||
|
@ -292,8 +332,7 @@ static int __JpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr) {
|
||||||
return getWidthHeight(width, height);
|
return getWidthHeight(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode)
|
static int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode) {
|
||||||
{
|
|
||||||
if (!Memory::IsValidAddress(jpegAddr)) {
|
if (!Memory::IsValidAddress(jpegAddr)) {
|
||||||
ERROR_LOG(ME, "sceJpegDecodeMJpegYCbCr: Bad JPEG address 0x%08x", jpegAddr);
|
ERROR_LOG(ME, "sceJpegDecodeMJpegYCbCr: Bad JPEG address 0x%08x", jpegAddr);
|
||||||
return getWidthHeight(0, 0);
|
return getWidthHeight(0, 0);
|
||||||
|
@ -303,8 +342,7 @@ static int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, in
|
||||||
return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr);
|
return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode)
|
static int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode) {
|
||||||
{
|
|
||||||
if (!Memory::IsValidAddress(jpegAddr)) {
|
if (!Memory::IsValidAddress(jpegAddr)) {
|
||||||
ERROR_LOG(ME, "sceJpegDecodeMJpegYCbCrSuccessively: Bad JPEG address 0x%08x", jpegAddr);
|
ERROR_LOG(ME, "sceJpegDecodeMJpegYCbCrSuccessively: Bad JPEG address 0x%08x", jpegAddr);
|
||||||
return getWidthHeight(0, 0);
|
return getWidthHeight(0, 0);
|
||||||
|
@ -315,14 +353,12 @@ static int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 y
|
||||||
return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr);
|
return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpeg_9B36444C()
|
static int sceJpeg_9B36444C() {
|
||||||
{
|
|
||||||
ERROR_LOG_REPORT(ME, "UNIMPL sceJpeg_9B36444C()");
|
ERROR_LOG_REPORT(ME, "UNIMPL sceJpeg_9B36444C()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegCreateMJpeg(int width, int height)
|
static int sceJpegCreateMJpeg(int width, int height) {
|
||||||
{
|
|
||||||
mjpegWidth = width;
|
mjpegWidth = width;
|
||||||
mjpegHeight = height;
|
mjpegHeight = height;
|
||||||
|
|
||||||
|
@ -330,20 +366,17 @@ static int sceJpegCreateMJpeg(int width, int height)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegInitMJpeg()
|
static int sceJpegInitMJpeg() {
|
||||||
{
|
|
||||||
WARN_LOG(ME, "sceJpegInitMJpeg()");
|
WARN_LOG(ME, "sceJpegInitMJpeg()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegMJpegCscWithColorOption()
|
static int sceJpegMJpegCscWithColorOption() {
|
||||||
{
|
|
||||||
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegMJpegCscWithColorOption()");
|
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegMJpegCscWithColorOption()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sceJpegDecompressAllImage()
|
static int sceJpegDecompressAllImage() {
|
||||||
{
|
|
||||||
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecompressAllImage()");
|
ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecompressAllImage()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +399,6 @@ const HLEFunction sceJpeg[] =
|
||||||
{0XA06A75C4, &WrapI_V<sceJpegMJpegCscWithColorOption>, "sceJpegMJpegCscWithColorOption", 'i', "" },
|
{0XA06A75C4, &WrapI_V<sceJpegMJpegCscWithColorOption>, "sceJpegMJpegCscWithColorOption", 'i', "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
void Register_sceJpeg()
|
void Register_sceJpeg() {
|
||||||
{
|
|
||||||
RegisterModule("sceJpeg", ARRAY_SIZE(sceJpeg), sceJpeg);
|
RegisterModule("sceJpeg", ARRAY_SIZE(sceJpeg), sceJpeg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue