engine/loaders: develop the ColorSpace feature infrastructure

Replace the existing fragile usage of the colorspace data type
with a new and robust concrete ColorSpace type.
This commit is contained in:
Hermet Park 2023-04-27 11:34:39 +09:00
parent bce5aef068
commit cf4484c1ad
19 changed files with 79 additions and 66 deletions

View file

@ -123,10 +123,10 @@ bool GlRenderer::endComposite(TVG_UNUSED Compositor* cmp)
}
int32_t GlRenderer::colorSpace()
ColorSpace GlRenderer::colorSpace()
{
//TODO: return a proper color space value.
return -1;
return ColorSpace::Unsupported;
}

View file

@ -50,7 +50,7 @@ public:
bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override;
bool endComposite(Compositor* cmp) override;
uint32_t colorSpace() override;
ColorSpace colorSpace() override;
static GlRenderer* gen();
static int init(TVG_UNUSED uint32_t threads);

View file

@ -1452,10 +1452,10 @@ void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
bool rasterCompositor(SwSurface* surface)
{
if (surface->cs == SwCanvas::ABGR8888 || surface->cs == SwCanvas::ABGR8888_STRAIGHT) {
if (surface->cs == ColorSpace::ABGR8888 || surface->cs == ColorSpace::ABGR8888S) {
surface->blender.join = _abgrJoin;
surface->blender.lumaValue = _abgrLumaValue;
} else if (surface->cs == SwCanvas::ARGB8888 || surface->cs == SwCanvas::ARGB8888_STRAIGHT) {
} else if (surface->cs == ColorSpace::ARGB8888 || surface->cs == ColorSpace::ARGB8888S) {
surface->blender.join = _argbJoin;
surface->blender.lumaValue = _argbLumaValue;
} else {

View file

@ -407,7 +407,7 @@ bool SwRenderer::viewport(const RenderRegion& vp)
}
bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace)
bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs)
{
if (!buffer || stride == 0 || w == 0 || h == 0 || w > stride) return false;
@ -417,7 +417,7 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
surface->stride = stride;
surface->w = w;
surface->h = h;
surface->cs = colorSpace;
surface->cs = cs;
vport.x = vport.y = 0;
vport.w = surface->w;
@ -447,7 +447,7 @@ void SwRenderer::clearCompositors()
bool SwRenderer::postRender()
{
//Unmultiply alpha if needed
if (surface->cs == SwCanvas::ABGR8888_STRAIGHT || surface->cs == SwCanvas::ARGB8888_STRAIGHT) {
if (surface->cs == ColorSpace::ABGR8888S || surface->cs == ColorSpace::ARGB8888S) {
rasterUnpremultiply(surface);
}
@ -755,10 +755,10 @@ SwRenderer::SwRenderer():mpool(globalMpool)
}
uint32_t SwRenderer::colorSpace()
ColorSpace SwRenderer::colorSpace()
{
if (surface) return surface->cs;
return tvg::SwCanvas::ARGB8888;
return ColorSpace::Unsupported;
}

View file

@ -50,7 +50,7 @@ public:
bool clear() override;
bool sync() override;
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace);
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs);
bool mempool(bool shared);
Compositor* target(const RenderRegion& region) override;
@ -58,7 +58,7 @@ public:
bool endComposite(Compositor* cmp) override;
void clearCompositors();
uint32_t colorSpace() override;
ColorSpace colorSpace() override;
static SwRenderer* gen();
static bool init(uint32_t threads);

View file

@ -37,7 +37,7 @@ public:
float vw = 0;
float vh = 0;
float w = 0, h = 0; //default image size
uint32_t colorSpace = SwCanvas::ARGB8888;
ColorSpace cs = ColorSpace::ARGB8888;
virtual ~LoadModule() {}
@ -50,7 +50,7 @@ public:
virtual bool read() = 0;
virtual bool close() = 0;
virtual unique_ptr<Surface> bitmap(uint32_t colorSpace) { return nullptr; }
virtual unique_ptr<Surface> bitmap(ColorSpace cs) { return nullptr; }
virtual unique_ptr<Paint> paint() { return nullptr; }
};

View file

@ -66,7 +66,7 @@ struct Picture::Impl
Surface* surface = nullptr; //bitmap picture uses
RenderData rd = nullptr; //engine data
float w = 0, h = 0;
uint32_t rendererColorSpace = 0;
ColorSpace rendererColorSpace = ColorSpace::Unsupported;
RenderMesh rm; //mesh data
bool resizing = false;

View file

@ -29,19 +29,30 @@
namespace tvg
{
using RenderData = void*;
enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255};
struct Surface;
enum ColorSpace
{
ABGR8888 = 0, //The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied.
ARGB8888, //The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied.
ABGR8888S, //The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied.
ARGB8888S, //The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied.
Unsupported //TODO: Change to the default, At the moment, we put it in the last to align with SwCanvas::Colorspace.
};
struct Surface
{
//TODO: Union for multiple types
uint32_t* buffer;
uint32_t stride;
uint32_t w, h;
uint32_t cs;
ColorSpace cs;
};
using RenderData = void*;
struct Compositor
{
CompositeMethod method;
@ -216,7 +227,7 @@ public:
virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
virtual bool endComposite(Compositor* cmp) = 0;
virtual uint32_t colorSpace() = 0;
virtual ColorSpace colorSpace() = 0;
};
}

View file

@ -85,7 +85,7 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
auto renderer = static_cast<SwRenderer*>(Canvas::pImpl->renderer);
if (!renderer) return Result::MemoryCorruption;
if (!renderer->target(buffer, stride, w, h, cs)) return Result::InvalidArguments;
if (!renderer->target(buffer, stride, w, h, static_cast<ColorSpace>(cs))) return Result::InvalidArguments;
//Paints must be updated again with this new target.
Canvas::pImpl->needRefresh();

View file

@ -29,29 +29,22 @@
/* Internal Class Implementation */
/************************************************************************/
void JpgLoader::clear()
{
if (freeData) free(data);
data = nullptr;
size = 0;
freeData = false;
}
uint32_t convertColorSpaceType(uint32_t colorSpace)
static uint32_t convertColorSpaceType(ColorSpace cs)
{
uint32_t tjpfColorSpace = TJPF_RGBX;
switch (colorSpace)
{
case SwCanvas::ARGB8888:
case SwCanvas::ARGB8888_STRAIGHT:
switch (cs) {
case ColorSpace::ARGB8888:
case ColorSpace::ARGB8888S:
default:
tjpfColorSpace = TJPF_BGRX;
break;
case SwCanvas::ABGR8888:
case SwCanvas::ABGR8888_STRAIGHT:
break;
case ColorSpace::ABGR8888:
case ColorSpace::ABGR8888S:
tjpfColorSpace = TJPF_RGBX;
break;
break;
}
return tjpfColorSpace;
}
@ -73,6 +66,15 @@ static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h)
}
}
void JpgLoader::clear()
{
if (freeData) free(data);
data = nullptr;
size = 0;
freeData = false;
}
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
@ -163,11 +165,11 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy)
bool JpgLoader::read()
{
if (image) tjFree(image);
image = (unsigned char *)tjAlloc(static_cast<int>(w) * static_cast<int>(h) * tjPixelSize[convertColorSpaceType(colorSpace)]);
image = (unsigned char *)tjAlloc(static_cast<int>(w) * static_cast<int>(h) * tjPixelSize[convertColorSpaceType(cs)]);
if (!image) return false;
//decompress jpg image
if (tjDecompress2(jpegDecompressor, data, size, image, static_cast<int>(w), 0, static_cast<int>(h), convertColorSpaceType(colorSpace), 0) < 0) {
if (tjDecompress2(jpegDecompressor, data, size, image, static_cast<int>(w), 0, static_cast<int>(h), convertColorSpaceType(cs), 0) < 0) {
TVGERR("JPG LOADER", "%s", tjGetErrorStr());
tjFree(image);
image = nullptr;
@ -185,11 +187,11 @@ bool JpgLoader::close()
}
unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
unique_ptr<Surface> JpgLoader::bitmap(ColorSpace cs)
{
if (!image) return nullptr;
if (this->colorSpace != colorSpace) {
this->colorSpace = colorSpace;
if (this->cs != cs) {
this->cs = cs;
_changeColorSpace(reinterpret_cast<uint32_t*>(image), w, h);
}
@ -198,7 +200,7 @@ unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
surface->stride = w;
surface->w = w;
surface->h = h;
surface->cs = colorSpace;
surface->cs = cs;
return unique_ptr<Surface>(surface);
}

View file

@ -38,7 +38,7 @@ public:
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
unique_ptr<Surface> bitmap(ColorSpace cs) override;
private:
void clear();

View file

@ -128,11 +128,11 @@ bool PngLoader::close()
return true;
}
unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
unique_ptr<Surface> PngLoader::bitmap(ColorSpace cs)
{
if (!content) return nullptr;
if (this->colorSpace != colorSpace) {
this->colorSpace = colorSpace;
if (this->cs != cs) {
this->cs = cs;
_changeColorSpace(content, w, h);
}
@ -141,7 +141,7 @@ unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
surface->stride = w;
surface->w = w;
surface->h = h;
surface->cs = colorSpace;
surface->cs = cs;
return unique_ptr<Surface>(surface);
}

View file

@ -37,7 +37,7 @@ public:
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
unique_ptr<Surface> bitmap(ColorSpace cs) override;
private:
png_imagep image = nullptr;

View file

@ -128,13 +128,13 @@ bool JpgLoader::close()
}
unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
unique_ptr<Surface> JpgLoader::bitmap(ColorSpace cs)
{
this->done();
if (!image) return nullptr;
if (this->colorSpace != colorSpace) {
this->colorSpace = colorSpace;
if (this->cs != cs) {
this->cs = cs;
_changeColorSpace(reinterpret_cast<uint32_t*>(image), static_cast<uint32_t>(w), static_cast<uint32_t>(h));
}
@ -143,7 +143,7 @@ unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
surface->stride = static_cast<uint32_t>(w);
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = colorSpace;
surface->cs = cs;
return unique_ptr<Surface>(surface);
}

View file

@ -45,7 +45,7 @@ public:
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
unique_ptr<Surface> bitmap(ColorSpace cs) override;
void run(unsigned tid) override;
};

View file

@ -125,7 +125,7 @@ bool PngLoader::open(const string& path)
h = static_cast<float>(height);
ret = true;
if (state.info_png.color.colortype == LCT_RGBA) colorSpace = SwCanvas::ABGR8888;
if (state.info_png.color.colortype == LCT_RGBA) cs = ColorSpace::ABGR8888;
goto finalize;
@ -161,7 +161,7 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
h = static_cast<float>(height);
this->size = size;
if (state.info_png.color.colortype == LCT_RGBA) colorSpace = SwCanvas::ABGR8888;
if (state.info_png.color.colortype == LCT_RGBA) cs = ColorSpace::ABGR8888;
return true;
}
@ -185,13 +185,13 @@ bool PngLoader::close()
}
unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
unique_ptr<Surface> PngLoader::bitmap(ColorSpace cs)
{
this->done();
if (!image) return nullptr;
if (this->colorSpace != colorSpace) {
this->colorSpace = colorSpace;
if (this->cs != cs) {
this->cs = cs;
_changeColorSpace(reinterpret_cast<uint32_t*>(image), static_cast<uint32_t>(w), static_cast<uint32_t>(h));
}
@ -200,7 +200,7 @@ unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
surface->stride = static_cast<uint32_t>(w);
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = colorSpace;
surface->cs = cs;
return unique_ptr<Surface>(surface);
}

View file

@ -48,7 +48,7 @@ public:
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
unique_ptr<Surface> bitmap(ColorSpace cs) override;
void run(unsigned tid) override;
};

View file

@ -90,11 +90,11 @@ bool RawLoader::close()
}
unique_ptr<Surface> RawLoader::bitmap(uint32_t colorSpace)
unique_ptr<Surface> RawLoader::bitmap(ColorSpace cs)
{
if (!content) return nullptr;
if (this->colorSpace != colorSpace) {
this->colorSpace = colorSpace;
if (this->cs != cs) {
this->cs = cs;
_changeColorSpace(content, static_cast<uint32_t>(w), static_cast<uint32_t>(h));
}
@ -103,7 +103,7 @@ unique_ptr<Surface> RawLoader::bitmap(uint32_t colorSpace)
surface->stride = static_cast<uint32_t>(w);
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = colorSpace;
surface->cs = cs;
return unique_ptr<Surface>(surface);
}

View file

@ -36,7 +36,7 @@ public:
bool read() override;
bool close() override;
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
unique_ptr<Surface> bitmap(ColorSpace cs) override;
};