8#ifndef _KIS_TIFF_YCBCR_READER_H_
9#define _KIS_TIFF_YCBCR_READER_H_
15#include <QSharedPointer>
41 const std::array<quint8, 5> &
poses,
44 uint16_t sampleformat,
45 uint16_t nbcolorssamples,
46 uint16_t extrasamplescount,
47 bool premultipliedAlpha,
95 template<
typename U = T,
96 typename std::enable_if<!std::numeric_limits<U>::is_integer,
104 quint32 numcols = dataWidth /
m_hsub;
106 for (quint32 index = 0; index < numcols; index++) {
108 for (
int vindex = 0; vindex <
m_vsub; vindex++) {
110 T *d =
reinterpret_cast<T *
>(it->rawData());
111 d[0] =
static_cast<T
>(tiffstream->nextValue());
112 d[3] = std::numeric_limits<T>::max();
115 d[3] =
static_cast<T
>(tiffstream->nextValue());
117 tiffstream->nextValue();
119 }
while (it->nextPixel());
122 m_bufferCb[buffPos] =
static_cast<T
>(tiffstream->nextValue());
123 m_bufferCr[buffPos] =
static_cast<T
>(tiffstream->nextValue());
129 template<
typename U = T,
130 typename std::enable_if<std::numeric_limits<U>::is_integer,
138 quint32 numcols = dataWidth /
m_hsub;
139 double coeff = std::numeric_limits<T>::max() / (double)(std::pow(2.0, this->
sourceDepth()) - 1);
143 for (quint32 index = 0; index < numcols; index++) {
145 for (
int vindex = 0; vindex <
m_vsub; vindex++) {
147 T *d =
reinterpret_cast<T *
>(it->rawData());
148 d[0] =
static_cast<T
>(tiffstream->nextValue() * coeff);
149 d[3] = std::numeric_limits<T>::max();
152 d[3] =
static_cast<T
>(tiffstream->nextValue() * coeff);
154 tiffstream->nextValue();
156 }
while (it->nextPixel());
159 m_bufferCb[buffPos] =
static_cast<T
>(tiffstream->nextValue() * coeff);
160 m_bufferCr[buffPos] =
static_cast<T
>(tiffstream->nextValue() * coeff);
166 template<typename U = T, typename std::enable_if<!std::numeric_limits<U>::is_integer,
void>
::type * =
nullptr>
void finalizeImpl()
172 T *d =
reinterpret_cast<T *
>(it->rawData());
179 auto unmultipliedColorsConsistent = [](T *d) {
return !(std::abs(d[3]) < std::numeric_limits<T>::epsilon()); };
181 auto checkUnmultipliedColorsConsistent = [
this](
const T *d) {
182 const T alpha = std::abs(d[3]);
184 if (alpha >=
static_cast<T
>(0.01)) {
196 if (!unmultipliedColorsConsistent(d)) {
201 d[i] = std::lroundf(d[i] * newAlpha);
206 if (checkUnmultipliedColorsConsistent(d)) {
210 newAlpha += std::numeric_limits<T>::epsilon();
213 const T alpha = d[3];
215 d[i] = std::lroundf(d[i] * alpha);
219 }
while (it->nextPixel());
224 template<typename U = T, typename std::enable_if<std::numeric_limits<U>::is_integer,
void>
::type * =
nullptr>
void finalizeImpl()
230 T *d =
reinterpret_cast<T *
>(it->rawData());
237 const T alpha = d[3];
238 const float factor = alpha == 0 ? 0 :
static_cast<float>(std::numeric_limits<T>::max()) / alpha;
241 d[i] = std::lroundf(d[i] * factor);
244 }
while (it->nextPixel());
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const std::array< quint8, 5 > & poses() const
quint16 nbExtraSamples() const
quint16 nbColorsSamples() const
KisPaintDeviceSP paintDevice() const
bool hasPremultipliedAlpha() const
quint16 sourceDepth() const
~KisTIFFYCbCrReader() override=default
std::unique_ptr< T[]> m_bufferCr
uint32_t copyDataToChannels(quint32 x, quint32 y, quint32 dataWidth, QSharedPointer< KisBufferStreamBase > tiffstream) override
std::unique_ptr< T[]> m_bufferCb
KisTIFFYCbCrReader(KisPaintDeviceSP device, quint32 width, quint32 height, const std::array< quint8, 5 > &poses, int32_t alphapos, uint16_t sourceDepth, uint16_t sampleformat, uint16_t nbcolorssamples, uint16_t extrasamplescount, bool premultipliedAlpha, KoColorTransformation *transformProfile, QSharedPointer< KisTIFFPostProcessor > postprocessor, uint16_t hsub, uint16_t vsub)
uint32_t copyDataToChannelsImpl(quint32 x, quint32 y, quint32 dataWidth, QSharedPointer< KisBufferStreamBase > tiffstream)
static bool qFuzzyCompare(half p1, half p2)