Core: Color formats
Vicki Pfau vi@endrift.com
Thu, 27 Jul 2017 12:59:06 -0700
3 files changed,
73 insertions(+),
12 deletions(-)
M
include/mgba/core/interface.h
→
include/mgba/core/interface.h
@@ -37,6 +37,29 @@ #define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19))
struct blip_t; +enum mColorFormat { + mCOLOR_XBGR8 = 0x00001, + mCOLOR_XRGB8 = 0x00002, + mCOLOR_BGRX8 = 0x00004, + mCOLOR_RGBX8 = 0x00008, + mCOLOR_ABGR8 = 0x00010, + mCOLOR_ARGB8 = 0x00020, + mCOLOR_BGRA8 = 0x00040, + mCOLOR_RGBA8 = 0x00080, + mCOLOR_RGB5 = 0x00100, + mCOLOR_BGR5 = 0x00200, + mCOLOR_RGB565 = 0x00400, + mCOLOR_BGR565 = 0x00800, + mCOLOR_ARGB5 = 0x01000, + mCOLOR_ABGR5 = 0x02000, + mCOLOR_RGBA5 = 0x04000, + mCOLOR_BGRA5 = 0x08000, + mCOLOR_RGB8 = 0x10000, + mCOLOR_BGR8 = 0x20000, + + mCOLOR_ANY = -1 +}; + struct mCoreCallbacks { void* context; void (*videoFrameStarted)(void* context);@@ -84,9 +107,9 @@ bool (*deserialize)(struct mRTCSource*, const struct mStateExtdataItem*);
}; struct mImageSource { - void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h); + void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h, int colorFormats); void (*stopRequestImage)(struct mImageSource*); - void (*requestImage)(struct mImageSource*, const uint32_t** buffer, size_t* stride); + void (*requestImage)(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat); }; enum mRTCGenericType {
M
src/gb/mbc.c
→
src/gb/mbc.c
@@ -244,7 +244,7 @@ case GB_POCKETCAM:
gb->memory.mbcWrite = _GBPocketCam; gb->memory.mbcRead = _GBPocketCamRead; if (gb->memory.cam && gb->memory.cam->startRequestImage) { - gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT); + gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT, mCOLOR_ANY); } break; }@@ -791,9 +791,10 @@ void _GBPocketCamCapture(struct GBMemory* memory) {
if (!memory->cam) { return; } - const uint32_t* image = NULL; + const void* image = NULL; size_t stride; - memory->cam->requestImage(memory->cam, &image, &stride); + enum mColorFormat format; + memory->cam->requestImage(memory->cam, &image, &stride, &format); if (!image) { return; }@@ -802,8 +803,44 @@ struct GBPocketCamState* pocketCam = &memory->mbcState.pocketCam;
size_t x, y; for (y = 0; y < GBCAM_HEIGHT; ++y) { for (x = 0; x < GBCAM_WIDTH; ++x) { - uint32_t color = image[y * stride + x]; - uint32_t gray = ((color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF)); + uint32_t gray; + uint32_t color; + switch (format) { + case mCOLOR_XBGR8: + case mCOLOR_XRGB8: + case mCOLOR_ARGB8: + case mCOLOR_ABGR8: + color = ((const uint32_t*) image)[y * stride + x]; + gray = (color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF); + break; + case mCOLOR_BGRX8: + case mCOLOR_RGBX8: + case mCOLOR_RGBA8: + case mCOLOR_BGRA8: + color = ((const uint32_t*) image)[y * stride + x]; + gray = ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF) + ((color >> 24) & 0xFF); + break; + case mCOLOR_BGR5: + case mCOLOR_RGB5: + case mCOLOR_ARGB5: + case mCOLOR_ABGR5: + color = ((const uint16_t*) image)[y * stride + x]; + gray = ((color << 3) & 0xF8) + ((color >> 2) & 0xF8) + ((color >> 7) & 0xF8); + break; + case mCOLOR_BGR565: + case mCOLOR_RGB565: + color = ((const uint16_t*) image)[y * stride + x]; + gray = ((color << 3) & 0xF8) + ((color >> 3) & 0xFC) + ((color >> 8) & 0xF8); + break; + case mCOLOR_BGRA5: + case mCOLOR_RGBA5: + color = ((const uint16_t*) image)[y * stride + x]; + gray = ((color << 2) & 0xF8) + ((color >> 3) & 0xF8) + ((color >> 8) & 0xF8); + break; + default: + mLOG(GB_MBC, WARN, "Unsupported pixel format: %X", format); + return; + } uint16_t exposure = (pocketCam->registers[2] << 8) | (pocketCam->registers[3]); gray = (gray + 1) * exposure / 0x300; // TODO: Additional processing
M
src/platform/qt/InputController.cpp
→
src/platform/qt/InputController.cpp
@@ -88,7 +88,7 @@ setLuminanceLevel(0);
#endif m_image.p = this; - m_image.startRequestImage = [](mImageSource* context, unsigned w, unsigned h) { + m_image.startRequestImage = [](mImageSource* context, unsigned w, unsigned h, int) { InputControllerImage* image = static_cast<InputControllerImage*>(context); image->w = w; image->h = h;@@ -109,19 +109,19 @@ QMetaObject::invokeMethod(image->p, "teardownCam");
#endif }; - m_image.requestImage = [](mImageSource* context, const uint32_t** buffer, size_t* stride) { + m_image.requestImage = [](mImageSource* context, const void** buffer, size_t* stride, mColorFormat* format) { InputControllerImage* image = static_cast<InputControllerImage*>(context); QSize size; { QMutexLocker locker(&image->mutex); if (image->outOfDate) { image->resizedImage = image->image.scaled(image->w, image->h, Qt::KeepAspectRatioByExpanding); - image->resizedImage = image->resizedImage.convertToFormat(QImage::Format_RGB32); + image->resizedImage = image->resizedImage.convertToFormat(QImage::Format_RGB16); image->outOfDate = false; } } size = image->resizedImage.size(); - const uint32_t* bits = reinterpret_cast<const uint32_t*>(image->resizedImage.constBits()); + const uint16_t* bits = reinterpret_cast<const uint16_t*>(image->resizedImage.constBits()); if (size.width() > image->w) { bits += (size.width() - image->w) / 2; }@@ -129,7 +129,8 @@ if (size.height() > image->h) {
bits += ((size.height() - image->h) / 2) * size.width(); } *buffer = bits; - *stride = size.width(); + *stride = image->resizedImage.bytesPerLine() / sizeof(*bits); + *format = mCOLOR_RGB565; }; }