Merge branch 'jpeg' of https://github.com/CPkmn/ppsspp into CPkmn-jpeg

This commit is contained in:
Henrik Rydgard 2013-07-05 00:08:21 +02:00
commit d2b874436d
2 changed files with 146 additions and 32 deletions

View File

@ -284,11 +284,21 @@ template<u32 func(u32, int, u32, int, int)> void WrapU_UIUII() {
RETURN(retval);
}
template<int func(u32, int, u32, int, int)> void WrapI_UIUII() {
int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
RETURN(retval);
}
template<u32 func(u32, int, u32, int)> void WrapU_UIUI() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);
}
template<int func(u32, int, u32, int)> void WrapI_UIUI() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);
}
template<u32 func(u32, int, u32)> void WrapU_UIU() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
RETURN(retval);
@ -314,6 +324,16 @@ template<int func(u32, int, int, u32, u32)> void WrapI_UIIUU() {
RETURN(retval);
}
template<int func(u32, u32, int, int)> void WrapI_UUII() {
int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);
}
template<int func(u32, u32, int, int, int)> void WrapI_UUIII() {
int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
RETURN(retval);
}
template<void func(u32, int, int, int)> void WrapV_UIII() {
func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
}

View File

@ -17,83 +17,177 @@
#include "Core/HLE/HLE.h"
#include "Core/Reporting.h"
#include "Common.h"
#include "native/ext/cityhash/city.h"
#include "native/ext/jpge/jpgd.h"
int jpegWidth, jpegHeight;
//Uncomment if you want to dump JPEGs loaded through sceJpeg to a file
//#define JPEG_DEBUG
int sceJpegDecompressAllImage()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecompressAllImage");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecompressAllImage()");
return 0;
}
int sceJpegMJpegCsc()
int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegMJpegCsc");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth);
return 0;
}
int sceJpegDecodeMJpeg()
int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpeg");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
return 0;
}
int sceJpegDecodeMJpegYCbCrSuccessively()
int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpegYCbCrSuccessively");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpegYCbCrSuccessively(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode);
return 0;
}
int sceJpegDeleteMJpeg()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDeleteMJpeg");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDeleteMJpeg()");
return 0;
}
int sceJpegDecodeMJpegSuccessively()
int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpegSuccessively");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode);
return 0;
}
int sceJpegCsc()
int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegCsc");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo);
return 0;
}
int sceJpegFinishMJpeg()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegFinishMJpeg");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegFinishMJpeg()");
return 0;
}
int sceJpegGetOutputInfo()
int getYCbCrBufferSize(int w, int h)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegGetOutputInfo");
return 0;
// Return necessary buffer size for conversion: 12 bits per pixel
return ((w * h) >> 1) * 3;
}
int sceJpegDecodeMJpegYCbCr()
int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr, int dhtMode)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegDecodeMJpegYCbCr");
return 0;
ERROR_LOG_REPORT(HLE, "sceJpegGetOutputInfo(%i, %i, %i, %i)", jpegAddr, jpegSize, colourInfoAddr, dhtMode);
// Buffer to store info about the color space in use.
// - Bits 24 to 32 (Always empty): 0x00
// - Bits 16 to 24 (Color mode): 0x00 (Unknown), 0x01 (Greyscale) or 0x02 (YCbCr)
// - Bits 8 to 16 (Vertical chroma subsampling value): 0x00, 0x01 or 0x02
// - Bits 0 to 8 (Horizontal chroma subsampling value): 0x00, 0x01 or 0x02
if (Memory::IsValidAddress(colourInfoAddr))
Memory::Write_U32(0x00020202, colourInfoAddr);
int w = 0, h = 0, actual_components = 0;
if (!Memory::IsValidAddress(jpegAddr))
{
ERROR_LOG(HLE, "sceJpegGetOutputInfo: Bad JPEG address 0x%08x", jpegAddr);
return 0xC000;
}
else // Memory address is good
{
// But data may not be...so check it
u8 *buf = Memory::GetPointer(jpegAddr);
unsigned char *jpegBuf = jpgd::decompress_jpeg_image_from_memory(buf, jpegSize, &w, &h, &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, &w, &h, &actual_components, components);
}
if (jpegBuf == NULL)
{
ERROR_LOG(HLE, "sceJpegGetOutputInfo: Bad JPEG data");
return 0xC000;
}
}
#ifdef JPEG_DEBUG
char jpeg_fname[256];
u8 *jpegBuf = Memory::GetPointer(jpegAddr);
uint32 jpeg_cityhash = CityHash32((const char *)jpegBuf, jpegSize);
sprintf(jpeg_fname, "Jpeg\\%X.jpg", jpeg_cityhash);
FILE *wfp = fopen(jpeg_fname, "wb");
fwrite(jpegBuf, 1, jpegSize, wfp);
fclose(wfp);
#endif //JPEG_DEBUG
return getYCbCrBufferSize(w, h);
}
int getWidthHeight(int width, int height)
{
return (width << 16) | height;
}
int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode)
{
ERROR_LOG_REPORT(HLE, "sceJpegDecodeMJpegYCbCr(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode);
if (!Memory::IsValidAddress(jpegAddr))
{
return getWidthHeight(0, 0);
}
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);
// TODO: There's more...
return getWidthHeight(width, height);
}
int sceJpeg_9B36444C()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpeg_9B36444C");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpeg_9B36444C()");
return 0;
}
int sceJpegCreateMJpeg()
int sceJpegCreateMJpeg(int width, int height)
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegCreateMJpeg");
ERROR_LOG_REPORT(HLE, "sceJpegCreateMJpeg(%i, %i)", width, height);
jpegWidth = width;
jpegHeight = height;
return 0;
}
int sceJpegInitMJpeg()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegInitMJpeg");
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegInitMJpeg()");
return 0;
}
int sceJpeg_A06A75C4()
{
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpeg_A06A75C4()");
return 0;
}
@ -101,19 +195,19 @@ int sceJpegInitMJpeg()
const HLEFunction sceJpeg[] =
{
{0x0425B986, WrapI_V<sceJpegDecompressAllImage>, "sceJpegDecompressAllImage"},
{0x04B5AE02, WrapI_V<sceJpegMJpegCsc>, "sceJpegMJpegCsc"},
{0x04B93CEF, WrapI_V<sceJpegDecodeMJpeg>, "sceJpegDecodeMJpeg"},
{0x227662D7, WrapI_V<sceJpegDecodeMJpegYCbCrSuccessively>, "sceJpegDecodeMJpegYCbCrSuccessively"},
{0x04B5AE02, WrapI_UUII<sceJpegMJpegCsc>, "sceJpegMJpegCsc"},
{0x04B93CEF, WrapI_UIUI<sceJpegDecodeMJpeg>, "sceJpegDecodeMJpeg"},
{0x227662D7, WrapI_UIUII<sceJpegDecodeMJpegYCbCrSuccessively>, "sceJpegDecodeMJpegYCbCrSuccessively"},
{0x48B602B7, WrapI_V<sceJpegDeleteMJpeg>, "sceJpegDeleteMJpeg"},
{0x64B6F978, WrapI_V<sceJpegDecodeMJpegSuccessively>, "sceJpegDecodeMJpegSuccessively"},
{0x67F0ED84, WrapI_V<sceJpegCsc>, "sceJpegCsc"},
{0x64B6F978, WrapI_UIUI<sceJpegDecodeMJpegSuccessively>, "sceJpegDecodeMJpegSuccessively"},
{0x67F0ED84, WrapI_UUIII<sceJpegCsc>, "sceJpegCsc"},
{0x7D2F3D7F, WrapI_V<sceJpegFinishMJpeg>, "sceJpegFinishMJpeg"},
{0x8F2BB012, WrapI_V<sceJpegGetOutputInfo>, "sceJpegGetOutputInfo"},
{0x91EED83C, WrapI_V<sceJpegDecodeMJpegYCbCr>, "sceJpegDecodeMJpegYCbCr"},
{0x8F2BB012, WrapI_UIUI<sceJpegGetOutputInfo>, "sceJpegGetOutputInfo"},
{0x91EED83C, WrapI_UIUII<sceJpegDecodeMJpegYCbCr>, "sceJpegDecodeMJpegYCbCr"},
{0x9B36444C, WrapI_V<sceJpeg_9B36444C>, "sceJpeg_9B36444C"},
{0x9D47469C, WrapI_V<sceJpegCreateMJpeg>, "sceJpegCreateMJpeg"},
{0x9D47469C, WrapI_II<sceJpegCreateMJpeg>, "sceJpegCreateMJpeg"},
{0xAC9E70E6, WrapI_V<sceJpegInitMJpeg>, "sceJpegInitMJpeg"},
{0xa06a75c4, 0, "sceJpeg_A06A75C4"},
{0xa06a75c4, WrapI_V<sceJpeg_A06A75C4>, "sceJpeg_A06A75C4"},
};
void Register_sceJpeg()