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#define DEBUG_DECLARE_ONLY 22141cc406Sopenharmony_ci 23141cc406Sopenharmony_ci#include "image.h" 24141cc406Sopenharmony_ci 25141cc406Sopenharmony_ci#include <array> 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_cinamespace genesys { 28141cc406Sopenharmony_ci 29141cc406Sopenharmony_cistruct PixelFormatDesc 30141cc406Sopenharmony_ci{ 31141cc406Sopenharmony_ci PixelFormat format; 32141cc406Sopenharmony_ci unsigned depth; 33141cc406Sopenharmony_ci unsigned channels; 34141cc406Sopenharmony_ci ColorOrder order; 35141cc406Sopenharmony_ci}; 36141cc406Sopenharmony_ci 37141cc406Sopenharmony_ciconst PixelFormatDesc s_known_pixel_formats[] = { 38141cc406Sopenharmony_ci { PixelFormat::I1, 1, 1, ColorOrder::RGB }, 39141cc406Sopenharmony_ci { PixelFormat::I8, 8, 1, ColorOrder::RGB }, 40141cc406Sopenharmony_ci { PixelFormat::I16, 16, 1, ColorOrder::RGB }, 41141cc406Sopenharmony_ci { PixelFormat::RGB111, 1, 3, ColorOrder::RGB }, 42141cc406Sopenharmony_ci { PixelFormat::RGB888, 8, 3, ColorOrder::RGB }, 43141cc406Sopenharmony_ci { PixelFormat::RGB161616, 16, 3, ColorOrder::RGB }, 44141cc406Sopenharmony_ci { PixelFormat::BGR888, 8, 3, ColorOrder::BGR }, 45141cc406Sopenharmony_ci { PixelFormat::BGR161616, 16, 3, ColorOrder::BGR }, 46141cc406Sopenharmony_ci}; 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci 49141cc406Sopenharmony_ciColorOrder get_pixel_format_color_order(PixelFormat format) 50141cc406Sopenharmony_ci{ 51141cc406Sopenharmony_ci for (const auto& desc : s_known_pixel_formats) { 52141cc406Sopenharmony_ci if (desc.format == format) 53141cc406Sopenharmony_ci return desc.order; 54141cc406Sopenharmony_ci } 55141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 56141cc406Sopenharmony_ci} 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci 59141cc406Sopenharmony_ciunsigned get_pixel_format_depth(PixelFormat format) 60141cc406Sopenharmony_ci{ 61141cc406Sopenharmony_ci for (const auto& desc : s_known_pixel_formats) { 62141cc406Sopenharmony_ci if (desc.format == format) 63141cc406Sopenharmony_ci return desc.depth; 64141cc406Sopenharmony_ci } 65141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 66141cc406Sopenharmony_ci} 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_ciunsigned get_pixel_channels(PixelFormat format) 69141cc406Sopenharmony_ci{ 70141cc406Sopenharmony_ci for (const auto& desc : s_known_pixel_formats) { 71141cc406Sopenharmony_ci if (desc.format == format) 72141cc406Sopenharmony_ci return desc.channels; 73141cc406Sopenharmony_ci } 74141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 75141cc406Sopenharmony_ci} 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_cistd::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width) 78141cc406Sopenharmony_ci{ 79141cc406Sopenharmony_ci std::size_t depth = get_pixel_format_depth(format) * get_pixel_channels(format); 80141cc406Sopenharmony_ci std::size_t total_bits = depth * width; 81141cc406Sopenharmony_ci return total_bits / 8 + ((total_bits % 8 > 0) ? 1 : 0); 82141cc406Sopenharmony_ci} 83141cc406Sopenharmony_ci 84141cc406Sopenharmony_cistd::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes) 85141cc406Sopenharmony_ci{ 86141cc406Sopenharmony_ci std::size_t depth = get_pixel_format_depth(format) * get_pixel_channels(format); 87141cc406Sopenharmony_ci return (row_bytes * 8) / depth; 88141cc406Sopenharmony_ci} 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ciPixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order) 91141cc406Sopenharmony_ci{ 92141cc406Sopenharmony_ci for (const auto& desc : s_known_pixel_formats) { 93141cc406Sopenharmony_ci if (desc.depth == depth && desc.channels == channels && desc.order == order) { 94141cc406Sopenharmony_ci return desc.format; 95141cc406Sopenharmony_ci } 96141cc406Sopenharmony_ci } 97141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d %d %d", depth, channels, 98141cc406Sopenharmony_ci static_cast<unsigned>(order)); 99141cc406Sopenharmony_ci} 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_cistatic inline unsigned read_bit(const std::uint8_t* data, std::size_t x) 102141cc406Sopenharmony_ci{ 103141cc406Sopenharmony_ci return (data[x / 8] >> (7 - (x % 8))) & 0x1; 104141cc406Sopenharmony_ci} 105141cc406Sopenharmony_ci 106141cc406Sopenharmony_cistatic inline void write_bit(std::uint8_t* data, std::size_t x, unsigned value) 107141cc406Sopenharmony_ci{ 108141cc406Sopenharmony_ci value = (value & 0x1) << (7 - (x % 8)); 109141cc406Sopenharmony_ci std::uint8_t mask = 0x1 << (7 - (x % 8)); 110141cc406Sopenharmony_ci 111141cc406Sopenharmony_ci data[x / 8] = (data[x / 8] & ~mask) | (value & mask); 112141cc406Sopenharmony_ci} 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ciPixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format) 115141cc406Sopenharmony_ci{ 116141cc406Sopenharmony_ci switch (format) { 117141cc406Sopenharmony_ci case PixelFormat::I1: { 118141cc406Sopenharmony_ci std::uint16_t val = read_bit(data, x) ? 0xffff : 0x0000; 119141cc406Sopenharmony_ci return Pixel(val, val, val); 120141cc406Sopenharmony_ci } 121141cc406Sopenharmony_ci case PixelFormat::RGB111: { 122141cc406Sopenharmony_ci x *= 3; 123141cc406Sopenharmony_ci std::uint16_t r = read_bit(data, x) ? 0xffff : 0x0000; 124141cc406Sopenharmony_ci std::uint16_t g = read_bit(data, x + 1) ? 0xffff : 0x0000; 125141cc406Sopenharmony_ci std::uint16_t b = read_bit(data, x + 2) ? 0xffff : 0x0000; 126141cc406Sopenharmony_ci return Pixel(r, g, b); 127141cc406Sopenharmony_ci } 128141cc406Sopenharmony_ci case PixelFormat::I8: { 129141cc406Sopenharmony_ci std::uint16_t val = std::uint16_t(data[x]) | (data[x] << 8); 130141cc406Sopenharmony_ci return Pixel(val, val, val); 131141cc406Sopenharmony_ci } 132141cc406Sopenharmony_ci case PixelFormat::I16: { 133141cc406Sopenharmony_ci x *= 2; 134141cc406Sopenharmony_ci std::uint16_t val = std::uint16_t(data[x]) | (data[x + 1] << 8); 135141cc406Sopenharmony_ci return Pixel(val, val, val); 136141cc406Sopenharmony_ci } 137141cc406Sopenharmony_ci case PixelFormat::RGB888: { 138141cc406Sopenharmony_ci x *= 3; 139141cc406Sopenharmony_ci std::uint16_t r = std::uint16_t(data[x]) | (data[x] << 8); 140141cc406Sopenharmony_ci std::uint16_t g = std::uint16_t(data[x + 1]) | (data[x + 1] << 8); 141141cc406Sopenharmony_ci std::uint16_t b = std::uint16_t(data[x + 2]) | (data[x + 2] << 8); 142141cc406Sopenharmony_ci return Pixel(r, g, b); 143141cc406Sopenharmony_ci } 144141cc406Sopenharmony_ci case PixelFormat::BGR888: { 145141cc406Sopenharmony_ci x *= 3; 146141cc406Sopenharmony_ci std::uint16_t b = std::uint16_t(data[x]) | (data[x] << 8); 147141cc406Sopenharmony_ci std::uint16_t g = std::uint16_t(data[x + 1]) | (data[x + 1] << 8); 148141cc406Sopenharmony_ci std::uint16_t r = std::uint16_t(data[x + 2]) | (data[x + 2] << 8); 149141cc406Sopenharmony_ci return Pixel(r, g, b); 150141cc406Sopenharmony_ci } 151141cc406Sopenharmony_ci case PixelFormat::RGB161616: { 152141cc406Sopenharmony_ci x *= 6; 153141cc406Sopenharmony_ci std::uint16_t r = std::uint16_t(data[x]) | (data[x + 1] << 8); 154141cc406Sopenharmony_ci std::uint16_t g = std::uint16_t(data[x + 2]) | (data[x + 3] << 8); 155141cc406Sopenharmony_ci std::uint16_t b = std::uint16_t(data[x + 4]) | (data[x + 5] << 8); 156141cc406Sopenharmony_ci return Pixel(r, g, b); 157141cc406Sopenharmony_ci } 158141cc406Sopenharmony_ci case PixelFormat::BGR161616: { 159141cc406Sopenharmony_ci x *= 6; 160141cc406Sopenharmony_ci std::uint16_t b = std::uint16_t(data[x]) | (data[x + 1] << 8); 161141cc406Sopenharmony_ci std::uint16_t g = std::uint16_t(data[x + 2]) | (data[x + 3] << 8); 162141cc406Sopenharmony_ci std::uint16_t r = std::uint16_t(data[x + 4]) | (data[x + 5] << 8); 163141cc406Sopenharmony_ci return Pixel(r, g, b); 164141cc406Sopenharmony_ci } 165141cc406Sopenharmony_ci default: 166141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 167141cc406Sopenharmony_ci } 168141cc406Sopenharmony_ci} 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_civoid set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format) 171141cc406Sopenharmony_ci{ 172141cc406Sopenharmony_ci switch (format) { 173141cc406Sopenharmony_ci case PixelFormat::I1: 174141cc406Sopenharmony_ci write_bit(data, x, pixel.r & 0x8000 ? 1 : 0); 175141cc406Sopenharmony_ci return; 176141cc406Sopenharmony_ci case PixelFormat::RGB111: { 177141cc406Sopenharmony_ci x *= 3; 178141cc406Sopenharmony_ci write_bit(data, x, pixel.r & 0x8000 ? 1 : 0); 179141cc406Sopenharmony_ci write_bit(data, x + 1,pixel.g & 0x8000 ? 1 : 0); 180141cc406Sopenharmony_ci write_bit(data, x + 2, pixel.b & 0x8000 ? 1 : 0); 181141cc406Sopenharmony_ci return; 182141cc406Sopenharmony_ci } 183141cc406Sopenharmony_ci case PixelFormat::I8: { 184141cc406Sopenharmony_ci float val = (pixel.r >> 8) * 0.3f; 185141cc406Sopenharmony_ci val += (pixel.g >> 8) * 0.59f; 186141cc406Sopenharmony_ci val += (pixel.b >> 8) * 0.11f; 187141cc406Sopenharmony_ci data[x] = static_cast<std::uint16_t>(val); 188141cc406Sopenharmony_ci return; 189141cc406Sopenharmony_ci } 190141cc406Sopenharmony_ci case PixelFormat::I16: { 191141cc406Sopenharmony_ci x *= 2; 192141cc406Sopenharmony_ci float val = pixel.r * 0.3f; 193141cc406Sopenharmony_ci val += pixel.g * 0.59f; 194141cc406Sopenharmony_ci val += pixel.b * 0.11f; 195141cc406Sopenharmony_ci auto val16 = static_cast<std::uint16_t>(val); 196141cc406Sopenharmony_ci data[x] = val16 & 0xff; 197141cc406Sopenharmony_ci data[x + 1] = (val16 >> 8) & 0xff; 198141cc406Sopenharmony_ci return; 199141cc406Sopenharmony_ci } 200141cc406Sopenharmony_ci case PixelFormat::RGB888: { 201141cc406Sopenharmony_ci x *= 3; 202141cc406Sopenharmony_ci data[x] = pixel.r >> 8; 203141cc406Sopenharmony_ci data[x + 1] = pixel.g >> 8; 204141cc406Sopenharmony_ci data[x + 2] = pixel.b >> 8; 205141cc406Sopenharmony_ci return; 206141cc406Sopenharmony_ci } 207141cc406Sopenharmony_ci case PixelFormat::BGR888: { 208141cc406Sopenharmony_ci x *= 3; 209141cc406Sopenharmony_ci data[x] = pixel.b >> 8; 210141cc406Sopenharmony_ci data[x + 1] = pixel.g >> 8; 211141cc406Sopenharmony_ci data[x + 2] = pixel.r >> 8; 212141cc406Sopenharmony_ci return; 213141cc406Sopenharmony_ci } 214141cc406Sopenharmony_ci case PixelFormat::RGB161616: { 215141cc406Sopenharmony_ci x *= 6; 216141cc406Sopenharmony_ci data[x] = pixel.r & 0xff; 217141cc406Sopenharmony_ci data[x + 1] = (pixel.r >> 8) & 0xff; 218141cc406Sopenharmony_ci data[x + 2] = pixel.g & 0xff; 219141cc406Sopenharmony_ci data[x + 3] = (pixel.g >> 8) & 0xff; 220141cc406Sopenharmony_ci data[x + 4] = pixel.b & 0xff; 221141cc406Sopenharmony_ci data[x + 5] = (pixel.b >> 8) & 0xff; 222141cc406Sopenharmony_ci return; 223141cc406Sopenharmony_ci } 224141cc406Sopenharmony_ci case PixelFormat::BGR161616: 225141cc406Sopenharmony_ci x *= 6; 226141cc406Sopenharmony_ci data[x] = pixel.b & 0xff; 227141cc406Sopenharmony_ci data[x + 1] = (pixel.b >> 8) & 0xff; 228141cc406Sopenharmony_ci data[x + 2] = pixel.g & 0xff; 229141cc406Sopenharmony_ci data[x + 3] = (pixel.g >> 8) & 0xff; 230141cc406Sopenharmony_ci data[x + 4] = pixel.r & 0xff; 231141cc406Sopenharmony_ci data[x + 5] = (pixel.r >> 8) & 0xff; 232141cc406Sopenharmony_ci return; 233141cc406Sopenharmony_ci default: 234141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 235141cc406Sopenharmony_ci } 236141cc406Sopenharmony_ci} 237141cc406Sopenharmony_ci 238141cc406Sopenharmony_ciRawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format) 239141cc406Sopenharmony_ci{ 240141cc406Sopenharmony_ci switch (format) { 241141cc406Sopenharmony_ci case PixelFormat::I1: 242141cc406Sopenharmony_ci return RawPixel(read_bit(data, x)); 243141cc406Sopenharmony_ci case PixelFormat::RGB111: { 244141cc406Sopenharmony_ci x *= 3; 245141cc406Sopenharmony_ci return RawPixel(read_bit(data, x) << 2 | 246141cc406Sopenharmony_ci (read_bit(data, x + 1) << 1) | 247141cc406Sopenharmony_ci (read_bit(data, x + 2))); 248141cc406Sopenharmony_ci } 249141cc406Sopenharmony_ci case PixelFormat::I8: 250141cc406Sopenharmony_ci return RawPixel(data[x]); 251141cc406Sopenharmony_ci case PixelFormat::I16: { 252141cc406Sopenharmony_ci x *= 2; 253141cc406Sopenharmony_ci return RawPixel(data[x], data[x + 1]); 254141cc406Sopenharmony_ci } 255141cc406Sopenharmony_ci case PixelFormat::RGB888: 256141cc406Sopenharmony_ci case PixelFormat::BGR888: { 257141cc406Sopenharmony_ci x *= 3; 258141cc406Sopenharmony_ci return RawPixel(data[x], data[x + 1], data[x + 2]); 259141cc406Sopenharmony_ci } 260141cc406Sopenharmony_ci case PixelFormat::RGB161616: 261141cc406Sopenharmony_ci case PixelFormat::BGR161616: { 262141cc406Sopenharmony_ci x *= 6; 263141cc406Sopenharmony_ci return RawPixel(data[x], data[x + 1], data[x + 2], 264141cc406Sopenharmony_ci data[x + 3], data[x + 4], data[x + 5]); 265141cc406Sopenharmony_ci } 266141cc406Sopenharmony_ci default: 267141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 268141cc406Sopenharmony_ci } 269141cc406Sopenharmony_ci} 270141cc406Sopenharmony_ci 271141cc406Sopenharmony_civoid set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format) 272141cc406Sopenharmony_ci{ 273141cc406Sopenharmony_ci switch (format) { 274141cc406Sopenharmony_ci case PixelFormat::I1: 275141cc406Sopenharmony_ci write_bit(data, x, pixel.data[0] & 0x1); 276141cc406Sopenharmony_ci return; 277141cc406Sopenharmony_ci case PixelFormat::RGB111: { 278141cc406Sopenharmony_ci x *= 3; 279141cc406Sopenharmony_ci write_bit(data, x, (pixel.data[0] >> 2) & 0x1); 280141cc406Sopenharmony_ci write_bit(data, x + 1, (pixel.data[0] >> 1) & 0x1); 281141cc406Sopenharmony_ci write_bit(data, x + 2, (pixel.data[0]) & 0x1); 282141cc406Sopenharmony_ci return; 283141cc406Sopenharmony_ci } 284141cc406Sopenharmony_ci case PixelFormat::I8: 285141cc406Sopenharmony_ci data[x] = pixel.data[0]; 286141cc406Sopenharmony_ci return; 287141cc406Sopenharmony_ci case PixelFormat::I16: { 288141cc406Sopenharmony_ci x *= 2; 289141cc406Sopenharmony_ci data[x] = pixel.data[0]; 290141cc406Sopenharmony_ci data[x + 1] = pixel.data[1]; 291141cc406Sopenharmony_ci return; 292141cc406Sopenharmony_ci } 293141cc406Sopenharmony_ci case PixelFormat::RGB888: 294141cc406Sopenharmony_ci case PixelFormat::BGR888: { 295141cc406Sopenharmony_ci x *= 3; 296141cc406Sopenharmony_ci data[x] = pixel.data[0]; 297141cc406Sopenharmony_ci data[x + 1] = pixel.data[1]; 298141cc406Sopenharmony_ci data[x + 2] = pixel.data[2]; 299141cc406Sopenharmony_ci return; 300141cc406Sopenharmony_ci } 301141cc406Sopenharmony_ci case PixelFormat::RGB161616: 302141cc406Sopenharmony_ci case PixelFormat::BGR161616: { 303141cc406Sopenharmony_ci x *= 6; 304141cc406Sopenharmony_ci data[x] = pixel.data[0]; 305141cc406Sopenharmony_ci data[x + 1] = pixel.data[1]; 306141cc406Sopenharmony_ci data[x + 2] = pixel.data[2]; 307141cc406Sopenharmony_ci data[x + 3] = pixel.data[3]; 308141cc406Sopenharmony_ci data[x + 4] = pixel.data[4]; 309141cc406Sopenharmony_ci data[x + 5] = pixel.data[5]; 310141cc406Sopenharmony_ci return; 311141cc406Sopenharmony_ci } 312141cc406Sopenharmony_ci default: 313141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 314141cc406Sopenharmony_ci } 315141cc406Sopenharmony_ci} 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_cistd::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, 318141cc406Sopenharmony_ci PixelFormat format) 319141cc406Sopenharmony_ci{ 320141cc406Sopenharmony_ci switch (format) { 321141cc406Sopenharmony_ci case PixelFormat::I1: 322141cc406Sopenharmony_ci return read_bit(data, x); 323141cc406Sopenharmony_ci case PixelFormat::RGB111: 324141cc406Sopenharmony_ci return read_bit(data, x * 3 + channel); 325141cc406Sopenharmony_ci case PixelFormat::I8: 326141cc406Sopenharmony_ci return data[x]; 327141cc406Sopenharmony_ci case PixelFormat::I16: { 328141cc406Sopenharmony_ci x *= 2; 329141cc406Sopenharmony_ci return data[x] | (data[x + 1] << 8); 330141cc406Sopenharmony_ci } 331141cc406Sopenharmony_ci case PixelFormat::RGB888: 332141cc406Sopenharmony_ci case PixelFormat::BGR888: 333141cc406Sopenharmony_ci return data[x * 3 + channel]; 334141cc406Sopenharmony_ci case PixelFormat::RGB161616: 335141cc406Sopenharmony_ci case PixelFormat::BGR161616: 336141cc406Sopenharmony_ci return data[x * 6 + channel * 2] | (data[x * 6 + channel * 2 + 1]) << 8; 337141cc406Sopenharmony_ci default: 338141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 339141cc406Sopenharmony_ci } 340141cc406Sopenharmony_ci} 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_civoid set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, 343141cc406Sopenharmony_ci std::uint16_t pixel, PixelFormat format) 344141cc406Sopenharmony_ci{ 345141cc406Sopenharmony_ci switch (format) { 346141cc406Sopenharmony_ci case PixelFormat::I1: 347141cc406Sopenharmony_ci write_bit(data, x, pixel & 0x1); 348141cc406Sopenharmony_ci return; 349141cc406Sopenharmony_ci case PixelFormat::RGB111: { 350141cc406Sopenharmony_ci write_bit(data, x * 3 + channel, pixel & 0x1); 351141cc406Sopenharmony_ci return; 352141cc406Sopenharmony_ci } 353141cc406Sopenharmony_ci case PixelFormat::I8: 354141cc406Sopenharmony_ci data[x] = pixel; 355141cc406Sopenharmony_ci return; 356141cc406Sopenharmony_ci case PixelFormat::I16: { 357141cc406Sopenharmony_ci x *= 2; 358141cc406Sopenharmony_ci data[x] = pixel; 359141cc406Sopenharmony_ci data[x + 1] = pixel >> 8; 360141cc406Sopenharmony_ci return; 361141cc406Sopenharmony_ci } 362141cc406Sopenharmony_ci case PixelFormat::RGB888: 363141cc406Sopenharmony_ci case PixelFormat::BGR888: { 364141cc406Sopenharmony_ci x *= 3; 365141cc406Sopenharmony_ci data[x + channel] = pixel; 366141cc406Sopenharmony_ci return; 367141cc406Sopenharmony_ci } 368141cc406Sopenharmony_ci case PixelFormat::RGB161616: 369141cc406Sopenharmony_ci case PixelFormat::BGR161616: { 370141cc406Sopenharmony_ci x *= 6; 371141cc406Sopenharmony_ci data[x + channel * 2] = pixel; 372141cc406Sopenharmony_ci data[x + channel * 2 + 1] = pixel >> 8; 373141cc406Sopenharmony_ci return; 374141cc406Sopenharmony_ci } 375141cc406Sopenharmony_ci default: 376141cc406Sopenharmony_ci throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); 377141cc406Sopenharmony_ci } 378141cc406Sopenharmony_ci} 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_citemplate<PixelFormat Format> 381141cc406Sopenharmony_ciPixel get_pixel_from_row(const std::uint8_t* data, std::size_t x) 382141cc406Sopenharmony_ci{ 383141cc406Sopenharmony_ci return get_pixel_from_row(data, x, Format); 384141cc406Sopenharmony_ci} 385141cc406Sopenharmony_ci 386141cc406Sopenharmony_citemplate<PixelFormat Format> 387141cc406Sopenharmony_civoid set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel) 388141cc406Sopenharmony_ci{ 389141cc406Sopenharmony_ci set_pixel_to_row(data, x, pixel, Format); 390141cc406Sopenharmony_ci} 391141cc406Sopenharmony_ci 392141cc406Sopenharmony_citemplate<PixelFormat Format> 393141cc406Sopenharmony_ciRawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x) 394141cc406Sopenharmony_ci{ 395141cc406Sopenharmony_ci return get_raw_pixel_from_row(data, x, Format); 396141cc406Sopenharmony_ci} 397141cc406Sopenharmony_ci 398141cc406Sopenharmony_citemplate<PixelFormat Format> 399141cc406Sopenharmony_civoid set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel) 400141cc406Sopenharmony_ci{ 401141cc406Sopenharmony_ci set_raw_pixel_to_row(data, x, pixel, Format); 402141cc406Sopenharmony_ci} 403141cc406Sopenharmony_ci 404141cc406Sopenharmony_citemplate<PixelFormat Format> 405141cc406Sopenharmony_cistd::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel) 406141cc406Sopenharmony_ci{ 407141cc406Sopenharmony_ci return get_raw_channel_from_row(data, x, channel, Format); 408141cc406Sopenharmony_ci} 409141cc406Sopenharmony_ci 410141cc406Sopenharmony_citemplate<PixelFormat Format> 411141cc406Sopenharmony_civoid set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel) 412141cc406Sopenharmony_ci{ 413141cc406Sopenharmony_ci set_raw_channel_to_row(data, x, channel, pixel, Format); 414141cc406Sopenharmony_ci} 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::I1>(const std::uint8_t* data, std::size_t x); 417141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::RGB111>(const std::uint8_t* data, std::size_t x); 418141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::I8>(const std::uint8_t* data, std::size_t x); 419141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::RGB888>(const std::uint8_t* data, std::size_t x); 420141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::BGR888>(const std::uint8_t* data, std::size_t x); 421141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::I16>(const std::uint8_t* data, std::size_t x); 422141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::RGB161616>(const std::uint8_t* data, std::size_t x); 423141cc406Sopenharmony_citemplate Pixel get_pixel_from_row<PixelFormat::BGR161616>(const std::uint8_t* data, std::size_t x); 424141cc406Sopenharmony_ci 425141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::I1>(const std::uint8_t* data, std::size_t x); 426141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::RGB111>(const std::uint8_t* data, std::size_t x); 427141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::I8>(const std::uint8_t* data, std::size_t x); 428141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::RGB888>(const std::uint8_t* data, std::size_t x); 429141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::BGR888>(const std::uint8_t* data, std::size_t x); 430141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::I16>(const std::uint8_t* data, std::size_t x); 431141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::RGB161616>(const std::uint8_t* data, std::size_t x); 432141cc406Sopenharmony_citemplate RawPixel get_raw_pixel_from_row<PixelFormat::BGR161616>(const std::uint8_t* data, std::size_t x); 433141cc406Sopenharmony_ci 434141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::I1>( 435141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 436141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::RGB111>( 437141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 438141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::I8>( 439141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 440141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::RGB888>( 441141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 442141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::BGR888>( 443141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 444141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::I16>( 445141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 446141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::RGB161616>( 447141cc406Sopenharmony_ci const std::uint8_t* data, std::size_t x, unsigned channel); 448141cc406Sopenharmony_citemplate std::uint16_t get_raw_channel_from_row<PixelFormat::BGR161616> 449141cc406Sopenharmony_ci (const std::uint8_t* data, std::size_t x, unsigned channel); 450141cc406Sopenharmony_ci 451141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::I1>(std::uint8_t* data, std::size_t x, Pixel pixel); 452141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::RGB111>(std::uint8_t* data, std::size_t x, Pixel pixel); 453141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::I8>(std::uint8_t* data, std::size_t x, Pixel pixel); 454141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::RGB888>(std::uint8_t* data, std::size_t x, Pixel pixel); 455141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::BGR888>(std::uint8_t* data, std::size_t x, Pixel pixel); 456141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::I16>(std::uint8_t* data, std::size_t x, Pixel pixel); 457141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::RGB161616>(std::uint8_t* data, std::size_t x, Pixel pixel); 458141cc406Sopenharmony_citemplate void set_pixel_to_row<PixelFormat::BGR161616>(std::uint8_t* data, std::size_t x, Pixel pixel); 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::I1>(std::uint8_t* data, std::size_t x, RawPixel pixel); 461141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::RGB111>(std::uint8_t* data, std::size_t x, RawPixel pixel); 462141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::I8>(std::uint8_t* data, std::size_t x, RawPixel pixel); 463141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::RGB888>(std::uint8_t* data, std::size_t x, RawPixel pixel); 464141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::BGR888>(std::uint8_t* data, std::size_t x, RawPixel pixel); 465141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::I16>(std::uint8_t* data, std::size_t x, RawPixel pixel); 466141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::RGB161616>(std::uint8_t* data, std::size_t x, RawPixel pixel); 467141cc406Sopenharmony_citemplate void set_raw_pixel_to_row<PixelFormat::BGR161616>(std::uint8_t* data, std::size_t x, RawPixel pixel); 468141cc406Sopenharmony_ci 469141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::I1>( 470141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 471141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::RGB111>( 472141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 473141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::I8>( 474141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 475141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::RGB888>( 476141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 477141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::BGR888>( 478141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 479141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::I16>( 480141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 481141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::RGB161616>( 482141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 483141cc406Sopenharmony_citemplate void set_raw_channel_to_row<PixelFormat::BGR161616>( 484141cc406Sopenharmony_ci std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); 485141cc406Sopenharmony_ci 486141cc406Sopenharmony_ci} // namespace genesys 487