Util: PNG utils should support 16-bit when applicable

This commit is contained in:
Jeffrey Pfau 2016-09-07 01:06:54 -07:00
parent 49a2a01f89
commit f7a9fe8e64
6 changed files with 36 additions and 17 deletions

View File

@ -91,6 +91,7 @@ Misc:
- GBA: Better debug logging if event processing breaks
- 3DS: 3D banner
- FFmpeg: Full support for libavcodec 56+
- Util: PNG utils should support 16-bit when applicable
0.4.1: (2016-07-11)
Bugfixes:

View File

@ -103,7 +103,7 @@ static void _drawState(struct GUIBackground* background, void* id) {
return;
}
struct VFile* vf = mCoreGetState(gbaBackground->p->core, stateId, false);
uint32_t* pixels = gbaBackground->screenshot;
color_t* pixels = gbaBackground->screenshot;
if (!pixels) {
pixels = anonymousMemoryMap(w * h * 4);
gbaBackground->screenshot = pixels;

View File

@ -26,7 +26,7 @@ struct mGUIBackground {
struct GUIBackground d;
struct mGUIRunner* p;
uint32_t* screenshot;
color_t* screenshot;
int screenshotId;
};
@ -62,7 +62,7 @@ struct mGUIRunner {
void (*gameUnloaded)(struct mGUIRunner*);
void (*prepareForFrame)(struct mGUIRunner*);
void (*drawFrame)(struct mGUIRunner*, bool faded);
void (*drawScreenshot)(struct mGUIRunner*, const uint32_t* pixels, unsigned width, unsigned height, bool faded);
void (*drawScreenshot)(struct mGUIRunner*, const color_t* pixels, unsigned width, unsigned height, bool faded);
void (*paused)(struct mGUIRunner*);
void (*unpaused)(struct mGUIRunner*);
void (*incrementScreenMode)(struct mGUIRunner*);

View File

@ -532,23 +532,16 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) {
_drawTex(runner->core, faded);
}
static void _drawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsigned width, unsigned height, bool faded) {
static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) {
C3D_Tex* tex = &outputTexture;
u16* newPixels = linearMemAlign(256 * height * sizeof(u32), 0x100);
color_t* newPixels = linearMemAlign(256 * height * sizeof(color_t), 0x100);
// Convert image from RGBX8 to BGR565
for (unsigned y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
// 0xXXBBGGRR -> 0bRRRRRGGGGGGBBBBB
u32 p = *pixels++;
newPixels[y * 256 + x] =
(p << 24 >> (24 + 3) << 11) | // R
(p << 16 >> (24 + 2) << 5) | // G
(p << 8 >> (24 + 3) << 0); // B
}
memset(&newPixels[y * 256 + width], 0, (256 - width) * sizeof(u32));
unsigned y;
for (y = 0; y < height; ++y) {
memcpy(&newPixels[y * 256], &pixels[y * width], width * sizeof(color_t));
memset(&newPixels[y * 256 + width], 0, (256 - width) * sizeof(color_t));
}
GSPGPU_FlushDataCache(newPixels, 256 * height * sizeof(u32));

View File

@ -7,6 +7,7 @@
#define PSP2_CONTEXT_H
#include "psp2-common.h"
#include "core/interface.h"
#include "util/gui.h"
struct mGUIRunner;
@ -20,7 +21,7 @@ void mPSP2PrepareForFrame(struct mGUIRunner* runner);
void mPSP2Paused(struct mGUIRunner* runner);
void mPSP2Unpaused(struct mGUIRunner* runner);
void mPSP2Draw(struct mGUIRunner* runner, bool faded);
void mPSP2DrawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsigned width, unsigned height, bool faded);
void mPSP2DrawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded);
void mPSP2IncrementScreenMode(struct mGUIRunner* runner);
void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit);
uint16_t mPSP2PollInput(struct mGUIRunner* runner);

View File

@ -65,6 +65,18 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s
for (i = 0; i < height; ++i) {
unsigned x;
for (x = 0; x < width; ++x) {
#ifdef COLOR_16_BIT
uint16_t c = ((uint16_t*) pixelData)[stride * i + x];
#ifdef COLOR_5_6_5
row[x * 3] = (c >> 8) & 0xF8;
row[x * 3 + 1] = (c >> 3) & 0xFC;
row[x * 3 + 2] = (c << 3) & 0xF8;
#else
row[x * ] = (c >> 7) & 0xF8;
row[x * + 1] = (c >> 2) & 0xF8;
row[x * + 2] = (c << 3) & 0xF8;
#endif
#else
#ifdef __BIG_ENDIAN__
row[x * 3] = pixelData[stride * i * 4 + x * 4 + 3];
row[x * 3 + 1] = pixelData[stride * i * 4 + x * 4 + 2];
@ -73,6 +85,7 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s
row[x * 3] = pixelData[stride * i * 4 + x * 4];
row[x * 3 + 1] = pixelData[stride * i * 4 + x * 4 + 1];
row[x * 3 + 2] = pixelData[stride * i * 4 + x * 4 + 2];
#endif
#endif
}
png_write_row(png, row);
@ -182,6 +195,17 @@ bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width
png_read_row(png, row, 0);
unsigned x;
for (x = 0; x < pngWidth; ++x) {
#ifdef COLOR_16_BIT
uint16_t c = row[x * 3 + 2] >> 3;
#ifdef COLOR_5_6_5
c |= (row[x * 3 + 1] << 3) & 0x7E0;
c |= (row[x * 3] << 8) & 0xF800;
#else
c |= (row[x * 3 + 1] << 2) & 0x3E0;
c |= (row[x * 3] << 7) & 0x7C00;
#endif
((uint16_t*) pixelData)[stride * i + x] = c;
#endif
#if __BIG_ENDIAN__
pixelData[stride * i * 4 + x * 4 + 3] = row[x * 3];
pixelData[stride * i * 4 + x * 4 + 2] = row[x * 3 + 1];