@@ -30,12 +30,215 @@ void example1()
3030//
3131// /////////////////////////////////////////////////////////////////////////
3232
33+ #include < OpenImageIO/imagebuf.h>
3334
35+ // BEGIN-imagebuf-get-pixel-avg
36+ void print_channel_averages (const std::string& filename)
37+ {
38+ // Set up the ImageBuf and read the file
39+ ImageBuf buf (filename);
40+ bool ok = buf.read (0 , 0 , true , TypeDesc::FLOAT); // Force a float buffer
41+ if (!ok)
42+ return ;
43+
44+ // Initialize a vector to contain the running total
45+ int nc = buf.nchannels ();
46+ std::vector<float > total (nc, 0 .0f );
47+
48+ // Iterate over all pixels of the image, summing channels separately
49+ for (ImageBuf::ConstIterator<float > it (buf); !it.done (); ++it)
50+ for (int c = 0 ; c < nc; ++c)
51+ total[c] += it[c];
52+
53+ // Print the averages
54+ imagesize_t npixels = buf.spec ().image_pixels ();
55+ for (int c = 0 ; c < nc; ++c)
56+ std::cout << " Channel " << c << " avg = " << (total[c] / npixels)
57+ << " \n " ;
58+ }
59+
60+ // END-imagebuf-get-pixel-avg
61+
62+ void print_channel_averages_example ()
63+ {
64+ const std::string filename = " findaverages.exr" ;
65+ int x_sz = 640 ;
66+ int y_sz = 480 ;
67+ ImageBuf A (ImageSpec (x_sz, y_sz, 3 , TypeDesc::FLOAT));
68+ for (int i = 0 ; i < x_sz; ++i)
69+ for (int j = 0 ; j < y_sz; ++j) {
70+ // Create a square RGB gradient so determining an average is interesting
71+ A.setpixel (i, j, 0 ,
72+ cspan<float >(
73+ { powf (float (i) / (x_sz - 1 ), 2 .0f ),
74+ powf (float (j) / (y_sz - 1 ), 2 .0f ),
75+ powf (float (i * j) / (x_sz * y_sz - 1 ), 2 .0f ) }));
76+ }
77+ if (!A.write (filename)) {
78+ std::cout << " error: " << A.geterror () << " \n " ;
79+ } else {
80+ print_channel_averages (filename);
81+ }
82+ }
83+
84+ // BEGIN-imagebuf-set-region-black
85+ bool make_black (ImageBuf& buf, ROI region)
86+ {
87+ if (buf.spec ().format != TypeDesc::FLOAT)
88+ return false ; // Assume it's a float buffer
89+
90+ // Clamp the region's channel range to the channels in the image
91+ region.chend = std::min (region.chend , buf.nchannels ());
92+ // Iterate over all pixels in the region...
93+ for (ImageBuf::Iterator<float > it (buf, region); !it.done (); ++it) {
94+ if (!it.exists ()) // Make sure the iterator is pointing
95+ continue ; // to a pixel in the data window
96+ for (int c = region.chbegin ; c < region.chend ; ++c)
97+ it[c] = 0 .0f ; // clear the value
98+ }
99+ return true ;
100+ }
101+ // END-imagebuf-set-region-black
102+
103+ void make_black_example ()
104+ {
105+ int x_sz = 640 ;
106+ int y_sz = 480 ;
107+ ImageBuf A (ImageSpec (x_sz, y_sz, 3 , TypeDesc::FLOAT));
108+ for (int i = 0 ; i < x_sz; ++i)
109+ for (int j = 0 ; j < y_sz; ++j) {
110+ // Create RGB gradient so region changing is easy to see
111+ A.setpixel (i, j, 0 ,
112+ cspan<float >({ float (i) / (x_sz - 1 ),
113+ float (j) / (y_sz - 1 ),
114+ float (i * j) / (x_sz * y_sz - 1 ) }));
115+ }
116+ // A rectangular region straddling the middle of the image above
117+ ROI region (x_sz / 4 , x_sz * 3 / 4 , y_sz / 4 , y_sz * 3 / 4 , 0 , 1 , 0 , 3 );
118+ if (make_black (A, region)) {
119+ A.write (" set-region-black.exr" );
120+ } else {
121+ std::cout << " error: buffer is not a float buffer\n " ;
122+ }
123+ }
124+
125+
126+
127+ // BEGIN-imagebuf-iterator-template
128+ #include < OpenImageIO/half.h>
129+ template <typename BUFT>
130+ static bool make_black_impl (ImageBuf& buf, ROI region)
131+ {
132+ // Clamp the region's channel range to the channels in the image
133+ region.chend = std::min (region.chend , buf.nchannels ());
134+
135+ // Iterate over all pixels in the region...
136+ for (ImageBuf::Iterator<BUFT> it (buf, region); !it.done (); ++it) {
137+ if (!it.exists ()) // Make sure the iterator is pointing
138+ continue ; // to a pixel in the data window
139+ for (int c = region.chbegin ; c < region.chend ; ++c)
140+ it[c] = 0 .0f ; // clear the value
141+ }
142+ return true ;
143+ }
144+
145+ bool make_black_templated (ImageBuf& buf, ROI region)
146+ {
147+ if (buf.spec ().format == TypeDesc::FLOAT)
148+ return make_black_impl<float >(buf, region);
149+ else if (buf.spec ().format == TypeDesc::HALF)
150+ return make_black_impl<half>(buf, region);
151+ else if (buf.spec ().format == TypeDesc::UINT8)
152+ return make_black_impl<unsigned char >(buf, region);
153+ else if (buf.spec ().format == TypeDesc::UINT16)
154+ return make_black_impl<unsigned short >(buf, region);
155+ else {
156+ buf.errorf (" Unsupported pixel data format %s" ,
157+ buf.spec ().format .c_str ());
158+ return false ;
159+ }
160+ }
161+ // END-imagebuf-iterator-template
162+
163+ void make_black_template_example ()
164+ {
165+ int x_sz = 640 ;
166+ int y_sz = 480 ;
167+ ImageBuf A (ImageSpec (x_sz, y_sz, 3 , TypeDesc::FLOAT));
168+ for (int i = 0 ; i < x_sz; ++i)
169+ for (int j = 0 ; j < y_sz; ++j) {
170+ // Create RGB gradient so region changing is easy to see
171+ A.setpixel (i, j, 0 ,
172+ cspan<float >({ float (i) / (x_sz - 1 ),
173+ float (j) / (y_sz - 1 ),
174+ float (i * j) / (x_sz * y_sz - 1 ) }));
175+ }
176+ // A rectangular region straddling the middle of the image above
177+ ROI region (x_sz / 4 , x_sz * 3 / 4 , y_sz / 4 , y_sz * 3 / 4 , 0 , 1 , 0 , 3 );
178+ if (make_black_templated (A, region)) {
179+ A.write (" set-region-black-template-float.exr" );
180+ } else {
181+ std::cout << " error: " << A.geterror () << " \n " ;
182+ }
183+
184+ ImageBuf B (ImageSpec (x_sz, y_sz, 3 , TypeDesc::UINT8));
185+ for (int i = 0 ; i < x_sz; ++i)
186+ for (int j = 0 ; j < y_sz; ++j) {
187+ // Create RGB gradient so region changing is easy to see
188+ B.setpixel (i, j, 0 ,
189+ cspan<float >({ float (i) / (x_sz - 1 ),
190+ float (j) / (y_sz - 1 ),
191+ float (i * j) / (x_sz * y_sz - 1 ) }));
192+ }
193+ // A rectangular region straddling the middle of the image above
194+ if (make_black_templated (B, region)) {
195+ B.write (" set-region-black-template-uint8.exr" );
196+ } else {
197+ std::cout << " error: " << B.geterror () << " \n " ;
198+ }
199+ }
200+
201+ // BEGIN-imagebuf-dispatch
202+ #include < OpenImageIO/imagebufalgo_util.h>
203+ bool make_black_dispatch (ImageBuf& buf, ROI region)
204+ {
205+ bool ok;
206+ OIIO_DISPATCH_COMMON_TYPES (ok, " make_black_dispatch" , make_black_impl,
207+ buf.spec ().format , buf, region);
208+ return ok;
209+ }
210+ // END-imagebuf-dispatch
211+
212+ void make_black_dispatch_example ()
213+ {
214+ int x_sz = 640 ;
215+ int y_sz = 480 ;
216+ ImageBuf A (ImageSpec (x_sz, y_sz, 3 , TypeDesc::UINT16));
217+ for (int i = 0 ; i < x_sz; ++i)
218+ for (int j = 0 ; j < y_sz; ++j) {
219+ // Create RGB gradient so region changing is easy to see
220+ A.setpixel (i, j, 0 ,
221+ cspan<float >({ float (i) / (x_sz - 1 ),
222+ float (j) / (y_sz - 1 ),
223+ float (i * j) / (x_sz * y_sz - 1 ) }));
224+ }
225+ // A rectangular region straddling the middle of the image above
226+ ROI region (x_sz / 4 , x_sz * 3 / 4 , y_sz / 4 , y_sz * 3 / 4 , 0 , 1 , 0 , 3 );
227+ if (make_black_templated (A, region)) {
228+ A.write (" set-region-black-template-dispatch.exr" );
229+ } else {
230+ std::cout << " error: " << A.geterror () << " \n " ;
231+ }
232+ }
34233
35234int main (int /* argc*/ , char ** /* argv*/ )
36235{
37236 // Each example function needs to get called here, or it won't execute
38237 // as part of the test.
39- example1 ();
238+ // example1();
239+ print_channel_averages_example ();
240+ make_black_example ();
241+ make_black_template_example ();
242+ make_black_dispatch_example ();
40243 return 0 ;
41244}
0 commit comments