blob: 1e2396904e21e61463542673dd9a25c6c49a51cd [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/scenic/lib/utils/pixel.h"
#include <lib/syslog/cpp/macros.h>
namespace utils {
namespace {
// List of supported pixel formats
std::vector<fuchsia::sysmem::PixelFormatType> kSupportedPixelFormats = {
fuchsia::sysmem::PixelFormatType::BGRA32, fuchsia::sysmem::PixelFormatType::R8G8B8A8};
} // namespace
uint8_t LinearToSrgb(const float val) {
// Function to convert from linear RGB to sRGB.
// (https://en.wikipedia.org/wiki/SRGB#From_CIE_XYZ_to_sRGB)
if (0.f <= val && val <= 0.0031308f) {
return static_cast<uint8_t>(roundf((val * 12.92f) * 255U));
}
return static_cast<uint8_t>(roundf(((powf(val, 1.0f / 2.4f) * 1.055f) - 0.055f) * 255U));
}
Pixel Pixel::FromUnormBgra(float blue, float green, float red, float alpha) {
return Pixel{LinearToSrgb(blue), LinearToSrgb(green), LinearToSrgb(red),
static_cast<uint8_t>(roundf(alpha * 255U))};
}
Pixel Pixel::FromVmo(const uint8_t* vmo_host, uint32_t stride, uint32_t x, uint32_t y,
fuchsia::sysmem::PixelFormatType type) {
if (type == fuchsia::sysmem::PixelFormatType::BGRA32) {
return FromVmoBgra(vmo_host, stride, x, y);
}
FX_DCHECK(type == fuchsia::sysmem::PixelFormatType::R8G8B8A8);
return FromVmoRgba(vmo_host, stride, x, y);
}
Pixel Pixel::FromVmoRgba(const uint8_t* vmo_host, uint32_t stride, uint32_t x, uint32_t y) {
uint8_t r = vmo_host[y * stride * 4 + x * 4];
uint8_t g = vmo_host[y * stride * 4 + x * 4 + 1];
uint8_t b = vmo_host[y * stride * 4 + x * 4 + 2];
uint8_t a = vmo_host[y * stride * 4 + x * 4 + 3];
return utils::Pixel(b, g, r, a);
}
Pixel Pixel::FromVmoBgra(const uint8_t* vmo_host, uint32_t stride, uint32_t x, uint32_t y) {
uint8_t b = vmo_host[y * stride * 4 + x * 4];
uint8_t g = vmo_host[y * stride * 4 + x * 4 + 1];
uint8_t r = vmo_host[y * stride * 4 + x * 4 + 2];
uint8_t a = vmo_host[y * stride * 4 + x * 4 + 3];
return utils::Pixel(b, g, r, a);
}
std::vector<uint8_t> Pixel::ToFormat(fuchsia::sysmem::PixelFormatType type) {
if (type == fuchsia::sysmem::PixelFormatType::BGRA32) {
return ToBgra();
}
FX_DCHECK(type == fuchsia::sysmem::PixelFormatType::R8G8B8A8);
return ToRgba();
}
bool Pixel::IsFormatSupported(fuchsia::sysmem::PixelFormatType type) {
return std::any_of(
kSupportedPixelFormats.begin(), kSupportedPixelFormats.end(),
[type](fuchsia::sysmem::PixelFormatType supported) { return supported == type; });
}
std::ostream& operator<<(std::ostream& stream, const Pixel& pixel) {
return stream << "{Pixel:" << " r:" << static_cast<unsigned int>(pixel.red)
<< " g:" << static_cast<unsigned int>(pixel.green)
<< " b:" << static_cast<unsigned int>(pixel.blue)
<< " a:" << static_cast<unsigned int>(pixel.alpha) << "}";
}
} // namespace utils