File indexing completed on 2024-06-23 04:27:14
0001 /** 0002 * SPDX-FileCopyrightText: 2020-2021 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com> 0003 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef KIS_HEIF_IMPORT_TOOLS_H 0009 #define KIS_HEIF_IMPORT_TOOLS_H 0010 0011 #include <cstdint> 0012 0013 #include <KoColorSpace.h> 0014 #include <KoColorSpaceTraits.h> 0015 #include <KoColorTransferFunctions.h> 0016 #include <kis_iterator_ng.h> 0017 0018 namespace Gray 0019 { 0020 template<int luma> 0021 inline void applyValue(KisHLineIteratorSP it, 0022 const uint8_t *imgG, 0023 int strideG, 0024 int x, 0025 int y) 0026 { 0027 if (luma == 8) { 0028 KoGrayU8Traits::setGray(it->rawData(), imgG[y * strideG + x]); 0029 } else { 0030 uint16_t source = 0031 KoGrayU16Traits::nativeArray(imgG)[y * (strideG / 2) + (x)]; 0032 0033 if (luma == 10) { 0034 KoGrayU16Traits::setGray( 0035 it->rawData(), 0036 static_cast<uint16_t>(float(0x03ffu & (source)) 0037 * multiplier10bit * max16bit)); 0038 } else if (luma == 12) { 0039 KoGrayU16Traits::setGray( 0040 it->rawData(), 0041 static_cast<uint16_t>(float(0x0fffu & (source)) 0042 * multiplier12bit * max16bit)); 0043 } else { 0044 KoGrayU16Traits::setGray( 0045 it->rawData(), 0046 static_cast<uint16_t>(float(source) * multiplier16bit)); 0047 } 0048 } 0049 } 0050 0051 template<int luma, bool hasAlpha> 0052 inline void applyAlpha(KisHLineIteratorSP it, 0053 const uint8_t *imgA, 0054 int strideA, 0055 int x, 0056 int y) 0057 { 0058 if (hasAlpha) { 0059 if (luma == 8) { 0060 KoGrayU8Traits::setOpacity(it->rawData(), 0061 quint8(imgA[y * strideA + x]), 0062 1); 0063 } else { 0064 uint16_t source = 0065 KoGrayU16Traits::nativeArray(imgA)[y * (strideA / 2) + x]; 0066 if (luma == 10) { 0067 KoGrayU16Traits::setOpacity( 0068 it->rawData(), 0069 static_cast<qreal>(float(0x0fff & (source)) 0070 * multiplier10bit), 0071 1); 0072 } else if (luma == 12) { 0073 KoGrayU16Traits::setOpacity( 0074 it->rawData(), 0075 static_cast<qreal>(float(0x0fff & (source)) 0076 * multiplier12bit), 0077 1); 0078 } else { 0079 KoGrayU16Traits::setOpacity( 0080 it->rawData(), 0081 static_cast<qreal>(float(source) * multiplier16bit), 0082 1); 0083 } 0084 } 0085 } else { 0086 if (luma == 8) { 0087 KoGrayU8Traits::setOpacity(it->rawData(), OPACITY_OPAQUE_U8, 1); 0088 } else { 0089 KoGrayU16Traits::setOpacity(it->rawData(), OPACITY_OPAQUE_U8, 1); 0090 } 0091 } 0092 } 0093 0094 template<int luma, bool hasAlpha> 0095 inline void readLayer(const int width, 0096 const int height, 0097 KisHLineIteratorSP it, 0098 const uint8_t *imgG, 0099 const uint8_t *imgA, 0100 const int strideG, 0101 const int strideA) 0102 { 0103 for (int y = 0; y < height; y++) { 0104 for (int x = 0; x < width; x++) { 0105 applyValue<luma>(it, imgG, strideG, x, y); 0106 0107 applyAlpha<luma, hasAlpha>(it, imgA, strideA, x, y); 0108 it->nextPixel(); 0109 } 0110 0111 it->nextRow(); 0112 } 0113 } 0114 0115 template<int luma, typename... Args> 0116 inline auto readPlanarWithLuma(bool hasAlpha, Args &&...args) 0117 { 0118 if (hasAlpha) { 0119 return Gray::readLayer<luma, true>(std::forward<Args>(args)...); 0120 } else { 0121 return Gray::readLayer<luma, false>(std::forward<Args>(args)...); 0122 } 0123 } 0124 0125 template<typename... Args> 0126 inline auto readPlanarLayer(const int luma, Args &&...args) 0127 { 0128 if (luma == 8) { 0129 return readPlanarWithLuma<8>(std::forward<Args>(args)...); 0130 } else if (luma == 10) { 0131 return readPlanarWithLuma<10>(std::forward<Args>(args)...); 0132 } else if (luma == 12) { 0133 return readPlanarWithLuma<12>(std::forward<Args>(args)...); 0134 } else { 0135 return readPlanarWithLuma<16>(std::forward<Args>(args)...); 0136 } 0137 } 0138 } // namespace Gray 0139 0140 namespace SDR 0141 { 0142 struct readLayerImpl { 0143 template<typename Arch> 0144 static void create(LinearizePolicy policy, 0145 bool applyOOTF, 0146 bool hasAlpha, 0147 const int width, 0148 const int height, 0149 const uint8_t *img, 0150 const int stride, 0151 KisHLineIteratorSP it, 0152 float displayGamma, 0153 float displayNits, 0154 const KoColorSpace *colorSpace); 0155 }; 0156 } // namespace SDR 0157 0158 namespace Planar 0159 { 0160 struct readLayerImpl { 0161 template<typename Arch> 0162 static void create(const int luma, 0163 LinearizePolicy policy, 0164 bool applyOOTF, 0165 bool hasAlpha, 0166 const int width, 0167 const int height, 0168 const uint8_t *imgR, 0169 const int strideR, 0170 const uint8_t *imgG, 0171 const int strideG, 0172 const uint8_t *imgB, 0173 const int strideB, 0174 const uint8_t *imgA, 0175 const int strideA, 0176 KisHLineIteratorSP it, 0177 float displayGamma, 0178 float displayNits, 0179 const KoColorSpace *colorSpace); 0180 }; 0181 } // namespace Planar 0182 0183 namespace HDR 0184 { 0185 struct readLayerImpl { 0186 template<typename Arch> 0187 static void create(const int luma, 0188 LinearizePolicy linearizePolicy, 0189 bool applyOOTF, 0190 const int channels, 0191 const int width, 0192 const int height, 0193 const uint8_t *img, 0194 const int stride, 0195 KisHLineIteratorSP it, 0196 float displayGamma, 0197 float displayNits, 0198 const KoColorSpace *colorSpace); 0199 }; 0200 } // namespace HDR 0201 0202 #endif // KIS_HEIF_IMPORT_TOOLS_H