/* sane - Scanner Access Now Easy. Copyright (C) 2019 Povilas Kanapickas This file is part of the SANE package. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see .s */ #ifndef BACKEND_GENESYS_IMAGE_PIXEL_H #define BACKEND_GENESYS_IMAGE_PIXEL_H #include "enums.h" #include #include #include namespace genesys { // 16-bit values are in host endian enum class PixelFormat { UNKNOWN, I1, RGB111, I8, RGB888, BGR888, I16, RGB161616, BGR161616, }; struct Pixel { Pixel() = default; Pixel(std::uint16_t red, std::uint16_t green, std::uint16_t blue) : r{red}, g{green}, b{blue} {} std::uint16_t r = 0; std::uint16_t g = 0; std::uint16_t b = 0; bool operator==(const Pixel& other) const { return r == other.r && g == other.g && b == other.b; } }; struct RawPixel { RawPixel() = default; RawPixel(std::uint8_t d0) : data{d0, 0, 0, 0, 0, 0} {} RawPixel(std::uint8_t d0, std::uint8_t d1) : data{d0, d1, 0, 0, 0, 0} {} RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2) : data{d0, d1, d2, 0, 0, 0} {} RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2, std::uint8_t d3, std::uint8_t d4, std::uint8_t d5) : data{d0, d1, d2, d3, d4, d5} {} std::uint8_t data[6] = {}; bool operator==(const RawPixel& other) const { return std::equal(std::begin(data), std::end(data), std::begin(other.data)); } }; ColorOrder get_pixel_format_color_order(PixelFormat format); unsigned get_pixel_format_depth(PixelFormat format); unsigned get_pixel_channels(PixelFormat format); std::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width); std::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes); PixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order); // retrieves or sets the logical pixel values in 16-bit range. Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format); // retrieves or sets the physical pixel values. The low bytes of the RawPixel are interpreted as // the retrieved values / values to set RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format); // retrieves or sets the physical value of specific channel of the pixel. The channels are numbered // in the same order as the pixel is laid out in memory, that is, whichever channel comes first // has the index 0. E.g. 0-th channel in RGB888 is the red byte, but in BGR888 is the blue byte. std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, PixelFormat format); void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel, PixelFormat format); template Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x); template void set_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); template Pixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x); template void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); template std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel); template void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); } // namespace genesys #endif // BACKEND_GENESYS_IMAGE_PIXEL_H