mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Update sceJpeg.cpp
This commit is contained in:
parent
e2024674a4
commit
e1d3b69a78
1 changed files with 105 additions and 12 deletions
|
@ -17,7 +17,16 @@
|
|||
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Common.h"
|
||||
#include "native\ext\cityhash\city.h"
|
||||
|
||||
// http://keyj.emphy.de/nanojpeg/
|
||||
#include "native\ext\njpeg\nanojpeg.h"
|
||||
|
||||
int jpegWidth, jpegHeight;
|
||||
|
||||
//Uncomment if you want to dump JPEGs loaded through sceJpeg to a file
|
||||
//#define JPEG_DEBUG
|
||||
|
||||
int sceJpegDecompressAllImage()
|
||||
{
|
||||
|
@ -64,19 +73,90 @@ int sceJpegCsc()
|
|||
int sceJpegFinishMJpeg()
|
||||
{
|
||||
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegFinishMJpeg");
|
||||
|
||||
njDone();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceJpegGetOutputInfo()
|
||||
int getYCbCrBufferSize()
|
||||
{
|
||||
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpegGetOutputInfo");
|
||||
return 0;
|
||||
int w = njGetWidth();
|
||||
int h = njGetHeight();
|
||||
// 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);
|
||||
|
||||
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);
|
||||
int result = njDecode(buf, jpegSize);
|
||||
if (result != 0) // (0 = success)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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 *jpegBuf = Memory::GetPointer(jpegAddr);
|
||||
int result = njDecode(jpegBuf, jpegSize);
|
||||
|
||||
if (result != 0) // (0 = success)
|
||||
{
|
||||
return getWidthHeight(0, 0);
|
||||
}
|
||||
|
||||
int width = njGetWidth();
|
||||
int height = njGetHeight();
|
||||
|
||||
// TODO: There's more...
|
||||
|
||||
return getWidthHeight(width, height);
|
||||
}
|
||||
|
||||
int sceJpeg_9B36444C()
|
||||
|
@ -85,15 +165,28 @@ int 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");
|
||||
|
||||
njInit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceJpeg_A06A75C4()
|
||||
{
|
||||
ERROR_LOG_REPORT(HLE, "UNIMPL sceJpeg_A06A75C4");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -108,12 +201,12 @@ const HLEFunction sceJpeg[] =
|
|||
{0x64B6F978, WrapI_V<sceJpegDecodeMJpegSuccessively>, "sceJpegDecodeMJpegSuccessively"},
|
||||
{0x67F0ED84, WrapI_V<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()
|
||||
|
|
Loading…
Add table
Reference in a new issue