3434
3535
3636#include " DPXColorConverter.h"
37+ #include < OpenImageIO/fmath.h>
38+ #include < OpenImageIO/span.h>
3739#include < algorithm>
3840
3941namespace dpx {
4042 template <typename DATA>
41- static inline bool SwapRGBABytes (const DATA *input, DATA *output, int pixels) {
42- // copy the data that could be destroyed to an additional buffer in case input == output
43- DATA tmp[2 ];
44- for (int i = 0 ; i < pixels; i++) {
45- memcpy (tmp, &input[i * 4 ], sizeof (DATA) * 2 );
46- output[i * 4 + 0 ] = input[i * 4 + 3 ];
47- output[i * 4 + 1 ] = input[i * 4 + 2 ];
48- output[i * 4 + 2 ] = tmp[1 ];
49- output[i * 4 + 3 ] = tmp[0 ];
43+ static inline bool SwapRGBABytes (OIIO::cspan<DATA> input, OIIO::span<DATA> output) {
44+ // Because we are within the lengths by definition, we can just use
45+ // data pointers below to avoid a bounds check on every one.
46+ size_t pixels = input.size () / 4 ;
47+ for (size_t i = 0 ; i < pixels; i++) {
48+ DATA a = input.data ()[i * 4 + 0 ], b = input.data ()[i * 4 + 1 ];
49+ output.data ()[i * 4 + 0 ] = input.data ()[i * 4 + 3 ];
50+ output.data ()[i * 4 + 1 ] = input.data ()[i * 4 + 2 ];
51+ output.data ()[i * 4 + 2 ] = b;
52+ output.data ()[i * 4 + 3 ] = a;
5053 }
5154 return true ;
5255 }
@@ -107,12 +110,12 @@ namespace dpx {
107110
108111 // 4:4:4
109112 template <typename DATA, unsigned int max>
110- static bool ConvertCbYCrToRGB (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
113+ static bool ConvertCbYCrToRGB (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
111114 const float *matrix = GetYCbCrToRGBColorMatrix (space);
112115 if (matrix == NULL )
113116 return false ;
114117 DATA RGB[3 ];
115- for (int i = 0 ; i < pixels; i++) {
118+ for (size_t i = 0 ; i < pixels; i++) {
116119 ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 3 ], RGB, matrix);
117120 memcpy (&output[i * 3 ], RGB, sizeof (DATA) * 3 );
118121 }
@@ -121,12 +124,12 @@ namespace dpx {
121124
122125 // 4:4:4:4
123126 template <typename DATA, unsigned int max>
124- static bool ConvertCbYCrAToRGBA (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
127+ static bool ConvertCbYCrAToRGBA (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
125128 const float *matrix = GetYCbCrToRGBColorMatrix (space);
126129 if (matrix == NULL )
127130 return false ;
128131 DATA RGBA[4 ];
129- for (int i = 0 ; i < pixels; i++) {
132+ for (size_t i = 0 ; i < pixels; i++) {
130133 ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 4 ], RGBA, matrix);
131134 RGBA[3 ] = input[i * 4 + 3 ];
132135 memcpy (&output[i * 4 ], RGBA, sizeof (DATA) * 4 );
@@ -136,12 +139,12 @@ namespace dpx {
136139
137140 // 4:2:2
138141 template <typename DATA, unsigned int max>
139- static bool ConvertCbYCrYToRGB (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
142+ static bool ConvertCbYCrYToRGB (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
140143 const float *matrix = GetYCbCrToRGBColorMatrix (space);
141144 if (matrix == NULL )
142145 return false ;
143146 DATA CbYCr[3 ];
144- for (int i = 0 ; i < pixels; i++) {
147+ for (size_t i = 0 ; i < pixels; i++) {
145148 // upsample to 4:4:4
146149 // FIXME: proper interpolation
147150 CbYCr[0 ] = input[(i | 1 ) * 2 ]; // Cb
@@ -155,12 +158,12 @@ namespace dpx {
155158
156159 // 4:2:2:4
157160 template <typename DATA, unsigned int max>
158- static bool ConvertCbYACrYAToRGBA (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
161+ static bool ConvertCbYACrYAToRGBA (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
159162 const float *matrix = GetYCbCrToRGBColorMatrix (space);
160163 if (matrix == NULL )
161164 return false ;
162165 DATA CbYCr[3 ];
163- for (int i = 0 ; i < pixels; i++) {
166+ for (size_t i = 0 ; i < pixels; i++) {
164167 // upsample to 4:4:4
165168 // FIXME: proper interpolation
166169 CbYCr[0 ] = input[(i | 1 ) * 3 ]; // Cb
@@ -174,7 +177,7 @@ namespace dpx {
174177 }
175178
176179 static inline bool ConvertToRGBInternal (const Descriptor desc, const DataSize size, const Characteristic space,
177- const void *input, void *output, const int pixels) {
180+ const void *input, void *output, const size_t pixels) {
178181 switch (desc) {
179182 // redundant calls
180183 case kRGB :
@@ -185,19 +188,19 @@ namespace dpx {
185188 case kABGR :
186189 switch (size) {
187190 case kByte :
188- return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
191+ return SwapRGBABytes (OIIO::cspan <U8>((const U8*)input, pixels* 4 ), OIIO::span<U8>((U8 *)output, pixels* 4 ) );
189192 case kWord :
190- return SwapRGBABytes<U16>((const U16 *)input, ( U16 *)output, pixels);
193+ return SwapRGBABytes (OIIO::cspan <U16>((const U16*)input, pixels* 4 ), OIIO::span<U16>(( U16*)output, pixels* 4 ) );
191194 case kInt :
192- return SwapRGBABytes<U32>((const U32 *)input, ( U32 *)output, pixels);
195+ return SwapRGBABytes (OIIO::cspan <U32>((const U32*)input, pixels* 4 ), OIIO::span<U32>(( U32*)output, pixels* 4 ) );
193196 case kFloat :
194- return SwapRGBABytes<R32>((const R32 *)input, ( R32 *)output, pixels);
197+ return SwapRGBABytes (OIIO::cspan <R32>((const R32*)input, pixels* 4 ), OIIO::span<R32>(( R32*)output, pixels* 4 ) );
195198 case kDouble :
196- return SwapRGBABytes<R64>((const R64 *)input, ( R64 *)output, pixels);
199+ return SwapRGBABytes (OIIO::cspan <R64>((const R64*)input, pixels* 4 ), OIIO::span<R64>(( R64*)output, pixels* 4 ) );
197200 }
198201 // shouldn't ever get here
199202 return false ;
200-
203+
201204
202205 // FIXME: can this be translated to RGB?
203206 // case kCompositeVideo:
@@ -287,7 +290,7 @@ namespace dpx {
287290 }
288291 }
289292
290- static inline int QueryRGBBufferSizeInternal (const Descriptor desc, const int pixels, const int bytes) {
293+ static inline int64_t QueryRGBBufferSizeInternal (const Descriptor desc, const size_t pixels, const size_t bytes) {
291294 switch (desc) {
292295 // case kCompositeVideo: // FIXME: can this be translated to RGB?
293296 case kCbYCrY : // 4:2:2 -> RGB, requires allocation
@@ -329,9 +332,10 @@ namespace dpx {
329332 }
330333 }
331334
332- int QueryRGBBufferSize (const Header &header, const int element, const Block &block) {
335+ int64_t QueryRGBBufferSize (const Header &header, const size_t element, const Block &block) {
333336 return QueryRGBBufferSizeInternal (header.ImageDescriptor (element),
334- (block.x2 - block.x1 + 1 ) * (block.y2 - block.y1 + 1 ),
337+ OIIO::clamped_mult64 (block.x2 - block.x1 + 1 ,
338+ block.y2 - block.y1 + 1 ),
335339 header.ComponentByteCount (element));
336340 }
337341
@@ -344,10 +348,12 @@ namespace dpx {
344348#endif /* NOT USED IN OIIO */
345349
346350 bool ConvertToRGB (const Header &header, const int element, const void *input, void *output, const Block &block) {
347- return ConvertToRGBInternal (header.ImageDescriptor (element),
348- header.ComponentDataSize (element), header.Colorimetric (element),
349- input, output, (block.x2 - block.x1 + 1 ) * (block.y2 - block.y1 + 1 ));
350- }
351+ return ConvertToRGBInternal (
352+ header.ImageDescriptor (element),
353+ header.ComponentDataSize (element), header.Colorimetric (element),
354+ input, output, OIIO::clamped_mult64 (block.x2 - block.x1 + 1 ,
355+ block.y2 - block.y1 + 1 ));
356+ }
351357
352358#if 0 /* NOT USED IN OIIO */
353359 bool ConvertToRGB(const Header &header, const int element, const void *input, void *output) {
@@ -479,7 +485,7 @@ namespace dpx {
479485#endif /* NOT USED IN OIIO */
480486
481487 static inline bool ConvertToNativeInternal (const Descriptor desc, const DataSize size, const Characteristic space,
482- const void *input, void *output, const int pixels) {
488+ const void *input, void *output, const size_t pixels) {
483489 switch (desc) {
484490 // redundant calls
485491 case kRGB :
@@ -491,15 +497,15 @@ namespace dpx {
491497 case kABGR:
492498 switch (size) {
493499 case kByte:
494- return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
500+ return SwapRGBABytes(OIIO::cspan <U8>((const U8*)input, pixels*4), OIIO::span<U8>((U8 *)output, pixels*4) );
495501 case kWord:
496- return SwapRGBABytes<U16>((const U16 *)input, ( U16 *)output, pixels);
502+ return SwapRGBABytes(OIIO::cspan <U16>((const U16*)input, pixels*4), OIIO::span<U16>(( U16*)output, pixels*4) );
497503 case kInt:
498- return SwapRGBABytes<U32>((const U32 *)input, ( U32 *)output, pixels);
504+ return SwapRGBABytes(OIIO::cspan <U32>((const U32*)input, pixels*4), OIIO::span<U32>(( U32*)output, pixels*4) );
499505 case kFloat:
500- return SwapRGBABytes<R32>((const R32 *)input, ( R32 *)output, pixels);
506+ return SwapRGBABytes(OIIO::cspan <R32>((const R32*)input, pixels*4), OIIO::span<R32>(( R32*)output, pixels*4) );
501507 case kDouble:
502- return SwapRGBABytes<R64>((const R64 *)input, ( R64 *)output, pixels);
508+ return SwapRGBABytes(OIIO::cspan <R64>((const R64*)input, pixels*4), OIIO::span<R64>(( R64*)output, pixels*4) );
503509 }
504510 // shouldn't ever get here
505511 return false;
@@ -647,7 +653,7 @@ namespace dpx {
647653 }
648654#endif /* NOT USED IN OIIO */
649655
650- bool ConvertToNative (const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const int width, const int height, const void *input, void *output) {
651- return ConvertToNativeInternal (desc, compSize, cmetr, input, output, width * height);
656+ bool ConvertToNative (const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const size_t width, const size_t height, const void *input, void *output) {
657+ return ConvertToNativeInternal (desc, compSize, cmetr, input, output, OIIO::clamped_mult64 ( width, height) );
652658 }
653659}
0 commit comments