1 /* sane - Scanner Access Now Easy. 2 3 Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> 4 5 This file is part of the SANE package. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef BACKEND_GENESYS_IMAGE_PIXEL_H 22 #define BACKEND_GENESYS_IMAGE_PIXEL_H 23 24 #include "enums.h" 25 #include <algorithm> 26 #include <cstdint> 27 #include <cstddef> 28 29 namespace genesys { 30 31 // 16-bit values are in host endian 32 enum class PixelFormat 33 { 34 UNKNOWN, 35 I1, 36 RGB111, 37 I8, 38 RGB888, 39 BGR888, 40 I16, 41 RGB161616, 42 BGR161616, 43 }; 44 45 struct Pixel 46 { 47 Pixel() = default; Pixelgenesys::Pixel48 Pixel(std::uint16_t red, std::uint16_t green, std::uint16_t blue) : 49 r{red}, g{green}, b{blue} {} 50 51 std::uint16_t r = 0; 52 std::uint16_t g = 0; 53 std::uint16_t b = 0; 54 operator ==genesys::Pixel55 bool operator==(const Pixel& other) const 56 { 57 return r == other.r && g == other.g && b == other.b; 58 } 59 }; 60 61 struct RawPixel 62 { 63 RawPixel() = default; RawPixelgenesys::RawPixel64 RawPixel(std::uint8_t d0) : data{d0, 0, 0, 0, 0, 0} {} RawPixelgenesys::RawPixel65 RawPixel(std::uint8_t d0, std::uint8_t d1) : data{d0, d1, 0, 0, 0, 0} {} RawPixelgenesys::RawPixel66 RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2) : data{d0, d1, d2, 0, 0, 0} {} RawPixelgenesys::RawPixel67 RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2, 68 std::uint8_t d3, std::uint8_t d4, std::uint8_t d5) : data{d0, d1, d2, d3, d4, d5} {} 69 std::uint8_t data[6] = {}; 70 operator ==genesys::RawPixel71 bool operator==(const RawPixel& other) const 72 { 73 return std::equal(std::begin(data), std::end(data), 74 std::begin(other.data)); 75 } 76 }; 77 78 ColorOrder get_pixel_format_color_order(PixelFormat format); 79 unsigned get_pixel_format_depth(PixelFormat format); 80 unsigned get_pixel_channels(PixelFormat format); 81 std::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width); 82 83 std::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes); 84 85 PixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order); 86 87 // retrieves or sets the logical pixel values in 16-bit range. 88 Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); 89 void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format); 90 91 // retrieves or sets the physical pixel values. The low bytes of the RawPixel are interpreted as 92 // the retrieved values / values to set 93 RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); 94 void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format); 95 96 // retrieves or sets the physical value of specific channel of the pixel. The channels are numbered 97 // in the same order as the pixel is laid out in memory, that is, whichever channel comes first 98 // has the index 0. E.g. 0-th channel in RGB888 is the red byte, but in BGR888 is the blue byte. 99 std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, 100 PixelFormat format); 101 void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel, 102 PixelFormat format); 103 104 template<PixelFormat Format> 105 Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x); 106 template<PixelFormat Format> 107 void set_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); 108 109 template<PixelFormat Format> 110 Pixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x); 111 template<PixelFormat Format> 112 void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); 113 114 template<PixelFormat Format> 115 std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel); 116 template<PixelFormat Format> 117 void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, 118 std::uint16_t pixel); 119 120 } // namespace genesys 121 122 #endif // BACKEND_GENESYS_IMAGE_PIXEL_H 123