Skip to content

Commit

Permalink
Merge branch 'indexed_scaling' into rgb_scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
mkalkbrenner committed Apr 1, 2024
2 parents 6404eeb + c0c8415 commit 8003a23
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 14 deletions.
45 changes: 34 additions & 11 deletions src/DMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,31 +760,54 @@ void DMD::PixelcadeDMDThread()
m_pUpdateBufferQueue[bufferPosition]->b);
}

// @todo scaling / centering
if (m_pUpdateBufferQueue[bufferPosition]->mode == Mode::RGB24 && width == 128 && height == 32)
if (m_pUpdateBufferQueue[bufferPosition]->mode == Mode::RGB24)
{
uint8_t rgb24Data[128 * 32 * 3];
uint8_t rgb24Data[256 * 64 * 3];
AdjustRGB24Depth(m_pUpdateBufferQueue[bufferPosition]->data, rgb24Data, length, palette,
m_pUpdateBufferQueue[bufferPosition]->depth);

uint8_t scaledBuffer[128 * 32 * 3];
if (width == 128 && height == 32)
memcpy(scaledBuffer, m_pUpdateBufferQueue[bufferPosition]->segData, 128 * 32 * 3);
else if (width == 128 && height == 16)
FrameUtil::Center(scaledBuffer, 128, 32, rgb24Data, 128, 16, 24);
else if (width == 192 && height == 64)
FrameUtil::ScaleDown(scaledBuffer, 128, 32, rgb24Data, 192, 64, 24);
else if (width == 256 && height == 64)
FrameUtil::ScaleDown(scaledBuffer, 128, 32, rgb24Data, 256, 64, 24);
else
continue;

for (int i = 0; i < length; i++)
{
int pos = i * 3;
uint32_t r = rgb24Data[pos];
uint32_t g = rgb24Data[pos + 1];
uint32_t b = rgb24Data[pos + 2];
uint32_t r = scaledBuffer[pos];
uint32_t g = scaledBuffer[pos + 1];
uint32_t b = scaledBuffer[pos + 2];

rgb565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3));
}
update = true;
}
// @todo scaling / centering
else if (m_pUpdateBufferQueue[bufferPosition]->mode == Mode::RGB16 && width == 128 && height == 32)
else if (m_pUpdateBufferQueue[bufferPosition]->mode == Mode::RGB16)
{
memcpy(rgb565Data, m_pUpdateBufferQueue[bufferPosition]->segData, 128 * 32 * sizeof(uint16_t));
if (width == 128 && height == 32)
memcpy(rgb565Data, m_pUpdateBufferQueue[bufferPosition]->segData, 128 * 32 * 2);
else if (width == 128 && height == 16)
FrameUtil::Center((uint8_t*)rgb565Data, 128, 32, (uint8_t*)m_pUpdateBufferQueue[bufferPosition]->segData,
128, 16, 16);
else if (width == 192 && height == 64)
FrameUtil::ScaleDown((uint8_t*)rgb565Data, 128, 32, (uint8_t*)m_pUpdateBufferQueue[bufferPosition]->segData,
192, 64, 16);
else if (width == 256 && height == 64)
FrameUtil::ScaleDown((uint8_t*)rgb565Data, 128, 32, (uint8_t*)m_pUpdateBufferQueue[bufferPosition]->segData,
256, 64, 16);
else
continue;

update = true;
}
else if (m_pUpdateBufferQueue[bufferPosition]->mode == Mode::Data ||
m_pUpdateBufferQueue[bufferPosition]->mode == Mode::AlphaNumeric)
else
{
uint8_t renderBuffer[256 * 64];

Expand Down
99 changes: 96 additions & 3 deletions src/FrameUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,17 +341,110 @@ void FrameUtil::ScaleDownPUP(uint8_t* pDestFrame, const uint8_t destWidth, const
}
}

void FrameUtil::CenterIndexed(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint8_t srcWidth, const uint8_t srcHeight)
void FrameUtil::ScaleDown(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint16_t srcWidth, const uint8_t srcHeight, uint8_t bits)
{
memset(pDestFrame, 0, destWidth * destHeight);
uint8_t xOffset = (destWidth - (srcWidth / 2)) / 2;
uint8_t yOffset = (destHeight - (srcHeight / 2)) / 2;
uint8_t bytes = bits / 8; // RGB24 (3 byte) or RGB16 (2 byte)

for (uint8_t y = 0; y < srcHeight; y += 2)
{
for (uint16_t x = 0; x < srcWidth; x += 2)
{
uint16_t upper_left = y * srcWidth * bytes + x * bytes;
uint16_t upper_right = upper_left + bytes;
uint16_t lower_left = upper_left + srcWidth * bytes;
uint16_t lower_right = lower_left + bytes;
uint16_t target = (xOffset + (x / 2) + (y / 2) * destHeight) * bytes;

if (x < srcWidth / 2)
{
if (y < srcHeight / 2)
{
if (memcmp(&pSrcFrame[upper_left], &pSrcFrame[upper_right], bytes) == 0 ||
memcmp(&pSrcFrame[upper_left], &pSrcFrame[lower_left], bytes) == 0 ||
memcmp(&pSrcFrame[upper_left], &pSrcFrame[lower_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_left], bytes);
else if (memcmp(&pSrcFrame[upper_right], &pSrcFrame[lower_left], bytes) == 0 ||
memcmp(&pSrcFrame[upper_right], &pSrcFrame[lower_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_right], bytes);
else if (memcmp(&pSrcFrame[lower_left], &pSrcFrame[lower_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_left], bytes);
else
memcpy(&pDestFrame[target], &pSrcFrame[upper_left], bytes);
}
else
{
if (memcmp(&pSrcFrame[lower_left], &pSrcFrame[lower_right], bytes) == 0 ||
memcmp(&pSrcFrame[lower_left], &pSrcFrame[upper_left], bytes) == 0 ||
memcmp(&pSrcFrame[lower_left], &pSrcFrame[upper_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_left], bytes);
else if (memcmp(&pSrcFrame[lower_right], &pSrcFrame[upper_left], bytes) == 0 ||
memcmp(&pSrcFrame[lower_right], &pSrcFrame[upper_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_right], bytes);
else if (memcmp(&pSrcFrame[upper_left], &pSrcFrame[upper_right], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_left], bytes);
else
memcpy(&pDestFrame[target], &pSrcFrame[lower_left], bytes);
}
}
else
{
if (y < srcHeight / 2)
{
if (memcmp(&pSrcFrame[upper_right], &pSrcFrame[upper_left], bytes) == 0 ||
memcmp(&pSrcFrame[upper_right], &pSrcFrame[lower_right], bytes) == 0 ||
memcmp(&pSrcFrame[upper_right], &pSrcFrame[lower_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_right], bytes);
else if (memcmp(&pSrcFrame[upper_left], &pSrcFrame[lower_right], bytes) == 0 ||
memcmp(&pSrcFrame[upper_left], &pSrcFrame[lower_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_left], bytes);
else if (memcmp(&pSrcFrame[lower_right], &pSrcFrame[lower_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_right], bytes);
else
memcpy(&pDestFrame[target], &pSrcFrame[upper_right], bytes);
}
else
{
if (memcmp(&pSrcFrame[lower_right], &pSrcFrame[lower_left], bytes) == 0 ||
memcmp(&pSrcFrame[lower_right], &pSrcFrame[upper_right], bytes) == 0 ||
memcmp(&pSrcFrame[lower_right], &pSrcFrame[upper_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_right], bytes);
else if (memcmp(&pSrcFrame[lower_left], &pSrcFrame[upper_right], bytes) == 0 ||
memcmp(&pSrcFrame[lower_left], &pSrcFrame[upper_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[lower_left], bytes);
else if (memcmp(&pSrcFrame[upper_right], &pSrcFrame[upper_left], bytes) == 0)
memcpy(&pDestFrame[target], &pSrcFrame[upper_right], bytes);
else
memcpy(&pDestFrame[target], &pSrcFrame[lower_right], bytes);
}
}
}
}
}

void FrameUtil::Center(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight, const uint8_t* pSrcFrame,
const uint8_t srcWidth, const uint8_t srcHeight, uint8_t bits)
{
uint8_t bytes = bits / 8; // RGB24 (3 byte) or RGB16 (2 byte)

memset(pDestFrame, 0, destWidth * destHeight * bytes);
uint8_t xOffset = (destWidth - srcWidth) / 2;
uint8_t yOffset = (destHeight - srcHeight) / 2;

for (uint8_t y = 0; y < srcHeight; y++)
{
memcpy(&pDestFrame[(yOffset + y) * destWidth + xOffset], &pSrcFrame[y * srcWidth], srcWidth);
memcpy(&pDestFrame[((yOffset + y) * destWidth + xOffset) * bytes], &pSrcFrame[y * srcWidth * bytes],
srcWidth * bytes);
}
}

void FrameUtil::CenterIndexed(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint8_t srcWidth, const uint8_t srcHeight)
{
Center(pDestFrame, destWidth, destHeight, pSrcFrame, srcWidth, srcHeight, 8);
}

} // namespace DMDUtil
4 changes: 4 additions & 0 deletions src/FrameUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ class FrameUtil
const uint8_t* pSrcFrame, const uint16_t srcWidth, const uint8_t srcHeight);
static void ScaleDownPUP(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint8_t srcWidth, const uint8_t srcHeight);
static void ScaleDown(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint16_t srcWidth, const uint8_t srcHeight, uint8_t bits);
static void CenterIndexed(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight,
const uint8_t* pSrcFrame, const uint8_t srcWidth, const uint8_t srcHeight);
static void Center(uint8_t* pDestFrame, const uint8_t destWidth, const uint8_t destHeight, const uint8_t* pSrcFrame,
const uint8_t srcWidth, const uint8_t srcHeight, uint8_t bits);
};

} // namespace DMDUtil

0 comments on commit 8003a23

Please sign in to comment.