adding format conversion support

This commit is contained in:
Blaise Tine 2021-04-01 17:54:55 -04:00
parent ac8104e27e
commit 387fe55610
4 changed files with 1368 additions and 0 deletions

View file

@ -0,0 +1,253 @@
#include "format.h"
struct GLSurfaceDesc {
uint8_t Format;
uint8_t *pBits;
int32_t Width;
int32_t Height;
int32_t Pitch;
};
class BlitTable {
public:
typedef void (*PfnCopy)(const GLSurfaceDesc &dstDesc,
uint32_t dstOffsetX,
uint32_t dstOffsetY,
uint32_t copyWidth,
uint32_t copyHeight,
const GLSurfaceDesc &srcDesc,
uint32_t srcOffsetX,
uint32_t srcOffsetY);
BlitTable() {
for (uint32_t s = 0; s < FORMAT_COLOR_SIZE_; ++s) {
for (uint32_t d = 0; d < FORMAT_COLOR_SIZE_; ++d) {
copyFuncs_[s][d] = CopyInvalid;
}
}
for (uint32_t s = 0; s < FORMAT_COLOR_SIZE_; ++s) {
switch (s) {
case FORMAT_A8:
case FORMAT_L8:
copyFuncs_[s][s] = CopyFast<uint8_t>;
break;
case FORMAT_A8L8:
copyFuncs_[FORMAT_A8L8][FORMAT_A8] = Copy<FORMAT_A8L8, FORMAT_A8>;
copyFuncs_[FORMAT_A8L8][FORMAT_A8L8] = CopyFast<uint16_t>;
break;
case FORMAT_R5G6B5:
copyFuncs_[FORMAT_R5G6B5][FORMAT_L8] = Copy<FORMAT_R5G6B5, FORMAT_L8>;
copyFuncs_[FORMAT_R5G6B5][FORMAT_R5G6B5] = CopyFast<uint16_t>;
copyFuncs_[FORMAT_R5G6B5][FORMAT_R8G8B8] =
Copy<FORMAT_R5G6B5, FORMAT_R8G8B8>;
copyFuncs_[FORMAT_R5G6B5][FORMAT_B8G8R8] =
Copy<FORMAT_R5G6B5, FORMAT_B8G8R8>;
copyFuncs_[FORMAT_R5G6B5][FORMAT_A8B8G8R8] =
Copy<FORMAT_R5G6B5, FORMAT_A8B8G8R8>;
copyFuncs_[FORMAT_R5G6B5][FORMAT_A8R8G8B8] =
Copy<FORMAT_R5G6B5, FORMAT_A8R8G8B8>;
break;
case FORMAT_A1R5G5B5:
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8] =
Copy<FORMAT_A1R5G5B5, FORMAT_A8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_L8] =
Copy<FORMAT_A1R5G5B5, FORMAT_L8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8L8] =
Copy<FORMAT_A1R5G5B5, FORMAT_A8L8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R8G8B8] =
Copy<FORMAT_A1R5G5B5, FORMAT_R8G8B8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8R8G8B8] =
Copy<FORMAT_A1R5G5B5, FORMAT_A8R8G8B8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R5G5B5A1] =
Copy<FORMAT_A1R5G5B5, FORMAT_R5G5B5A1>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R4G4B4A4] =
Copy<FORMAT_A1R5G5B5, FORMAT_R4G4B4A4>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_B8G8R8] =
Copy<FORMAT_A1R5G5B5, FORMAT_B8G8R8>;
copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8B8G8R8] =
Copy<FORMAT_A1R5G5B5, FORMAT_A8B8G8R8>;
break;
case FORMAT_A4R4G4B4:
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8] =
Copy<FORMAT_A4R4G4B4, FORMAT_A8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_L8] =
Copy<FORMAT_A4R4G4B4, FORMAT_L8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8L8] =
Copy<FORMAT_A4R4G4B4, FORMAT_A8L8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R8G8B8] =
Copy<FORMAT_A4R4G4B4, FORMAT_R8G8B8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8R8G8B8] =
Copy<FORMAT_A4R4G4B4, FORMAT_A8R8G8B8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R5G5B5A1] =
Copy<FORMAT_A4R4G4B4, FORMAT_R5G5B5A1>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R4G4B4A4] =
Copy<FORMAT_A4R4G4B4, FORMAT_R4G4B4A4>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_B8G8R8] =
Copy<FORMAT_A4R4G4B4, FORMAT_B8G8R8>;
copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8B8G8R8] =
Copy<FORMAT_A4R4G4B4, FORMAT_A8B8G8R8>;
break;
case FORMAT_R8G8B8:
copyFuncs_[FORMAT_R8G8B8][FORMAT_L8] = Copy<FORMAT_R8G8B8, FORMAT_L8>;
copyFuncs_[FORMAT_R8G8B8][FORMAT_R5G6B5] =
Copy<FORMAT_R8G8B8, FORMAT_R5G6B5>;
copyFuncs_[FORMAT_R8G8B8][FORMAT_R8G8B8] = CopyFast<uint24_t>;
copyFuncs_[FORMAT_R8G8B8][FORMAT_B8G8R8] =
Copy<FORMAT_R8G8B8, FORMAT_B8G8R8>;
copyFuncs_[FORMAT_R8G8B8][FORMAT_A8B8G8R8] =
Copy<FORMAT_R8G8B8, FORMAT_A8B8G8R8>;
copyFuncs_[FORMAT_R8G8B8][FORMAT_A8R8G8B8] =
Copy<FORMAT_R8G8B8, FORMAT_A8R8G8B8>;
break;
case FORMAT_A8R8G8B8:
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8] =
Copy<FORMAT_A8R8G8B8, FORMAT_A8>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_L8] =
Copy<FORMAT_A8R8G8B8, FORMAT_L8>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8L8] =
Copy<FORMAT_A8R8G8B8, FORMAT_A8L8>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R5G6B5] =
Copy<FORMAT_A8R8G8B8, FORMAT_R5G6B5>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R8G8B8] =
Copy<FORMAT_A8R8G8B8, FORMAT_R8G8B8>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8R8G8B8] = CopyFast<uint32_t>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R5G5B5A1] =
Copy<FORMAT_A8R8G8B8, FORMAT_R5G5B5A1>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R4G4B4A4] =
Copy<FORMAT_A8R8G8B8, FORMAT_R4G4B4A4>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_B8G8R8] =
Copy<FORMAT_A8R8G8B8, FORMAT_B8G8R8>;
copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8B8G8R8] =
Copy<FORMAT_A8R8G8B8, FORMAT_A8B8G8R8>;
break;
case FORMAT_R5G5B5A1:
copyFuncs_[FORMAT_R5G5B5A1][FORMAT_A8] =
Copy<FORMAT_R5G5B5A1, FORMAT_A8>;
copyFuncs_[FORMAT_R5G5B5A1][FORMAT_L8] =
Copy<FORMAT_R5G5B5A1, FORMAT_L8>;
copyFuncs_[FORMAT_R5G5B5A1][FORMAT_A8L8] =
Copy<FORMAT_R5G5B5A1, FORMAT_A8L8>;
copyFuncs_[FORMAT_R5G5B5A1][FORMAT_RGB] =
Copy<FORMAT_R5G5B5A1, FORMAT_RGB>;
copyFuncs_[FORMAT_R5G5B5A1][FORMAT_ARGB] =
Copy<FORMAT_R5G5B5A1, FORMAT_ARGB>;
break;
case FORMAT_R4G4B4A4:
copyFuncs_[FORMAT_R4G4B4A4][FORMAT_A8] =
Copy<FORMAT_R4G4B4A4, FORMAT_A8>;
copyFuncs_[FORMAT_R4G4B4A4][FORMAT_L8] =
Copy<FORMAT_R4G4B4A4, FORMAT_L8>;
copyFuncs_[FORMAT_R4G4B4A4][FORMAT_A8L8] =
Copy<FORMAT_R4G4B4A4, FORMAT_A8L8>;
copyFuncs_[FORMAT_R4G4B4A4][FORMAT_RGB] =
Copy<FORMAT_R4G4B4A4, FORMAT_RGB>;
copyFuncs_[FORMAT_R4G4B4A4][FORMAT_ARGB] =
Copy<FORMAT_R4G4B4A4, FORMAT_ARGB>;
break;
case FORMAT_B8G8R8:
copyFuncs_[FORMAT_B8G8R8][FORMAT_L8] = Copy<FORMAT_B8G8R8, FORMAT_L8>;
copyFuncs_[FORMAT_B8G8R8][FORMAT_RGB] = Copy<FORMAT_B8G8R8, FORMAT_RGB>;
break;
case FORMAT_A8B8G8R8:
copyFuncs_[FORMAT_A8B8G8R8][FORMAT_A8] =
Copy<FORMAT_A8B8G8R8, FORMAT_A8>;
copyFuncs_[FORMAT_A8B8G8R8][FORMAT_L8] =
Copy<FORMAT_A8B8G8R8, FORMAT_L8>;
copyFuncs_[FORMAT_A8B8G8R8][FORMAT_A8L8] =
Copy<FORMAT_A8B8G8R8, FORMAT_A8L8>;
copyFuncs_[FORMAT_A8B8G8R8][FORMAT_RGB] =
Copy<FORMAT_A8B8G8R8, FORMAT_RGB>;
copyFuncs_[FORMAT_A8B8G8R8][FORMAT_ARGB] =
Copy<FORMAT_A8B8G8R8, FORMAT_ARGB>;
break;
}
}
}
PfnCopy get(uint32_t srcFormat, uint32_t dstFormat) const {
assert(srcFormat < FORMAT_COLOR_SIZE_);
assert(dstFormat < FORMAT_COLOR_SIZE_);
return copyFuncs_[srcFormat][dstFormat];
}
private:
template <ePixelFormat SrcFormat, ePixelFormat DstFormat>
static void Copy(const GLSurfaceDesc &dstDesc,
uint32_t dstOffsetX,
uint32_t dstOffsetY,
uint32_t copyWidth,
uint32_t copyHeight,
const GLSurfaceDesc &srcDesc,
uint32_t srcOffsetX,
uint32_t srcOffsetY) {
auto srcBPP = TFormatInfo<SrcFormat>::CBSIZE;
auto dstBPP = TFormatInfo<DstFormat>::CBSIZE;
auto srcNextLine = srcDesc.Pitch;
auto dstNextLine = dstDesc.Pitch;
auto pbSrc = srcDesc.pBits + srcOffsetX * srcBPP + srcOffsetY * srcDesc.Pitch;
auto pbDst = dstDesc.pBits + dstOffsetX * dstBPP + dstOffsetY * dstDesc.Pitch;
while (copyHeight--) {
auto pSrc = reinterpret_cast<const typename TFormatInfo<SrcFormat>::TYPE *>(pbSrc);
for (auto *pDst = reinterpret_cast<typename TFormatInfo<DstFormat>::TYPE *>(
pbDst),
*const pEnd = pDst + copyWidth;
pDst != pEnd; ++pDst, ++pSrc) {
auto tmp = Format::ConvertFrom<SrcFormat, true>(pSrc);
Format::ConvertTo<DstFormat>(pDst, tmp);
}
pbSrc += srcNextLine;
pbDst += dstNextLine;
}
}
template <typename Type>
static void CopyFast(const GLSurfaceDesc &dstDesc, uint32_t dstOffsetX,
uint32_t dstOffsetY, uint32_t copyWidth,
uint32_t copyHeight, const GLSurfaceDesc &srcDesc,
uint32_t srcOffsetX, uint32_t srcOffsetY) {
auto nBPP = sizeof(Type);
auto srcNextLine = srcDesc.Pitch;
auto dstNextLine = dstDesc.Pitch;
auto pbSrc = srcDesc.pBits + srcOffsetX * nBPP + srcOffsetY * srcDesc.Pitch;
auto pbDst = dstDesc.pBits + dstOffsetX * nBPP + dstOffsetY * dstDesc.Pitch;
while (copyHeight--) {
auto pSrc = reinterpret_cast<const Type *>(pbSrc);
for (auto *pDst = reinterpret_cast<Type *>(pbDst), *const pEnd = pDst + copyWidth;
pDst != pEnd; ++pDst, ++pSrc) {
*pDst = *pSrc;
}
pbSrc += srcNextLine;
pbDst += dstNextLine;
}
}
static void CopyInvalid(const GLSurfaceDesc & /*dstDesc*/,
uint32_t /*dstOffsetX*/,
uint32_t /*dstOffsetY*/,
uint32_t /*copyWidth*/,
uint32_t /*copyHeight*/,
const GLSurfaceDesc & /*srcDesc*/,
uint32_t /*srcOffsetX*/,
uint32_t /*srcOffsetY*/)
{
std::abort();
}
PfnCopy copyFuncs_[FORMAT_COLOR_SIZE_][FORMAT_COLOR_SIZE_];
};

View file

@ -0,0 +1,64 @@
//
// Copyright (c) Blaise Tine. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools
// installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR
// INDEMNITIES.
//
#pragma once
#include <cstdint>
#include <assert.h>
struct ColorARGB {
union {
struct {
uint32_t value;
};
struct {
uint8_t b, g, r, a;
};
struct {
uint8_t m[4];
};
};
ColorARGB() {}
ColorARGB(int a, int r, int g, int b) {
assert((a >= 0) && (a <= 0xff));
assert((r >= 0) && (r <= 0xff));
assert((g >= 0) && (g <= 0xff));
assert((b >= 0) && (b <= 0xff));
this->b = static_cast<uint8_t>(b);
this->g = static_cast<uint8_t>(g);
this->r = static_cast<uint8_t>(r);
this->a = static_cast<uint8_t>(a);
}
ColorARGB(int r, int g, int b) {
assert((r >= 0) && (r <= 0xff));
assert((g >= 0) && (g <= 0xff));
assert((b >= 0) && (b <= 0xff));
this->b = static_cast<uint8_t>(b);
this->g = static_cast<uint8_t>(g);
this->r = static_cast<uint8_t>(r);
}
ColorARGB(int value) {
this->value = value;
}
void operator=(const ColorARGB &rhs) {
this->value = rhs.value;
}
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,37 @@
//
// Copyright (c) Blaise Tine. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools
// installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR
// INDEMNITIES.
//
#pragma once
#include <cstdint>
struct uint24_t {
uint8_t m[3];
explicit uint24_t(uint32_t value) {
m[0] = (value >> 0) & 0xff;
m[1] = (value >> 8) & 0xff;
m[2] = (value >> 16) & 0xff;
}
explicit uint24_t(uint8_t x, uint8_t y, uint8_t z) {
m[0] = x;
m[1] = y;
m[2] = z;
}
operator uint32_t() const {
return (m[2] << 16) | (m[1] << 8) | m[0];
}
};