New upstream version 2.5.5
Matteo F. Vescovi
2 years ago
0 | 0 | # OpenEXR Release Notes |
1 | 1 | |
2 | * [Version 2.5.5](#version-255-february-12-2021) February 12, 2021 | |
2 | 3 | * [Version 2.5.4](#version-254-december-31-2020) December 31, 2020 |
3 | 4 | * [Version 2.5.3](#version-253-august-12-2020) August 12, 2020 |
4 | 5 | * [Version 2.5.2](#version-252-june-15-2020) June 15, 2020 |
37 | 38 | * [Version 1.0.1](#version-101) |
38 | 39 | * [Version 1.0](#version-10) |
39 | 40 | |
41 | ## Version 2.5.5 (February 12, 2021) | |
42 | ||
43 | Patch release with various bug/sanitizer/security fixes, primarily | |
44 | related to reading corrupted input files, but also a fix for universal | |
45 | build support on macOS. | |
46 | ||
47 | Specific OSS-fuzz issues include: | |
48 | ||
49 | * OSS-fuzz [#30291](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30291) | |
50 | * OSS-fuzz [#29106](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29106) | |
51 | * OSS-fuzz [#28971](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28971) | |
52 | * OSS-fuzz [#29829](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29829) | |
53 | * OSS-fuzz [#30121](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30121) | |
54 | ||
55 | ### Merged Pull Requests | |
56 | ||
57 | * [#914](https://github.com/AcademySoftwareFoundation/openexr/pull/914) additional verification of DWA data sizes | |
58 | * [#910](https://github.com/AcademySoftwareFoundation/openexr/pull/910) update tileoffset sanitycheck to handle ripmaps | |
59 | * [#903](https://github.com/AcademySoftwareFoundation/openexr/pull/903) prevent overflows by using Int64 for all vars in DWA initialize | |
60 | * [#901](https://github.com/AcademySoftwareFoundation/openexr/pull/901) Use size_t for DWA buffersize calculation | |
61 | * [#897](https://github.com/AcademySoftwareFoundation/openexr/pull/897) prevent overflow in RgbaFile cachePadding | |
62 | * [#896](https://github.com/AcademySoftwareFoundation/openexr/pull/896) add buffer size validation to FastHuf decode | |
63 | * [#893](https://github.com/AcademySoftwareFoundation/openexr/pull/893) Include <limits> where required by newer compilers | |
64 | * [#889](https://github.com/AcademySoftwareFoundation/openexr/pull/889) Add explicit #include <limits> for numeric_limits | |
65 | * [#854](https://github.com/AcademySoftwareFoundation/openexr/pull/854) Fix Apple Universal 2 (arm64/x86_64) builds | |
66 | ||
40 | 67 | ## Version 2.5.4 (December 31, 2020) |
41 | ||
68 | ||
42 | 69 | Patch release with various bug/sanitizer/security fixes, primarily |
43 | 70 | related to reading corrupted input files. |
44 | 71 |
71 | 71 | _thread.join (); |
72 | 72 | } |
73 | 73 | |
74 | void | |
75 | Thread::join() | |
76 | { | |
77 | if ( _thread.joinable () ) | |
78 | _thread.join (); | |
79 | } | |
80 | ||
81 | bool | |
82 | Thread::joinable() const | |
83 | { | |
84 | return _thread.joinable(); | |
85 | } | |
74 | 86 | |
75 | 87 | void |
76 | 88 | Thread::start () |
107 | 119 | { |
108 | 120 | throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform."); |
109 | 121 | } |
122 | ||
123 | void | |
124 | Thread::join () | |
125 | { | |
126 | throw IEX_NAMESPACE::NoImplExc ("Threads not supported / enabled on this platform."); | |
127 | } | |
128 | ||
129 | bool | |
130 | Thread::joinable () const | |
131 | { | |
132 | throw IEX_NAMESPACE::NoImplExc ("Threads not supported / enabled on this platform."); | |
133 | } | |
134 | ||
110 | 135 | # endif |
111 | 136 | #endif |
112 | 137 |
128 | 128 | ILMTHREAD_EXPORT void start (); |
129 | 129 | ILMTHREAD_EXPORT virtual void run () = 0; |
130 | 130 | |
131 | // | |
132 | // wait for thread to exit - must be called before deleting thread | |
133 | // | |
134 | void join(); | |
135 | bool joinable() const; | |
136 | ||
131 | 137 | private: |
132 | 138 | |
133 | 139 | #ifdef ILMBASE_FORCE_CXX03 |
422 | 422 | size_t curT = _data.threads.size(); |
423 | 423 | for (size_t i = 0; i != curT; ++i) |
424 | 424 | { |
425 | _data.taskSemaphore.post(); | |
426 | _data.threadSemaphore.wait(); | |
425 | if (_data.threads[i]->joinable()) | |
426 | { | |
427 | _data.taskSemaphore.post(); | |
428 | _data.threadSemaphore.wait(); | |
429 | } | |
427 | 430 | } |
428 | 431 | |
429 | 432 | // |
430 | 433 | // Join all the threads |
431 | 434 | // |
432 | 435 | for (size_t i = 0; i != curT; ++i) |
436 | { | |
437 | if (_data.threads[i]->joinable()) | |
438 | _data.threads[i]->join(); | |
439 | ||
433 | 440 | delete _data.threads[i]; |
434 | ||
441 | } | |
442 | ||
435 | 443 | Lock lock1 (_data.taskMutex); |
436 | 444 | #ifdef ILMBASE_FORCE_CXX03 |
437 | 445 | Lock lock2 (_data.stopMutex); |
3 | 3 | dnl |
4 | 4 | |
5 | 5 | dnl Process this file with autoconf to produce a configure script. |
6 | AC_INIT(IlmBase, 2.5.4) | |
6 | AC_INIT(IlmBase, 2.5.5) | |
7 | 7 | |
8 | 8 | AC_SUBST(ILMBASE_VERSION_MAJOR, 2) |
9 | 9 | AC_SUBST(ILMBASE_VERSION_MINOR, 5) |
10 | AC_SUBST(ILMBASE_VERSION_PATCH, 4) | |
10 | AC_SUBST(ILMBASE_VERSION_PATCH, 5) | |
11 | 11 | |
12 | 12 | AC_SUBST(ILMBASE_VERSION, ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}) |
13 | 13 | AC_SUBST(ILMBASE_VERSION_API, ${ILMBASE_VERSION_MAJOR}_${ILMBASE_VERSION_MINOR}) |
21 | 21 | |
22 | 22 | |
23 | 23 | LIBTOOL_CURRENT=25 |
24 | LIBTOOL_REVISION=3 | |
24 | LIBTOOL_REVISION=4 | |
25 | 25 | LIBTOOL_AGE=0 |
26 | 26 | LIBTOOL_VERSION=$LIBTOOL_CURRENT:$LIBTOOL_REVISION:$LIBTOOL_AGE |
27 | 27 | AC_SUBST(LIBTOOL_VERSION) |
64 | 64 | |
65 | 65 | #include "Iex.h" |
66 | 66 | |
67 | #include <algorithm> | |
68 | #include <assert.h> | |
67 | 69 | #include <string> |
68 | 70 | #include <vector> |
69 | #include <assert.h> | |
70 | 71 | #include <limits> |
71 | #include <algorithm> | |
72 | ||
73 | 72 | |
74 | 73 | #include "ImfNamespace.h" |
75 | 74 | OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER |
63 | 63 | #include <vector> |
64 | 64 | #include <algorithm> |
65 | 65 | #include <assert.h> |
66 | #include <string> | |
67 | #include <vector> | |
66 | 68 | #include <limits> |
67 | 69 | |
68 | 70 | #include "ImfNamespace.h" |
155 | 155 | #include <cctype> |
156 | 156 | #include <cassert> |
157 | 157 | #include <algorithm> |
158 | #include <limits> | |
158 | 159 | |
159 | 160 | #include <cstddef> |
160 | 161 | |
2604 | 2605 | throw IEX_NAMESPACE::BaseExc("DC data corrupt."); |
2605 | 2606 | } |
2606 | 2607 | } |
2608 | else | |
2609 | { | |
2610 | // if the compressed size is 0, then the uncompressed size must also be zero | |
2611 | if (totalDcUncompressedCount!=0) | |
2612 | { | |
2613 | throw IEX_NAMESPACE::BaseExc("DC data corrupt."); | |
2614 | } | |
2615 | } | |
2607 | 2616 | |
2608 | 2617 | // |
2609 | 2618 | // Uncompress the RLE data into _rleBuffer, then unRLE the results |
2930 | 2939 | // of channels we have. |
2931 | 2940 | // |
2932 | 2941 | |
2933 | int maxOutBufferSize = 0; | |
2934 | int numLossyDctChans = 0; | |
2935 | int unknownBufferSize = 0; | |
2936 | int rleBufferSize = 0; | |
2937 | ||
2938 | int maxLossyDctAcSize = (int)ceil ((float)numScanLines() / 8.0f) * | |
2939 | (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) * | |
2942 | Int64 maxOutBufferSize = 0; | |
2943 | Int64 numLossyDctChans = 0; | |
2944 | Int64 unknownBufferSize = 0; | |
2945 | Int64 rleBufferSize = 0; | |
2946 | ||
2947 | Int64 maxLossyDctAcSize = static_cast<Int64>(ceil ((float)numScanLines() / 8.0f)) * | |
2948 | static_cast<Int64>(ceil ((float)(_max[0] - _min[0] + 1) / 8.0f)) * | |
2940 | 2949 | 63 * sizeof (unsigned short); |
2941 | 2950 | |
2942 | int maxLossyDctDcSize = (int)ceil ((float)numScanLines() / 8.0f) * | |
2943 | (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) * | |
2951 | Int64 maxLossyDctDcSize = static_cast<Int64>(ceil ((float)numScanLines() / 8.0f)) * | |
2952 | static_cast<Int64>(ceil ((float)(_max[0] - _min[0] + 1) / 8.0f)) * | |
2944 | 2953 | sizeof (unsigned short); |
2954 | ||
2955 | Int64 pixelCount = static_cast<Int64>(numScanLines()) * static_cast<Int64>(_max[0] - _min[0] + 1); | |
2945 | 2956 | |
2946 | 2957 | for (unsigned int chan = 0; chan < _channelData.size(); ++chan) |
2947 | 2958 | { |
2957 | 2968 | // |
2958 | 2969 | |
2959 | 2970 | maxOutBufferSize += std::max( |
2960 | (int)(2 * maxLossyDctAcSize + 65536), | |
2961 | (int)compressBound (maxLossyDctAcSize) ); | |
2971 | 2lu * maxLossyDctAcSize + 65536lu, | |
2972 | static_cast<Int64>(compressBound (maxLossyDctAcSize)) ); | |
2962 | 2973 | numLossyDctChans++; |
2963 | 2974 | break; |
2964 | 2975 | |
2969 | 2980 | // of the source data. |
2970 | 2981 | // |
2971 | 2982 | |
2972 | int rleAmount = 2 * numScanLines() * (_max[0] - _min[0] + 1) * | |
2973 | OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); | |
2983 | Int64 rleAmount = 2 * pixelCount * OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); | |
2974 | 2984 | |
2975 | 2985 | rleBufferSize += rleAmount; |
2976 | 2986 | } |
2979 | 2989 | |
2980 | 2990 | case UNKNOWN: |
2981 | 2991 | |
2982 | unknownBufferSize += numScanLines() * (_max[0] - _min[0] + 1) * | |
2983 | OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); | |
2992 | unknownBufferSize += pixelCount * OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); | |
2984 | 2993 | break; |
2985 | 2994 | |
2986 | 2995 | default: |
2997 | 3006 | // which could take slightly more space |
2998 | 3007 | // |
2999 | 3008 | |
3000 | maxOutBufferSize += (int)compressBound ((uLongf)rleBufferSize); | |
3009 | maxOutBufferSize += static_cast<Int64>(compressBound (rleBufferSize)); | |
3001 | 3010 | |
3002 | 3011 | // |
3003 | 3012 | // And the same goes for the UNKNOWN data |
3004 | 3013 | // |
3005 | 3014 | |
3006 | maxOutBufferSize += (int)compressBound ((uLongf)unknownBufferSize); | |
3015 | maxOutBufferSize += static_cast<Int64>(compressBound (unknownBufferSize)); | |
3007 | 3016 | |
3008 | 3017 | // |
3009 | 3018 | // Allocate a zip/deflate compressor big enought to hold the DC data |
3050 | 3059 | // to Huffman encoding |
3051 | 3060 | // |
3052 | 3061 | |
3053 | if (static_cast<size_t>(maxLossyDctAcSize * numLossyDctChans) > _packedAcBufferSize) | |
3062 | if (maxLossyDctAcSize * numLossyDctChans > _packedAcBufferSize) | |
3054 | 3063 | { |
3055 | 3064 | _packedAcBufferSize = maxLossyDctAcSize * numLossyDctChans; |
3056 | 3065 | if (_packedAcBuffer != 0) |
3062 | 3071 | // _packedDcBuffer holds one quantized DCT coef per 8x8 block |
3063 | 3072 | // |
3064 | 3073 | |
3065 | if (static_cast<size_t>(maxLossyDctDcSize * numLossyDctChans) > _packedDcBufferSize) | |
3074 | if (maxLossyDctDcSize * numLossyDctChans > _packedDcBufferSize) | |
3066 | 3075 | { |
3067 | 3076 | _packedDcBufferSize = maxLossyDctDcSize * numLossyDctChans; |
3068 | 3077 | if (_packedDcBuffer != 0) |
3070 | 3079 | _packedDcBuffer = new char[_packedDcBufferSize]; |
3071 | 3080 | } |
3072 | 3081 | |
3073 | if (static_cast<size_t>(rleBufferSize) > _rleBufferSize) | |
3082 | if ( rleBufferSize > _rleBufferSize ) | |
3074 | 3083 | { |
3075 | 3084 | _rleBufferSize = rleBufferSize; |
3076 | 3085 | if (_rleBuffer != 0) |
3089 | 3098 | // all in one swoop (for each compression scheme). |
3090 | 3099 | // |
3091 | 3100 | |
3092 | int planarUncBufferSize[NUM_COMPRESSOR_SCHEMES]; | |
3101 | Int64 planarUncBufferSize[NUM_COMPRESSOR_SCHEMES]; | |
3093 | 3102 | for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i) |
3094 | 3103 | planarUncBufferSize[i] = 0; |
3095 | 3104 | |
3101 | 3110 | break; |
3102 | 3111 | |
3103 | 3112 | case RLE: |
3104 | planarUncBufferSize[RLE] += | |
3105 | numScanLines() * (_max[0] - _min[0] + 1) * | |
3113 | planarUncBufferSize[RLE] += pixelCount * | |
3106 | 3114 | OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); |
3107 | 3115 | break; |
3108 | 3116 | |
3109 | 3117 | case UNKNOWN: |
3110 | planarUncBufferSize[UNKNOWN] += | |
3111 | numScanLines() * (_max[0] - _min[0] + 1) * | |
3118 | planarUncBufferSize[UNKNOWN] += pixelCount * | |
3112 | 3119 | OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type); |
3113 | 3120 | break; |
3114 | 3121 | |
3125 | 3132 | |
3126 | 3133 | if (planarUncBufferSize[UNKNOWN] > 0) |
3127 | 3134 | { |
3128 | planarUncBufferSize[UNKNOWN] = | |
3129 | compressBound ((uLongf)planarUncBufferSize[UNKNOWN]); | |
3135 | planarUncBufferSize[UNKNOWN] = | |
3136 | static_cast<Int64>( compressBound (planarUncBufferSize[UNKNOWN]) ); | |
3130 | 3137 | } |
3131 | 3138 | |
3132 | 3139 | for (int i = 0; i < NUM_COMPRESSOR_SCHEMES; ++i) |
3133 | 3140 | { |
3134 | if (static_cast<size_t>(planarUncBufferSize[i]) > _planarUncBufferSize[i]) | |
3141 | if ( planarUncBufferSize[i] > _planarUncBufferSize[i]) | |
3135 | 3142 | { |
3136 | 3143 | _planarUncBufferSize[i] = planarUncBufferSize[i]; |
3137 | 3144 | if (_planarUncBuffer[i] != 0) |
3138 | 3145 | delete[] _planarUncBuffer[i]; |
3146 | ||
3147 | if (planarUncBufferSize[i] > std::numeric_limits<size_t>::max()) | |
3148 | { | |
3149 | throw IEX_NAMESPACE::ArgExc("DWA buffers too large"); | |
3150 | } | |
3151 | ||
3139 | 3152 | _planarUncBuffer[i] = new char[planarUncBufferSize[i]]; |
3140 | 3153 | } |
3141 | 3154 | } |
168 | 168 | std::vector<CscChannelSet> _cscSets; |
169 | 169 | std::vector<Classifier> _channelRules; |
170 | 170 | |
171 | char *_packedAcBuffer; | |
172 | size_t _packedAcBufferSize; | |
173 | char *_packedDcBuffer; | |
174 | size_t _packedDcBufferSize; | |
175 | char *_rleBuffer; | |
176 | size_t _rleBufferSize; | |
177 | char *_outBuffer; | |
178 | size_t _outBufferSize; | |
179 | char *_planarUncBuffer[NUM_COMPRESSOR_SCHEMES]; | |
180 | size_t _planarUncBufferSize[NUM_COMPRESSOR_SCHEMES]; | |
171 | char* _packedAcBuffer; | |
172 | Int64 _packedAcBufferSize; | |
173 | char* _packedDcBuffer; | |
174 | Int64 _packedDcBufferSize; | |
175 | char* _rleBuffer; | |
176 | Int64 _rleBufferSize; | |
177 | char* _outBuffer; | |
178 | Int64 _outBufferSize; | |
179 | char* _planarUncBuffer[NUM_COMPRESSOR_SCHEMES]; | |
180 | Int64 _planarUncBufferSize[NUM_COMPRESSOR_SCHEMES]; | |
181 | 181 | |
182 | 182 | Zip *_zip; |
183 | 183 | float _dwaCompressionLevel; |
58 | 58 | #define _SSE_ALIGNMENT 32 |
59 | 59 | #define _SSE_ALIGNMENT_MASK 0x0F |
60 | 60 | #define _AVX_ALIGNMENT_MASK 0x1F |
61 | ||
62 | // | |
63 | // Test if we should enable GCC inline asm paths for AVX | |
64 | // | |
65 | ||
66 | #ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX | |
67 | ||
68 | #define IMF_HAVE_GCC_INLINEASM | |
69 | ||
70 | #ifdef __LP64__ | |
71 | #define IMF_HAVE_GCC_INLINEASM_64 | |
72 | #endif /* __LP64__ */ | |
73 | ||
74 | #endif /* OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX */ | |
75 | 61 | |
76 | 62 | // |
77 | 63 | // A simple 64-element array, aligned properly for SIMD access. |
466 | 452 | // I'll take the asm. |
467 | 453 | // |
468 | 454 | |
469 | #if defined IMF_HAVE_GCC_INLINEASM | |
455 | #if defined IMF_HAVE_GCC_INLINEASM_X86 | |
470 | 456 | __asm__ |
471 | 457 | ("vmovaps (%0), %%ymm0 \n" |
472 | 458 | "vmovaps 0x20(%0), %%ymm1 \n" |
505 | 491 | ); |
506 | 492 | #else |
507 | 493 | convertFloatToHalf64_scalar (dst, src); |
508 | #endif /* IMF_HAVE_GCC_INLINEASM */ | |
494 | #endif /* IMF_HAVE_GCC_INLINEASM_X86 */ | |
509 | 495 | } |
510 | 496 | |
511 | 497 | |
682 | 668 | void |
683 | 669 | fromHalfZigZag_f16c (unsigned short *src, float *dst) |
684 | 670 | { |
685 | #if defined IMF_HAVE_GCC_INLINEASM_64 | |
671 | #if defined IMF_HAVE_GCC_INLINEASM_X86_64 | |
686 | 672 | __asm__ |
687 | 673 | |
688 | 674 | /* x3 <- 0 |
834 | 820 | |
835 | 821 | #else |
836 | 822 | fromHalfZigZag_scalar(src, dst); |
837 | #endif /* defined IMF_HAVE_GCC_INLINEASM_64 */ | |
823 | #endif /* defined IMF_HAVE_GCC_INLINEASM_X86_64 */ | |
838 | 824 | } |
839 | 825 | |
840 | 826 | |
1606 | 1592 | void |
1607 | 1593 | dctInverse8x8_avx (float *data) |
1608 | 1594 | { |
1609 | #if defined IMF_HAVE_GCC_INLINEASM_64 | |
1595 | #if defined IMF_HAVE_GCC_INLINEASM_X86_64 | |
1610 | 1596 | |
1611 | 1597 | /* The column-major version of M1, followed by the |
1612 | 1598 | * column-major version of M2: |
1734 | 1720 | } else { |
1735 | 1721 | assert(false); // Invalid template instance parameter |
1736 | 1722 | } |
1737 | #else /* IMF_HAVE_GCC_INLINEASM_64 */ | |
1723 | #else /* IMF_HAVE_GCC_INLINEASM_X86_64 */ | |
1738 | 1724 | |
1739 | 1725 | dctInverse8x8_scalar<zeroedRows>(data); |
1740 | 1726 | |
1741 | #endif /* IMF_HAVE_GCC_INLINEASM_64 */ | |
1727 | #endif /* IMF_HAVE_GCC_INLINEASM_X86_64 */ | |
1742 | 1728 | } |
1743 | 1729 | |
1744 | 1730 |
1118 | 1118 | if (FastHufDecoder::enabled() && nBits > 128) |
1119 | 1119 | { |
1120 | 1120 | FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM); |
1121 | ||
1122 | // must be nBytes remaining in buffer | |
1123 | if( ptr-compressed + nBytes > nCompressed) | |
1124 | { | |
1125 | notEnoughData(); | |
1126 | return; | |
1127 | } | |
1128 | ||
1121 | 1129 | fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw); |
1122 | 1130 | } |
1123 | 1131 | else |
171 | 171 | |
172 | 172 | static int LOG2_CACHE_LINE_SIZE = 8; |
173 | 173 | |
174 | int i = LOG2_CACHE_LINE_SIZE + 2; | |
174 | size_t i = LOG2_CACHE_LINE_SIZE + 2; | |
175 | 175 | |
176 | 176 | while ((size >> i) > 1) |
177 | 177 | ++i; |
178 | 178 | |
179 | if (size > (1 << (i + 1)) - 64) | |
180 | return 64 + ((1 << (i + 1)) - size); | |
181 | ||
182 | if (size < (1 << i) + 64) | |
183 | return 64 + ((1 << i) - size); | |
179 | if (size > (1ll << (i + 1)) - 64ll) | |
180 | return 64ll + ((1ll << (i + 1ll)) - size); | |
181 | ||
182 | if (size < (1ll << i) + 64ll) | |
183 | return 64ll + ((1ll << i) - size); | |
184 | 184 | |
185 | 185 | return 0; |
186 | 186 | } |
62 | 62 | #endif // IMF_HAVE_SSE2 && __GNUC__ |
63 | 63 | |
64 | 64 | |
65 | #ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX | |
65 | #ifdef IMF_HAVE_GCC_INLINEASM_X86 | |
66 | 66 | |
67 | 67 | void xgetbv(int n, int &eax, int &edx) |
68 | 68 | { |
73 | 73 | : /* Clobber */); |
74 | 74 | } |
75 | 75 | |
76 | #else // OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX | |
76 | #else // IMF_HAVE_GCC_INLINEASM_X86 | |
77 | 77 | |
78 | 78 | void xgetbv(int n, int &eax, int &edx) |
79 | 79 | { |
80 | 80 | eax = edx = 0; |
81 | 81 | } |
82 | 82 | |
83 | #endif // OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX | |
83 | #endif // IMF_HAVE_GCC_INLINEASM_X86 | |
84 | 84 | |
85 | 85 | } // namespace |
86 | 86 |
38 | 38 | #include "ImfSimd.h" |
39 | 39 | #include <stdlib.h> |
40 | 40 | #include "ImfExport.h" |
41 | #include "OpenEXRConfig.h" | |
42 | #include "OpenEXRConfigInternal.h" | |
41 | 43 | |
42 | 44 | OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER |
43 | 45 | |
46 | // | |
47 | // Test if we should enable GCC inline asm paths for AVX | |
48 | // | |
49 | ||
50 | #if defined(OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX) && (defined(_M_X64) || defined(__x86_64__)) | |
51 | ||
52 | #define IMF_HAVE_GCC_INLINEASM_X86 | |
53 | ||
54 | #ifdef __LP64__ | |
55 | #define IMF_HAVE_GCC_INLINEASM_X86_64 | |
56 | #endif /* __LP64__ */ | |
57 | ||
58 | #endif /* OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX */ | |
44 | 59 | |
45 | 60 | static unsigned long systemEndianCheckValue = 0x12345678; |
46 | 61 | static unsigned long* systemEndianCheckPointer = &systemEndianCheckValue; |
252 | 252 | Data (Data&& other) = delete; |
253 | 253 | Data& operator = (Data&& other) = delete; |
254 | 254 | |
255 | static const int gLargeChunkTableSize = 1024*1024; | |
256 | void validateStreamSize(); // throw an exception if the file is significantly | |
257 | // smaller than the data/tile geometry would require | |
258 | ||
259 | ||
255 | 260 | inline TileBuffer * getTileBuffer (int number); |
256 | 261 | // hash function from tile indices |
257 | 262 | // into our vector of tile buffers |
298 | 303 | } |
299 | 304 | |
300 | 305 | |
306 | ||
307 | // | |
308 | // avoid allocating excessive memory due to large lineOffsets table size. | |
309 | // If the chunktablesize claims to be large, | |
310 | // check the file is big enough to contain the table before allocating memory | |
311 | // in the bytesPerLineTable and the lineOffsets table. | |
312 | // Attempt to read the last entry in the first level of the table. Either the seekg() or the read() | |
313 | // call will throw an exception if the file is much too small to contain the table. | |
314 | // | |
315 | ||
316 | // assumes the input stream pointer is at (or before) the beginning of the chunk table | |
317 | ||
318 | ||
319 | void | |
320 | TiledInputFile::Data::validateStreamSize() | |
321 | { | |
322 | const TileDescription& td = header.tileDescription(); | |
323 | Int64 chunkCount; | |
324 | ||
325 | if (td.mode==RIPMAP_LEVELS) | |
326 | { | |
327 | // use slow function to calculate exact size of ripmap | |
328 | chunkCount = getTiledChunkOffsetTableSize(header); | |
329 | } | |
330 | else | |
331 | { | |
332 | // for ONE_LEVEL image, calculate exact number of tiles | |
333 | // MIPMAP_LEVELS images will have roughly 1/3 more tiles than this | |
334 | // but 'chunkCount' can be less than the real offset table size for a meaningful sanity check | |
335 | // | |
336 | const Box2i &dataWindow = header.dataWindow(); | |
337 | Int64 tileWidth = td.xSize; | |
338 | Int64 tileHeight = td.ySize; | |
339 | ||
340 | Int64 tilesX = (static_cast<Int64>(dataWindow.max.x+1-dataWindow.min.x) + tileWidth -1) / tileWidth; | |
341 | Int64 tilesY = (static_cast<Int64>(dataWindow.max.y+1-dataWindow.min.y) + tileHeight -1) / tileHeight; | |
342 | ||
343 | chunkCount = tilesX*tilesY; | |
344 | } | |
345 | ||
346 | if (chunkCount > gLargeChunkTableSize) | |
347 | { | |
348 | ||
349 | Int64 pos = _streamData->is->tellg(); | |
350 | _streamData->is->seekg(pos + (chunkCount-1)*sizeof(Int64)); | |
351 | Int64 temp; | |
352 | OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_streamData->is, temp); | |
353 | _streamData->is->seekg(pos); | |
354 | } | |
355 | ||
356 | } | |
357 | ||
301 | 358 | namespace { |
302 | 359 | |
303 | 360 | void |
608 | 665 | // The frame buffer contains a slice for this channel. |
609 | 666 | // |
610 | 667 | |
611 | char *writePtr = slice.base + | |
668 | intptr_t base = reinterpret_cast<intptr_t>(slice.base); | |
669 | char *writePtr = reinterpret_cast<char*>(base + | |
612 | 670 | (y - yOffset) * slice.yStride + |
613 | 671 | (tileRange.min.x - xOffset) * |
614 | slice.xStride; | |
672 | slice.xStride); | |
615 | 673 | |
616 | 674 | char *endPtr = writePtr + |
617 | 675 | (numPixelsPerScanLine - 1) * slice.xStride; |
730 | 788 | _data->_streamData = new InputStreamMutex(); |
731 | 789 | _data->_streamData->is = is; |
732 | 790 | _data->header.readFrom (*_data->_streamData->is, _data->version); |
791 | ||
733 | 792 | initialize(); |
734 | 793 | //read tile offsets - we are not multipart or deep |
735 | 794 | _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false); |
972 | 1031 | |
973 | 1032 | _data->header.sanityCheck (true); |
974 | 1033 | |
1034 | // | |
1035 | // before allocating memory for tile offsets, confirm file is large enough | |
1036 | // to contain tile offset table | |
1037 | // (for multipart files, the chunk offset table has already been read) | |
1038 | // | |
1039 | if (!isMultiPart(_data->version)) | |
1040 | { | |
1041 | _data->validateStreamSize(); | |
1042 | } | |
975 | 1043 | _data->tileDesc = _data->header.tileDescription(); |
976 | 1044 | _data->lineOrder = _data->header.lineOrder(); |
977 | 1045 |
44 | 44 | #include <ImfChannelList.h> |
45 | 45 | #include <ImfTileDescription.h> |
46 | 46 | #include <algorithm> |
47 | #include <limits> | |
47 | 48 | |
48 | 49 | #include "ImfNamespace.h" |
49 | 50 |
39 | 39 | #include "ImfStandardAttributes.h" |
40 | 40 | #include <algorithm> |
41 | 41 | #include <iostream> |
42 | #include <limits> | |
42 | 43 | #include <assert.h> |
43 | 44 | #include <IlmThread.h> |
44 | 45 | #include <ImathBox.h> |
43 | 43 | #include "ImfStandardAttributes.h" |
44 | 44 | #include <algorithm> |
45 | 45 | #include <iostream> |
46 | #include <limits> | |
46 | 47 | #include <assert.h> |
47 | 48 | #include <IlmThread.h> |
48 | 49 | #include <ImathBox.h> |
18 | 18 | sysconf(_SC_NPROCESSORS_ONLN); |
19 | 19 | } |
20 | 20 | " OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN |
21 | ) | |
21 | ) | |
22 | 22 | |
23 | 23 | check_cxx_source_compiles( |
24 | 24 | " |
25 | 25 | int main() |
26 | 26 | { |
27 | #if defined(_M_X64) || defined(__x86_64__) | |
27 | 28 | #if defined(__SSE2__) |
28 | 29 | int n = 0; |
29 | 30 | int eax = 0; |
34 | 35 | : \"=a\"(eax), \"=d\"(edx) : \"c\"(n) : ); |
35 | 36 | #else |
36 | 37 | # error No SSE support enabled to query AVX support |
38 | #endif | |
37 | 39 | #endif |
38 | 40 | } |
39 | 41 | " OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX |
46 | 48 | |
47 | 49 | if(APPLE) |
48 | 50 | set(OPENEXR_IMF_HAVE_DARWIN TRUE) |
49 | if (${CMAKE_OSX_ARCHITECTURES} MATCHES arm64) | |
50 | set(OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX FALSE) | |
51 | endif() | |
52 | 51 | endif() |
53 | 52 | |
54 | 53 | configure_file(OpenEXRConfig.h.in_cmake ${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h) |
4 | 4 | |
5 | 5 | dnl Process this file with autoconf to produce a configure script. |
6 | 6 | |
7 | AC_INIT(OpenEXR, 2.5.4) | |
7 | AC_INIT(OpenEXR, 2.5.5) | |
8 | 8 | AC_CONFIG_MACRO_DIR([m4]) |
9 | 9 | |
10 | 10 | AC_SUBST(OPENEXR_VERSION_MAJOR, 2) |
11 | 11 | AC_SUBST(OPENEXR_VERSION_MINOR, 5) |
12 | AC_SUBST(OPENEXR_VERSION_PATCH, 4) | |
12 | AC_SUBST(OPENEXR_VERSION_PATCH, 5) | |
13 | 13 | |
14 | 14 | AC_SUBST(OPENEXR_VERSION, ${OPENEXR_VERSION_MAJOR}.${OPENEXR_VERSION_MINOR}.${OPENEXR_VERSION_PATCH}) |
15 | 15 | AC_SUBST(OPENEXR_VERSION_API, ${OPENEXR_VERSION_MAJOR}_${OPENEXR_VERSION_MINOR}) |
23 | 23 | |
24 | 24 | |
25 | 25 | LIBTOOL_CURRENT=25 |
26 | LIBTOOL_REVISION=3 | |
26 | LIBTOOL_REVISION=4 | |
27 | 27 | LIBTOOL_AGE=0 |
28 | 28 | LIBTOOL_VERSION=$LIBTOOL_CURRENT:$LIBTOOL_REVISION:$LIBTOOL_AGE |
29 | 29 | AC_SUBST(LIBTOOL_VERSION) |
3 | 3 | dnl |
4 | 4 | |
5 | 5 | dnl Process this file with autoconf to produce a configure script. |
6 | AC_INIT(PyIlmBase, 2.5.4) | |
6 | AC_INIT(PyIlmBase, 2.5.5) | |
7 | 7 | AC_SUBST(PYILMBASE_VERSION, 2.5.4) |
8 | 8 | AC_CANONICAL_HOST |
9 | 9 | AC_CONFIG_SRCDIR(PyIex/iexmodule.cpp) |
16 | 16 | |
17 | 17 | |
18 | 18 | LIBTOOL_CURRENT=25 |
19 | LIBTOOL_REVISION=3 | |
19 | LIBTOOL_REVISION=4 | |
20 | 20 | LIBTOOL_AGE=0 |
21 | 21 | LIBTOOL_VERSION=$LIBTOOL_CURRENT:$LIBTOOL_REVISION:$LIBTOOL_AGE |
22 | 22 | AC_SUBST(LIBTOOL_VERSION) |