1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci   Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   This file is part of the SANE package.
6141cc406Sopenharmony_ci
7141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
8141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
9141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
10141cc406Sopenharmony_ci   License, or (at your option) any later version.
11141cc406Sopenharmony_ci
12141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
13141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
14141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15141cc406Sopenharmony_ci   General Public License for more details.
16141cc406Sopenharmony_ci
17141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
18141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
19141cc406Sopenharmony_ci*/
20141cc406Sopenharmony_ci
21141cc406Sopenharmony_ci#ifndef BACKEND_GENESYS_IMAGE_PIXEL_H
22141cc406Sopenharmony_ci#define BACKEND_GENESYS_IMAGE_PIXEL_H
23141cc406Sopenharmony_ci
24141cc406Sopenharmony_ci#include "enums.h"
25141cc406Sopenharmony_ci#include <algorithm>
26141cc406Sopenharmony_ci#include <cstdint>
27141cc406Sopenharmony_ci#include <cstddef>
28141cc406Sopenharmony_ci
29141cc406Sopenharmony_cinamespace genesys {
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci// 16-bit values are in host endian
32141cc406Sopenharmony_cienum class PixelFormat
33141cc406Sopenharmony_ci{
34141cc406Sopenharmony_ci    UNKNOWN,
35141cc406Sopenharmony_ci    I1,
36141cc406Sopenharmony_ci    RGB111,
37141cc406Sopenharmony_ci    I8,
38141cc406Sopenharmony_ci    RGB888,
39141cc406Sopenharmony_ci    BGR888,
40141cc406Sopenharmony_ci    I16,
41141cc406Sopenharmony_ci    RGB161616,
42141cc406Sopenharmony_ci    BGR161616,
43141cc406Sopenharmony_ci};
44141cc406Sopenharmony_ci
45141cc406Sopenharmony_cistruct Pixel
46141cc406Sopenharmony_ci{
47141cc406Sopenharmony_ci    Pixel() = default;
48141cc406Sopenharmony_ci    Pixel(std::uint16_t red, std::uint16_t green, std::uint16_t blue) :
49141cc406Sopenharmony_ci        r{red}, g{green}, b{blue} {}
50141cc406Sopenharmony_ci
51141cc406Sopenharmony_ci    std::uint16_t r = 0;
52141cc406Sopenharmony_ci    std::uint16_t g = 0;
53141cc406Sopenharmony_ci    std::uint16_t b = 0;
54141cc406Sopenharmony_ci
55141cc406Sopenharmony_ci    bool operator==(const Pixel& other) const
56141cc406Sopenharmony_ci    {
57141cc406Sopenharmony_ci        return r == other.r && g == other.g && b == other.b;
58141cc406Sopenharmony_ci    }
59141cc406Sopenharmony_ci};
60141cc406Sopenharmony_ci
61141cc406Sopenharmony_cistruct RawPixel
62141cc406Sopenharmony_ci{
63141cc406Sopenharmony_ci    RawPixel() = default;
64141cc406Sopenharmony_ci    RawPixel(std::uint8_t d0) : data{d0, 0, 0, 0, 0, 0} {}
65141cc406Sopenharmony_ci    RawPixel(std::uint8_t d0, std::uint8_t d1) : data{d0, d1, 0, 0, 0, 0} {}
66141cc406Sopenharmony_ci    RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2) : data{d0, d1, d2, 0, 0, 0} {}
67141cc406Sopenharmony_ci    RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2,
68141cc406Sopenharmony_ci             std::uint8_t d3, std::uint8_t d4, std::uint8_t d5) : data{d0, d1, d2, d3, d4, d5} {}
69141cc406Sopenharmony_ci    std::uint8_t data[6] = {};
70141cc406Sopenharmony_ci
71141cc406Sopenharmony_ci    bool operator==(const RawPixel& other) const
72141cc406Sopenharmony_ci    {
73141cc406Sopenharmony_ci        return std::equal(std::begin(data), std::end(data),
74141cc406Sopenharmony_ci                          std::begin(other.data));
75141cc406Sopenharmony_ci    }
76141cc406Sopenharmony_ci};
77141cc406Sopenharmony_ci
78141cc406Sopenharmony_ciColorOrder get_pixel_format_color_order(PixelFormat format);
79141cc406Sopenharmony_ciunsigned get_pixel_format_depth(PixelFormat format);
80141cc406Sopenharmony_ciunsigned get_pixel_channels(PixelFormat format);
81141cc406Sopenharmony_cistd::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width);
82141cc406Sopenharmony_ci
83141cc406Sopenharmony_cistd::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes);
84141cc406Sopenharmony_ci
85141cc406Sopenharmony_ciPixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order);
86141cc406Sopenharmony_ci
87141cc406Sopenharmony_ci// retrieves or sets the logical pixel values in 16-bit range.
88141cc406Sopenharmony_ciPixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format);
89141cc406Sopenharmony_civoid set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format);
90141cc406Sopenharmony_ci
91141cc406Sopenharmony_ci// retrieves or sets the physical pixel values. The low bytes of the RawPixel are interpreted as
92141cc406Sopenharmony_ci// the retrieved values / values to set
93141cc406Sopenharmony_ciRawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format);
94141cc406Sopenharmony_civoid set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format);
95141cc406Sopenharmony_ci
96141cc406Sopenharmony_ci// retrieves or sets the physical value of specific channel of the pixel. The channels are numbered
97141cc406Sopenharmony_ci// in the same order as the pixel is laid out in memory, that is, whichever channel comes first
98141cc406Sopenharmony_ci// has the index 0. E.g. 0-th channel in RGB888 is the red byte, but in BGR888 is the blue byte.
99141cc406Sopenharmony_cistd::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel,
100141cc406Sopenharmony_ci                                       PixelFormat format);
101141cc406Sopenharmony_civoid set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel,
102141cc406Sopenharmony_ci                            PixelFormat format);
103141cc406Sopenharmony_ci
104141cc406Sopenharmony_citemplate<PixelFormat Format>
105141cc406Sopenharmony_ciPixel get_pixel_from_row(const std::uint8_t* data, std::size_t x);
106141cc406Sopenharmony_citemplate<PixelFormat Format>
107141cc406Sopenharmony_civoid set_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel);
108141cc406Sopenharmony_ci
109141cc406Sopenharmony_citemplate<PixelFormat Format>
110141cc406Sopenharmony_ciPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x);
111141cc406Sopenharmony_citemplate<PixelFormat Format>
112141cc406Sopenharmony_civoid set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel);
113141cc406Sopenharmony_ci
114141cc406Sopenharmony_citemplate<PixelFormat Format>
115141cc406Sopenharmony_cistd::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel);
116141cc406Sopenharmony_citemplate<PixelFormat Format>
117141cc406Sopenharmony_civoid set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel,
118141cc406Sopenharmony_ci                            std::uint16_t pixel);
119141cc406Sopenharmony_ci
120141cc406Sopenharmony_ci} // namespace genesys
121141cc406Sopenharmony_ci
122141cc406Sopenharmony_ci#endif // BACKEND_GENESYS_IMAGE_PIXEL_H
123