Initial release
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
// This file is part of VSTGUI. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this
|
||||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
||||
|
||||
#include "pixelbuffer.h"
|
||||
#include "vstguibase.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VSTGUI {
|
||||
namespace PixelBuffer {
|
||||
namespace Private {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4293)
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<int8_t bs1, int8_t bs2, int8_t bs3, int8_t bs4>
|
||||
inline uint32_t shuffle (uint32_t input)
|
||||
{
|
||||
static constexpr auto s1 = bs1 * 8;
|
||||
static constexpr auto s2 = bs2 * 8;
|
||||
static constexpr auto s3 = bs3 * 8;
|
||||
static constexpr auto s4 = bs4 * 8;
|
||||
|
||||
uint32_t b1 = (input & 0xFF000000);
|
||||
uint32_t b2 = (input & 0x00FF0000);
|
||||
uint32_t b3 = (input & 0x0000FF00);
|
||||
uint32_t b4 = (input & 0x000000FF);
|
||||
|
||||
if constexpr (ByteOrder::kNativeByteOrder == ByteOrder::kLittleEndianByteOrder)
|
||||
{
|
||||
b1 = (s4 >= 0) ? b1 >> s4 : b1 << -s4;
|
||||
b2 = (s3 >= 0) ? b2 >> s3 : b2 << -s3;
|
||||
b3 = (s2 >= 0) ? b3 >> s2 : b3 << -s2;
|
||||
b4 = (s1 >= 0) ? b4 >> s1 : b4 << -s1;
|
||||
}
|
||||
else
|
||||
{
|
||||
b1 = (s1 >= 0) ? b1 << s1 : b1 >> -s1;
|
||||
b2 = (s2 >= 0) ? b2 << s2 : b2 >> -s2;
|
||||
b3 = (s3 >= 0) ? b3 << s3 : b3 >> -s3;
|
||||
b4 = (s4 >= 0) ? b4 << s4 : b4 >> -s4;
|
||||
}
|
||||
|
||||
return b1 | b2 | b3 | b4;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<Format SourceFormat, Format DestinationFormat>
|
||||
inline void convert (uint8_t* buffer, uint32_t bytesPerRow, uint32_t width, uint32_t height)
|
||||
{
|
||||
for (auto y = 0u; y < height; ++y, buffer += bytesPerRow)
|
||||
{
|
||||
auto intPtr = reinterpret_cast<uint32_t*> (buffer);
|
||||
for (auto x = 0u; x < width; ++x, ++intPtr)
|
||||
{
|
||||
auto pixel = *intPtr;
|
||||
switch (SourceFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
switch (DestinationFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
*intPtr = shuffle<-2, 0, 2, 0> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
*intPtr = shuffle<-3, -1, 1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
*intPtr = shuffle<-1, -1, -1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
switch (DestinationFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
*intPtr = shuffle<-2, 0, 2, 0> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
*intPtr = shuffle<-1, -1, -1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
*intPtr = shuffle<-3, -1, 1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
switch (DestinationFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
*intPtr = shuffle<-1, -1, -1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
*intPtr = shuffle<-3, -1, 1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
*intPtr = shuffle<-2, 0, 2, 0> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
switch (DestinationFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
*intPtr = shuffle<-3, -1, 1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
*intPtr = shuffle<-1, -1, -1, 3> (pixel);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
*intPtr = shuffle<0, -2, 0, 2> (pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Private
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void convert (Format srcFormat, Format dstFormat, uint8_t* buffer, uint32_t bytesPerRow,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
using namespace Private;
|
||||
switch (srcFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
switch (dstFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
return;
|
||||
case Format::ABGR:
|
||||
{
|
||||
convert<Format::ARGB, Format::ABGR> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
convert<Format::ARGB, Format::RGBA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
convert<Format::ARGB, Format::BGRA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
switch (dstFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
convert<Format::ABGR, Format::ARGB> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
return;
|
||||
case Format::RGBA:
|
||||
{
|
||||
convert<Format::ABGR, Format::RGBA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
convert<Format::ABGR, Format::BGRA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
switch (dstFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
convert<Format::RGBA, Format::ARGB> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
convert<Format::RGBA, Format::ABGR> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
return;
|
||||
case Format::BGRA:
|
||||
{
|
||||
convert<Format::RGBA, Format::BGRA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
{
|
||||
switch (dstFormat)
|
||||
{
|
||||
case Format::ARGB:
|
||||
{
|
||||
convert<Format::BGRA, Format::ARGB> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::ABGR:
|
||||
{
|
||||
convert<Format::BGRA, Format::ABGR> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::RGBA:
|
||||
{
|
||||
convert<Format::BGRA, Format::RGBA> (buffer, bytesPerRow, width, height);
|
||||
break;
|
||||
}
|
||||
case Format::BGRA:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // PixelBuffer
|
||||
} // VSTGUI
|
||||
Reference in New Issue
Block a user