/src/openexr/src/lib/OpenEXR/ImfMisc.cpp
Line | Count | Source |
1 | | // |
2 | | // SPDX-License-Identifier: BSD-3-Clause |
3 | | // Copyright (c) Contributors to the OpenEXR Project. |
4 | | // |
5 | | |
6 | | //----------------------------------------------------------------------------- |
7 | | // |
8 | | // Miscellaneous helper functions for OpenEXR image file I/O |
9 | | // |
10 | | //----------------------------------------------------------------------------- |
11 | | |
12 | | #include "ImfNamespace.h" |
13 | | #include <Iex.h> |
14 | | #include <ImathFun.h> |
15 | | #include <ImfAttribute.h> |
16 | | #include <ImfChannelList.h> |
17 | | #include <ImfCompressor.h> |
18 | | #include <ImfConvert.h> |
19 | | #include <ImfHeader.h> |
20 | | #include <ImfMisc.h> |
21 | | #include <ImfPartType.h> |
22 | | #include <ImfStdIO.h> |
23 | | #include <ImfTileDescription.h> |
24 | | #include <ImfXdr.h> |
25 | | |
26 | | #include <codecvt> |
27 | | #include <locale> |
28 | | |
29 | | OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER |
30 | | |
31 | | using IMATH_NAMESPACE::Box2i; |
32 | | using IMATH_NAMESPACE::divp; |
33 | | using IMATH_NAMESPACE::modp; |
34 | | using std::vector; |
35 | | |
36 | | int |
37 | | pixelTypeSize (PixelType type) |
38 | 0 | { |
39 | 0 | int size; |
40 | |
|
41 | 0 | switch (type) |
42 | 0 | { |
43 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
44 | |
|
45 | 0 | size = Xdr::size<unsigned int> (); |
46 | 0 | break; |
47 | | |
48 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
49 | |
|
50 | 0 | size = Xdr::size<half> (); |
51 | 0 | break; |
52 | | |
53 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
54 | |
|
55 | 0 | size = Xdr::size<float> (); |
56 | 0 | break; |
57 | | |
58 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel type."); |
59 | 0 | } |
60 | | |
61 | 0 | return size; |
62 | 0 | } |
63 | | |
64 | | int |
65 | | numSamples (int s, int a, int b) |
66 | 0 | { |
67 | 0 | int a1 = divp (a, s); |
68 | 0 | int b1 = divp (b, s); |
69 | 0 | return b1 - a1 + ((a1 * s < a) ? 0 : 1); |
70 | 0 | } |
71 | | |
72 | | size_t |
73 | | bytesPerLineTable (const Header& header, vector<size_t>& bytesPerLine) |
74 | 0 | { |
75 | 0 | const Box2i& dataWindow = header.dataWindow (); |
76 | 0 | const ChannelList& channels = header.channels (); |
77 | |
|
78 | 0 | bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1); |
79 | |
|
80 | 0 | for (ChannelList::ConstIterator c = channels.begin (); c != channels.end (); |
81 | 0 | ++c) |
82 | 0 | { |
83 | 0 | size_t nBytes = size_t (pixelTypeSize (c.channel ().type)) * |
84 | 0 | size_t (dataWindow.max.x - dataWindow.min.x + 1) / |
85 | 0 | size_t (c.channel ().xSampling); |
86 | |
|
87 | 0 | for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) |
88 | 0 | if (modp (y, c.channel ().ySampling) == 0) |
89 | 0 | bytesPerLine[i] += nBytes; |
90 | 0 | } |
91 | |
|
92 | 0 | size_t maxBytesPerLine = 0; |
93 | |
|
94 | 0 | for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) |
95 | 0 | if (maxBytesPerLine < bytesPerLine[i]) |
96 | 0 | maxBytesPerLine = bytesPerLine[i]; |
97 | |
|
98 | 0 | return maxBytesPerLine; |
99 | 0 | } |
100 | | |
101 | | static int |
102 | | roundToNextMultiple (int n, int d) |
103 | 0 | { |
104 | 0 | return ((n + d - 1) / d) * d; |
105 | 0 | } |
106 | | |
107 | | static int |
108 | | roundToPrevMultiple (int n, int d) |
109 | 0 | { |
110 | 0 | return (n / d) * d; |
111 | 0 | } |
112 | | |
113 | | size_t |
114 | | bytesPerDeepLineTable ( |
115 | | const Header& header, |
116 | | int minY, |
117 | | int maxY, |
118 | | const char* base, |
119 | | int xStride, |
120 | | int yStride, |
121 | | vector<size_t>& bytesPerLine) |
122 | 0 | { |
123 | 0 | const Box2i& dataWindow = header.dataWindow (); |
124 | 0 | const ChannelList& channels = header.channels (); |
125 | |
|
126 | 0 | for (ChannelList::ConstIterator c = channels.begin (); c != channels.end (); |
127 | 0 | ++c) |
128 | 0 | { |
129 | 0 | const int ySampling = abs (c.channel ().ySampling); |
130 | 0 | const int xSampling = abs (c.channel ().xSampling); |
131 | 0 | const uint64_t pixelSize = pixelTypeSize (c.channel ().type); |
132 | | |
133 | | // Here we transform from the domain over all pixels into the domain |
134 | | // of actual samples. We want to sample points in [minY, maxY] where |
135 | | // (y % ySampling) == 0. However, doing this by rejecting samples |
136 | | // requires O(height*width) modulo computations, which were a |
137 | | // significant bottleneck in the previous implementation of this |
138 | | // function. For the low, low price of 4 divisions per channel, we |
139 | | // can tighten the y & x ranges to the least and greatest roots of the |
140 | | // sampling function and then stride by the sampling rate. |
141 | 0 | const int sampleMinY = roundToNextMultiple (minY, ySampling); |
142 | 0 | const int sampleMaxY = roundToPrevMultiple (maxY, ySampling); |
143 | 0 | const int sampleMinX = |
144 | 0 | roundToNextMultiple (dataWindow.min.x, xSampling); |
145 | 0 | const int sampleMaxX = |
146 | 0 | roundToPrevMultiple (dataWindow.max.x, xSampling); |
147 | |
|
148 | 0 | for (int y = sampleMinY; y <= sampleMaxY; y += ySampling) |
149 | 0 | { |
150 | 0 | uint64_t nBytes = 0; |
151 | 0 | for (int x = sampleMinX; x <= sampleMaxX; x += xSampling) |
152 | 0 | { |
153 | 0 | nBytes += pixelSize * static_cast<uint64_t> (sampleCount ( |
154 | 0 | base, xStride, yStride, x, y)); |
155 | 0 | } |
156 | | |
157 | | // |
158 | | // architectures where size_t is smaller than 64 bits may overflow |
159 | | // (scanlines with more than 2^32 bytes are not currently supported so this should not occur with valid files) |
160 | | // |
161 | 0 | if (static_cast<uint64_t> (bytesPerLine[y - dataWindow.min.y]) + |
162 | 0 | nBytes > |
163 | 0 | SIZE_MAX) |
164 | 0 | { |
165 | 0 | throw IEX_NAMESPACE::IoExc ("Scanline size too large"); |
166 | 0 | } |
167 | | |
168 | 0 | bytesPerLine[y - dataWindow.min.y] += nBytes; |
169 | 0 | } |
170 | 0 | } |
171 | | |
172 | 0 | size_t maxBytesPerLine = 0; |
173 | |
|
174 | 0 | for (int y = minY; y <= maxY; ++y) |
175 | 0 | { |
176 | 0 | if (maxBytesPerLine < bytesPerLine[y - dataWindow.min.y]) |
177 | 0 | { |
178 | 0 | maxBytesPerLine = bytesPerLine[y - dataWindow.min.y]; |
179 | 0 | } |
180 | 0 | } |
181 | |
|
182 | 0 | return maxBytesPerLine; |
183 | 0 | } |
184 | | |
185 | | size_t |
186 | | bytesPerDeepLineTable ( |
187 | | const Header& header, |
188 | | char* base, |
189 | | int xStride, |
190 | | int yStride, |
191 | | vector<size_t>& bytesPerLine) |
192 | 0 | { |
193 | 0 | return bytesPerDeepLineTable ( |
194 | 0 | header, |
195 | 0 | header.dataWindow ().min.y, |
196 | 0 | header.dataWindow ().max.y, |
197 | 0 | base, |
198 | 0 | xStride, |
199 | 0 | yStride, |
200 | 0 | bytesPerLine); |
201 | 0 | } |
202 | | |
203 | | void |
204 | | offsetInLineBufferTable ( |
205 | | const vector<size_t>& bytesPerLine, |
206 | | int scanline1, |
207 | | int scanline2, |
208 | | int linesInLineBuffer, |
209 | | vector<size_t>& offsetInLineBuffer) |
210 | 0 | { |
211 | 0 | offsetInLineBuffer.resize (bytesPerLine.size ()); |
212 | |
|
213 | 0 | size_t offset = 0; |
214 | |
|
215 | 0 | for (int i = scanline1; i <= scanline2; ++i) |
216 | 0 | { |
217 | 0 | if (i % linesInLineBuffer == 0) offset = 0; |
218 | |
|
219 | 0 | offsetInLineBuffer[i] = offset; |
220 | 0 | offset += bytesPerLine[i]; |
221 | 0 | } |
222 | 0 | } |
223 | | |
224 | | void |
225 | | offsetInLineBufferTable ( |
226 | | const vector<size_t>& bytesPerLine, |
227 | | int linesInLineBuffer, |
228 | | vector<size_t>& offsetInLineBuffer) |
229 | 0 | { |
230 | 0 | offsetInLineBufferTable ( |
231 | 0 | bytesPerLine, |
232 | 0 | 0, |
233 | 0 | bytesPerLine.size () - 1, |
234 | 0 | linesInLineBuffer, |
235 | 0 | offsetInLineBuffer); |
236 | 0 | } |
237 | | |
238 | | int |
239 | | lineBufferMinY (int y, int minY, int linesInLineBuffer) |
240 | 0 | { |
241 | 0 | return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY; |
242 | 0 | } |
243 | | |
244 | | int |
245 | | lineBufferMaxY (int y, int minY, int linesInLineBuffer) |
246 | 0 | { |
247 | 0 | return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1; |
248 | 0 | } |
249 | | |
250 | | Compressor::Format |
251 | | defaultFormat (Compressor* compressor) |
252 | 0 | { |
253 | 0 | return compressor ? compressor->format () : Compressor::XDR; |
254 | 0 | } |
255 | | |
256 | | //obsolete |
257 | | int |
258 | | numLinesInBuffer (Compressor* compressor) |
259 | 0 | { |
260 | 0 | return compressor ? compressor->numScanLines () : 1; |
261 | 0 | } |
262 | | |
263 | | void |
264 | | copyIntoFrameBuffer ( |
265 | | const char*& readPtr, |
266 | | char* writePtr, |
267 | | char* endPtr, |
268 | | size_t xStride, |
269 | | bool fill, |
270 | | double fillValue, |
271 | | Compressor::Format format, |
272 | | PixelType typeInFrameBuffer, |
273 | | PixelType typeInFile) |
274 | 0 | { |
275 | | // |
276 | | // Copy a horizontal row of pixels from an input |
277 | | // file's line or tile buffer to a frame buffer. |
278 | | // |
279 | |
|
280 | 0 | if (fill) |
281 | 0 | { |
282 | | // |
283 | | // The file contains no data for this channel. |
284 | | // Store a default value in the frame buffer. |
285 | | // |
286 | |
|
287 | 0 | switch (typeInFrameBuffer) |
288 | 0 | { |
289 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
290 | |
|
291 | 0 | { |
292 | 0 | unsigned int fillVal = (unsigned int) (fillValue); |
293 | |
|
294 | 0 | while (writePtr <= endPtr) |
295 | 0 | { |
296 | 0 | *(unsigned int*) writePtr = fillVal; |
297 | 0 | writePtr += xStride; |
298 | 0 | } |
299 | 0 | } |
300 | 0 | break; |
301 | | |
302 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
303 | |
|
304 | 0 | { |
305 | 0 | half fillVal = half (fillValue); |
306 | |
|
307 | 0 | while (writePtr <= endPtr) |
308 | 0 | { |
309 | 0 | *(half*) writePtr = fillVal; |
310 | 0 | writePtr += xStride; |
311 | 0 | } |
312 | 0 | } |
313 | 0 | break; |
314 | | |
315 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
316 | |
|
317 | 0 | { |
318 | 0 | float fillVal = float (fillValue); |
319 | |
|
320 | 0 | while (writePtr <= endPtr) |
321 | 0 | { |
322 | 0 | *(float*) writePtr = fillVal; |
323 | 0 | writePtr += xStride; |
324 | 0 | } |
325 | 0 | } |
326 | 0 | break; |
327 | | |
328 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
329 | 0 | } |
330 | 0 | } |
331 | 0 | else if (format == Compressor::XDR) |
332 | 0 | { |
333 | | // |
334 | | // The line or tile buffer is in XDR format. |
335 | | // |
336 | | // Convert the pixels from the file's machine- |
337 | | // independent representation, and store the |
338 | | // results in the frame buffer. |
339 | | // |
340 | |
|
341 | 0 | switch (typeInFrameBuffer) |
342 | 0 | { |
343 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
344 | |
|
345 | 0 | switch (typeInFile) |
346 | 0 | { |
347 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
348 | |
|
349 | 0 | while (writePtr <= endPtr) |
350 | 0 | { |
351 | 0 | Xdr::read<CharPtrIO> ( |
352 | 0 | readPtr, *(unsigned int*) writePtr); |
353 | 0 | writePtr += xStride; |
354 | 0 | } |
355 | 0 | break; |
356 | | |
357 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
358 | |
|
359 | 0 | while (writePtr <= endPtr) |
360 | 0 | { |
361 | 0 | half h; |
362 | 0 | Xdr::read<CharPtrIO> (readPtr, h); |
363 | 0 | *(unsigned int*) writePtr = halfToUint (h); |
364 | 0 | writePtr += xStride; |
365 | 0 | } |
366 | 0 | break; |
367 | | |
368 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
369 | |
|
370 | 0 | while (writePtr <= endPtr) |
371 | 0 | { |
372 | 0 | float f; |
373 | 0 | Xdr::read<CharPtrIO> (readPtr, f); |
374 | 0 | *(unsigned int*) writePtr = floatToUint (f); |
375 | 0 | writePtr += xStride; |
376 | 0 | } |
377 | 0 | break; |
378 | | |
379 | 0 | default: |
380 | 0 | throw IEX_NAMESPACE::ArgExc ( |
381 | 0 | "Unknown pixel data type."); |
382 | 0 | } |
383 | 0 | break; |
384 | | |
385 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
386 | |
|
387 | 0 | switch (typeInFile) |
388 | 0 | { |
389 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
390 | |
|
391 | 0 | while (writePtr <= endPtr) |
392 | 0 | { |
393 | 0 | unsigned int ui; |
394 | 0 | Xdr::read<CharPtrIO> (readPtr, ui); |
395 | 0 | *(half*) writePtr = uintToHalf (ui); |
396 | 0 | writePtr += xStride; |
397 | 0 | } |
398 | 0 | break; |
399 | | |
400 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
401 | |
|
402 | 0 | while (writePtr <= endPtr) |
403 | 0 | { |
404 | 0 | Xdr::read<CharPtrIO> (readPtr, *(half*) writePtr); |
405 | 0 | writePtr += xStride; |
406 | 0 | } |
407 | 0 | break; |
408 | | |
409 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
410 | |
|
411 | 0 | while (writePtr <= endPtr) |
412 | 0 | { |
413 | 0 | float f; |
414 | 0 | Xdr::read<CharPtrIO> (readPtr, f); |
415 | 0 | *(half*) writePtr = floatToHalf (f); |
416 | 0 | writePtr += xStride; |
417 | 0 | } |
418 | 0 | break; |
419 | 0 | default: |
420 | |
|
421 | 0 | throw IEX_NAMESPACE::ArgExc ( |
422 | 0 | "Unknown pixel data type."); |
423 | 0 | } |
424 | 0 | break; |
425 | | |
426 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
427 | |
|
428 | 0 | switch (typeInFile) |
429 | 0 | { |
430 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
431 | |
|
432 | 0 | while (writePtr <= endPtr) |
433 | 0 | { |
434 | 0 | unsigned int ui; |
435 | 0 | Xdr::read<CharPtrIO> (readPtr, ui); |
436 | 0 | *(float*) writePtr = float (ui); |
437 | 0 | writePtr += xStride; |
438 | 0 | } |
439 | 0 | break; |
440 | | |
441 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
442 | |
|
443 | 0 | while (writePtr <= endPtr) |
444 | 0 | { |
445 | 0 | half h; |
446 | 0 | Xdr::read<CharPtrIO> (readPtr, h); |
447 | 0 | *(float*) writePtr = float (h); |
448 | 0 | writePtr += xStride; |
449 | 0 | } |
450 | 0 | break; |
451 | | |
452 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
453 | |
|
454 | 0 | while (writePtr <= endPtr) |
455 | 0 | { |
456 | 0 | Xdr::read<CharPtrIO> (readPtr, *(float*) writePtr); |
457 | 0 | writePtr += xStride; |
458 | 0 | } |
459 | 0 | break; |
460 | 0 | default: |
461 | |
|
462 | 0 | throw IEX_NAMESPACE::ArgExc ( |
463 | 0 | "Unknown pixel data type."); |
464 | 0 | } |
465 | 0 | break; |
466 | | |
467 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
468 | 0 | } |
469 | 0 | } |
470 | 0 | else |
471 | 0 | { |
472 | | // |
473 | | // The line or tile buffer is in NATIVE format. |
474 | | // Copy the results into the frame buffer. |
475 | | // |
476 | |
|
477 | 0 | switch (typeInFrameBuffer) |
478 | 0 | { |
479 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
480 | |
|
481 | 0 | switch (typeInFile) |
482 | 0 | { |
483 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
484 | |
|
485 | 0 | while (writePtr <= endPtr) |
486 | 0 | { |
487 | 0 | for (size_t i = 0; i < sizeof (unsigned int); ++i) |
488 | 0 | writePtr[i] = readPtr[i]; |
489 | |
|
490 | 0 | readPtr += sizeof (unsigned int); |
491 | 0 | writePtr += xStride; |
492 | 0 | } |
493 | 0 | break; |
494 | | |
495 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
496 | |
|
497 | 0 | while (writePtr <= endPtr) |
498 | 0 | { |
499 | 0 | half h = *(half*) readPtr; |
500 | 0 | *(unsigned int*) writePtr = halfToUint (h); |
501 | 0 | readPtr += sizeof (half); |
502 | 0 | writePtr += xStride; |
503 | 0 | } |
504 | 0 | break; |
505 | | |
506 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
507 | |
|
508 | 0 | while (writePtr <= endPtr) |
509 | 0 | { |
510 | 0 | float f; |
511 | |
|
512 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
513 | 0 | ((char*) &f)[i] = readPtr[i]; |
514 | |
|
515 | 0 | *(unsigned int*) writePtr = floatToUint (f); |
516 | 0 | readPtr += sizeof (float); |
517 | 0 | writePtr += xStride; |
518 | 0 | } |
519 | 0 | break; |
520 | | |
521 | 0 | default: |
522 | |
|
523 | 0 | throw IEX_NAMESPACE::ArgExc ( |
524 | 0 | "Unknown pixel data type."); |
525 | 0 | } |
526 | 0 | break; |
527 | | |
528 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
529 | |
|
530 | 0 | switch (typeInFile) |
531 | 0 | { |
532 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
533 | |
|
534 | 0 | while (writePtr <= endPtr) |
535 | 0 | { |
536 | 0 | unsigned int ui; |
537 | |
|
538 | 0 | for (size_t i = 0; i < sizeof (unsigned int); ++i) |
539 | 0 | ((char*) &ui)[i] = readPtr[i]; |
540 | |
|
541 | 0 | *(half*) writePtr = uintToHalf (ui); |
542 | 0 | readPtr += sizeof (unsigned int); |
543 | 0 | writePtr += xStride; |
544 | 0 | } |
545 | 0 | break; |
546 | | |
547 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
548 | | |
549 | | // If we're tightly packed, just memcpy |
550 | 0 | if (xStride == sizeof (half)) |
551 | 0 | { |
552 | 0 | int numBytes = endPtr - writePtr + sizeof (half); |
553 | 0 | memcpy (writePtr, readPtr, numBytes); |
554 | 0 | readPtr += numBytes; |
555 | 0 | writePtr += numBytes; |
556 | 0 | } |
557 | 0 | else |
558 | 0 | { |
559 | 0 | while (writePtr <= endPtr) |
560 | 0 | { |
561 | 0 | *(half*) writePtr = *(half*) readPtr; |
562 | 0 | readPtr += sizeof (half); |
563 | 0 | writePtr += xStride; |
564 | 0 | } |
565 | 0 | } |
566 | 0 | break; |
567 | | |
568 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
569 | |
|
570 | 0 | while (writePtr <= endPtr) |
571 | 0 | { |
572 | 0 | float f; |
573 | |
|
574 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
575 | 0 | ((char*) &f)[i] = readPtr[i]; |
576 | |
|
577 | 0 | *(half*) writePtr = floatToHalf (f); |
578 | 0 | readPtr += sizeof (float); |
579 | 0 | writePtr += xStride; |
580 | 0 | } |
581 | 0 | break; |
582 | 0 | default: |
583 | |
|
584 | 0 | throw IEX_NAMESPACE::ArgExc ( |
585 | 0 | "Unknown pixel data type."); |
586 | 0 | } |
587 | 0 | break; |
588 | | |
589 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
590 | |
|
591 | 0 | switch (typeInFile) |
592 | 0 | { |
593 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
594 | |
|
595 | 0 | while (writePtr <= endPtr) |
596 | 0 | { |
597 | 0 | unsigned int ui; |
598 | |
|
599 | 0 | for (size_t i = 0; i < sizeof (unsigned int); ++i) |
600 | 0 | ((char*) &ui)[i] = readPtr[i]; |
601 | |
|
602 | 0 | *(float*) writePtr = float (ui); |
603 | 0 | readPtr += sizeof (unsigned int); |
604 | 0 | writePtr += xStride; |
605 | 0 | } |
606 | 0 | break; |
607 | | |
608 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
609 | |
|
610 | 0 | while (writePtr <= endPtr) |
611 | 0 | { |
612 | 0 | half h = *(half*) readPtr; |
613 | 0 | *(float*) writePtr = float (h); |
614 | 0 | readPtr += sizeof (half); |
615 | 0 | writePtr += xStride; |
616 | 0 | } |
617 | 0 | break; |
618 | | |
619 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
620 | |
|
621 | 0 | while (writePtr <= endPtr) |
622 | 0 | { |
623 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
624 | 0 | writePtr[i] = readPtr[i]; |
625 | |
|
626 | 0 | readPtr += sizeof (float); |
627 | 0 | writePtr += xStride; |
628 | 0 | } |
629 | 0 | break; |
630 | 0 | default: |
631 | |
|
632 | 0 | throw IEX_NAMESPACE::ArgExc ( |
633 | 0 | "Unknown pixel data type."); |
634 | 0 | } |
635 | 0 | break; |
636 | | |
637 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
638 | 0 | } |
639 | 0 | } |
640 | 0 | } |
641 | | |
642 | | void |
643 | | copyIntoDeepFrameBuffer ( |
644 | | const char*& readPtr, |
645 | | char* base, |
646 | | const char* sampleCountBase, |
647 | | ptrdiff_t sampleCountXStride, |
648 | | ptrdiff_t sampleCountYStride, |
649 | | int y, |
650 | | int minX, |
651 | | int maxX, |
652 | | int xOffsetForSampleCount, |
653 | | int yOffsetForSampleCount, |
654 | | int xOffsetForData, |
655 | | int yOffsetForData, |
656 | | ptrdiff_t sampleStride, |
657 | | ptrdiff_t xPointerStride, |
658 | | ptrdiff_t yPointerStride, |
659 | | bool fill, |
660 | | double fillValue, |
661 | | Compressor::Format format, |
662 | | PixelType typeInFrameBuffer, |
663 | | PixelType typeInFile) |
664 | 0 | { |
665 | | // |
666 | | // Copy a horizontal row of pixels from an input |
667 | | // file's line or tile buffer to a frame buffer. |
668 | | // |
669 | |
|
670 | 0 | if (fill) |
671 | 0 | { |
672 | | // |
673 | | // The file contains no data for this channel. |
674 | | // Store a default value in the frame buffer. |
675 | | // |
676 | |
|
677 | 0 | switch (typeInFrameBuffer) |
678 | 0 | { |
679 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
680 | |
|
681 | 0 | { |
682 | 0 | unsigned int fillVal = (unsigned int) (fillValue); |
683 | |
|
684 | 0 | for (int x = minX; x <= maxX; x++) |
685 | 0 | { |
686 | 0 | char* writePtr = *( |
687 | 0 | char**) (base + (y - yOffsetForData) * yPointerStride + |
688 | 0 | (x - xOffsetForData) * xPointerStride); |
689 | 0 | if (writePtr) |
690 | 0 | { |
691 | 0 | int count = sampleCount ( |
692 | 0 | sampleCountBase, |
693 | 0 | sampleCountXStride, |
694 | 0 | sampleCountYStride, |
695 | 0 | x - xOffsetForSampleCount, |
696 | 0 | y - yOffsetForSampleCount); |
697 | 0 | for (int i = 0; i < count; i++) |
698 | 0 | { |
699 | 0 | *(unsigned int*) writePtr = fillVal; |
700 | 0 | writePtr += sampleStride; |
701 | 0 | } |
702 | 0 | } |
703 | 0 | } |
704 | 0 | } |
705 | 0 | break; |
706 | | |
707 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
708 | |
|
709 | 0 | { |
710 | 0 | half fillVal = half (fillValue); |
711 | |
|
712 | 0 | for (int x = minX; x <= maxX; x++) |
713 | 0 | { |
714 | 0 | char* writePtr = *( |
715 | 0 | char**) (base + (y - yOffsetForData) * yPointerStride + |
716 | 0 | (x - xOffsetForData) * xPointerStride); |
717 | |
|
718 | 0 | if (writePtr) |
719 | 0 | { |
720 | 0 | int count = sampleCount ( |
721 | 0 | sampleCountBase, |
722 | 0 | sampleCountXStride, |
723 | 0 | sampleCountYStride, |
724 | 0 | x - xOffsetForSampleCount, |
725 | 0 | y - yOffsetForSampleCount); |
726 | 0 | for (int i = 0; i < count; i++) |
727 | 0 | { |
728 | 0 | *(half*) writePtr = fillVal; |
729 | 0 | writePtr += sampleStride; |
730 | 0 | } |
731 | 0 | } |
732 | 0 | } |
733 | 0 | } |
734 | 0 | break; |
735 | | |
736 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
737 | |
|
738 | 0 | { |
739 | 0 | float fillVal = float (fillValue); |
740 | |
|
741 | 0 | for (int x = minX; x <= maxX; x++) |
742 | 0 | { |
743 | 0 | char* writePtr = *( |
744 | 0 | char**) (base + (y - yOffsetForData) * yPointerStride + |
745 | 0 | (x - xOffsetForData) * xPointerStride); |
746 | |
|
747 | 0 | if (writePtr) |
748 | 0 | { |
749 | 0 | int count = sampleCount ( |
750 | 0 | sampleCountBase, |
751 | 0 | sampleCountXStride, |
752 | 0 | sampleCountYStride, |
753 | 0 | x - xOffsetForSampleCount, |
754 | 0 | y - yOffsetForSampleCount); |
755 | 0 | for (int i = 0; i < count; i++) |
756 | 0 | { |
757 | 0 | *(float*) writePtr = fillVal; |
758 | 0 | writePtr += sampleStride; |
759 | 0 | } |
760 | 0 | } |
761 | 0 | } |
762 | 0 | } |
763 | 0 | break; |
764 | | |
765 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
766 | 0 | } |
767 | 0 | } |
768 | 0 | else if (format == Compressor::XDR) |
769 | 0 | { |
770 | | // |
771 | | // The line or tile buffer is in XDR format. |
772 | | // |
773 | | // Convert the pixels from the file's machine- |
774 | | // independent representation, and store the |
775 | | // results in the frame buffer. |
776 | | // |
777 | |
|
778 | 0 | switch (typeInFrameBuffer) |
779 | 0 | { |
780 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
781 | |
|
782 | 0 | switch (typeInFile) |
783 | 0 | { |
784 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
785 | |
|
786 | 0 | for (int x = minX; x <= maxX; x++) |
787 | 0 | { |
788 | 0 | char* writePtr = *( |
789 | 0 | char**) (base + |
790 | 0 | (y - yOffsetForData) * yPointerStride + |
791 | 0 | (x - xOffsetForData) * xPointerStride); |
792 | |
|
793 | 0 | int count = sampleCount ( |
794 | 0 | sampleCountBase, |
795 | 0 | sampleCountXStride, |
796 | 0 | sampleCountYStride, |
797 | 0 | x - xOffsetForSampleCount, |
798 | 0 | y - yOffsetForSampleCount); |
799 | 0 | if (writePtr) |
800 | 0 | { |
801 | |
|
802 | 0 | for (int i = 0; i < count; i++) |
803 | 0 | { |
804 | 0 | Xdr::read<CharPtrIO> ( |
805 | 0 | readPtr, *(unsigned int*) writePtr); |
806 | 0 | writePtr += sampleStride; |
807 | 0 | } |
808 | 0 | } |
809 | 0 | else |
810 | 0 | { |
811 | 0 | Xdr::skip<CharPtrIO> ( |
812 | 0 | readPtr, |
813 | 0 | count * Xdr::size<unsigned int> ()); |
814 | 0 | } |
815 | 0 | } |
816 | 0 | break; |
817 | | |
818 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
819 | |
|
820 | 0 | for (int x = minX; x <= maxX; x++) |
821 | 0 | { |
822 | 0 | char* writePtr = *( |
823 | 0 | char**) (base + |
824 | 0 | (y - yOffsetForData) * yPointerStride + |
825 | 0 | (x - xOffsetForData) * xPointerStride); |
826 | |
|
827 | 0 | int count = sampleCount ( |
828 | 0 | sampleCountBase, |
829 | 0 | sampleCountXStride, |
830 | 0 | sampleCountYStride, |
831 | 0 | x - xOffsetForSampleCount, |
832 | 0 | y - yOffsetForSampleCount); |
833 | 0 | if (writePtr) |
834 | 0 | { |
835 | |
|
836 | 0 | for (int i = 0; i < count; i++) |
837 | 0 | { |
838 | 0 | half h; |
839 | 0 | Xdr::read<CharPtrIO> (readPtr, h); |
840 | 0 | *(unsigned int*) writePtr = halfToUint (h); |
841 | 0 | writePtr += sampleStride; |
842 | 0 | } |
843 | 0 | } |
844 | 0 | else |
845 | 0 | { |
846 | 0 | Xdr::skip<CharPtrIO> ( |
847 | 0 | readPtr, count * Xdr::size<half> ()); |
848 | 0 | } |
849 | 0 | } |
850 | 0 | break; |
851 | | |
852 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
853 | |
|
854 | 0 | for (int x = minX; x <= maxX; x++) |
855 | 0 | { |
856 | 0 | char* writePtr = *( |
857 | 0 | char**) (base + |
858 | 0 | (y - yOffsetForData) * yPointerStride + |
859 | 0 | (x - xOffsetForData) * xPointerStride); |
860 | |
|
861 | 0 | int count = sampleCount ( |
862 | 0 | sampleCountBase, |
863 | 0 | sampleCountXStride, |
864 | 0 | sampleCountYStride, |
865 | 0 | x - xOffsetForSampleCount, |
866 | 0 | y - yOffsetForSampleCount); |
867 | |
|
868 | 0 | if (writePtr) |
869 | 0 | { |
870 | 0 | for (int i = 0; i < count; i++) |
871 | 0 | { |
872 | 0 | float f; |
873 | 0 | Xdr::read<CharPtrIO> (readPtr, f); |
874 | 0 | *(unsigned int*) writePtr = floatToUint (f); |
875 | 0 | writePtr += sampleStride; |
876 | 0 | } |
877 | 0 | } |
878 | 0 | else |
879 | 0 | { |
880 | 0 | Xdr::skip<CharPtrIO> ( |
881 | 0 | readPtr, count * Xdr::size<float> ()); |
882 | 0 | } |
883 | 0 | } |
884 | 0 | break; |
885 | 0 | default: |
886 | 0 | throw IEX_NAMESPACE::ArgExc ( |
887 | 0 | "Unknown pixel data type."); |
888 | 0 | } |
889 | 0 | break; |
890 | | |
891 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
892 | |
|
893 | 0 | switch (typeInFile) |
894 | 0 | { |
895 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
896 | |
|
897 | 0 | for (int x = minX; x <= maxX; x++) |
898 | 0 | { |
899 | 0 | char* writePtr = *( |
900 | 0 | char**) (base + |
901 | 0 | (y - yOffsetForData) * yPointerStride + |
902 | 0 | (x - xOffsetForData) * xPointerStride); |
903 | |
|
904 | 0 | int count = sampleCount ( |
905 | 0 | sampleCountBase, |
906 | 0 | sampleCountXStride, |
907 | 0 | sampleCountYStride, |
908 | 0 | x - xOffsetForSampleCount, |
909 | 0 | y - yOffsetForSampleCount); |
910 | 0 | if (writePtr) |
911 | 0 | { |
912 | |
|
913 | 0 | for (int i = 0; i < count; i++) |
914 | 0 | { |
915 | 0 | unsigned int ui; |
916 | 0 | Xdr::read<CharPtrIO> (readPtr, ui); |
917 | 0 | *(half*) writePtr = uintToHalf (ui); |
918 | 0 | writePtr += sampleStride; |
919 | 0 | } |
920 | 0 | } |
921 | 0 | else |
922 | 0 | { |
923 | 0 | Xdr::skip<CharPtrIO> ( |
924 | 0 | readPtr, |
925 | 0 | count * Xdr::size<unsigned int> ()); |
926 | 0 | } |
927 | 0 | } |
928 | 0 | break; |
929 | | |
930 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
931 | |
|
932 | 0 | for (int x = minX; x <= maxX; x++) |
933 | 0 | { |
934 | 0 | char* writePtr = *( |
935 | 0 | char**) (base + |
936 | 0 | (y - yOffsetForData) * yPointerStride + |
937 | 0 | (x - xOffsetForData) * xPointerStride); |
938 | |
|
939 | 0 | int count = sampleCount ( |
940 | 0 | sampleCountBase, |
941 | 0 | sampleCountXStride, |
942 | 0 | sampleCountYStride, |
943 | 0 | x - xOffsetForSampleCount, |
944 | 0 | y - yOffsetForSampleCount); |
945 | 0 | if (writePtr) |
946 | 0 | { |
947 | |
|
948 | 0 | for (int i = 0; i < count; i++) |
949 | 0 | { |
950 | 0 | Xdr::read<CharPtrIO> ( |
951 | 0 | readPtr, *(half*) writePtr); |
952 | 0 | writePtr += sampleStride; |
953 | 0 | } |
954 | 0 | } |
955 | 0 | else |
956 | 0 | { |
957 | 0 | Xdr::skip<CharPtrIO> ( |
958 | 0 | readPtr, count * Xdr::size<half> ()); |
959 | 0 | } |
960 | 0 | } |
961 | 0 | break; |
962 | | |
963 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
964 | |
|
965 | 0 | for (int x = minX; x <= maxX; x++) |
966 | 0 | { |
967 | 0 | char* writePtr = *( |
968 | 0 | char**) (base + |
969 | 0 | (y - yOffsetForData) * yPointerStride + |
970 | 0 | (x - xOffsetForData) * xPointerStride); |
971 | |
|
972 | 0 | int count = sampleCount ( |
973 | 0 | sampleCountBase, |
974 | 0 | sampleCountXStride, |
975 | 0 | sampleCountYStride, |
976 | 0 | x - xOffsetForSampleCount, |
977 | 0 | y - yOffsetForSampleCount); |
978 | 0 | if (writePtr) |
979 | 0 | { |
980 | 0 | for (int i = 0; i < count; i++) |
981 | 0 | { |
982 | 0 | float f; |
983 | 0 | Xdr::read<CharPtrIO> (readPtr, f); |
984 | 0 | *(half*) writePtr = floatToHalf (f); |
985 | 0 | writePtr += sampleStride; |
986 | 0 | } |
987 | 0 | } |
988 | 0 | else |
989 | 0 | { |
990 | 0 | Xdr::skip<CharPtrIO> ( |
991 | 0 | readPtr, count * Xdr::size<float> ()); |
992 | 0 | } |
993 | 0 | } |
994 | 0 | break; |
995 | 0 | default: |
996 | |
|
997 | 0 | throw IEX_NAMESPACE::ArgExc ( |
998 | 0 | "Unknown pixel data type."); |
999 | 0 | } |
1000 | 0 | break; |
1001 | | |
1002 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1003 | |
|
1004 | 0 | switch (typeInFile) |
1005 | 0 | { |
1006 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1007 | |
|
1008 | 0 | for (int x = minX; x <= maxX; x++) |
1009 | 0 | { |
1010 | 0 | char* writePtr = *( |
1011 | 0 | char**) (base + |
1012 | 0 | (y - yOffsetForData) * yPointerStride + |
1013 | 0 | (x - xOffsetForData) * xPointerStride); |
1014 | |
|
1015 | 0 | int count = sampleCount ( |
1016 | 0 | sampleCountBase, |
1017 | 0 | sampleCountXStride, |
1018 | 0 | sampleCountYStride, |
1019 | 0 | x - xOffsetForSampleCount, |
1020 | 0 | y - yOffsetForSampleCount); |
1021 | 0 | if (writePtr) |
1022 | 0 | { |
1023 | 0 | for (int i = 0; i < count; i++) |
1024 | 0 | { |
1025 | 0 | unsigned int ui; |
1026 | 0 | Xdr::read<CharPtrIO> (readPtr, ui); |
1027 | 0 | *(float*) writePtr = float (ui); |
1028 | 0 | writePtr += sampleStride; |
1029 | 0 | } |
1030 | 0 | } |
1031 | 0 | else |
1032 | 0 | { |
1033 | 0 | Xdr::skip<CharPtrIO> ( |
1034 | 0 | readPtr, |
1035 | 0 | count * Xdr::size<unsigned int> ()); |
1036 | 0 | } |
1037 | 0 | } |
1038 | 0 | break; |
1039 | | |
1040 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1041 | |
|
1042 | 0 | for (int x = minX; x <= maxX; x++) |
1043 | 0 | { |
1044 | 0 | char* writePtr = *( |
1045 | 0 | char**) (base + |
1046 | 0 | (y - yOffsetForData) * yPointerStride + |
1047 | 0 | (x - xOffsetForData) * xPointerStride); |
1048 | |
|
1049 | 0 | int count = sampleCount ( |
1050 | 0 | sampleCountBase, |
1051 | 0 | sampleCountXStride, |
1052 | 0 | sampleCountYStride, |
1053 | 0 | x - xOffsetForSampleCount, |
1054 | 0 | y - yOffsetForSampleCount); |
1055 | 0 | if (writePtr) |
1056 | 0 | { |
1057 | |
|
1058 | 0 | for (int i = 0; i < count; i++) |
1059 | 0 | { |
1060 | 0 | half h; |
1061 | 0 | Xdr::read<CharPtrIO> (readPtr, h); |
1062 | 0 | *(float*) writePtr = float (h); |
1063 | 0 | writePtr += sampleStride; |
1064 | 0 | } |
1065 | 0 | } |
1066 | 0 | else |
1067 | 0 | { |
1068 | 0 | Xdr::skip<CharPtrIO> ( |
1069 | 0 | readPtr, count * Xdr::size<half> ()); |
1070 | 0 | } |
1071 | 0 | } |
1072 | 0 | break; |
1073 | | |
1074 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1075 | |
|
1076 | 0 | for (int x = minX; x <= maxX; x++) |
1077 | 0 | { |
1078 | 0 | char* writePtr = *( |
1079 | 0 | char**) (base + |
1080 | 0 | (y - yOffsetForData) * yPointerStride + |
1081 | 0 | (x - xOffsetForData) * xPointerStride); |
1082 | |
|
1083 | 0 | int count = sampleCount ( |
1084 | 0 | sampleCountBase, |
1085 | 0 | sampleCountXStride, |
1086 | 0 | sampleCountYStride, |
1087 | 0 | x - xOffsetForSampleCount, |
1088 | 0 | y - yOffsetForSampleCount); |
1089 | 0 | if (writePtr) |
1090 | 0 | { |
1091 | |
|
1092 | 0 | for (int i = 0; i < count; i++) |
1093 | 0 | { |
1094 | 0 | Xdr::read<CharPtrIO> ( |
1095 | 0 | readPtr, *(float*) writePtr); |
1096 | 0 | writePtr += sampleStride; |
1097 | 0 | } |
1098 | 0 | } |
1099 | 0 | else |
1100 | 0 | { |
1101 | 0 | Xdr::skip<CharPtrIO> ( |
1102 | 0 | readPtr, count * Xdr::size<float> ()); |
1103 | 0 | } |
1104 | 0 | } |
1105 | 0 | break; |
1106 | 0 | default: |
1107 | |
|
1108 | 0 | throw IEX_NAMESPACE::ArgExc ( |
1109 | 0 | "Unknown pixel data type."); |
1110 | 0 | } |
1111 | 0 | break; |
1112 | | |
1113 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1114 | 0 | } |
1115 | 0 | } |
1116 | 0 | else |
1117 | 0 | { |
1118 | | // |
1119 | | // The line or tile buffer is in NATIVE format. |
1120 | | // Copy the results into the frame buffer. |
1121 | | // |
1122 | |
|
1123 | 0 | switch (typeInFrameBuffer) |
1124 | 0 | { |
1125 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1126 | |
|
1127 | 0 | switch (typeInFile) |
1128 | 0 | { |
1129 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1130 | |
|
1131 | 0 | for (int x = minX; x <= maxX; x++) |
1132 | 0 | { |
1133 | 0 | char* writePtr = *( |
1134 | 0 | char**) (base + |
1135 | 0 | (y - yOffsetForData) * yPointerStride + |
1136 | 0 | (x - xOffsetForData) * xPointerStride); |
1137 | |
|
1138 | 0 | int count = sampleCount ( |
1139 | 0 | sampleCountBase, |
1140 | 0 | sampleCountXStride, |
1141 | 0 | sampleCountYStride, |
1142 | 0 | x - xOffsetForSampleCount, |
1143 | 0 | y - yOffsetForSampleCount); |
1144 | |
|
1145 | 0 | if (writePtr) |
1146 | 0 | { |
1147 | 0 | for (int i = 0; i < count; i++) |
1148 | 0 | { |
1149 | 0 | for (size_t i = 0; |
1150 | 0 | i < sizeof (unsigned int); |
1151 | 0 | ++i) |
1152 | 0 | writePtr[i] = readPtr[i]; |
1153 | |
|
1154 | 0 | readPtr += sizeof (unsigned int); |
1155 | 0 | writePtr += sampleStride; |
1156 | 0 | } |
1157 | 0 | } |
1158 | 0 | else { readPtr += sizeof (unsigned int) * count; } |
1159 | 0 | } |
1160 | 0 | break; |
1161 | | |
1162 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1163 | |
|
1164 | 0 | for (int x = minX; x <= maxX; x++) |
1165 | 0 | { |
1166 | 0 | char* writePtr = *( |
1167 | 0 | char**) (base + |
1168 | 0 | (y - yOffsetForData) * yPointerStride + |
1169 | 0 | (x - xOffsetForData) * xPointerStride); |
1170 | |
|
1171 | 0 | int count = sampleCount ( |
1172 | 0 | sampleCountBase, |
1173 | 0 | sampleCountXStride, |
1174 | 0 | sampleCountYStride, |
1175 | 0 | x - xOffsetForSampleCount, |
1176 | 0 | y - yOffsetForSampleCount); |
1177 | |
|
1178 | 0 | if (writePtr) |
1179 | 0 | { |
1180 | 0 | for (int i = 0; i < count; i++) |
1181 | 0 | { |
1182 | 0 | half h = *(half*) readPtr; |
1183 | 0 | *(unsigned int*) writePtr = halfToUint (h); |
1184 | 0 | readPtr += sizeof (half); |
1185 | 0 | writePtr += sampleStride; |
1186 | 0 | } |
1187 | 0 | } |
1188 | 0 | else { readPtr += sizeof (half) * count; } |
1189 | 0 | } |
1190 | 0 | break; |
1191 | | |
1192 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1193 | |
|
1194 | 0 | for (int x = minX; x <= maxX; x++) |
1195 | 0 | { |
1196 | 0 | char* writePtr = *( |
1197 | 0 | char**) (base + |
1198 | 0 | (y - yOffsetForData) * yPointerStride + |
1199 | 0 | (x - xOffsetForData) * xPointerStride); |
1200 | |
|
1201 | 0 | int count = sampleCount ( |
1202 | 0 | sampleCountBase, |
1203 | 0 | sampleCountXStride, |
1204 | 0 | sampleCountYStride, |
1205 | 0 | x - xOffsetForSampleCount, |
1206 | 0 | y - yOffsetForSampleCount); |
1207 | |
|
1208 | 0 | if (writePtr) |
1209 | 0 | { |
1210 | |
|
1211 | 0 | for (int i = 0; i < count; i++) |
1212 | 0 | { |
1213 | 0 | float f; |
1214 | |
|
1215 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
1216 | 0 | ((char*) &f)[i] = readPtr[i]; |
1217 | |
|
1218 | 0 | *(unsigned int*) writePtr = floatToUint (f); |
1219 | 0 | readPtr += sizeof (float); |
1220 | 0 | writePtr += sampleStride; |
1221 | 0 | } |
1222 | 0 | } |
1223 | 0 | else { readPtr += sizeof (float) * count; } |
1224 | 0 | } |
1225 | 0 | break; |
1226 | 0 | default: |
1227 | |
|
1228 | 0 | throw IEX_NAMESPACE::ArgExc ( |
1229 | 0 | "Unknown pixel data type."); |
1230 | 0 | } |
1231 | 0 | break; |
1232 | | |
1233 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1234 | |
|
1235 | 0 | switch (typeInFile) |
1236 | 0 | { |
1237 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1238 | |
|
1239 | 0 | for (int x = minX; x <= maxX; x++) |
1240 | 0 | { |
1241 | 0 | char* writePtr = *( |
1242 | 0 | char**) (base + |
1243 | 0 | (y - yOffsetForData) * yPointerStride + |
1244 | 0 | (x - xOffsetForData) * xPointerStride); |
1245 | |
|
1246 | 0 | int count = sampleCount ( |
1247 | 0 | sampleCountBase, |
1248 | 0 | sampleCountXStride, |
1249 | 0 | sampleCountYStride, |
1250 | 0 | x - xOffsetForSampleCount, |
1251 | 0 | y - yOffsetForSampleCount); |
1252 | |
|
1253 | 0 | if (writePtr) |
1254 | 0 | { |
1255 | 0 | for (int i = 0; i < count; i++) |
1256 | 0 | { |
1257 | 0 | unsigned int ui; |
1258 | |
|
1259 | 0 | for (size_t i = 0; |
1260 | 0 | i < sizeof (unsigned int); |
1261 | 0 | ++i) |
1262 | 0 | ((char*) &ui)[i] = readPtr[i]; |
1263 | |
|
1264 | 0 | *(half*) writePtr = uintToHalf (ui); |
1265 | 0 | readPtr += sizeof (unsigned int); |
1266 | 0 | writePtr += sampleStride; |
1267 | 0 | } |
1268 | 0 | } |
1269 | 0 | else { readPtr += sizeof (unsigned int) * count; } |
1270 | 0 | } |
1271 | 0 | break; |
1272 | | |
1273 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1274 | |
|
1275 | 0 | for (int x = minX; x <= maxX; x++) |
1276 | 0 | { |
1277 | 0 | char* writePtr = *( |
1278 | 0 | char**) (base + |
1279 | 0 | (y - yOffsetForData) * yPointerStride + |
1280 | 0 | (x - xOffsetForData) * xPointerStride); |
1281 | |
|
1282 | 0 | int count = sampleCount ( |
1283 | 0 | sampleCountBase, |
1284 | 0 | sampleCountXStride, |
1285 | 0 | sampleCountYStride, |
1286 | 0 | x - xOffsetForSampleCount, |
1287 | 0 | y - yOffsetForSampleCount); |
1288 | |
|
1289 | 0 | if (writePtr) |
1290 | 0 | { |
1291 | 0 | for (int i = 0; i < count; i++) |
1292 | 0 | { |
1293 | 0 | *(half*) writePtr = *(half*) readPtr; |
1294 | 0 | readPtr += sizeof (half); |
1295 | 0 | writePtr += sampleStride; |
1296 | 0 | } |
1297 | 0 | } |
1298 | 0 | else { readPtr += sizeof (half) * count; } |
1299 | 0 | } |
1300 | 0 | break; |
1301 | | |
1302 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1303 | |
|
1304 | 0 | for (int x = minX; x <= maxX; x++) |
1305 | 0 | { |
1306 | 0 | char* writePtr = *( |
1307 | 0 | char**) (base + |
1308 | 0 | (y - yOffsetForData) * yPointerStride + |
1309 | 0 | (x - xOffsetForData) * xPointerStride); |
1310 | |
|
1311 | 0 | int count = sampleCount ( |
1312 | 0 | sampleCountBase, |
1313 | 0 | sampleCountXStride, |
1314 | 0 | sampleCountYStride, |
1315 | 0 | x - xOffsetForSampleCount, |
1316 | 0 | y - yOffsetForSampleCount); |
1317 | |
|
1318 | 0 | if (writePtr) |
1319 | 0 | { |
1320 | 0 | for (int i = 0; i < count; i++) |
1321 | 0 | { |
1322 | 0 | float f; |
1323 | |
|
1324 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
1325 | 0 | ((char*) &f)[i] = readPtr[i]; |
1326 | |
|
1327 | 0 | *(half*) writePtr = floatToHalf (f); |
1328 | 0 | readPtr += sizeof (float); |
1329 | 0 | writePtr += sampleStride; |
1330 | 0 | } |
1331 | 0 | } |
1332 | 0 | else { readPtr += sizeof (float) * count; } |
1333 | 0 | } |
1334 | 0 | break; |
1335 | 0 | default: |
1336 | |
|
1337 | 0 | throw IEX_NAMESPACE::ArgExc ( |
1338 | 0 | "Unknown pixel data type."); |
1339 | 0 | } |
1340 | 0 | break; |
1341 | | |
1342 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1343 | |
|
1344 | 0 | switch (typeInFile) |
1345 | 0 | { |
1346 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1347 | |
|
1348 | 0 | for (int x = minX; x <= maxX; x++) |
1349 | 0 | { |
1350 | 0 | char* writePtr = *( |
1351 | 0 | char**) (base + |
1352 | 0 | (y - yOffsetForData) * yPointerStride + |
1353 | 0 | (x - xOffsetForData) * xPointerStride); |
1354 | |
|
1355 | 0 | int count = sampleCount ( |
1356 | 0 | sampleCountBase, |
1357 | 0 | sampleCountXStride, |
1358 | 0 | sampleCountYStride, |
1359 | 0 | x - xOffsetForSampleCount, |
1360 | 0 | y - yOffsetForSampleCount); |
1361 | |
|
1362 | 0 | if (writePtr) |
1363 | 0 | { |
1364 | 0 | for (int i = 0; i < count; i++) |
1365 | 0 | { |
1366 | 0 | unsigned int ui; |
1367 | |
|
1368 | 0 | for (size_t i = 0; |
1369 | 0 | i < sizeof (unsigned int); |
1370 | 0 | ++i) |
1371 | 0 | ((char*) &ui)[i] = readPtr[i]; |
1372 | |
|
1373 | 0 | *(float*) writePtr = float (ui); |
1374 | 0 | readPtr += sizeof (unsigned int); |
1375 | 0 | writePtr += sampleStride; |
1376 | 0 | } |
1377 | 0 | } |
1378 | 0 | else { readPtr += sizeof (unsigned int) * count; } |
1379 | 0 | } |
1380 | 0 | break; |
1381 | | |
1382 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1383 | |
|
1384 | 0 | for (int x = minX; x <= maxX; x++) |
1385 | 0 | { |
1386 | 0 | char* writePtr = *( |
1387 | 0 | char**) (base + |
1388 | 0 | (y - yOffsetForData) * yPointerStride + |
1389 | 0 | (x - xOffsetForData) * xPointerStride); |
1390 | |
|
1391 | 0 | int count = sampleCount ( |
1392 | 0 | sampleCountBase, |
1393 | 0 | sampleCountXStride, |
1394 | 0 | sampleCountYStride, |
1395 | 0 | x - xOffsetForSampleCount, |
1396 | 0 | y - yOffsetForSampleCount); |
1397 | |
|
1398 | 0 | if (writePtr) |
1399 | 0 | { |
1400 | 0 | for (int i = 0; i < count; i++) |
1401 | 0 | { |
1402 | 0 | half h = *(half*) readPtr; |
1403 | 0 | *(float*) writePtr = float (h); |
1404 | 0 | readPtr += sizeof (half); |
1405 | 0 | writePtr += sampleStride; |
1406 | 0 | } |
1407 | 0 | } |
1408 | 0 | else { readPtr += sizeof (half) * count; } |
1409 | 0 | } |
1410 | 0 | break; |
1411 | | |
1412 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1413 | |
|
1414 | 0 | for (int x = minX; x <= maxX; x++) |
1415 | 0 | { |
1416 | 0 | char* writePtr = *( |
1417 | 0 | char**) (base + |
1418 | 0 | (y - yOffsetForData) * yPointerStride + |
1419 | 0 | (x - xOffsetForData) * xPointerStride); |
1420 | |
|
1421 | 0 | int count = sampleCount ( |
1422 | 0 | sampleCountBase, |
1423 | 0 | sampleCountXStride, |
1424 | 0 | sampleCountYStride, |
1425 | 0 | x - xOffsetForSampleCount, |
1426 | 0 | y - yOffsetForSampleCount); |
1427 | |
|
1428 | 0 | if (writePtr) |
1429 | 0 | { |
1430 | 0 | for (int i = 0; i < count; i++) |
1431 | 0 | { |
1432 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
1433 | 0 | writePtr[i] = readPtr[i]; |
1434 | |
|
1435 | 0 | readPtr += sizeof (float); |
1436 | 0 | writePtr += sampleStride; |
1437 | 0 | } |
1438 | 0 | } |
1439 | 0 | else { readPtr += sizeof (float) * count; } |
1440 | 0 | } |
1441 | 0 | break; |
1442 | 0 | default: |
1443 | |
|
1444 | 0 | throw IEX_NAMESPACE::ArgExc ( |
1445 | 0 | "Unknown pixel data type."); |
1446 | 0 | } |
1447 | 0 | break; |
1448 | | |
1449 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1450 | 0 | } |
1451 | 0 | } |
1452 | 0 | } |
1453 | | |
1454 | | void |
1455 | | skipChannel (const char*& readPtr, PixelType typeInFile, size_t xSize) |
1456 | 0 | { |
1457 | 0 | switch (typeInFile) |
1458 | 0 | { |
1459 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1460 | |
|
1461 | 0 | Xdr::skip<CharPtrIO> (readPtr, Xdr::size<unsigned int> () * xSize); |
1462 | 0 | break; |
1463 | | |
1464 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1465 | |
|
1466 | 0 | Xdr::skip<CharPtrIO> (readPtr, Xdr::size<half> () * xSize); |
1467 | 0 | break; |
1468 | | |
1469 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1470 | |
|
1471 | 0 | Xdr::skip<CharPtrIO> (readPtr, Xdr::size<float> () * xSize); |
1472 | 0 | break; |
1473 | | |
1474 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1475 | 0 | } |
1476 | 0 | } |
1477 | | |
1478 | | namespace |
1479 | | { |
1480 | | // |
1481 | | // helper function to realign floats |
1482 | | // for architectures that require 32-bit alignment for float reading |
1483 | | // |
1484 | | |
1485 | | struct FBytes |
1486 | | { |
1487 | | uint8_t b[4]; |
1488 | | }; |
1489 | | union bytesUintOrFloat |
1490 | | { |
1491 | | FBytes b; |
1492 | | float f; |
1493 | | unsigned int u; |
1494 | | }; |
1495 | | } // namespace |
1496 | | |
1497 | | void |
1498 | | convertInPlace ( |
1499 | | char*& writePtr, const char*& readPtr, PixelType type, size_t numPixels) |
1500 | 0 | { |
1501 | 0 | switch (type) |
1502 | 0 | { |
1503 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1504 | |
|
1505 | 0 | for (size_t j = 0; j < numPixels; ++j) |
1506 | 0 | { |
1507 | 0 | union bytesUintOrFloat tmp; |
1508 | 0 | tmp.b = *reinterpret_cast<const FBytes*> (readPtr); |
1509 | 0 | Xdr::write<CharPtrIO> (writePtr, tmp.u); |
1510 | 0 | readPtr += sizeof (unsigned int); |
1511 | 0 | } |
1512 | 0 | break; |
1513 | | |
1514 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1515 | |
|
1516 | 0 | for (size_t j = 0; j < numPixels; ++j) |
1517 | 0 | { |
1518 | 0 | Xdr::write<CharPtrIO> (writePtr, *(const half*) readPtr); |
1519 | 0 | readPtr += sizeof (half); |
1520 | 0 | } |
1521 | 0 | break; |
1522 | | |
1523 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1524 | |
|
1525 | 0 | for (size_t j = 0; j < numPixels; ++j) |
1526 | 0 | { |
1527 | 0 | union bytesUintOrFloat tmp; |
1528 | 0 | tmp.b = *reinterpret_cast<const FBytes*> (readPtr); |
1529 | 0 | Xdr::write<CharPtrIO> (writePtr, tmp.f); |
1530 | 0 | readPtr += sizeof (float); |
1531 | 0 | } |
1532 | 0 | break; |
1533 | | |
1534 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1535 | 0 | } |
1536 | 0 | } |
1537 | | |
1538 | | void |
1539 | | copyFromFrameBuffer ( |
1540 | | char*& writePtr, |
1541 | | const char*& readPtr, |
1542 | | const char* endPtr, |
1543 | | size_t xStride, |
1544 | | Compressor::Format format, |
1545 | | PixelType type) |
1546 | 0 | { |
1547 | 0 | char* localWritePtr = writePtr; |
1548 | 0 | const char* localReadPtr = readPtr; |
1549 | | // |
1550 | | // Copy a horizontal row of pixels from a frame |
1551 | | // buffer to an output file's line or tile buffer. |
1552 | | // |
1553 | |
|
1554 | 0 | if (format == Compressor::XDR) |
1555 | 0 | { |
1556 | | // |
1557 | | // The line or tile buffer is in XDR format. |
1558 | | // |
1559 | |
|
1560 | 0 | switch (type) |
1561 | 0 | { |
1562 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1563 | |
|
1564 | 0 | while (localReadPtr <= endPtr) |
1565 | 0 | { |
1566 | 0 | Xdr::write<CharPtrIO> ( |
1567 | 0 | localWritePtr, *(const unsigned int*) localReadPtr); |
1568 | 0 | localReadPtr += xStride; |
1569 | 0 | } |
1570 | 0 | break; |
1571 | | |
1572 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1573 | |
|
1574 | 0 | while (localReadPtr <= endPtr) |
1575 | 0 | { |
1576 | 0 | Xdr::write<CharPtrIO> ( |
1577 | 0 | localWritePtr, *(const half*) localReadPtr); |
1578 | 0 | localReadPtr += xStride; |
1579 | 0 | } |
1580 | 0 | break; |
1581 | | |
1582 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1583 | |
|
1584 | 0 | while (localReadPtr <= endPtr) |
1585 | 0 | { |
1586 | 0 | Xdr::write<CharPtrIO> ( |
1587 | 0 | localWritePtr, *(const float*) localReadPtr); |
1588 | 0 | localReadPtr += xStride; |
1589 | 0 | } |
1590 | 0 | break; |
1591 | | |
1592 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1593 | 0 | } |
1594 | 0 | } |
1595 | 0 | else |
1596 | 0 | { |
1597 | | // |
1598 | | // The line or tile buffer is in NATIVE format. |
1599 | | // |
1600 | |
|
1601 | 0 | switch (type) |
1602 | 0 | { |
1603 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1604 | |
|
1605 | 0 | while (localReadPtr <= endPtr) |
1606 | 0 | { |
1607 | 0 | for (size_t i = 0; i < sizeof (unsigned int); ++i) |
1608 | 0 | *localWritePtr++ = localReadPtr[i]; |
1609 | |
|
1610 | 0 | localReadPtr += xStride; |
1611 | 0 | } |
1612 | 0 | break; |
1613 | | |
1614 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1615 | |
|
1616 | 0 | while (localReadPtr <= endPtr) |
1617 | 0 | { |
1618 | 0 | *(half*) localWritePtr = *(const half*) localReadPtr; |
1619 | 0 | localWritePtr += sizeof (half); |
1620 | 0 | localReadPtr += xStride; |
1621 | 0 | } |
1622 | 0 | break; |
1623 | | |
1624 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1625 | |
|
1626 | 0 | while (localReadPtr <= endPtr) |
1627 | 0 | { |
1628 | 0 | for (size_t i = 0; i < sizeof (float); ++i) |
1629 | 0 | *localWritePtr++ = localReadPtr[i]; |
1630 | |
|
1631 | 0 | localReadPtr += xStride; |
1632 | 0 | } |
1633 | 0 | break; |
1634 | | |
1635 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1636 | 0 | } |
1637 | 0 | } |
1638 | | |
1639 | 0 | writePtr = localWritePtr; |
1640 | 0 | readPtr = localReadPtr; |
1641 | 0 | } |
1642 | | |
1643 | | void |
1644 | | copyFromDeepFrameBuffer ( |
1645 | | char*& writePtr, |
1646 | | const char* base, |
1647 | | char* sampleCountBase, |
1648 | | ptrdiff_t sampleCountXStride, |
1649 | | ptrdiff_t sampleCountYStride, |
1650 | | int y, |
1651 | | int xMin, |
1652 | | int xMax, |
1653 | | int xOffsetForSampleCount, |
1654 | | int yOffsetForSampleCount, |
1655 | | int xOffsetForData, |
1656 | | int yOffsetForData, |
1657 | | ptrdiff_t sampleStride, |
1658 | | ptrdiff_t dataXStride, |
1659 | | ptrdiff_t dataYStride, |
1660 | | Compressor::Format format, |
1661 | | PixelType type) |
1662 | 0 | { |
1663 | | // |
1664 | | // Copy a horizontal row of pixels from a frame |
1665 | | // buffer to an output file's line or tile buffer. |
1666 | | // |
1667 | |
|
1668 | 0 | if (format == Compressor::XDR) |
1669 | 0 | { |
1670 | | // |
1671 | | // The line or tile buffer is in XDR format. |
1672 | | // |
1673 | |
|
1674 | 0 | switch (type) |
1675 | 0 | { |
1676 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1677 | |
|
1678 | 0 | for (int x = xMin; x <= xMax; x++) |
1679 | 0 | { |
1680 | 0 | unsigned int count = sampleCount ( |
1681 | 0 | sampleCountBase, |
1682 | 0 | sampleCountXStride, |
1683 | 0 | sampleCountYStride, |
1684 | 0 | x - xOffsetForSampleCount, |
1685 | 0 | y - yOffsetForSampleCount); |
1686 | 0 | const char* ptr = base + |
1687 | 0 | (y - yOffsetForData) * dataYStride + |
1688 | 0 | (x - xOffsetForData) * dataXStride; |
1689 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1690 | 0 | for (unsigned int i = 0; i < count; i++) |
1691 | 0 | { |
1692 | 0 | Xdr::write<CharPtrIO> ( |
1693 | 0 | writePtr, *(const unsigned int*) readPtr); |
1694 | 0 | readPtr += sampleStride; |
1695 | 0 | } |
1696 | 0 | } |
1697 | 0 | break; |
1698 | | |
1699 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1700 | |
|
1701 | 0 | for (int x = xMin; x <= xMax; x++) |
1702 | 0 | { |
1703 | 0 | unsigned int count = sampleCount ( |
1704 | 0 | sampleCountBase, |
1705 | 0 | sampleCountXStride, |
1706 | 0 | sampleCountYStride, |
1707 | 0 | x - xOffsetForSampleCount, |
1708 | 0 | y - yOffsetForSampleCount); |
1709 | 0 | const char* ptr = base + |
1710 | 0 | (y - yOffsetForData) * dataYStride + |
1711 | 0 | (x - xOffsetForData) * dataXStride; |
1712 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1713 | 0 | for (unsigned int i = 0; i < count; i++) |
1714 | 0 | { |
1715 | 0 | Xdr::write<CharPtrIO> ( |
1716 | 0 | writePtr, *(const half*) readPtr); |
1717 | 0 | readPtr += sampleStride; |
1718 | 0 | } |
1719 | 0 | } |
1720 | 0 | break; |
1721 | | |
1722 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1723 | |
|
1724 | 0 | for (int x = xMin; x <= xMax; x++) |
1725 | 0 | { |
1726 | 0 | unsigned int count = sampleCount ( |
1727 | 0 | sampleCountBase, |
1728 | 0 | sampleCountXStride, |
1729 | 0 | sampleCountYStride, |
1730 | 0 | x - xOffsetForSampleCount, |
1731 | 0 | y - yOffsetForSampleCount); |
1732 | 0 | const char* ptr = base + |
1733 | 0 | (y - yOffsetForData) * dataYStride + |
1734 | 0 | (x - xOffsetForData) * dataXStride; |
1735 | |
|
1736 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1737 | 0 | for (unsigned int i = 0; i < count; i++) |
1738 | 0 | { |
1739 | 0 | Xdr::write<CharPtrIO> ( |
1740 | 0 | writePtr, *(const float*) readPtr); |
1741 | 0 | readPtr += sampleStride; |
1742 | 0 | } |
1743 | 0 | } |
1744 | 0 | break; |
1745 | | |
1746 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1747 | 0 | } |
1748 | 0 | } |
1749 | 0 | else |
1750 | 0 | { |
1751 | | // |
1752 | | // The line or tile buffer is in NATIVE format. |
1753 | | // |
1754 | |
|
1755 | 0 | switch (type) |
1756 | 0 | { |
1757 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1758 | |
|
1759 | 0 | for (int x = xMin; x <= xMax; x++) |
1760 | 0 | { |
1761 | 0 | unsigned int count = sampleCount ( |
1762 | 0 | sampleCountBase, |
1763 | 0 | sampleCountXStride, |
1764 | 0 | sampleCountYStride, |
1765 | 0 | x - xOffsetForSampleCount, |
1766 | 0 | y - yOffsetForSampleCount); |
1767 | |
|
1768 | 0 | const char* ptr = base + |
1769 | 0 | (y - yOffsetForData) * dataYStride + |
1770 | 0 | (x - xOffsetForData) * dataXStride; |
1771 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1772 | 0 | for (unsigned int i = 0; i < count; i++) |
1773 | 0 | { |
1774 | 0 | for (size_t j = 0; j < sizeof (unsigned int); ++j) |
1775 | 0 | *writePtr++ = readPtr[j]; |
1776 | |
|
1777 | 0 | readPtr += sampleStride; |
1778 | 0 | } |
1779 | 0 | } |
1780 | 0 | break; |
1781 | | |
1782 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1783 | |
|
1784 | 0 | for (int x = xMin; x <= xMax; x++) |
1785 | 0 | { |
1786 | 0 | unsigned int count = sampleCount ( |
1787 | 0 | sampleCountBase, |
1788 | 0 | sampleCountXStride, |
1789 | 0 | sampleCountYStride, |
1790 | 0 | x - xOffsetForSampleCount, |
1791 | 0 | y - yOffsetForSampleCount); |
1792 | 0 | const char* ptr = base + |
1793 | 0 | (y - yOffsetForData) * dataYStride + |
1794 | 0 | (x - xOffsetForData) * dataXStride; |
1795 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1796 | 0 | for (unsigned int i = 0; i < count; i++) |
1797 | 0 | { |
1798 | 0 | *(half*) writePtr = *(const half*) readPtr; |
1799 | 0 | writePtr += sizeof (half); |
1800 | 0 | readPtr += sampleStride; |
1801 | 0 | } |
1802 | 0 | } |
1803 | 0 | break; |
1804 | | |
1805 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1806 | |
|
1807 | 0 | for (int x = xMin; x <= xMax; x++) |
1808 | 0 | { |
1809 | 0 | unsigned int count = sampleCount ( |
1810 | 0 | sampleCountBase, |
1811 | 0 | sampleCountXStride, |
1812 | 0 | sampleCountYStride, |
1813 | 0 | x - xOffsetForSampleCount, |
1814 | 0 | y - yOffsetForSampleCount); |
1815 | |
|
1816 | 0 | const char* ptr = base + |
1817 | 0 | (y - yOffsetForData) * dataYStride + |
1818 | 0 | (x - xOffsetForData) * dataXStride; |
1819 | 0 | const char* readPtr = ((const char**) ptr)[0]; |
1820 | 0 | for (unsigned int i = 0; i < count; i++) |
1821 | 0 | { |
1822 | 0 | for (size_t j = 0; j < sizeof (float); ++j) |
1823 | 0 | *writePtr++ = readPtr[j]; |
1824 | |
|
1825 | 0 | readPtr += sampleStride; |
1826 | 0 | } |
1827 | 0 | } |
1828 | 0 | break; |
1829 | | |
1830 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1831 | 0 | } |
1832 | 0 | } |
1833 | 0 | } |
1834 | | |
1835 | | void |
1836 | | fillChannelWithZeroes ( |
1837 | | char*& writePtr, Compressor::Format format, PixelType type, size_t xSize) |
1838 | 0 | { |
1839 | 0 | if (format == Compressor::XDR) |
1840 | 0 | { |
1841 | | // |
1842 | | // Fill with data in XDR format. |
1843 | | // |
1844 | |
|
1845 | 0 | switch (type) |
1846 | 0 | { |
1847 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1848 | |
|
1849 | 0 | for (size_t j = 0; j < xSize; ++j) |
1850 | 0 | Xdr::write<CharPtrIO> (writePtr, (unsigned int) 0); |
1851 | |
|
1852 | 0 | break; |
1853 | | |
1854 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1855 | |
|
1856 | 0 | for (size_t j = 0; j < xSize; ++j) |
1857 | 0 | Xdr::write<CharPtrIO> (writePtr, (half) 0); |
1858 | |
|
1859 | 0 | break; |
1860 | | |
1861 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1862 | |
|
1863 | 0 | for (size_t j = 0; j < xSize; ++j) |
1864 | 0 | Xdr::write<CharPtrIO> (writePtr, (float) 0); |
1865 | |
|
1866 | 0 | break; |
1867 | | |
1868 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1869 | 0 | } |
1870 | 0 | } |
1871 | 0 | else |
1872 | 0 | { |
1873 | | // |
1874 | | // Fill with data in NATIVE format. |
1875 | | // |
1876 | |
|
1877 | 0 | switch (type) |
1878 | 0 | { |
1879 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT: |
1880 | |
|
1881 | 0 | for (size_t j = 0; j < xSize; ++j) |
1882 | 0 | { |
1883 | 0 | static const unsigned int ui = 0; |
1884 | |
|
1885 | 0 | for (size_t i = 0; i < sizeof (ui); ++i) |
1886 | 0 | *writePtr++ = ((char*) &ui)[i]; |
1887 | 0 | } |
1888 | 0 | break; |
1889 | | |
1890 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF: |
1891 | |
|
1892 | 0 | for (size_t j = 0; j < xSize; ++j) |
1893 | 0 | { |
1894 | 0 | *(half*) writePtr = half (0); |
1895 | 0 | writePtr += sizeof (half); |
1896 | 0 | } |
1897 | 0 | break; |
1898 | | |
1899 | 0 | case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT: |
1900 | |
|
1901 | 0 | for (size_t j = 0; j < xSize; ++j) |
1902 | 0 | { |
1903 | 0 | static const float f = 0; |
1904 | |
|
1905 | 0 | for (size_t i = 0; i < sizeof (f); ++i) |
1906 | 0 | *writePtr++ = ((char*) &f)[i]; |
1907 | 0 | } |
1908 | 0 | break; |
1909 | | |
1910 | 0 | default: throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type."); |
1911 | 0 | } |
1912 | 0 | } |
1913 | 0 | } |
1914 | | |
1915 | | bool |
1916 | | usesLongNames (const Header& header) |
1917 | 0 | { |
1918 | | // |
1919 | | // If an OpenEXR file contains any attribute names, attribute type names |
1920 | | // or channel names longer than 31 characters, then the file cannot be |
1921 | | // read by older versions of the OpenEXR library (up to OpenEXR 1.6.1). |
1922 | | // Before writing the file header, we check if the header contains |
1923 | | // any names longer than 31 characters; if it does, then we set the |
1924 | | // LONG_NAMES_FLAG in the file version number. Older versions of the |
1925 | | // OpenEXR library will refuse to read files that have the LONG_NAMES_FLAG |
1926 | | // set. Without the flag, older versions of the library would mis- |
1927 | | // interpret the file as broken. |
1928 | | // |
1929 | |
|
1930 | 0 | for (Header::ConstIterator i = header.begin (); i != header.end (); ++i) |
1931 | 0 | { |
1932 | 0 | if (strlen (i.name ()) >= 32 || |
1933 | 0 | strlen (i.attribute ().typeName ()) >= 32) |
1934 | 0 | return true; |
1935 | 0 | } |
1936 | | |
1937 | 0 | const ChannelList& channels = header.channels (); |
1938 | |
|
1939 | 0 | for (ChannelList::ConstIterator i = channels.begin (); i != channels.end (); |
1940 | 0 | ++i) |
1941 | 0 | { |
1942 | 0 | if (strlen (i.name ()) >= 32) return true; |
1943 | 0 | } |
1944 | | |
1945 | 0 | return false; |
1946 | 0 | } |
1947 | | |
1948 | | int |
1949 | | getScanlineChunkOffsetTableSize (const Header& header) |
1950 | 0 | { |
1951 | 0 | const Box2i& dataWindow = header.dataWindow (); |
1952 | | |
1953 | | // |
1954 | | // use int64_t types to prevent overflow in lineOffsetSize for images with |
1955 | | // extremely high dataWindows |
1956 | | // |
1957 | 0 | int64_t linesInBuffer = numLinesInBuffer (header.compression ()); |
1958 | |
|
1959 | 0 | int64_t lineOffsetSize = |
1960 | 0 | (static_cast<int64_t> (dataWindow.max.y) - |
1961 | 0 | static_cast<int64_t> (dataWindow.min.y) + linesInBuffer) / |
1962 | 0 | linesInBuffer; |
1963 | |
|
1964 | 0 | return static_cast<int> (lineOffsetSize); |
1965 | 0 | } |
1966 | | |
1967 | | // |
1968 | | // Located in ImfTiledMisc.cpp |
1969 | | // |
1970 | | int getTiledChunkOffsetTableSize (const Header& header); |
1971 | | |
1972 | | int |
1973 | | getChunkOffsetTableSize (const Header& header) |
1974 | 0 | { |
1975 | | // |
1976 | | // if there is a type in the header which indicates the part is not a currently supported type, |
1977 | | // use the chunkCount attribute |
1978 | | // |
1979 | |
|
1980 | 0 | if (header.hasType () && !isSupportedType (header.type ())) |
1981 | 0 | { |
1982 | 0 | if (header.hasChunkCount ()) { return header.chunkCount (); } |
1983 | 0 | else |
1984 | 0 | { |
1985 | 0 | throw IEX_NAMESPACE::ArgExc ("unsupported header type to " |
1986 | 0 | "get chunk offset table size"); |
1987 | 0 | } |
1988 | 0 | } |
1989 | | |
1990 | | // |
1991 | | // part is a known type - ignore the header attribute and compute the chunk size from the header |
1992 | | // |
1993 | 0 | if (isTiled (header.type ()) == false) |
1994 | 0 | return getScanlineChunkOffsetTableSize (header); |
1995 | 0 | else |
1996 | 0 | return getTiledChunkOffsetTableSize (header); |
1997 | 0 | } |
1998 | | |
1999 | | std::wstring |
2000 | | WidenFilename (const char* filename) |
2001 | 0 | { |
2002 | 0 | std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter; |
2003 | 0 | return converter.from_bytes (filename); |
2004 | 0 | } |
2005 | | |
2006 | | const char* |
2007 | | getLibraryVersion () |
2008 | 0 | { |
2009 | 0 | return OPENEXR_VERSION_STRING; |
2010 | 0 | } |
2011 | | |
2012 | | OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT |