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+ size_t pixels = input.size () / 4 ;
45+ if (pixels * 4 + 3 >= input.size () || pixels * 4 + 3 >= output.size ())
46+ return false ;
47+ // Because we checked the lengths, we can just use data pointers below
48+ for (size_t i = 0 ; i < pixels; i++) {
49+ DATA a = input.data ()[i * 4 + 0 ], b = input.data ()[i * 4 + 1 ];
50+ output.data ()[i * 4 + 0 ] = input.data ()[i * 4 + 3 ];
51+ output.data ()[i * 4 + 1 ] = input.data ()[i * 4 + 2 ];
52+ output.data ()[i * 4 + 2 ] = b;
53+ output.data ()[i * 4 + 3 ] = a;
5054 }
5155 return true ;
5256 }
@@ -107,12 +111,12 @@ namespace dpx {
107111
108112 // 4:4:4
109113 template <typename DATA, unsigned int max>
110- static bool ConvertCbYCrToRGB (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
114+ static bool ConvertCbYCrToRGB (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
111115 const float *matrix = GetYCbCrToRGBColorMatrix (space);
112116 if (matrix == NULL )
113117 return false ;
114118 DATA RGB[3 ];
115- for (int i = 0 ; i < pixels; i++) {
119+ for (size_t i = 0 ; i < pixels; i++) {
116120 ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 3 ], RGB, matrix);
117121 memcpy (&output[i * 3 ], RGB, sizeof (DATA) * 3 );
118122 }
@@ -121,12 +125,12 @@ namespace dpx {
121125
122126 // 4:4:4:4
123127 template <typename DATA, unsigned int max>
124- static bool ConvertCbYCrAToRGBA (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
128+ static bool ConvertCbYCrAToRGBA (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
125129 const float *matrix = GetYCbCrToRGBColorMatrix (space);
126130 if (matrix == NULL )
127131 return false ;
128132 DATA RGBA[4 ];
129- for (int i = 0 ; i < pixels; i++) {
133+ for (size_t i = 0 ; i < pixels; i++) {
130134 ConvertPixelYCbCrToRGB<DATA, max>(&input[i * 4 ], RGBA, matrix);
131135 RGBA[3 ] = input[i * 4 + 3 ];
132136 memcpy (&output[i * 4 ], RGBA, sizeof (DATA) * 4 );
@@ -136,12 +140,12 @@ namespace dpx {
136140
137141 // 4:2:2
138142 template <typename DATA, unsigned int max>
139- static bool ConvertCbYCrYToRGB (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
143+ static bool ConvertCbYCrYToRGB (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
140144 const float *matrix = GetYCbCrToRGBColorMatrix (space);
141145 if (matrix == NULL )
142146 return false ;
143147 DATA CbYCr[3 ];
144- for (int i = 0 ; i < pixels; i++) {
148+ for (size_t i = 0 ; i < pixels; i++) {
145149 // upsample to 4:4:4
146150 // FIXME: proper interpolation
147151 CbYCr[0 ] = input[(i | 1 ) * 2 ]; // Cb
@@ -155,12 +159,12 @@ namespace dpx {
155159
156160 // 4:2:2:4
157161 template <typename DATA, unsigned int max>
158- static bool ConvertCbYACrYAToRGBA (const Characteristic space, const DATA *input, DATA *output, const int pixels) {
162+ static bool ConvertCbYACrYAToRGBA (const Characteristic space, const DATA *input, DATA *output, const size_t pixels) {
159163 const float *matrix = GetYCbCrToRGBColorMatrix (space);
160164 if (matrix == NULL )
161165 return false ;
162166 DATA CbYCr[3 ];
163- for (int i = 0 ; i < pixels; i++) {
167+ for (size_t i = 0 ; i < pixels; i++) {
164168 // upsample to 4:4:4
165169 // FIXME: proper interpolation
166170 CbYCr[0 ] = input[(i | 1 ) * 3 ]; // Cb
@@ -174,7 +178,7 @@ namespace dpx {
174178 }
175179
176180 static inline bool ConvertToRGBInternal (const Descriptor desc, const DataSize size, const Characteristic space,
177- const void *input, void *output, const int pixels) {
181+ const void *input, void *output, const size_t pixels) {
178182 switch (desc) {
179183 // redundant calls
180184 case kRGB :
@@ -185,19 +189,19 @@ namespace dpx {
185189 case kABGR :
186190 switch (size) {
187191 case kByte :
188- return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
192+ return SwapRGBABytes (OIIO::cspan <U8>((const U8*)input, pixels* 4 ), OIIO::span<U8>((U8 *)output, pixels* 4 ) );
189193 case kWord :
190- return SwapRGBABytes<U16>((const U16 *)input, ( U16 *)output, pixels);
194+ return SwapRGBABytes (OIIO::cspan <U16>((const U16*)input, pixels* 4 ), OIIO::span<U16>(( U16*)output, pixels* 4 ) );
191195 case kInt :
192- return SwapRGBABytes<U32>((const U32 *)input, ( U32 *)output, pixels);
196+ return SwapRGBABytes (OIIO::cspan <U32>((const U32*)input, pixels* 4 ), OIIO::span<U32>(( U32*)output, pixels* 4 ) );
193197 case kFloat :
194- return SwapRGBABytes<R32>((const R32 *)input, ( R32 *)output, pixels);
198+ return SwapRGBABytes (OIIO::cspan <R32>((const R32*)input, pixels* 4 ), OIIO::span<R32>(( R32*)output, pixels* 4 ) );
195199 case kDouble :
196- return SwapRGBABytes<R64>((const R64 *)input, ( R64 *)output, pixels);
200+ return SwapRGBABytes (OIIO::cspan <R64>((const R64*)input, pixels* 4 ), OIIO::span<R64>(( R64*)output, pixels* 4 ) );
197201 }
198202 // shouldn't ever get here
199203 return false ;
200-
204+
201205
202206 // FIXME: can this be translated to RGB?
203207 // case kCompositeVideo:
@@ -287,7 +291,7 @@ namespace dpx {
287291 }
288292 }
289293
290- static inline int QueryRGBBufferSizeInternal (const Descriptor desc, const int pixels, const int bytes) {
294+ static inline int64_t QueryRGBBufferSizeInternal (const Descriptor desc, const size_t pixels, const size_t bytes) {
291295 switch (desc) {
292296 // case kCompositeVideo: // FIXME: can this be translated to RGB?
293297 case kCbYCrY : // 4:2:2 -> RGB, requires allocation
@@ -329,9 +333,10 @@ namespace dpx {
329333 }
330334 }
331335
332- int QueryRGBBufferSize (const Header &header, const int element, const Block &block) {
336+ int64_t QueryRGBBufferSize (const Header &header, const size_t element, const Block &block) {
333337 return QueryRGBBufferSizeInternal (header.ImageDescriptor (element),
334- (block.x2 - block.x1 + 1 ) * (block.y2 - block.y1 + 1 ),
338+ OIIO::clamped_mult64 (block.x2 - block.x1 + 1 ,
339+ block.y2 - block.y1 + 1 ),
335340 header.ComponentByteCount (element));
336341 }
337342
@@ -344,10 +349,12 @@ namespace dpx {
344349#endif /* NOT USED IN OIIO */
345350
346351 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- }
352+ return ConvertToRGBInternal (
353+ header.ImageDescriptor (element),
354+ header.ComponentDataSize (element), header.Colorimetric (element),
355+ input, output, OIIO::clamped_mult64 (block.x2 - block.x1 + 1 ,
356+ block.y2 - block.y1 + 1 ));
357+ }
351358
352359#if 0 /* NOT USED IN OIIO */
353360 bool ConvertToRGB(const Header &header, const int element, const void *input, void *output) {
@@ -479,7 +486,7 @@ namespace dpx {
479486#endif /* NOT USED IN OIIO */
480487
481488 static inline bool ConvertToNativeInternal (const Descriptor desc, const DataSize size, const Characteristic space,
482- const void *input, void *output, const int pixels) {
489+ const void *input, void *output, const size_t pixels) {
483490 switch (desc) {
484491 // redundant calls
485492 case kRGB :
@@ -491,15 +498,15 @@ namespace dpx {
491498 case kABGR:
492499 switch (size) {
493500 case kByte:
494- return SwapRGBABytes<U8>((const U8 *)input, (U8 *)output, pixels);
501+ return SwapRGBABytes(OIIO::cspan <U8>((const U8*)input, pixels*4), OIIO::span<U8>((U8 *)output, pixels*4) );
495502 case kWord:
496- return SwapRGBABytes<U16>((const U16 *)input, ( U16 *)output, pixels);
503+ return SwapRGBABytes(OIIO::cspan <U16>((const U16*)input, pixels*4), OIIO::span<U16>(( U16*)output, pixels*4) );
497504 case kInt:
498- return SwapRGBABytes<U32>((const U32 *)input, ( U32 *)output, pixels);
505+ return SwapRGBABytes(OIIO::cspan <U32>((const U32*)input, pixels*4), OIIO::span<U32>(( U32*)output, pixels*4) );
499506 case kFloat:
500- return SwapRGBABytes<R32>((const R32 *)input, ( R32 *)output, pixels);
507+ return SwapRGBABytes(OIIO::cspan <R32>((const R32*)input, pixels*4), OIIO::span<R32>(( R32*)output, pixels*4) );
501508 case kDouble:
502- return SwapRGBABytes<R64>((const R64 *)input, ( R64 *)output, pixels);
509+ return SwapRGBABytes(OIIO::cspan <R64>((const R64*)input, pixels*4), OIIO::span<R64>(( R64*)output, pixels*4) );
503510 }
504511 // shouldn't ever get here
505512 return false;
@@ -647,7 +654,7 @@ namespace dpx {
647654 }
648655#endif /* NOT USED IN OIIO */
649656
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);
657+ bool ConvertToNative (const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const size_t width, const size_t height, const void *input, void *output) {
658+ return ConvertToNativeInternal (desc, compSize, cmetr, input, output, OIIO::clamped_mult64 ( width, height) );
652659 }
653660}
0 commit comments