1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5
6 #ifdef NDEBUG
7 # undef NDEBUG
8 #endif
9
10 #include "testDeepTiledBasic.h"
11 #include "random.h"
12
13 #include <assert.h>
14 #include <string.h>
15
16 #include <ImfDeepTiledInputFile.h>
17 #include <ImfDeepTiledOutputFile.h>
18
19 #include <ImfArray.h>
20 #include <ImfChannelList.h>
21 #include <ImfDeepFrameBuffer.h>
22 #include <ImfHeader.h>
23 #include <ImfPartType.h>
24 #include <IlmThreadPool.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <vector>
29
30 namespace IMF = OPENEXR_IMF_NAMESPACE;
31 using namespace IMF;
32 using namespace IMATH_NAMESPACE;
33 using namespace ILMTHREAD_NAMESPACE;
34 using namespace std;
35
36 namespace
37 {
38
39 const int width = 273;
40 const int height = 169;
41 const int minX = 10;
42 const int minY = 11;
43 const Box2i dataWindow(V2i(minX, minY), V2i(minX + width - 1, minY + height - 1));
44 const Box2i displayWindow(V2i(0, 0), V2i(minX + width * 2, minY + height * 2));
45
46 vector<int> channelTypes;
47 Array2D< Array2D<unsigned int> > sampleCountWhole;
48 Header header;
49
generateRandomFile(int channelCount,Compression compression,bool bulkWrite,bool relativeCoords,const std::string & filename)50 void generateRandomFile (int channelCount,
51 Compression compression,
52 bool bulkWrite,
53 bool relativeCoords,
54 const std::string & filename)
55 {
56 if (relativeCoords)
57 assert(bulkWrite == false);
58
59 cout << "generating " << flush;
60 header = Header(displayWindow, dataWindow,
61 1,
62 IMATH_NAMESPACE::V2f (0, 0),
63 1,
64 INCREASING_Y,
65 compression);
66 cout << "compression " << compression << " " << flush;
67
68 //
69 // Add channels.
70 //
71
72 channelTypes.clear();
73
74 for (int i = 0; i < channelCount; i++)
75 {
76 int type = random_int(3);
77 stringstream ss;
78 ss << i;
79 string str = ss.str();
80 if (type == 0)
81 header.channels().insert(str, Channel(IMF::UINT));
82 if (type == 1)
83 header.channels().insert(str, Channel(IMF::HALF));
84 if (type == 2)
85 header.channels().insert(str, Channel(IMF::FLOAT));
86 channelTypes.push_back(type);
87 }
88
89 header.setType(DEEPTILE);
90 header.setTileDescription(
91 TileDescription(random_int(width) + 1, random_int(height) + 1, RIPMAP_LEVELS));
92
93
94 //
95 // Set up the output file
96 //
97 remove (filename.c_str());
98 DeepTiledOutputFile file(filename.c_str(), header, 8);
99
100 DeepFrameBuffer frameBuffer;
101
102 Array<Array2D< void* > > data(channelCount);
103 for (int i = 0; i < channelCount; i++)
104 data[i].resizeErase(height, width);
105
106 Array2D<unsigned int> sampleCount;
107 sampleCount.resizeErase(height, width);
108
109 cout << " tileSizeX " << file.tileXSize()
110 << " tileSizeY " << file.tileYSize() << " ";
111
112 sampleCountWhole.resizeErase(file.numYLevels(), file.numXLevels());
113 for (int i = 0; i < sampleCountWhole.height(); i++)
114 for (int j = 0; j < sampleCountWhole.width(); j++)
115 sampleCountWhole[i][j].resizeErase(height, width);
116
117 int memOffset;
118 if (relativeCoords)
119 memOffset = 0;
120 else
121 memOffset = dataWindow.min.x + dataWindow.min.y * width;
122
123 frameBuffer.insertSampleCountSlice (Slice (IMF::UINT,
124 (char *) (&sampleCount[0][0] - memOffset),
125 sizeof (unsigned int) * 1,
126 sizeof (unsigned int) * width,
127 1, 1,
128 0,
129 relativeCoords,
130 relativeCoords));
131
132 for (int i = 0; i < channelCount; i++)
133 {
134 PixelType type = NUM_PIXELTYPES;
135 if (channelTypes[i] == 0)
136 type = IMF::UINT;
137 if (channelTypes[i] == 1)
138 type = IMF::HALF;
139 if (channelTypes[i] == 2)
140 type = IMF::FLOAT;
141
142 stringstream ss;
143 ss << i;
144 string str = ss.str();
145
146 int sampleSize = 0;
147 if (channelTypes[i] == 0) sampleSize = sizeof (unsigned int);
148 if (channelTypes[i] == 1) sampleSize = sizeof (half);
149 if (channelTypes[i] == 2) sampleSize = sizeof (float);
150
151 int pointerSize = sizeof (char *);
152
153 frameBuffer.insert (str,
154 DeepSlice (type,
155 (char *) (&data[i][0][0] - memOffset),
156 pointerSize * 1,
157 pointerSize * width,
158 sampleSize,
159 1, 1,
160 0,
161 relativeCoords,
162 relativeCoords));
163 }
164
165 file.setFrameBuffer(frameBuffer);
166
167 cout << "writing " << flush;
168
169 if (bulkWrite)
170 cout << "bulk " << flush;
171 else
172 {
173 if (relativeCoords == false)
174 cout << "per-tile " << flush;
175 else
176 cout << "per-tile with relative coordinates " << flush;
177 }
178
179 for (int ly = 0; ly < file.numYLevels(); ly++)
180 for (int lx = 0; lx < file.numXLevels(); lx++)
181 {
182 Box2i dataWindowL = file.dataWindowForLevel(lx, ly);
183
184 if (bulkWrite)
185 {
186 //
187 // Bulk write (without relative coordinates).
188 //
189
190 for (int j = 0; j < file.numYTiles(ly); j++)
191 {
192 for (int i = 0; i < file.numXTiles(lx); i++)
193 {
194 Box2i box = file.dataWindowForTile(i, j, lx, ly);
195 for (int y = box.min.y; y <= box.max.y; y++)
196 for (int x = box.min.x; x <= box.max.x; x++)
197 {
198 int dwy = y - dataWindowL.min.y;
199 int dwx = x - dataWindowL.min.x;
200 sampleCount[dwy][dwx] = random_int(10) + 1;
201 sampleCountWhole[ly][lx][dwy][dwx] = sampleCount[dwy][dwx];
202 for (int k = 0; k < channelCount; k++)
203 {
204 if (channelTypes[k] == 0)
205 data[k][dwy][dwx] = new unsigned int[sampleCount[dwy][dwx]];
206 if (channelTypes[k] == 1)
207 data[k][dwy][dwx] = new half[sampleCount[dwy][dwx]];
208 if (channelTypes[k] == 2)
209 data[k][dwy][dwx] = new float[sampleCount[dwy][dwx]];
210 for (unsigned int l = 0; l < sampleCount[dwy][dwx]; l++)
211 {
212 if (channelTypes[k] == 0)
213 ((unsigned int*)data[k][dwy][dwx])[l] = (dwy * width + dwx) % 2049;
214 if (channelTypes[k] == 1)
215 ((half*)data[k][dwy][dwx])[l] = (dwy* width + dwx) % 2049;
216 if (channelTypes[k] == 2)
217 ((float*)data[k][dwy][dwx])[l] = (dwy * width + dwx) % 2049;
218 }
219 }
220 }
221 }
222 }
223
224 file.writeTiles(0, file.numXTiles(lx) - 1, 0, file.numYTiles(ly) - 1, lx, ly);
225 }
226 else if (bulkWrite == false)
227 {
228 if (relativeCoords == false)
229 {
230 //
231 // Per-tile write without relative coordinates.
232 //
233
234 for (int j = 0; j < file.numYTiles(ly); j++)
235 {
236 for (int i = 0; i < file.numXTiles(lx); i++)
237 {
238 Box2i box = file.dataWindowForTile(i, j, lx, ly);
239 for (int y = box.min.y; y <= box.max.y; y++)
240 for (int x = box.min.x; x <= box.max.x; x++)
241 {
242 int dwy = y - dataWindowL.min.y;
243 int dwx = x - dataWindowL.min.x;
244 sampleCount[dwy][dwx] = random_int(10) + 1;
245 sampleCountWhole[ly][lx][dwy][dwx] = sampleCount[dwy][dwx];
246 for (int k = 0; k < channelCount; k++)
247 {
248 if (channelTypes[k] == 0)
249 data[k][dwy][dwx] = new unsigned int[sampleCount[dwy][dwx]];
250 if (channelTypes[k] == 1)
251 data[k][dwy][dwx] = new half[sampleCount[dwy][dwx]];
252 if (channelTypes[k] == 2)
253 data[k][dwy][dwx] = new float[sampleCount[dwy][dwx]];
254 for (unsigned int l = 0; l < sampleCount[dwy][dwx]; l++)
255 {
256 if (channelTypes[k] == 0)
257 ((unsigned int*)data[k][dwy][dwx])[l] = (dwy * width + dwx) % 2049;
258 if (channelTypes[k] == 1)
259 ((half*)data[k][dwy][dwx])[l] = (dwy* width + dwx) % 2049;
260 if (channelTypes[k] == 2)
261 ((float*)data[k][dwy][dwx])[l] = (dwy * width + dwx) % 2049;
262 }
263 }
264 }
265 file.writeTile(i, j, lx, ly);
266 }
267 }
268 }
269 else if (relativeCoords)
270 {
271 //
272 // Per-tile write with relative coordinates.
273 //
274
275 for (int j = 0; j < file.numYTiles(ly); j++)
276 {
277 for (int i = 0; i < file.numXTiles(lx); i++)
278 {
279 Box2i box = file.dataWindowForTile(i, j, lx, ly);
280 for (int y = box.min.y; y <= box.max.y; y++)
281 for (int x = box.min.x; x <= box.max.x; x++)
282 {
283 int dwy = y - dataWindowL.min.y;
284 int dwx = x - dataWindowL.min.x;
285 int ty = y - box.min.y;
286 int tx = x - box.min.x;
287 sampleCount[ty][tx] = random_int(10) + 1;
288 sampleCountWhole[ly][lx][dwy][dwx] = sampleCount[ty][tx];
289 for (int k = 0; k < channelCount; k++)
290 {
291 if (channelTypes[k] == 0)
292 data[k][ty][tx] = new unsigned int[sampleCount[ty][tx]];
293 if (channelTypes[k] == 1)
294 data[k][ty][tx] = new half[sampleCount[ty][tx]];
295 if (channelTypes[k] == 2)
296 data[k][ty][tx] = new float[sampleCount[ty][tx]];
297 for (unsigned int l = 0; l < sampleCount[ty][tx]; l++)
298 {
299 if (channelTypes[k] == 0)
300 ((unsigned int*)data[k][ty][tx])[l] =
301 (dwy * width + dwx) % 2049;
302 if (channelTypes[k] == 1)
303 ((half*)data[k][ty][tx])[l] =
304 (dwy * width + dwx) % 2049;
305 if (channelTypes[k] == 2)
306 ((float*)data[k][ty][tx])[l] =
307 (dwy * width + dwx) % 2049;
308 }
309 }
310 }
311 file.writeTile(i, j, lx, ly);
312
313 for (int y = box.min.y; y <= box.max.y; y++)
314 for (int x = box.min.x; x <= box.max.x; x++)
315 for (int k = 0; k < channelCount; k++)
316 {
317 int ty = y - box.min.y;
318 int tx = x - box.min.x;
319 if (channelTypes[k] == 0)
320 delete[] (unsigned int*) data[k][ty][tx];
321 if (channelTypes[k] == 1)
322 delete[] (half*) data[k][ty][tx];
323 if (channelTypes[k] == 2)
324 delete[] (float*) data[k][ty][tx];
325 }
326 }
327 }
328 }
329 }
330
331 if (relativeCoords == false)
332 {
333 for (int i = 0; i < file.levelHeight(ly); i++)
334 for (int j = 0; j < file.levelWidth(lx); j++)
335 for (int k = 0; k < channelCount; k++)
336 {
337 if (channelTypes[k] == 0)
338 delete[] (unsigned int*) data[k][i][j];
339 if (channelTypes[k] == 1)
340 delete[] (half*) data[k][i][j];
341 if (channelTypes[k] == 2)
342 delete[] (float*) data[k][i][j];
343 }
344 }
345 }
346 }
347
checkValue(void * sampleRawData,int sampleCount,int channelType,int dwx,int dwy)348 void checkValue (void* sampleRawData,
349 int sampleCount,
350 int channelType,
351 int dwx,
352 int dwy)
353 {
354 for (int l = 0; l < sampleCount; l++)
355 {
356 if (channelType == 0)
357 {
358 unsigned int* value = (unsigned int*)(sampleRawData);
359 if (value[l] != static_cast<unsigned int>((dwy * width + dwx) % 2049))
360 cout << dwx << ", " << dwy << " error, should be "
361 << (dwy * width + dwx) % 2049 << ", is " << value[l]
362 << endl << flush;
363 assert (value[l] == static_cast<unsigned int>((dwy * width + dwx) % 2049));
364 }
365 if (channelType == 1)
366 {
367 half* value = (half*)(sampleRawData);
368 if (value[l] != (dwy * width + dwx) % 2049)
369 cout << dwx << ", " << dwy << " error, should be "
370 << (dwy * width + dwx) % 2049 << ", is " << value[l]
371 << endl << flush;
372 assert (value[l] == (dwy * width + dwx) % 2049);
373 }
374 if (channelType == 2)
375 {
376 float* value = (float*)(sampleRawData);
377 if (value[l] != (dwy * width + dwx) % 2049)
378 cout << dwx << ", " << dwy << " error, should be "
379 << (dwy * width + dwx) % 2049 << ", is " << value[l]
380 << endl << flush;
381 assert (value[l] == (dwy * width + dwx) % 2049);
382 }
383 }
384 }
385
readFile(int channelCount,bool bulkRead,bool relativeCoords,bool randomChannels,const std::string & filename)386 void readFile (int channelCount,
387 bool bulkRead,
388 bool relativeCoords,
389 bool randomChannels,
390 const std::string & filename)
391 {
392 if (relativeCoords)
393 assert(bulkRead == false);
394
395 cout << "reading " << flush;
396
397 DeepTiledInputFile file (filename.c_str(), 4);
398
399 const Header& fileHeader = file.header();
400 assert (fileHeader.displayWindow() == header.displayWindow());
401 assert (fileHeader.dataWindow() == header.dataWindow());
402 assert (fileHeader.pixelAspectRatio() == header.pixelAspectRatio());
403 assert (fileHeader.screenWindowCenter() == header.screenWindowCenter());
404 assert (fileHeader.screenWindowWidth() == header.screenWindowWidth());
405 assert (fileHeader.lineOrder() == header.lineOrder());
406 assert (fileHeader.compression() == header.compression());
407 assert (fileHeader.channels() == header.channels());
408 assert (fileHeader.type() == header.type());
409 assert (fileHeader.tileDescription() == header.tileDescription());
410
411 Array2D<unsigned int> localSampleCount;
412 localSampleCount.resizeErase(height, width);
413
414 // also test filling channels. Generate up to 2 extra channels
415 int fillChannels=random_int(3);
416
417 Array<Array2D< void* > > data(channelCount+fillChannels);
418 for (int i = 0; i < channelCount+fillChannels; i++)
419 data[i].resizeErase(height, width);
420
421 DeepFrameBuffer frameBuffer;
422
423 int memOffset;
424 if (relativeCoords)
425 memOffset = 0;
426 else
427 memOffset = dataWindow.min.x + dataWindow.min.y * width;
428 frameBuffer.insertSampleCountSlice (Slice (IMF::UINT,
429 (char *) (&localSampleCount[0][0] - memOffset),
430 sizeof (unsigned int) * 1,
431 sizeof (unsigned int) * width,
432 1, 1,
433 0,
434 relativeCoords,
435 relativeCoords));
436
437
438 vector<int> read_channel(channelCount);
439 int channels_added=0;
440 for (int i = 0; i < channelCount; i++)
441 {
442 if(randomChannels)
443 {
444 read_channel[i] = random_int(2);
445
446 }
447 if(!randomChannels || read_channel[i]==1)
448 {
449 PixelType type = IMF::NUM_PIXELTYPES;
450 if (channelTypes[i] == 0)
451 type = IMF::UINT;
452 if (channelTypes[i] == 1)
453 type = IMF::HALF;
454 if (channelTypes[i] == 2)
455 type = IMF::FLOAT;
456
457 stringstream ss;
458 ss << i;
459 string str = ss.str();
460
461 int sampleSize = 0;
462 if (channelTypes[i] == 0) sampleSize = sizeof (unsigned int);
463 if (channelTypes[i] == 1) sampleSize = sizeof (half);
464 if (channelTypes[i] == 2) sampleSize = sizeof (float);
465
466 int pointerSize = sizeof (char *);
467
468 frameBuffer.insert (str,
469 DeepSlice (type,
470 (char *) (&data[i][0][0] - memOffset),
471 pointerSize * 1,
472 pointerSize * width,
473 sampleSize,
474 1, 1,
475 0,
476 relativeCoords,
477 relativeCoords));
478 channels_added++;
479 }
480 }
481 if(channels_added==0)
482 {
483 cout << "skipping " <<flush;
484 return;
485 }
486 for(int i = 0 ; i < fillChannels ; ++i )
487 {
488 PixelType type = IMF::FLOAT;
489 int sampleSize = sizeof(float);
490 int pointerSize = sizeof (char *);
491 stringstream ss;
492 // generate channel names that aren't in file but (might) interleave with existing file
493 ss << i << "fill";
494 string str = ss.str();
495 frameBuffer.insert (str,
496 DeepSlice (type,
497 (char *) (&data[i+channelCount][0][0] - memOffset),
498 pointerSize * 1,
499 pointerSize * width,
500 sampleSize,
501 1, 1,
502 0,
503 relativeCoords,
504 relativeCoords));
505 }
506
507 file.setFrameBuffer(frameBuffer);
508
509 if (bulkRead)
510 cout << "bulk " << flush;
511 else
512 {
513 if (relativeCoords == false)
514 cout << "per-tile " << flush;
515 else
516 cout << "per-tile with relative coordinates " << flush;
517 }
518
519 for (int ly = 0; ly < file.numYLevels(); ly++)
520 for (int lx = 0; lx < file.numXLevels(); lx++)
521 {
522 Box2i dataWindowL = file.dataWindowForLevel(lx, ly);
523
524 if (bulkRead)
525 {
526 //
527 // Testing bulk read (without relative coordinates).
528 //
529
530 file.readPixelSampleCounts(0, file.numXTiles(lx) - 1, 0, file.numYTiles(ly) - 1, lx, ly);
531
532 for (int i = 0; i < file.numYTiles(ly); i++)
533 {
534 for (int j = 0; j < file.numXTiles(lx); j++)
535 {
536 Box2i box = file.dataWindowForTile(j, i, lx, ly);
537 for (int y = box.min.y; y <= box.max.y; y++)
538 for (int x = box.min.x; x <= box.max.x; x++)
539 {
540 int dwy = y - dataWindowL.min.y;
541 int dwx = x - dataWindowL.min.x;
542 assert(localSampleCount[dwy][dwx] == sampleCountWhole[ly][lx][dwy][dwx]);
543
544 for (size_t k = 0; k < channelTypes.size(); k++)
545 {
546 if (channelTypes[k] == 0)
547 data[k][dwy][dwx] = new unsigned int[localSampleCount[dwy][dwx]];
548 if (channelTypes[k] == 1)
549 data[k][dwy][dwx] = new half[localSampleCount[dwy][dwx]];
550 if (channelTypes[k] == 2)
551 data[k][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
552 }
553
554 for( int f = 0 ; f < fillChannels ; ++f )
555 {
556 data[f + channelTypes.size()][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
557 }
558
559 }
560
561 }
562 }
563
564 file.readTiles(0, file.numXTiles(lx) - 1, 0, file.numYTiles(ly) - 1, lx, ly);
565 }
566 else if (bulkRead == false)
567 {
568 if (relativeCoords == false)
569 {
570 //
571 // Testing per-tile read without relative coordinates.
572 //
573
574 for (int i = 0; i < file.numYTiles(ly); i++)
575 {
576 for (int j = 0; j < file.numXTiles(lx); j++)
577 {
578 file.readPixelSampleCount(j, i, lx, ly);
579
580 Box2i box = file.dataWindowForTile(j, i, lx, ly);
581 for (int y = box.min.y; y <= box.max.y; y++)
582 for (int x = box.min.x; x <= box.max.x; x++)
583 {
584 int dwy = y - dataWindowL.min.y;
585 int dwx = x - dataWindowL.min.x;
586 assert(localSampleCount[dwy][dwx] == sampleCountWhole[ly][lx][dwy][dwx]);
587
588 for (size_t k = 0; k < channelTypes.size(); k++)
589 {
590 if (channelTypes[k] == 0)
591 data[k][dwy][dwx] = new unsigned int[localSampleCount[dwy][dwx]];
592 if (channelTypes[k] == 1)
593 data[k][dwy][dwx] = new half[localSampleCount[dwy][dwx]];
594 if (channelTypes[k] == 2)
595 data[k][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
596 }
597 for( int f = 0 ; f < fillChannels ; ++f )
598 {
599 data[f + channelTypes.size()][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
600 }
601 }
602
603 file.readTile(j, i, lx, ly);
604 }
605 }
606 }
607 else if (relativeCoords)
608 {
609 //
610 // Testing per-tile read with relative coordinates.
611 //
612
613 for (int i = 0; i < file.numYTiles(ly); i++)
614 {
615 for (int j = 0; j < file.numXTiles(lx); j++)
616 {
617 file.readPixelSampleCount(j, i, lx, ly);
618
619 Box2i box = file.dataWindowForTile(j, i, lx, ly);
620 for (int y = box.min.y; y <= box.max.y; y++)
621 for (int x = box.min.x; x <= box.max.x; x++)
622 {
623 int dwy = y - dataWindowL.min.y;
624 int dwx = x - dataWindowL.min.x;
625 int ty = y - box.min.y;
626 int tx = x - box.min.x;
627 assert(localSampleCount[ty][tx] == sampleCountWhole[ly][lx][dwy][dwx]);
628
629 for (size_t k = 0; k < channelTypes.size(); k++)
630 {
631 if( !randomChannels || read_channel[k]==1)
632 {
633 if (channelTypes[k] == 0)
634 data[k][ty][tx] = new unsigned int[localSampleCount[ty][tx]];
635 if (channelTypes[k] == 1)
636 data[k][ty][tx] = new half[localSampleCount[ty][tx]];
637 if (channelTypes[k] == 2)
638 data[k][ty][tx] = new float[localSampleCount[ty][tx]];
639 }
640
641
642 }
643 for( int f = 0 ; f < fillChannels ; ++f )
644 {
645 data[f + channelTypes.size()][ty][tx] = new float[localSampleCount[ty][tx]];
646 }
647 }
648
649 file.readTile(j, i, lx, ly);
650
651 for (int y = box.min.y; y <= box.max.y; y++)
652 for (int x = box.min.x; x <= box.max.x; x++)
653 {
654 int dwy = y - dataWindowL.min.y;
655 int dwx = x - dataWindowL.min.x;
656 int ty = y - box.min.y;
657 int tx = x - box.min.x;
658
659 for (size_t k = 0; k < channelTypes.size(); k++)
660 {
661 if( !randomChannels || read_channel[k]==1)
662 {
663 checkValue(data[k][ty][tx],
664 localSampleCount[ty][tx],
665 channelTypes[k],
666 dwx, dwy);
667 if (channelTypes[k] == 0)
668 delete[] (unsigned int*) data[k][ty][tx];
669 if (channelTypes[k] == 1)
670 delete[] (half*) data[k][ty][tx];
671 if (channelTypes[k] == 2)
672 delete[] (float*) data[k][ty][tx];
673 }
674 }
675 for( int f = 0 ; f < fillChannels ; ++f )
676 {
677 delete[] (float*) data[f+channelTypes.size()][ty][tx];
678 }
679 }
680 }
681 }
682 }
683 }
684
685 if (relativeCoords == false)
686 {
687 for (int i = 0; i < file.levelHeight(ly); i++)
688 for (int j = 0; j < file.levelWidth(lx); j++)
689 for (int k = 0; k < channelCount; k++)
690 {
691 if( !randomChannels || read_channel[k]==1)
692 {
693 for (unsigned int l = 0; l < localSampleCount[i][j]; l++)
694 {
695 if (channelTypes[k] == 0)
696 {
697 unsigned int* value = (unsigned int*)(data[k][i][j]);
698 if (value[l] != static_cast<unsigned int>(i * width + j) % 2049)
699 cout << j << ", " << i << " error, should be "
700 << (i * width + j) % 2049 << ", is " << value[l]
701 << endl << flush;
702 assert (value[l] == static_cast<unsigned int>(i * width + j) % 2049);
703 }
704 if (channelTypes[k] == 1)
705 {
706 half* value = (half*)(data[k][i][j]);
707 if (value[l] != (i * width + j) % 2049)
708 cout << j << ", " << i << " error, should be "
709 << (i * width + j) % 2049 << ", is " << value[l]
710 << endl << flush;
711 assert (((half*)(data[k][i][j]))[l] == (i * width + j) % 2049);
712 }
713 if (channelTypes[k] == 2)
714 {
715 float* value = (float*)(data[k][i][j]);
716 if (value[l] != (i * width + j) % 2049)
717 cout << j << ", " << i << " error, should be "
718 << (i * width + j) % 2049 << ", is " << value[l]
719 << endl << flush;
720 assert (((float*)(data[k][i][j]))[l] == (i * width + j) % 2049);
721 }
722 }
723 }
724 }
725
726 for (int i = 0; i < file.levelHeight(ly); i++)
727 for (int j = 0; j < file.levelWidth(lx); j++)
728 {
729 for (int k = 0; k < channelCount; k++)
730 {
731 if (channelTypes[k] == 0)
732 delete[] (unsigned int*) data[k][i][j];
733 if (channelTypes[k] == 1)
734 delete[] (half*) data[k][i][j];
735 if (channelTypes[k] == 2)
736 delete[] (float*) data[k][i][j];
737 }
738 for( int f = 0 ; f < fillChannels ; ++f )
739 {
740 delete[] (float*) data[f+channelTypes.size()][i][j];
741 }
742 }
743 }
744 }
745 }
746
readWriteTestWithAbsoluateCoordinates(int channelCount,int testTimes,const std::string & tempDir)747 void readWriteTestWithAbsoluateCoordinates (int channelCount,
748 int testTimes,
749 const std::string & tempDir)
750 {
751 cout << "Testing files with " << channelCount
752 << " channels, using absolute coordinates "
753 << testTimes << " times."
754 << endl << flush;
755
756 std::string fn = tempDir + "imf_test_deep_tiled_basic.exr";
757
758 for (int i = 0; i < testTimes; i++)
759 {
760 int compressionIndex = i % 3;
761 Compression compression;
762 switch (compressionIndex)
763 {
764 case 0:
765 compression = NO_COMPRESSION;
766 break;
767 case 1:
768 compression = RLE_COMPRESSION;
769 break;
770 case 2:
771 compression = ZIPS_COMPRESSION;
772 break;
773 }
774
775 generateRandomFile (channelCount, compression, false, false, fn);
776 readFile (channelCount, false, false, false , fn);
777 readFile (channelCount, false, false, true , fn);
778 remove (fn.c_str());
779 cout << endl << flush;
780
781 generateRandomFile (channelCount, compression, true, false, fn);
782 readFile (channelCount, true, false, false, fn);
783 readFile (channelCount, true, false, true, fn);
784
785 remove (fn.c_str());
786 cout << endl << flush;
787
788 generateRandomFile (channelCount, compression, false, true, fn);
789 readFile (channelCount, false, true, false , fn);
790 readFile (channelCount, false, true, true , fn);
791
792 remove (fn.c_str());
793 cout << endl << flush;
794 }
795 }
796
797 } // namespace
798
testDeepTiledBasic(const std::string & tempDir)799 void testDeepTiledBasic (const std::string & tempDir)
800 {
801 try
802 {
803 cout << "Testing the DeepTiledInput/OutputFile for basic use" << endl;
804
805 random_reseed(1);
806
807 int numThreads = ThreadPool::globalThreadPool().numThreads();
808 ThreadPool::globalThreadPool().setNumThreads(2);
809
810 for(int pass = 0 ; pass < 4 ; pass++)
811 {
812 readWriteTestWithAbsoluateCoordinates ( 1, 2, tempDir);
813 readWriteTestWithAbsoluateCoordinates ( 3, 2, tempDir);
814 readWriteTestWithAbsoluateCoordinates (10, 2, tempDir);
815 }
816 ThreadPool::globalThreadPool().setNumThreads(numThreads);
817
818 cout << "ok\n" << endl;
819 }
820 catch (const std::exception &e)
821 {
822 cerr << "ERROR -- caught exception: " << e.what() << endl;
823 assert (false);
824 }
825 }
826