From a7d3b8f71060ba9a734ebaaebb2203cfda7b1627 Mon Sep 17 00:00:00 2001 From: shenweip Date: Fri, 4 Oct 2013 23:33:03 +0800 Subject: [PATCH 1/6] Add a new type u24. --- Common/CommonTypes.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Common/CommonTypes.h b/Common/CommonTypes.h index 59d581426..1155d4bdc 100644 --- a/Common/CommonTypes.h +++ b/Common/CommonTypes.h @@ -28,6 +28,14 @@ #endif #endif +typedef struct u24 { + unsigned char value[3]; + + operator unsigned int(){ + return 0x00000000 | (value[0] << 16) | (value[1] << 8) | (value[2] << 0); + } +} u24; + #ifdef _WIN32 typedef unsigned __int8 u8; From b1f81999fadaf5c44b2c7686475b5c41cdf72ecf Mon Sep 17 00:00:00 2001 From: shenweip Date: Sat, 5 Oct 2013 00:04:51 +0800 Subject: [PATCH 2/6] Fix someting wrong. --- Core/HLE/sceJpeg.cpp | 6 +++++- Core/HLE/sceMpeg.cpp | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index 50a30e577..f2158340d 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -52,7 +52,7 @@ u32 convertYCbCrToABGR (int y, int cb, int cr) { if (g > 0xFF) g = 0xFF; if(g < 0) g = 0; if (b > 0xFF) b = 0xFF; if(b < 0) b = 0; - return 0xFF000000 | (r << 16) | (g << 8) | (b << 0); + return 0xFF000000 | (b << 16) | (g << 8) | (r << 0); } //Uncomment if you want to dump JPEGs loaded through sceJpeg to a file @@ -192,6 +192,10 @@ int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr, int dht uint32 jpeg_cityhash = CityHash32((const char *)jpegBuf, jpegSize); sprintf(jpeg_fname, "Jpeg\\%X.jpg", jpeg_cityhash); FILE *wfp = fopen(jpeg_fname, "wb"); + if (!wfp) { + _wmkdir(L"Jpeg\\"); + wfp = fopen(jpeg_fname, "wb"); + } fwrite(jpegBuf, 1, jpegSize, wfp); fclose(wfp); #endif //JPEG_DEBUG diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 55d404308..5b0e0cc25 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1363,11 +1363,11 @@ u32 sceMpegAvcResourceInit(u32 mpeg) return 0; } -u32 convertARGBToYCbCr(u32 abgr) { +u32 convertABGRToYCbCr(u32 abgr) { //see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information. - u8 r = (abgr >> 16) & 0xFF; + u8 r = (abgr >> 0) & 0xFF; u8 g = (abgr >> 8) & 0xFF; - u8 b = (abgr >> 0) & 0xFF; + u8 b = (abgr >> 16) & 0xFF; int y = 0.299f * r + 0.587f * g + 0.114f * b + 0; int cb = -0.169f * r - 0.331f * g + 0.499f * b + 128.0f; int cr = 0.499f * r - 0.418f * g - 0.0813f * b + 128.0f; @@ -1390,15 +1390,15 @@ int __MpegAvcConvertToYuv420(const void *data, u32 bufferOutputAddr, int width, for (int y = 0; y < height; ++y) { for (int x = 0; x < width; x += 4) { - u32 argb0 = imageBuffer[x + 0]; - u32 argb1 = imageBuffer[x + 1]; - u32 argb2 = imageBuffer[x + 2]; - u32 argb3 = imageBuffer[x + 3]; + u32 abgr0 = imageBuffer[x + 0]; + u32 abgr1 = imageBuffer[x + 1]; + u32 abgr2 = imageBuffer[x + 2]; + u32 abgr3 = imageBuffer[x + 3]; - u32 yCbCr0 = convertARGBToYCbCr(argb0); - u32 yCbCr1 = convertARGBToYCbCr(argb1); - u32 yCbCr2 = convertARGBToYCbCr(argb2); - u32 yCbCr3 = convertARGBToYCbCr(argb3); + u32 yCbCr0 = convertABGRToYCbCr(abgr0); + u32 yCbCr1 = convertABGRToYCbCr(abgr1); + u32 yCbCr2 = convertABGRToYCbCr(abgr2); + u32 yCbCr3 = convertABGRToYCbCr(abgr3); Y[x + 0] = (yCbCr0 >> 16) & 0xFF; Y[x + 1] = (yCbCr1 >> 16) & 0xFF; From a7f7d64f31f3d517f91d377c00b076a7b6b2ac5b Mon Sep 17 00:00:00 2001 From: shenweip Date: Sat, 5 Oct 2013 01:04:41 +0800 Subject: [PATCH 3/6] More work in sceJpegDecodeMJpegYCbCr. --- Core/HLE/sceJpeg.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index f2158340d..97405875b 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -208,6 +208,57 @@ int getWidthHeight(int width, int height) return (width << 16) | height; } +u32 convertRGBToYCbCr(u32 rgb) { + //see http://en.wikipedia.org/wiki/Yuv#Y.27UV444_to_RGB888_conversion for more information. + u8 r = (rgb >> 16) & 0xFF; + u8 g = (rgb >> 8) & 0xFF; + u8 b = (rgb >> 0) & 0xFF; + int y = 0.299f * r + 0.587f * g + 0.114f * b + 0; + int cb = -0.169f * r - 0.331f * g + 0.499f * b + 128.0f; + int cr = 0.499f * r - 0.418f * g - 0.0813f * b + 128.0f; + + // check yCbCr value + if ( y > 0xFF) y = 0xFF; if ( y < 0) y = 0; + if (cb > 0xFF) cb = 0xFF; if (cb < 0) cb = 0; + if (cr > 0xFF) cr = 0xFF; if (cr < 0) cr = 0; + + return (y << 16) | (cb << 8) | cr; +} + +int __JpegDecodeMJpegYCbCr(const void *data, u32 bufferOutputAddr, int width, int height) { + u24 *imageBuffer = (u24*)data; + int sizeY = width * height; + int sizeCb = sizeY >> 2; + u8 *Y = (u8*)Memory::GetPointer(bufferOutputAddr); + u8 *Cb = Y + sizeY; + u8 *Cr = Cb + sizeCb; + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; x += 4) { + u32 abgr0 = imageBuffer[x + 0]; + u32 abgr1 = imageBuffer[x + 1]; + u32 abgr2 = imageBuffer[x + 2]; + u32 abgr3 = imageBuffer[x + 3]; + + u32 yCbCr0 = convertRGBToYCbCr(abgr0); + u32 yCbCr1 = convertRGBToYCbCr(abgr1); + u32 yCbCr2 = convertRGBToYCbCr(abgr2); + u32 yCbCr3 = convertRGBToYCbCr(abgr3); + + Y[x + 0] = (yCbCr0 >> 16) & 0xFF; + Y[x + 1] = (yCbCr1 >> 16) & 0xFF; + Y[x + 2] = (yCbCr2 >> 16) & 0xFF; + Y[x + 3] = (yCbCr3 >> 16) & 0xFF; + + *Cb++ = (yCbCr0 >> 8) & 0xFF; + *Cr++ = yCbCr0 & 0xFF; + } + imageBuffer += width; + Y += width ; + } + return (width << 16) | height; +} + int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode) { ERROR_LOG_REPORT(ME, "sceJpegDecodeMJpegYCbCr(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); @@ -229,7 +280,8 @@ int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCr } if (jpegBuf == NULL) return getWidthHeight(0, 0); - + if (actual_components == 3) + __JpegDecodeMJpegYCbCr(jpegBuf, yCbCrAddr, width, height); // TODO: There's more... return getWidthHeight(width, height); From d8f1ddd6fa65e48c1c04403347288137af6c8612 Mon Sep 17 00:00:00 2001 From: shenweip Date: Sat, 5 Oct 2013 01:18:13 +0800 Subject: [PATCH 4/6] Implemented sceJpegMJpegCsc. --- Core/HLE/sceJpeg.cpp | 68 +++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index 97405875b..aee971715 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -64,38 +64,7 @@ int sceJpegDecompressAllImage() return 0; } -int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth) -{ - ERROR_LOG_REPORT(ME, "UNIMPL sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth); - return 0; -} - -int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) -{ - ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); - return 0; -} - -int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode) -{ - ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpegYCbCrSuccessively(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); - return 0; -} - -int sceJpegDeleteMJpeg() -{ - ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDeleteMJpeg()"); - return 0; -} - -int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) -{ - ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); - return 0; -} - -int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo) -{ +void __JpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth) { int height = widthHeight & 0xFFF; int width = (widthHeight >> 16) & 0xFFF; int lineWidth = std::min(width, bufferWidth); @@ -132,6 +101,41 @@ int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, i imageBuffer += width; imageBuffer += skipEndOfLine; } +} +int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth) +{ + __JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth); + DEBUG_LOG(ME, "UNIMPL sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth); + return 0; +} + +int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) +{ + ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); + return 0; +} + +int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCrSize, int dhtMode) +{ + ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpegYCbCrSuccessively(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); + return 0; +} + +int sceJpegDeleteMJpeg() +{ + ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDeleteMJpeg()"); + return 0; +} + +int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageAddr, int dhtMode) +{ + ERROR_LOG_REPORT(ME, "UNIMPL sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); + return 0; +} + +int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo) +{ + __JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth); DEBUG_LOG(ME, "UNIMPL sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo); return 0; } From 54492732b51c9cd6828e5883729353f140a96dc7 Mon Sep 17 00:00:00 2001 From: shenweip Date: Sat, 5 Oct 2013 02:52:33 +0800 Subject: [PATCH 5/6] Rename u24 to u24_be. --- Common/CommonTypes.h | 4 ++-- Core/HLE/sceJpeg.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/CommonTypes.h b/Common/CommonTypes.h index 1155d4bdc..bc67c19ac 100644 --- a/Common/CommonTypes.h +++ b/Common/CommonTypes.h @@ -28,13 +28,13 @@ #endif #endif -typedef struct u24 { +struct u24_be { unsigned char value[3]; operator unsigned int(){ return 0x00000000 | (value[0] << 16) | (value[1] << 8) | (value[2] << 0); } -} u24; +}; #ifdef _WIN32 diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index aee971715..c29a3f2e6 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -230,7 +230,7 @@ u32 convertRGBToYCbCr(u32 rgb) { } int __JpegDecodeMJpegYCbCr(const void *data, u32 bufferOutputAddr, int width, int height) { - u24 *imageBuffer = (u24*)data; + u24_be *imageBuffer = (u24_be*)data; int sizeY = width * height; int sizeCb = sizeY >> 2; u8 *Y = (u8*)Memory::GetPointer(bufferOutputAddr); From 4ac4ea38dd0a6dcd587f0baf147cf64540748fe4 Mon Sep 17 00:00:00 2001 From: shenweip Date: Sat, 5 Oct 2013 08:40:55 +0800 Subject: [PATCH 6/6] Rename __JpegDecodeMJpegYCbCr to __JpegConvertRGBToYCbCr. --- Core/HLE/sceJpeg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index c29a3f2e6..68d5ce785 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -229,7 +229,7 @@ u32 convertRGBToYCbCr(u32 rgb) { return (y << 16) | (cb << 8) | cr; } -int __JpegDecodeMJpegYCbCr(const void *data, u32 bufferOutputAddr, int width, int height) { +int __JpegConvertRGBToYCbCr (const void *data, u32 bufferOutputAddr, int width, int height) { u24_be *imageBuffer = (u24_be*)data; int sizeY = width * height; int sizeCb = sizeY >> 2; @@ -285,7 +285,7 @@ int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, int yCbCr if (jpegBuf == NULL) return getWidthHeight(0, 0); if (actual_components == 3) - __JpegDecodeMJpegYCbCr(jpegBuf, yCbCrAddr, width, height); + __JpegConvertRGBToYCbCr(jpegBuf, yCbCrAddr, width, height); // TODO: There's more... return getWidthHeight(width, height);