blob: 05b5f6ae5e0f62b3dd42f64265122aeff2185d25 [file] [log] [blame]
// Copyright 2022 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.
#ifndef SRC_CAMERA_LIB_RAW_FORMATS_RAW_COLOR_FILTER_H_
#define SRC_CAMERA_LIB_RAW_FORMATS_RAW_COLOR_FILTER_H_
#include "src/camera/lib/raw_formats/pointer_list.h"
#include "src/camera/lib/raw_formats/raw_hash.h"
namespace camera::raw {
/* Pixel colors that can make up the color filter. The 3 tranditional bayer colors are red, green,
and blue, with green appearing twice. However in some instances it is useful to be able to
distinguish between the two green pixels, so GREENr (for the greens on the same row as RED
pixels) and GREENb (for greens on the same as BLUE pixles) have been added.
There are also camera color filters which have moved away from the bayer patterns/colors and this
library should be able to support them as well. However, other colors will be added to this
enumeration as the actual formats which require them are added. This avoids guessing and adding
things we may never need or that may clash with things we want to add in the future. However some
of those future colors may include GREEN (for formats with only one green value), YELLOW, WHITE
and/or CLEAR, EMERALD, ane NIR (near infra-red).
*/
enum class PixelColor {
RED,
GREENr,
GREENb,
BLUE,
};
/* Represents the color filter of a raw image. Some examples include the 4 basic bayer patterns
which are defined as constants below. Many (but not all) raw formats will require the image width
and height to be even multiples of the color filter pattern width and height respectively.
*/
struct ColorFilter {
const uint32_t width;
const uint32_t height;
const PointerList<PixelColor> rows;
constexpr explicit ColorFilter(const PointerList<PixelColor>& r)
: width(static_cast<uint32_t>(r.element_array_size())),
height(static_cast<uint32_t>(r.size())),
rows(r) {}
constexpr explicit ColorFilter(PointerList<PixelColor>&& r)
: width(static_cast<uint32_t>(r.element_array_size())),
height(static_cast<uint32_t>(r.size())),
rows(std::move(r)) {}
};
// Given a ColorFilter, return the color of the specified pixel.
// Pixel is specified as an x (width) and y (height) coordinate.
constexpr PixelColor GetPixelColor(const ColorFilter& filter, uint32_t x, uint32_t y) {
uint32_t filter_y = y % filter.height;
uint32_t filter_x = x % filter.width;
return filter.rows[filter_y][filter_x];
}
// Given a ColorFilter and the image width/height, return the color of the specified pixel.
// Pixel is specified as an index (0 to (width * height) - 1).
constexpr PixelColor GetPixelColor(const ColorFilter& filter, uint32_t width, uint32_t /*height*/,
uint32_t pixel_index) {
uint32_t y = pixel_index / width;
uint32_t x = pixel_index - (y * width);
return GetPixelColor(filter, x, y);
}
namespace internal {
template <>
struct hash<ColorFilter> {
constexpr size_t operator()(ColorFilter const& filter) {
size_t seed = 0;
internal::hash_combine(seed, filter.width);
internal::hash_combine(seed, filter.height);
for (uint32_t j = 0; j < filter.height; ++j) {
for (uint32_t i = 0; i < filter.width; ++i) {
internal::hash_combine(seed, filter.rows[j][i]);
}
}
return seed;
}
};
constexpr const PixelColor kBGGRRow0[] = {PixelColor::BLUE, PixelColor::GREENb};
constexpr const PixelColor kBGGRRow1[] = {PixelColor::GREENr, PixelColor::RED};
constexpr const PixelColor* kBGGRRows[] = {&(kBGGRRow0[0]), &(kBGGRRow1[0])};
constexpr const uint64_t kBGGRWidth = sizeof(kBGGRRow0) / sizeof(*kBGGRRow0);
constexpr const uint64_t kBGGRHeight = sizeof(kBGGRRows) / sizeof(*kBGGRRows);
constexpr const PointerList<PixelColor> kBGGRRowsList(kBGGRRows, kBGGRHeight, kBGGRWidth);
constexpr const PixelColor kGBRGRow0[] = {PixelColor::GREENb, PixelColor::BLUE};
constexpr const PixelColor kGBRGRow1[] = {PixelColor::RED, PixelColor::GREENr};
constexpr const PixelColor* kGBRGRows[] = {&(kGBRGRow0[0]), &(kGBRGRow1[0])};
constexpr const uint64_t kGBRGWidth = sizeof(kGBRGRow0) / sizeof(*kGBRGRow0);
constexpr const uint64_t kGBRGHeight = sizeof(kGBRGRows) / sizeof(*kGBRGRows);
constexpr const PointerList<PixelColor> kGBRGRowsList(kGBRGRows, kGBRGHeight, kGBRGWidth);
constexpr const PixelColor kGRBGRow0[] = {PixelColor::GREENr, PixelColor::RED};
constexpr const PixelColor kGRBGRow1[] = {PixelColor::BLUE, PixelColor::GREENb};
constexpr const PixelColor* kGRBGRows[] = {&(kGRBGRow0[0]), &(kGRBGRow1[0])};
constexpr const uint64_t kGRBGWidth = sizeof(kGRBGRow0) / sizeof(*kGRBGRow0);
constexpr const uint64_t kGRBGHeight = sizeof(kGRBGRows) / sizeof(*kGRBGRows);
constexpr const PointerList<PixelColor> kGRBGRowsList(kGRBGRows, kGRBGHeight, kGRBGWidth);
constexpr const PixelColor kRGGBRow0[] = {PixelColor::RED, PixelColor::GREENr};
constexpr const PixelColor kRGGBRow1[] = {PixelColor::GREENb, PixelColor::BLUE};
constexpr const PixelColor* kRGGBRows[] = {&(kRGGBRow0[0]), &(kRGGBRow1[0])};
constexpr const uint64_t kRGGBWidth = sizeof(kRGGBRow0) / sizeof(*kRGGBRow0);
constexpr const uint64_t kRGGBHeight = sizeof(kRGGBRows) / sizeof(*kRGGBRows);
constexpr const PointerList<PixelColor> kRGGBRowsList(kRGGBRows, kRGGBHeight, kRGGBWidth);
} // namespace internal
// The 4 common bayer phases.
constexpr ColorFilter kBayerBGGR(internal::kBGGRRowsList);
constexpr ColorFilter kBayerGBRG(internal::kGBRGRowsList);
constexpr ColorFilter kBayerGRBG(internal::kGRBGRowsList);
constexpr ColorFilter kBayerRGGB(internal::kRGGBRowsList);
} // namespace camera::raw
#endif // SRC_CAMERA_LIB_RAW_FORMATS_RAW_COLOR_FILTER_H_