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 As a special exception, the authors of SANE give permission for 21 additional uses of the libraries contained in this release of SANE. 22 23 The exception is that, if you link a SANE library with other files 24 to produce an executable, this does not by itself cause the 25 resulting executable to be covered by the GNU General Public 26 License. Your use of that executable is in no way restricted on 27 account of linking the SANE library code into it. 28 29 This exception does not, however, invalidate any other reasons why 30 the executable file might be covered by the GNU General Public 31 License. 32 33 If you submit changes to SANE to the maintainers to be included in 34 a subsequent release, you agree by submitting the changes that 35 those changes may be distributed with this exception intact. 36 37 If you write modifications of your own for SANE, it is your choice 38 whether to permit this exception to apply to your modifications. 39 If you do not wish that, delete this exception notice. 40 */ 41 42 #ifndef BACKEND_GENESYS_IMAGE_PIXEL_H 43 #define BACKEND_GENESYS_IMAGE_PIXEL_H 44 45 #include "enums.h" 46 #include <algorithm> 47 #include <cstdint> 48 #include <cstddef> 49 50 namespace genesys { 51 52 // 16-bit values are in host endian 53 enum class PixelFormat 54 { 55 UNKNOWN, 56 I1, 57 RGB111, 58 I8, 59 RGB888, 60 BGR888, 61 I16, 62 RGB161616, 63 BGR161616, 64 }; 65 66 struct Pixel 67 { 68 Pixel() = default; PixelPixel69 Pixel(std::uint16_t red, std::uint16_t green, std::uint16_t blue) : 70 r{red}, g{green}, b{blue} {} 71 72 std::uint16_t r = 0; 73 std::uint16_t g = 0; 74 std::uint16_t b = 0; 75 76 bool operator==(const Pixel& other) const 77 { 78 return r == other.r && g == other.g && b == other.b; 79 } 80 }; 81 82 struct RawPixel 83 { 84 RawPixel() = default; RawPixelRawPixel85 RawPixel(std::uint8_t d0) : data{d0, 0, 0, 0, 0, 0} {} RawPixelRawPixel86 RawPixel(std::uint8_t d0, std::uint8_t d1) : data{d0, d1, 0, 0, 0, 0} {} RawPixelRawPixel87 RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2) : data{d0, d1, d2, 0, 0, 0} {} RawPixelRawPixel88 RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2, 89 std::uint8_t d3, std::uint8_t d4, std::uint8_t d5) : data{d0, d1, d2, d3, d4, d5} {} 90 std::uint8_t data[6] = {}; 91 92 bool operator==(const RawPixel& other) const 93 { 94 return std::equal(std::begin(data), std::end(data), 95 std::begin(other.data)); 96 } 97 }; 98 99 ColorOrder get_pixel_format_color_order(PixelFormat format); 100 unsigned get_pixel_format_depth(PixelFormat format); 101 unsigned get_pixel_channels(PixelFormat format); 102 std::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width); 103 104 std::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes); 105 106 PixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order); 107 108 // retrieves or sets the logical pixel values in 16-bit range. 109 Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); 110 void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format); 111 112 // retrieves or sets the physical pixel values. The low bytes of the RawPixel are interpreted as 113 // the retrieved values / values to set 114 RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); 115 void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format); 116 117 // retrieves or sets the physical value of specific channel of the pixel. The channels are numbered 118 // in the same order as the pixel is laid out in memory, that is, whichever channel comes first 119 // has the index 0. E.g. 0-th channel in RGB888 is the red byte, but in BGR888 is the blue byte. 120 std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, 121 PixelFormat format); 122 void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel, 123 PixelFormat format); 124 125 template<PixelFormat Format> 126 Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x); 127 template<PixelFormat Format> 128 void set_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); 129 130 template<PixelFormat Format> 131 Pixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x); 132 template<PixelFormat Format> 133 void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); 134 135 template<PixelFormat Format> 136 std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel); 137 template<PixelFormat Format> 138 void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, 139 std::uint16_t pixel); 140 141 } // namespace genesys 142 143 #endif // BACKEND_GENESYS_IMAGE_PIXEL_H 144