@@ -40,9 +40,22 @@ namespace video::rgb
4040namespace
4141{
4242
43- template <typename T> T swapLowestBytes (const T &val)
43+ template <int bitDepth>
44+ using UintValueType = typename std::conditional_t <bitDepth == 8 ,
45+ uint8_t *,
46+ std::conditional_t <bitDepth == 16 , uint16_t *, uint32_t *>>;
47+
48+ template <int bitDepth, typename T> T swapLowestBytes (const T &val)
4449{
45- return ((val & 0xff ) << 8 ) + ((val & 0xff00 ) >> 8 );
50+ if (bitDepth <= 8 ) {
51+ return val;
52+ }
53+ if (bitDepth <= 16 ) {
54+ return ((val & 0xff ) << 8 ) | ((val & 0xff00 ) >> 8 );
55+ }
56+ if (bitDepth <= 32 ) {
57+ return ((val & 0xff ) << 24 ) | ((val & 0xff00 ) << 8 ) | ((val & 0xff0000 ) >> 8 ) | ((val & 0xff000000 ) >> 24 );
58+ }
4659};
4760
4861int getOffsetToFirstByteOfComponent (const Channel channel,
@@ -73,7 +86,7 @@ void convertRGBToARGB(const QByteArray & sourceBuffer,
7386 const auto offsetToNextValue =
7487 srcPixelFormat.getDataLayout () == DataLayout::Planar ? 1 : srcPixelFormat.nrChannels ();
7588
76- typedef typename std::conditional<bitDepth == 8 , uint8_t *, uint16_t *>::type InValueType ;
89+ using InValueType = UintValueType<bitDepth> ;
7790 const auto setAlpha = outputHasAlpha && srcPixelFormat.hasAlpha ();
7891
7992 const auto rawData = (InValueType)sourceBuffer.data ();
@@ -96,9 +109,9 @@ void convertRGBToARGB(const QByteArray & sourceBuffer,
96109 const auto isBigEndian = bitDepth > 8 && srcPixelFormat.getEndianess () == Endianness::Big;
97110 auto convertValue = [&isBigEndian, &rightShift](
98111 const InValueType sourceData, const int scale, const bool invert) {
99- auto value = static_cast <int >(sourceData[0 ]);
112+ auto value = static_cast <int64_t >(sourceData[0 ]);
100113 if (isBigEndian)
101- value = swapLowestBytes (value);
114+ value = swapLowestBytes<bitDepth> (value);
102115 value = ((value * scale) >> rightShift);
103116 value = functions::clip (value, 0 , 255 );
104117 if (invert)
@@ -161,7 +174,7 @@ void convertRGBPlaneToARGB(const QByteArray & sourceBuffer,
161174 const auto offsetToNextValue =
162175 srcPixelFormat.getDataLayout () == DataLayout::Planar ? 1 : srcPixelFormat.nrChannels ();
163176
164- typedef typename std::conditional<bitDepth == 8 , uint8_t *, uint16_t *>::type InValueType ;
177+ using InValueType = UintValueType<bitDepth> ;
165178
166179 auto src = (InValueType)sourceBuffer.data ();
167180 const auto displayComponentOffset = srcPixelFormat.getChannelPosition (displayChannel);
@@ -172,9 +185,9 @@ void convertRGBPlaneToARGB(const QByteArray & sourceBuffer,
172185
173186 for (size_t i = 0 ; i < frameSize.width * frameSize.height ; i++)
174187 {
175- auto val = static_cast <int >(src[0 ]);
188+ auto val = static_cast <int64_t >(src[0 ]);
176189 if (bitDepth > 8 && srcPixelFormat.getEndianess () == Endianness::Big)
177- val = swapLowestBytes (val);
190+ val = swapLowestBytes<bitDepth> (val);
178191 val = (val * scale) >> shiftTo8Bit;
179192 val = functions::clip (val, 0 , 255 );
180193 if (invert)
@@ -202,7 +215,7 @@ rgba_t getPixelValue(const QByteArray & sourceBuffer,
202215 srcPixelFormat.getDataLayout () == DataLayout::Planar ? 1 : srcPixelFormat.nrChannels ();
203216 const auto offsetPixelPos = frameSize.width * pixelPos.y () + pixelPos.x ();
204217
205- typedef typename std::conditional<bitDepth == 8 , uint8_t *, uint16_t *>::type InValueType ;
218+ using InValueType = UintValueType<bitDepth> ;
206219
207220 const auto rawData = (InValueType)sourceBuffer.data ();
208221 auto srcPixel = rawData + offsetPixelPos * offsetToNextValue;
@@ -218,7 +231,7 @@ rgba_t getPixelValue(const QByteArray & sourceBuffer,
218231 auto src = srcPixel + offset;
219232 auto val = (unsigned )src[0 ];
220233 if (bitDepth > 8 && srcPixelFormat.getEndianess () == Endianness::Big)
221- val = swapLowestBytes (val);
234+ val = swapLowestBytes<bitDepth> (val);
222235 value[channel] = val;
223236 }
224237
@@ -238,7 +251,7 @@ void convertInputRGBToARGB(const QByteArray & sourceBuffer,
238251 const bool premultiplyAlpha)
239252{
240253 const auto bitsPerSample = srcPixelFormat.getBitsPerSample ();
241- if (bitsPerSample < 8 || bitsPerSample > 16 )
254+ if (bitsPerSample < 8 || bitsPerSample > 32 )
242255 throw std::invalid_argument (" Invalid bit depth in pixel format for conversion" );
243256
244257 if (bitsPerSample == 8 )
@@ -251,7 +264,7 @@ void convertInputRGBToARGB(const QByteArray & sourceBuffer,
251264 limitedRange,
252265 outputHasAlpha,
253266 premultiplyAlpha);
254- else
267+ else if ( 9 <= bitsPerSample && bitsPerSample <= 16 )
255268 convertRGBToARGB<16 >(sourceBuffer,
256269 srcPixelFormat,
257270 targetBuffer,
@@ -261,6 +274,16 @@ void convertInputRGBToARGB(const QByteArray & sourceBuffer,
261274 limitedRange,
262275 outputHasAlpha,
263276 premultiplyAlpha);
277+ else
278+ convertRGBToARGB<32 >(sourceBuffer,
279+ srcPixelFormat,
280+ targetBuffer,
281+ frameSize,
282+ componentInvert,
283+ componentScale,
284+ limitedRange,
285+ outputHasAlpha,
286+ premultiplyAlpha);
264287}
265288
266289void convertSinglePlaneOfRGBToGreyscaleARGB (const QByteArray & sourceBuffer,
@@ -273,7 +296,7 @@ void convertSinglePlaneOfRGBToGreyscaleARGB(const QByteArray & sourceBuffer,
273296 const bool limitedRange)
274297{
275298 const auto bitsPerSample = srcPixelFormat.getBitsPerSample ();
276- if (bitsPerSample < 8 || bitsPerSample > 16 )
299+ if (bitsPerSample < 8 || bitsPerSample > 32 )
277300 throw std::invalid_argument (" Invalid bit depth in pixel format for conversion" );
278301
279302 if (bitsPerSample == 8 )
@@ -285,7 +308,7 @@ void convertSinglePlaneOfRGBToGreyscaleARGB(const QByteArray & sourceBuffer,
285308 scale,
286309 invert,
287310 limitedRange);
288- else
311+ else if ( 9 <= bitsPerSample && bitsPerSample <= 16 )
289312 convertRGBPlaneToARGB<16 >(sourceBuffer,
290313 srcPixelFormat,
291314 targetBuffer,
@@ -294,6 +317,15 @@ void convertSinglePlaneOfRGBToGreyscaleARGB(const QByteArray & sourceBuffer,
294317 scale,
295318 invert,
296319 limitedRange);
320+ else
321+ convertRGBPlaneToARGB<32 >(sourceBuffer,
322+ srcPixelFormat,
323+ targetBuffer,
324+ frameSize,
325+ displayChannel,
326+ scale,
327+ invert,
328+ limitedRange);
297329}
298330
299331rgba_t getPixelValueFromBuffer (const QByteArray & sourceBuffer,
@@ -302,13 +334,15 @@ rgba_t getPixelValueFromBuffer(const QByteArray & sourceBuffer,
302334 const QPoint & pixelPos)
303335{
304336 const auto bitsPerSample = srcPixelFormat.getBitsPerSample ();
305- if (bitsPerSample < 8 || bitsPerSample > 16 )
337+ if (bitsPerSample < 8 || bitsPerSample > 32 )
306338 throw std::invalid_argument (" Invalid bit depth in pixel format for conversion" );
307339
308340 if (bitsPerSample == 8 )
309341 return getPixelValue<8 >(sourceBuffer, srcPixelFormat, frameSize, pixelPos);
310- else
342+ else if ( 9 <= bitsPerSample && bitsPerSample <= 16 )
311343 return getPixelValue<16 >(sourceBuffer, srcPixelFormat, frameSize, pixelPos);
344+ else
345+ return getPixelValue<32 >(sourceBuffer, srcPixelFormat, frameSize, pixelPos);
312346}
313347
314348} // namespace video::rgb
0 commit comments