blob: a8c719ad0486a0f96c8cfe09eda6bb4c74608387 [file] [log] [blame]
// Copyright 2018 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/lib/yuv/yuv.h"
#include <algorithm>
#include <cmath>
namespace {
uint8_t NormalizedFloatToUnsignedByte(float in) {
int32_t out = std::roundf(in * 255.0f);
return static_cast<uint8_t>(std::clamp(out, 0, 255));
}
} // namespace
namespace yuv {
// Letting compiler decide whether to inline, for now.
void YuvToBgra(uint8_t y_raw, uint8_t u_raw, uint8_t v_raw, uint8_t* bgra) {
// Convert from encoded space to normalized space assuming eItuNarrow.
int32_t y = static_cast<int32_t>(y_raw) - 16;
int32_t u = static_cast<int32_t>(u_raw) - 128;
int32_t v = static_cast<int32_t>(v_raw) - 128;
// Note: Normally, we would clamp here. But some drivers do not clamp in the
// middle of their implementation, and this function is used for pixel tests.
float fy = static_cast<float>(y) / 219.0f;
float fu = static_cast<float>(u) / 224.0f;
float fv = static_cast<float>(v) / 224.0f;
// Convert from YUV to RGB using the coefficients for eYcbcr709.
float r = fy + 1.5748f * fv;
float g = fy - (0.13397432f / 0.7152f) * fu - (0.33480248f / 0.7152) * fv;
float b = fy + 1.8556f * fu;
bgra[0] = NormalizedFloatToUnsignedByte(b); // blue
bgra[1] = NormalizedFloatToUnsignedByte(g); // green
bgra[2] = NormalizedFloatToUnsignedByte(r); // red
bgra[3] = 0xff; // alpha
}
} // namespace yuv