image: add crn support to the image plugin.
[xonotic/netradiant.git] / libs / crunch / crn_decomp.h
1 // File: crn_decomp.h - Fast CRN->DXTc texture transcoder header file library
2 // Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC
3 // See Copyright Notice and license at the end of this file.
4 //
5 // This single header file contains *all* of the code necessary to unpack .CRN files to raw DXTn bits.
6 // It does NOT depend on the crn compression library.
7 //
8 // Note: This is a single file, stand-alone C++ library which is controlled by the use of the following macro:
9 //   If CRND_INCLUDE_CRND_H is NOT defined, the header is included.
10 //
11 // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing
12 #ifndef CRND_INCLUDE_CRND_H
13 #define CRND_INCLUDE_CRND_H
14
15 // Include crn_defs.h (only to bring in some basic CRN-related types and structures).
16 #include "crn_defs.h"
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #ifdef WIN32
21 #include <memory.h>
22 #elif defined(__APPLE__)
23 #include <malloc/malloc.h>
24 #else
25 #include <malloc.h>
26 #endif
27 #include <stdarg.h>
28 #include <new>  // needed for placement new, _msize, _expand
29 #include <exception>
30
31 #define CRND_RESTRICT __restrict
32
33 #ifdef _MSC_VER
34 #pragma warning(disable : 4127)  // warning C4127: conditional expression is constant
35 #endif
36
37 #ifdef CRND_DEVEL
38 #ifndef _WIN32_WINNT
39 #define _WIN32_WINNT 0x500
40 #endif
41 #ifndef WIN32_LEAN_AND_MEAN
42 #define WIN32_LEAN_AND_MEAN
43 #endif
44 #ifndef
45 #define NOMINMAX
46 #endif
47 #include "windows.h"  // only for IsDebuggerPresent(), DebugBreak(), and OutputDebugStringA()
48 #endif
49
50 // File: crnd_types.h
51 namespace crnd {
52 const crn_uint8 cUINT8_MIN = 0;
53 const crn_uint8 cUINT8_MAX = 0xFFU;
54 const uint16 cUINT16_MIN = 0;
55 const uint16 cUINT16_MAX = 0xFFFFU;
56 const uint32 cUINT32_MIN = 0;
57 const uint32 cUINT32_MAX = 0xFFFFFFFFU;
58
59 const int8 cINT8_MIN = -128;
60 const int8 cINT8_MAX = 127;
61 const int16 cINT16_MIN = -32768;
62 const int16 cINT16_MAX = 32767;
63 const int32 cINT32_MIN = (-2147483647 - 1);
64 const int32 cINT32_MAX = 2147483647;
65
66 enum eClear { cClear };
67
68 const uint32 cIntBits = 32U;
69
70 template <typename T>
71 struct int_traits {
72   enum { cMin = crnd::cINT32_MIN,
73          cMax = crnd::cINT32_MAX,
74          cSigned = true };
75 };
76
77 template <>
78 struct int_traits<int8> {
79   enum { cMin = crnd::cINT8_MIN,
80          cMax = crnd::cINT8_MAX,
81          cSigned = true };
82 };
83 template <>
84 struct int_traits<int16> {
85   enum { cMin = crnd::cINT16_MIN,
86          cMax = crnd::cINT16_MAX,
87          cSigned = true };
88 };
89 template <>
90 struct int_traits<int32> {
91   enum { cMin = crnd::cINT32_MIN,
92          cMax = crnd::cINT32_MAX,
93          cSigned = true };
94 };
95
96 template <>
97 struct int_traits<uint8> {
98   enum { cMin = 0,
99          cMax = crnd::cUINT8_MAX,
100          cSigned = false };
101 };
102 template <>
103 struct int_traits<uint16> {
104   enum { cMin = 0,
105          cMax = crnd::cUINT16_MAX,
106          cSigned = false };
107 };
108 template <>
109 struct int_traits<uint32> {
110   enum { cMin = 0,
111          cMax = crnd::cUINT32_MAX,
112          cSigned = false };
113 };
114
115 struct empty_type {};
116
117 }  // namespace crnd
118
119 // File: crnd_platform.h
120 namespace crnd {
121
122 bool crnd_is_debugger_present();
123 void crnd_debug_break();
124 void crnd_output_debug_string(const char* p);
125
126 // actually in crnd_assert.cpp
127 void crnd_assert(const char* pExp, const char* pFile, unsigned line);
128 void crnd_fail(const char* pExp, const char* pFile, unsigned line);
129
130 }  // namespace crnd
131
132 // File: crnd_assert.h
133 namespace crnd {
134 class decompression_exception : public std::exception {};
135
136 // HACK: Try to crash less when asked to decode invalid inputs.
137 #define CRND_ASSERT(_exp) (!!(_exp) ? (void)0 : throw decompression_exception())
138
139 void crnd_trace(const char* pFmt, va_list args);
140 void crnd_trace(const char* pFmt, ...);
141
142 }  // namespace crnd
143
144 // File: crnd_helpers.h
145 namespace crnd {
146 namespace helpers {
147 template <typename T>
148 struct rel_ops {
149   friend bool operator!=(const T& x, const T& y) { return (!(x == y)); }
150   friend bool operator>(const T& x, const T& y) { return (y < x); }
151   friend bool operator<=(const T& x, const T& y) { return (!(y < x)); }
152   friend bool operator>=(const T& x, const T& y) { return (!(x < y)); }
153 };
154
155 template <typename T>
156 inline T* construct(T* p) {
157   return new (static_cast<void*>(p)) T;
158 }
159
160 template <typename T, typename U>
161 inline T* construct(T* p, const U& init) {
162   return new (static_cast<void*>(p)) T(init);
163 }
164
165 template <typename T>
166 void construct_array(T* p, uint32 n) {
167   T* q = p + n;
168   for (; p != q; ++p)
169     new (static_cast<void*>(p)) T;
170 }
171
172 template <typename T, typename U>
173 void construct_array(T* p, uint32 n, const U& init) {
174   T* q = p + n;
175   for (; p != q; ++p)
176     new (static_cast<void*>(p)) T(init);
177 }
178
179 template <typename T>
180 inline void destruct(T* p) {
181   p->~T();
182 }
183
184 template <typename T>
185 inline void destruct_array(T* p, uint32 n) {
186   T* q = p + n;
187   for (; p != q; ++p)
188     p->~T();
189 }
190
191 }  // namespace helpers
192
193 }  // namespace crnd
194
195 // File: crnd_traits.h
196 namespace crnd {
197 template <typename T>
198 struct scalar_type {
199   enum { cFlag = false };
200   static inline void construct(T* p) { helpers::construct(p); }
201   static inline void construct(T* p, const T& init) { helpers::construct(p, init); }
202   static inline void construct_array(T* p, uint32 n) { helpers::construct_array(p, n); }
203   static inline void destruct(T* p) { helpers::destruct(p); }
204   static inline void destruct_array(T* p, uint32 n) { helpers::destruct_array(p, n); }
205 };
206
207 template <typename T>
208 struct scalar_type<T*> {
209   enum { cFlag = true };
210   static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
211   static inline void construct(T** p, T* init) { *p = init; }
212   static inline void construct_array(T** p, uint32 n) { memset(p, 0, sizeof(T*) * n); }
213   static inline void destruct(T**) {}
214   static inline void destruct_array(T**, uint32) {}
215 };
216
217 #define CRND_DEFINE_BUILT_IN_TYPE(X)                                                    \
218   template <>                                                                           \
219   struct scalar_type<X> {                                                               \
220     enum { cFlag = true };                                                              \
221     static inline void construct(X* p) { memset(p, 0, sizeof(X)); }                     \
222     static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); }  \
223     static inline void construct_array(X* p, uint32 n) { memset(p, 0, sizeof(X) * n); } \
224     static inline void destruct(X*) {}                                                  \
225     static inline void destruct_array(X*, uint32) {}                                    \
226   };
227
228 CRND_DEFINE_BUILT_IN_TYPE(bool)
229 CRND_DEFINE_BUILT_IN_TYPE(char)
230 CRND_DEFINE_BUILT_IN_TYPE(unsigned char)
231 CRND_DEFINE_BUILT_IN_TYPE(short)
232 CRND_DEFINE_BUILT_IN_TYPE(unsigned short)
233 CRND_DEFINE_BUILT_IN_TYPE(int)
234 CRND_DEFINE_BUILT_IN_TYPE(unsigned int)
235 CRND_DEFINE_BUILT_IN_TYPE(long)
236 CRND_DEFINE_BUILT_IN_TYPE(unsigned long)
237 CRND_DEFINE_BUILT_IN_TYPE(int64)
238 CRND_DEFINE_BUILT_IN_TYPE(uint64)
239 CRND_DEFINE_BUILT_IN_TYPE(float)
240 CRND_DEFINE_BUILT_IN_TYPE(double)
241 CRND_DEFINE_BUILT_IN_TYPE(long double)
242
243 #undef CRND_DEFINE_BUILT_IN_TYPE
244
245 // See: http://erdani.org/publications/cuj-2004-06.pdf
246
247 template <typename T>
248 struct bitwise_movable {
249   enum { cFlag = false };
250 };
251
252 // Defines type Q as bitwise movable.
253 #define CRND_DEFINE_BITWISE_MOVABLE(Q) \
254   template <>                          \
255   struct bitwise_movable<Q> {          \
256     enum { cFlag = true };             \
257   };
258
259 // From yasli_traits.h:
260 // Credit goes to Boost;
261 // also found in the C++ Templates book by Vandevoorde and Josuttis
262
263 typedef char (&yes_t)[1];
264 typedef char (&no_t)[2];
265
266 template <class U>
267 yes_t class_test(int U::*);
268 template <class U>
269 no_t class_test(...);
270
271 template <class T>
272 struct is_class {
273   enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
274 };
275
276 template <typename T>
277 struct is_pointer {
278   enum { value = false };
279 };
280
281 template <typename T>
282 struct is_pointer<T*> {
283   enum { value = true };
284 };
285
286 #define CRND_IS_POD(T) __is_pod(T)
287
288 }  // namespace crnd
289
290 // File: crnd_mem.h
291 namespace crnd {
292 void* crnd_malloc(size_t size, size_t* pActual_size = NULL);
293 void* crnd_realloc(void* p, size_t size, size_t* pActual_size = NULL, bool movable = true);
294 void crnd_free(void* p);
295 size_t crnd_msize(void* p);
296
297 template <typename T>
298 inline T* crnd_new() {
299   T* p = static_cast<T*>(crnd_malloc(sizeof(T)));
300   if (!p)
301     return NULL;
302
303   return helpers::construct(p);
304 }
305
306 template <typename T>
307 inline T* crnd_new(const T& init) {
308   T* p = static_cast<T*>(crnd_malloc(sizeof(T)));
309   if (!p)
310     return NULL;
311
312   return helpers::construct(p, init);
313 }
314
315 template <typename T>
316 inline T* crnd_new_array(uint32 num) {
317   if (!num)
318     num = 1;
319
320   uint8* q = static_cast<uint8*>(crnd_malloc(CRND_MIN_ALLOC_ALIGNMENT + sizeof(T) * num));
321   if (!q)
322     return NULL;
323
324   T* p = reinterpret_cast<T*>(q + CRND_MIN_ALLOC_ALIGNMENT);
325
326   reinterpret_cast<uint32*>(p)[-1] = num;
327   reinterpret_cast<uint32*>(p)[-2] = ~num;
328
329   helpers::construct_array(p, num);
330   return p;
331 }
332
333 template <typename T>
334 inline void crnd_delete(T* p) {
335   if (p) {
336     helpers::destruct(p);
337     crnd_free(p);
338   }
339 }
340
341 template <typename T>
342 inline void crnd_delete_array(T* p) {
343   if (p) {
344     const uint32 num = reinterpret_cast<uint32*>(p)[-1];
345     CRND_ASSERT(num && (num == ~reinterpret_cast<uint32*>(p)[-2]));
346
347     helpers::destruct_array(p, num);
348
349     crnd_free(reinterpret_cast<uint8*>(p) - CRND_MIN_ALLOC_ALIGNMENT);
350   }
351 }
352
353 }  // namespace crnd
354
355 // File: crnd_math.h
356 namespace crnd {
357 namespace math {
358 const float cNearlyInfinite = 1.0e+37f;
359
360 const float cDegToRad = 0.01745329252f;
361 const float cRadToDeg = 57.29577951f;
362
363 extern uint32 g_bitmasks[32];
364
365 // Yes I know these should probably be pass by ref, not val:
366 // http://www.stepanovpapers.com/notes.pdf
367 // Just don't use them on non-simple (non built-in) types!
368 template <typename T>
369 inline T minimum(T a, T b) {
370   return (a < b) ? a : b;
371 }
372
373 template <typename T>
374 inline T minimum(T a, T b, T c) {
375   return minimum(minimum(a, b), c);
376 }
377
378 template <typename T>
379 inline T maximum(T a, T b) {
380   return (a > b) ? a : b;
381 }
382
383 template <typename T>
384 inline T maximum(T a, T b, T c) {
385   return maximum(maximum(a, b), c);
386 }
387
388 template <typename T>
389 inline T clamp(T value, T low, T high) {
390   return (value < low) ? low : ((value > high) ? high : value);
391 }
392
393 template <typename T>
394 inline T square(T value) {
395   return value * value;
396 }
397
398 inline bool is_power_of_2(uint32 x) {
399   return x && ((x & (x - 1U)) == 0U);
400 }
401
402 // From "Hackers Delight"
403 inline int next_pow2(uint32 val) {
404   val--;
405   val |= val >> 16;
406   val |= val >> 8;
407   val |= val >> 4;
408   val |= val >> 2;
409   val |= val >> 1;
410   return val + 1;
411 }
412
413 // Returns the total number of bits needed to encode v.
414 inline uint32 total_bits(uint32 v) {
415   uint32 l = 0;
416   while (v > 0U) {
417     v >>= 1;
418     l++;
419   }
420   return l;
421 }
422
423 inline uint floor_log2i(uint v) {
424   uint l = 0;
425   while (v > 1U) {
426     v >>= 1;
427     l++;
428   }
429   return l;
430 }
431
432 inline uint ceil_log2i(uint v) {
433   uint l = floor_log2i(v);
434   if ((l != cIntBits) && (v > (1U << l)))
435     l++;
436   return l;
437 }
438 }
439 }
440
441 // File: crnd_utils.h
442 namespace crnd {
443 namespace utils {
444 template <typename T>
445 inline void zero_object(T& obj) {
446   memset(&obj, 0, sizeof(obj));
447 }
448
449 template <typename T>
450 inline void zero_this(T* pObj) {
451   memset(pObj, 0, sizeof(*pObj));
452 }
453
454 template <typename T>
455 inline void swap(T& left, T& right) {
456   T temp(left);
457   left = right;
458   right = temp;
459 }
460
461 inline void invert_buf(void* pBuf, uint32 size) {
462   uint8* p = static_cast<uint8*>(pBuf);
463
464   const uint32 half_size = size >> 1;
465   for (uint32 i = 0; i < half_size; i++)
466     swap(p[i], p[size - 1U - i]);
467 }
468
469 static inline uint16 swap16(uint16 x) {
470   return static_cast<uint16>((x << 8) | (x >> 8));
471 }
472 static inline uint32 swap32(uint32 x) {
473   return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
474 }
475
476 uint32 compute_max_mips(uint32 width, uint32 height);
477
478 }  // namespace utils
479
480 }  // namespace crnd
481
482 // File: crnd_vector.h
483 namespace crnd {
484 struct elemental_vector {
485   void* m_p;
486   uint32 m_size;
487   uint32 m_capacity;
488
489   typedef void (*object_mover)(void* pDst, void* pSrc, uint32 num);
490
491   bool increase_capacity(uint32 min_new_capacity, bool grow_hint, uint32 element_size, object_mover pRelocate);
492 };
493
494 #ifdef _MSC_VER
495 #pragma warning(push)
496 #pragma warning(disable : 4127)  //  warning C4127: conditional expression is constant
497 #endif
498
499 template <typename T>
500 class vector : public helpers::rel_ops<vector<T> > {
501  public:
502   typedef T* iterator;
503   typedef const T* const_iterator;
504   typedef T value_type;
505   typedef T& reference;
506   typedef const T& const_reference;
507   typedef T* pointer;
508   typedef const T* const_pointer;
509
510   inline vector()
511       : m_p(NULL),
512         m_size(0),
513         m_capacity(0),
514         m_alloc_failed(false) {
515   }
516
517   inline vector(const vector& other)
518       : m_p(NULL),
519         m_size(0),
520         m_capacity(0),
521         m_alloc_failed(false) {
522     *this = other;
523   }
524
525   inline vector(uint32 size)
526       : m_p(NULL),
527         m_size(0),
528         m_capacity(0),
529         m_alloc_failed(false) {
530     resize(size);
531   }
532
533   inline ~vector() {
534     clear();
535   }
536
537   // I don't like this. Not at all. But exceptions, or just failing suck worse.
538   inline bool get_alloc_failed() const { return m_alloc_failed; }
539   inline void clear_alloc_failed() { m_alloc_failed = false; }
540
541   inline bool assign(const vector& other) {
542     if (this == &other)
543       return true;
544
545     if (m_capacity == other.m_size)
546       resize(0);
547     else {
548       clear();
549
550       if (!increase_capacity(other.m_size, false))
551         return false;
552     }
553
554     if (scalar_type<T>::cFlag)
555       memcpy(m_p, other.m_p, other.m_size * sizeof(T));
556     else {
557       T* pDst = m_p;
558       const T* pSrc = other.m_p;
559       for (uint32 i = other.m_size; i > 0; i--)
560         helpers::construct(pDst++, *pSrc++);
561     }
562
563     m_size = other.m_size;
564
565     return true;
566   }
567
568   inline vector& operator=(const vector& other) {
569     assign(other);
570     return *this;
571   }
572
573   inline const T* begin() const { return m_p; }
574   T* begin() { return m_p; }
575
576   inline const T* end() const { return m_p + m_size; }
577   T* end() { return m_p + m_size; }
578
579   inline bool empty() const { return !m_size; }
580   inline uint32 size() const { return m_size; }
581   inline uint32 capacity() const { return m_capacity; }
582
583   inline const T& operator[](uint32 i) const {
584     CRND_ASSERT(i < m_size);
585     return m_p[i];
586   }
587   inline T& operator[](uint32 i) {
588     CRND_ASSERT(i < m_size);
589     return m_p[i];
590   }
591
592   inline const T& front() const {
593     CRND_ASSERT(m_size);
594     return m_p[0];
595   }
596   inline T& front() {
597     CRND_ASSERT(m_size);
598     return m_p[0];
599   }
600
601   inline const T& back() const {
602     CRND_ASSERT(m_size);
603     return m_p[m_size - 1];
604   }
605   inline T& back() {
606     CRND_ASSERT(m_size);
607     return m_p[m_size - 1];
608   }
609
610   inline void clear() {
611     if (m_p) {
612       scalar_type<T>::destruct_array(m_p, m_size);
613       crnd_free(m_p);
614       m_p = NULL;
615       m_size = 0;
616       m_capacity = 0;
617     }
618
619     m_alloc_failed = false;
620   }
621
622   inline bool reserve(uint32 new_capacity) {
623     if (!increase_capacity(new_capacity, false))
624       return false;
625
626     return true;
627   }
628
629   inline bool resize(uint32 new_size) {
630     if (m_size != new_size) {
631       if (new_size < m_size)
632         scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
633       else {
634         if (new_size > m_capacity) {
635           if (!increase_capacity(new_size, new_size == (m_size + 1)))
636             return false;
637         }
638
639         scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
640       }
641
642       m_size = new_size;
643     }
644
645     return true;
646   }
647
648   inline bool push_back(const T& obj) {
649     CRND_ASSERT(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));
650
651     if (m_size >= m_capacity) {
652       if (!increase_capacity(m_size + 1, true))
653         return false;
654     }
655
656     scalar_type<T>::construct(m_p + m_size, obj);
657     m_size++;
658
659     return true;
660   }
661
662   inline void pop_back() {
663     CRND_ASSERT(m_size);
664
665     if (m_size) {
666       m_size--;
667       scalar_type<T>::destruct(&m_p[m_size]);
668     }
669   }
670
671   inline void insert(uint32 index, const T* p, uint32 n) {
672     CRND_ASSERT(index <= m_size);
673     if (!n)
674       return;
675
676     const uint32 orig_size = m_size;
677     resize(m_size + n);
678
679     const T* pSrc = m_p + orig_size - 1;
680     T* pDst = const_cast<T*>(pSrc) + n;
681
682     const uint32 num_to_move = orig_size - index;
683
684     for (uint32 i = 0; i < num_to_move; i++) {
685       CRND_ASSERT((pDst - m_p) < (int)m_size);
686       *pDst-- = *pSrc--;
687     }
688
689     pSrc = p;
690     pDst = m_p + index;
691
692     for (uint32 i = 0; i < n; i++) {
693       CRND_ASSERT((pDst - m_p) < (int)m_size);
694       *pDst++ = *p++;
695     }
696   }
697
698   inline void erase(uint32 start, uint32 n) {
699     CRND_ASSERT((start + n) <= m_size);
700
701     if (!n)
702       return;
703
704     const uint32 num_to_move = m_size - (start + n);
705
706     T* pDst = m_p + start;
707     T* pDst_end = pDst + num_to_move;
708     const T* pSrc = m_p + start + n;
709
710     while (pDst != pDst_end)
711       *pDst++ = *pSrc++;
712
713     scalar_type<T>::destruct_array(pDst_end, n);
714
715     m_size -= n;
716   }
717
718   inline void erase(uint32 index) {
719     erase(index, 1);
720   }
721
722   inline void erase(T* p) {
723     CRND_ASSERT((p >= m_p) && (p < (m_p + m_size)));
724     erase(p - m_p);
725   }
726
727   inline bool operator==(const vector& rhs) const {
728     if (m_size != rhs.m_size)
729       return false;
730     else if (m_size) {
731       if (scalar_type<T>::cFlag)
732         return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0;
733       else {
734         const T* pSrc = m_p;
735         const T* pDst = rhs.m_p;
736         for (uint32 i = m_size; i; i--)
737           if (!(*pSrc++ == *pDst++))
738             return false;
739       }
740     }
741
742     return true;
743   }
744
745   inline bool operator<(const vector& rhs) const {
746     const uint32 min_size = math::minimum(m_size, rhs.m_size);
747
748     const T* pSrc = m_p;
749     const T* pSrc_end = m_p + min_size;
750     const T* pDst = rhs.m_p;
751
752     while ((pSrc < pSrc_end) && (*pSrc == *pDst)) {
753       pSrc++;
754       pDst++;
755     }
756
757     if (pSrc < pSrc_end)
758       return *pSrc < *pDst;
759
760     return m_size < rhs.m_size;
761   }
762
763   void swap(vector& other) {
764     utils::swap(m_p, other.m_p);
765     utils::swap(m_size, other.m_size);
766     utils::swap(m_capacity, other.m_capacity);
767   }
768
769  private:
770   T* m_p;
771   uint32 m_size;
772   uint32 m_capacity;
773   bool m_alloc_failed;
774
775   template <typename Q>
776   struct is_vector {
777     enum { cFlag = false };
778   };
779   template <typename Q>
780   struct is_vector<vector<Q> > {
781     enum { cFlag = true };
782   };
783
784   static void object_mover(void* pDst_void, void* pSrc_void, uint32 num) {
785     T* pSrc = static_cast<T*>(pSrc_void);
786     T* const pSrc_end = pSrc + num;
787     T* pDst = static_cast<T*>(pDst_void);
788
789     while (pSrc != pSrc_end) {
790       helpers::construct<T>(pDst, *pSrc);
791       pSrc->~T();
792       pSrc++;
793       pDst++;
794     }
795   }
796
797   inline bool increase_capacity(uint32 min_new_capacity, bool grow_hint) {
798     if (!reinterpret_cast<elemental_vector*>(this)->increase_capacity(
799             min_new_capacity, grow_hint, sizeof(T),
800             ((scalar_type<T>::cFlag) || (is_vector<T>::cFlag) || (bitwise_movable<T>::cFlag) || CRND_IS_POD(T)) ? NULL : object_mover)) {
801       m_alloc_failed = true;
802       return false;
803     }
804     return true;
805   }
806 };
807
808 #ifdef _MSC_VER
809 #pragma warning(pop)
810 #endif
811
812 extern void vector_test();
813
814 }  // namespace crnd
815
816 // File: crnd_private.h
817 namespace crnd {
818 const crn_header* crnd_get_header(const void* pData, uint32 data_size);
819
820 }  // namespace crnd
821
822 // File: checksum.h
823 namespace crnd {
824 // crc16() intended for small buffers - doesn't use an acceleration table.
825 const uint16 cInitCRC16 = 0;
826 uint16 crc16(const void* pBuf, uint32 len, uint16 crc = cInitCRC16);
827
828 }  // namespace crnd
829
830 // File: crnd_color.h
831 namespace crnd {
832 template <typename component_type>
833 struct color_quad_component_traits {
834   enum {
835     cSigned = false,
836     cFloat = false,
837     cMin = cUINT8_MIN,
838     cMax = cUINT8_MAX
839   };
840 };
841
842 template <>
843 struct color_quad_component_traits<int16> {
844   enum {
845     cSigned = true,
846     cFloat = false,
847     cMin = cINT16_MIN,
848     cMax = cINT16_MAX
849   };
850 };
851
852 template <>
853 struct color_quad_component_traits<uint16> {
854   enum {
855     cSigned = false,
856     cFloat = false,
857     cMin = cUINT16_MIN,
858     cMax = cUINT16_MAX
859   };
860 };
861
862 template <>
863 struct color_quad_component_traits<int32> {
864   enum {
865     cSigned = true,
866     cFloat = false,
867     cMin = cINT32_MIN,
868     cMax = cINT32_MAX
869   };
870 };
871
872 template <>
873 struct color_quad_component_traits<uint32> {
874   enum {
875     cSigned = false,
876     cFloat = false,
877     cMin = cUINT32_MIN,
878     cMax = cUINT32_MAX
879   };
880 };
881
882 template <>
883 struct color_quad_component_traits<float> {
884   enum {
885     cSigned = false,
886     cFloat = true,
887     cMin = cINT32_MIN,
888     cMax = cINT32_MAX
889   };
890 };
891
892 template <>
893 struct color_quad_component_traits<double> {
894   enum {
895     cSigned = false,
896     cFloat = true,
897     cMin = cINT32_MIN,
898     cMax = cINT32_MAX
899   };
900 };
901
902 #ifdef _MSC_VER
903 #pragma warning(push)
904 #pragma warning(disable : 4201)  //  warning C4201: nonstandard extension used : nameless struct/union
905 #pragma warning(disable : 4127)  //  warning C4127: conditional expression is constant
906 #endif
907
908 template <typename component_type, typename parameter_type>
909 class color_quad : public helpers::rel_ops<color_quad<component_type, parameter_type> > {
910   static parameter_type clamp(parameter_type v) {
911     if (component_traits::cFloat)
912       return v;
913     else {
914       if (v < component_traits::cMin)
915         return component_traits::cMin;
916       else if (v > component_traits::cMax)
917         return component_traits::cMax;
918       return v;
919     }
920   }
921
922  public:
923   typedef component_type component_t;
924   typedef parameter_type parameter_t;
925   typedef color_quad_component_traits<component_type> component_traits;
926
927   enum { cNumComps = 4 };
928
929   union {
930     struct
931     {
932       component_type r;
933       component_type g;
934       component_type b;
935       component_type a;
936     };
937
938     component_type c[cNumComps];
939   };
940
941   inline color_quad() {
942   }
943
944   inline color_quad(eClear)
945       : r(0), g(0), b(0), a(0) {
946   }
947
948   inline color_quad(const color_quad& other)
949       : r(other.r), g(other.g), b(other.b), a(other.a) {
950   }
951
952   inline color_quad(parameter_type y, parameter_type alpha = component_traits::cMax) {
953     set(y, alpha);
954   }
955
956   inline color_quad(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax) {
957     set(red, green, blue, alpha);
958   }
959
960   template <typename other_component_type, typename other_parameter_type>
961   inline color_quad(const color_quad<other_component_type, other_parameter_type>& other)
962       : r(clamp(other.r)), g(clamp(other.g)), b(clamp(other.b)), a(clamp(other.a)) {
963   }
964
965   inline void clear() {
966     r = 0;
967     g = 0;
968     b = 0;
969     a = 0;
970   }
971
972   inline color_quad& operator=(const color_quad& other) {
973     r = other.r;
974     g = other.g;
975     b = other.b;
976     a = other.a;
977     return *this;
978   }
979
980   template <typename other_component_type, typename other_parameter_type>
981   inline color_quad& operator=(const color_quad<other_component_type, other_parameter_type>& other) {
982     r = clamp(other.r);
983     g = clamp(other.g);
984     b = clamp(other.b);
985     a = clamp(other.a);
986     return *this;
987   }
988
989   inline color_quad& set(parameter_type y, parameter_type alpha = component_traits::cMax) {
990     y = clamp(y);
991     r = static_cast<component_type>(y);
992     g = static_cast<component_type>(y);
993     b = static_cast<component_type>(y);
994     a = static_cast<component_type>(alpha);
995     return *this;
996   }
997
998   inline color_quad& set(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax) {
999     r = static_cast<component_type>(clamp(red));
1000     g = static_cast<component_type>(clamp(green));
1001     b = static_cast<component_type>(clamp(blue));
1002     a = static_cast<component_type>(clamp(alpha));
1003     return *this;
1004   }
1005
1006   inline color_quad& set_noclamp_rgba(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha) {
1007     r = static_cast<component_type>(red);
1008     g = static_cast<component_type>(green);
1009     b = static_cast<component_type>(blue);
1010     a = static_cast<component_type>(alpha);
1011     return *this;
1012   }
1013
1014   inline color_quad& set_noclamp_rgb(parameter_type red, parameter_type green, parameter_type blue) {
1015     r = static_cast<component_type>(red);
1016     g = static_cast<component_type>(green);
1017     b = static_cast<component_type>(blue);
1018     return *this;
1019   }
1020
1021   static inline parameter_type get_min_comp() { return component_traits::cMin; }
1022   static inline parameter_type get_max_comp() { return component_traits::cMax; }
1023   static inline bool get_comps_are_signed() { return component_traits::cSigned; }
1024
1025   inline component_type operator[](uint32 i) const {
1026     CRND_ASSERT(i < cNumComps);
1027     return c[i];
1028   }
1029   inline component_type& operator[](uint32 i) {
1030     CRND_ASSERT(i < cNumComps);
1031     return c[i];
1032   }
1033
1034   inline color_quad& set_component(uint32 i, parameter_type f) {
1035     CRND_ASSERT(i < cNumComps);
1036
1037     c[i] = static_cast<component_type>(clamp(f));
1038
1039     return *this;
1040   }
1041
1042   inline color_quad& clamp(const color_quad& l, const color_quad& h) {
1043     for (uint32 i = 0; i < cNumComps; i++)
1044       c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l[i], h[i]));
1045     return *this;
1046   }
1047
1048   inline color_quad& clamp(parameter_type l, parameter_type h) {
1049     for (uint32 i = 0; i < cNumComps; i++)
1050       c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l, h));
1051     return *this;
1052   }
1053
1054   // Returns CCIR 601 luma (consistent with color_utils::RGB_To_Y).
1055   inline parameter_type get_luma() const {
1056     return static_cast<parameter_type>((19595U * r + 38470U * g + 7471U * b + 32768) >> 16U);
1057   }
1058
1059   // Returns REC 709 luma.
1060   inline parameter_type get_luma_rec709() const {
1061     return static_cast<parameter_type>((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U);
1062   }
1063
1064   inline uint32 squared_distance(const color_quad& c, bool alpha = true) const {
1065     return math::square(r - c.r) + math::square(g - c.g) + math::square(b - c.b) + (alpha ? math::square(a - c.a) : 0);
1066   }
1067
1068   inline bool rgb_equals(const color_quad& rhs) const {
1069     return (r == rhs.r) && (g == rhs.g) && (b == rhs.b);
1070   }
1071
1072   inline bool operator==(const color_quad& rhs) const {
1073     return (r == rhs.r) && (g == rhs.g) && (b == rhs.b) && (a == rhs.a);
1074   }
1075
1076   inline bool operator<(const color_quad& rhs) const {
1077     for (uint32 i = 0; i < cNumComps; i++) {
1078       if (c[i] < rhs.c[i])
1079         return true;
1080       else if (!(c[i] == rhs.c[i]))
1081         return false;
1082     }
1083     return false;
1084   }
1085
1086   inline color_quad& operator+=(const color_quad& other) {
1087     for (uint32 i = 0; i < 4; i++)
1088       c[i] = static_cast<component_type>(clamp(c[i] + other.c[i]));
1089     return *this;
1090   }
1091
1092   inline color_quad& operator-=(const color_quad& other) {
1093     for (uint32 i = 0; i < 4; i++)
1094       c[i] = static_cast<component_type>(clamp(c[i] - other.c[i]));
1095     return *this;
1096   }
1097
1098   inline color_quad& operator*=(parameter_type v) {
1099     for (uint32 i = 0; i < 4; i++)
1100       c[i] = static_cast<component_type>(clamp(c[i] * v));
1101     return *this;
1102   }
1103
1104   inline color_quad& operator/=(parameter_type v) {
1105     for (uint32 i = 0; i < 4; i++)
1106       c[i] = static_cast<component_type>(c[i] / v);
1107     return *this;
1108   }
1109
1110   inline color_quad get_swizzled(uint32 x, uint32 y, uint32 z, uint32 w) const {
1111     CRND_ASSERT((x | y | z | w) < 4);
1112     return color_quad(c[x], c[y], c[z], c[w]);
1113   }
1114
1115   inline friend color_quad operator+(const color_quad& lhs, const color_quad& rhs) {
1116     color_quad result(lhs);
1117     result += rhs;
1118     return result;
1119   }
1120
1121   inline friend color_quad operator-(const color_quad& lhs, const color_quad& rhs) {
1122     color_quad result(lhs);
1123     result -= rhs;
1124     return result;
1125   }
1126
1127   inline friend color_quad operator*(const color_quad& lhs, parameter_type v) {
1128     color_quad result(lhs);
1129     result *= v;
1130     return result;
1131   }
1132
1133   friend inline color_quad operator/(const color_quad& lhs, parameter_type v) {
1134     color_quad result(lhs);
1135     result /= v;
1136     return result;
1137   }
1138
1139   friend inline color_quad operator*(parameter_type v, const color_quad& rhs) {
1140     color_quad result(rhs);
1141     result *= v;
1142     return result;
1143   }
1144
1145   inline uint32 get_min_component_index(bool alpha = true) const {
1146     uint32 index = 0;
1147     uint32 limit = alpha ? cNumComps : (cNumComps - 1);
1148     for (uint32 i = 1; i < limit; i++)
1149       if (c[i] < c[index])
1150         index = i;
1151     return index;
1152   }
1153
1154   inline uint32 get_max_component_index(bool alpha = true) const {
1155     uint32 index = 0;
1156     uint32 limit = alpha ? cNumComps : (cNumComps - 1);
1157     for (uint32 i = 1; i < limit; i++)
1158       if (c[i] > c[index])
1159         index = i;
1160     return index;
1161   }
1162
1163   inline void get_float4(float* pDst) {
1164     for (uint32 i = 0; i < 4; i++)
1165       pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin);
1166   }
1167
1168   inline void get_float3(float* pDst) {
1169     for (uint32 i = 0; i < 3; i++)
1170       pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin);
1171   }
1172
1173   static inline color_quad make_black() {
1174     return color_quad(0, 0, 0, component_traits::cMax);
1175   }
1176
1177   static inline color_quad make_white() {
1178     return color_quad(component_traits::cMax, component_traits::cMax, component_traits::cMax, component_traits::cMax);
1179   }
1180 };  // class color_quad
1181
1182 #ifdef _MSC_VER
1183 #pragma warning(pop)
1184 #endif
1185
1186 template <typename c, typename q>
1187 struct scalar_type<color_quad<c, q> > {
1188   enum { cFlag = true };
1189   static inline void construct(color_quad<c, q>* p) {}
1190   static inline void construct(color_quad<c, q>* p, const color_quad<c, q>& init) { memcpy(p, &init, sizeof(color_quad<c, q>)); }
1191   static inline void construct_array(color_quad<c, q>* p, uint32 n) { p, n; }
1192   static inline void destruct(color_quad<c, q>* p) { p; }
1193   static inline void destruct_array(color_quad<c, q>* p, uint32 n) { p, n; }
1194 };
1195
1196 typedef color_quad<uint8, int> color_quad_u8;
1197 typedef color_quad<int16, int> color_quad_i16;
1198 typedef color_quad<uint16, int> color_quad_u16;
1199 typedef color_quad<int32, int> color_quad_i32;
1200 typedef color_quad<uint32, uint32> color_quad_u32;
1201 typedef color_quad<float, float> color_quad_f;
1202 typedef color_quad<double, double> color_quad_d;
1203
1204 }  // namespace crnd
1205
1206 // File: crnd_dxt.h
1207 namespace crnd {
1208 enum dxt_format {
1209   cDXTInvalid = -1,
1210
1211   // cDXT1/1A must appear first!
1212   cDXT1,
1213   cDXT1A,
1214
1215   cDXT3,
1216   cDXT5,
1217   cDXT5A,
1218
1219   cDXN_XY,  // inverted relative to standard ATI2, 360's DXN
1220   cDXN_YX   // standard ATI2
1221 };
1222
1223 enum dxt_constants {
1224   cDXTBlockShift = 2U,
1225   cDXTBlockSize = 1U << cDXTBlockShift,
1226
1227   cDXT1BytesPerBlock = 8U,
1228   cDXT5NBytesPerBlock = 16U,
1229
1230   cDXT1SelectorBits = 2U,
1231   cDXT1SelectorValues = 1U << cDXT1SelectorBits,
1232   cDXT1SelectorMask = cDXT1SelectorValues - 1U,
1233
1234   cDXT5SelectorBits = 3U,
1235   cDXT5SelectorValues = 1U << cDXT5SelectorBits,
1236   cDXT5SelectorMask = cDXT5SelectorValues - 1U
1237 };
1238
1239 const float cDXT1MaxLinearValue = 3.0f;
1240 const float cDXT1InvMaxLinearValue = 1.0f / 3.0f;
1241
1242 const float cDXT5MaxLinearValue = 7.0f;
1243 const float cDXT5InvMaxLinearValue = 1.0f / 7.0f;
1244
1245 // Converts DXT1 raw color selector index to a linear value.
1246 extern const uint8 g_dxt1_to_linear[cDXT1SelectorValues];
1247
1248 // Converts DXT5 raw alpha selector index to a linear value.
1249 extern const uint8 g_dxt5_to_linear[cDXT5SelectorValues];
1250
1251 // Converts DXT1 linear color selector index to a raw value (inverse of g_dxt1_to_linear).
1252 extern const uint8 g_dxt1_from_linear[cDXT1SelectorValues];
1253
1254 // Converts DXT5 linear alpha selector index to a raw value (inverse of g_dxt5_to_linear).
1255 extern const uint8 g_dxt5_from_linear[cDXT5SelectorValues];
1256
1257 extern const uint8 g_six_alpha_invert_table[cDXT5SelectorValues];
1258 extern const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues];
1259
1260 struct dxt1_block {
1261   uint8 m_low_color[2];
1262   uint8 m_high_color[2];
1263
1264   enum { cNumSelectorBytes = 4 };
1265   uint8 m_selectors[cNumSelectorBytes];
1266
1267   inline void clear() {
1268     utils::zero_this(this);
1269   }
1270
1271   // These methods assume the in-memory rep is in LE byte order.
1272   inline uint32 get_low_color() const {
1273     return m_low_color[0] | (m_low_color[1] << 8U);
1274   }
1275
1276   inline uint32 get_high_color() const {
1277     return m_high_color[0] | (m_high_color[1] << 8U);
1278   }
1279
1280   inline void set_low_color(uint16 c) {
1281     m_low_color[0] = static_cast<uint8>(c & 0xFF);
1282     m_low_color[1] = static_cast<uint8>((c >> 8) & 0xFF);
1283   }
1284
1285   inline void set_high_color(uint16 c) {
1286     m_high_color[0] = static_cast<uint8>(c & 0xFF);
1287     m_high_color[1] = static_cast<uint8>((c >> 8) & 0xFF);
1288   }
1289
1290   inline uint32 get_selector(uint32 x, uint32 y) const {
1291     CRND_ASSERT((x < 4U) && (y < 4U));
1292     return (m_selectors[y] >> (x * cDXT1SelectorBits)) & cDXT1SelectorMask;
1293   }
1294
1295   inline void set_selector(uint32 x, uint32 y, uint32 val) {
1296     CRND_ASSERT((x < 4U) && (y < 4U) && (val < 4U));
1297
1298     m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits)));
1299     m_selectors[y] |= (val << (x * cDXT1SelectorBits));
1300   }
1301
1302   static uint16 pack_color(const color_quad_u8& color, bool scaled, uint32 bias = 127U);
1303   static uint16 pack_color(uint32 r, uint32 g, uint32 b, bool scaled, uint32 bias = 127U);
1304
1305   static color_quad_u8 unpack_color(uint16 packed_color, bool scaled, uint32 alpha = 255U);
1306   static void unpack_color(uint32& r, uint32& g, uint32& b, uint16 packed_color, bool scaled);
1307
1308   static uint32 get_block_colors3(color_quad_u8* pDst, uint16 color0, uint16 color1);
1309   static uint32 get_block_colors4(color_quad_u8* pDst, uint16 color0, uint16 color1);
1310   // pDst must point to an array at least cDXT1SelectorValues long.
1311   static uint32 get_block_colors(color_quad_u8* pDst, uint16 color0, uint16 color1);
1312
1313   static color_quad_u8 unpack_endpoint(uint32 endpoints, uint32 index, bool scaled, uint32 alpha = 255U);
1314   static uint32 pack_endpoints(uint32 lo, uint32 hi);
1315 };
1316
1317 CRND_DEFINE_BITWISE_MOVABLE(dxt1_block);
1318
1319 struct dxt3_block {
1320   enum { cNumAlphaBytes = 8 };
1321   uint8 m_alpha[cNumAlphaBytes];
1322
1323   void set_alpha(uint32 x, uint32 y, uint32 value, bool scaled);
1324   uint32 get_alpha(uint32 x, uint32 y, bool scaled) const;
1325 };
1326
1327 CRND_DEFINE_BITWISE_MOVABLE(dxt3_block);
1328
1329 struct dxt5_block {
1330   uint8 m_endpoints[2];
1331
1332   enum { cNumSelectorBytes = 6 };
1333   uint8 m_selectors[cNumSelectorBytes];
1334
1335   inline void clear() {
1336     utils::zero_this(this);
1337   }
1338
1339   inline uint32 get_low_alpha() const {
1340     return m_endpoints[0];
1341   }
1342
1343   inline uint32 get_high_alpha() const {
1344     return m_endpoints[1];
1345   }
1346
1347   inline void set_low_alpha(uint32 i) {
1348     CRND_ASSERT(i <= cUINT8_MAX);
1349     m_endpoints[0] = static_cast<uint8>(i);
1350   }
1351
1352   inline void set_high_alpha(uint32 i) {
1353     CRND_ASSERT(i <= cUINT8_MAX);
1354     m_endpoints[1] = static_cast<uint8>(i);
1355   }
1356
1357   uint32 get_endpoints_as_word() const { return m_endpoints[0] | (m_endpoints[1] << 8); }
1358
1359   uint32 get_selectors_as_word(uint32 index) {
1360     CRND_ASSERT(index < 3);
1361     return m_selectors[index * 2] | (m_selectors[index * 2 + 1] << 8);
1362   }
1363
1364   inline uint32 get_selector(uint32 x, uint32 y) const {
1365     CRND_ASSERT((x < 4U) && (y < 4U));
1366
1367     uint32 selector_index = (y * 4) + x;
1368     uint32 bit_index = selector_index * cDXT5SelectorBits;
1369
1370     uint32 byte_index = bit_index >> 3;
1371     uint32 bit_ofs = bit_index & 7;
1372
1373     uint32 v = m_selectors[byte_index];
1374     if (byte_index < (cNumSelectorBytes - 1))
1375       v |= (m_selectors[byte_index + 1] << 8);
1376
1377     return (v >> bit_ofs) & 7;
1378   }
1379
1380   inline void set_selector(uint32 x, uint32 y, uint32 val) {
1381     CRND_ASSERT((x < 4U) && (y < 4U) && (val < 8U));
1382
1383     uint32 selector_index = (y * 4) + x;
1384     uint32 bit_index = selector_index * cDXT5SelectorBits;
1385
1386     uint32 byte_index = bit_index >> 3;
1387     uint32 bit_ofs = bit_index & 7;
1388
1389     uint32 v = m_selectors[byte_index];
1390     if (byte_index < (cNumSelectorBytes - 1))
1391       v |= (m_selectors[byte_index + 1] << 8);
1392
1393     v &= (~(7 << bit_ofs));
1394     v |= (val << bit_ofs);
1395
1396     m_selectors[byte_index] = static_cast<uint8>(v);
1397     if (byte_index < (cNumSelectorBytes - 1))
1398       m_selectors[byte_index + 1] = static_cast<uint8>(v >> 8);
1399   }
1400
1401   // Results written to alpha channel.
1402   static uint32 get_block_values6(color_quad_u8* pDst, uint32 l, uint32 h);
1403   static uint32 get_block_values8(color_quad_u8* pDst, uint32 l, uint32 h);
1404   static uint32 get_block_values(color_quad_u8* pDst, uint32 l, uint32 h);
1405
1406   static uint32 get_block_values6(uint32* pDst, uint32 l, uint32 h);
1407   static uint32 get_block_values8(uint32* pDst, uint32 l, uint32 h);
1408   // pDst must point to an array at least cDXT5SelectorValues long.
1409   static uint32 get_block_values(uint32* pDst, uint32 l, uint32 h);
1410
1411   static uint32 unpack_endpoint(uint32 packed, uint32 index);
1412   static uint32 pack_endpoints(uint32 lo, uint32 hi);
1413 };
1414
1415 CRND_DEFINE_BITWISE_MOVABLE(dxt5_block);
1416
1417 }  // namespace crnd
1418
1419 // File: crnd_prefix_coding.h
1420 #ifdef _XBOX
1421 #define CRND_PREFIX_CODING_USE_FIXED_TABLE_SIZE 1
1422 #else
1423 #define CRND_PREFIX_CODING_USE_FIXED_TABLE_SIZE 0
1424 #endif
1425
1426 namespace crnd {
1427 namespace prefix_coding {
1428 const uint32 cMaxExpectedCodeSize = 16;
1429 const uint32 cMaxSupportedSyms = 8192;
1430 const uint32 cMaxTableBits = 11;
1431
1432 class decoder_tables {
1433  public:
1434   inline decoder_tables()
1435       : m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) {
1436   }
1437
1438   inline decoder_tables(const decoder_tables& other)
1439       : m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) {
1440     *this = other;
1441   }
1442
1443   decoder_tables& operator=(const decoder_tables& other) {
1444     if (this == &other)
1445       return *this;
1446
1447     clear();
1448
1449     memcpy(this, &other, sizeof(*this));
1450
1451     if (other.m_lookup) {
1452       m_lookup = crnd_new_array<uint32>(m_cur_lookup_size);
1453       if (m_lookup)
1454         memcpy(m_lookup, other.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
1455     }
1456
1457     if (other.m_sorted_symbol_order) {
1458       m_sorted_symbol_order = crnd_new_array<uint16>(m_cur_sorted_symbol_order_size);
1459       if (m_sorted_symbol_order)
1460         memcpy(m_sorted_symbol_order, other.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
1461     }
1462
1463     return *this;
1464   }
1465
1466   inline void clear() {
1467     if (m_lookup) {
1468       crnd_delete_array(m_lookup);
1469       m_lookup = 0;
1470       m_cur_lookup_size = 0;
1471     }
1472
1473     if (m_sorted_symbol_order) {
1474       crnd_delete_array(m_sorted_symbol_order);
1475       m_sorted_symbol_order = NULL;
1476       m_cur_sorted_symbol_order_size = 0;
1477     }
1478   }
1479
1480   inline ~decoder_tables() {
1481     if (m_lookup)
1482       crnd_delete_array(m_lookup);
1483
1484     if (m_sorted_symbol_order)
1485       crnd_delete_array(m_sorted_symbol_order);
1486   }
1487
1488   bool init(uint32 num_syms, const uint8* pCodesizes, uint32 table_bits);
1489
1490   // DO NOT use any complex classes here - it is bitwise copied.
1491
1492   uint32 m_num_syms;
1493   uint32 m_total_used_syms;
1494   uint32 m_table_bits;
1495   uint32 m_table_shift;
1496   uint32 m_table_max_code;
1497   uint32 m_decode_start_code_size;
1498
1499   uint8 m_min_code_size;
1500   uint8 m_max_code_size;
1501
1502   uint32 m_max_codes[cMaxExpectedCodeSize + 1];
1503   int32 m_val_ptrs[cMaxExpectedCodeSize + 1];
1504
1505   uint32 m_cur_lookup_size;
1506   uint32* m_lookup;
1507
1508   uint32 m_cur_sorted_symbol_order_size;
1509   uint16* m_sorted_symbol_order;
1510
1511   inline uint32 get_unshifted_max_code(uint32 len) const {
1512     CRND_ASSERT((len >= 1) && (len <= cMaxExpectedCodeSize));
1513     uint32 k = m_max_codes[len - 1];
1514     if (!k)
1515       return crnd::cUINT32_MAX;
1516     return (k - 1) >> (16 - len);
1517   }
1518 };
1519
1520 }  // namespace prefix_coding
1521
1522 }  // namespace crnd
1523
1524 // File: crnd_symbol_codec.h
1525 namespace crnd {
1526 class static_huffman_data_model {
1527  public:
1528   static_huffman_data_model();
1529   static_huffman_data_model(const static_huffman_data_model& other);
1530   ~static_huffman_data_model();
1531
1532   static_huffman_data_model& operator=(const static_huffman_data_model& rhs);
1533
1534   bool init(uint32 total_syms, const uint8* pCode_sizes, uint32 code_size_limit);
1535   void clear();
1536
1537   inline bool is_valid() const { return m_pDecode_tables != NULL; }
1538
1539   inline uint32 get_total_syms() const { return m_total_syms; }
1540
1541   inline uint32 get_code_size(uint32 sym) const { return m_code_sizes[sym]; }
1542
1543   inline const uint8* get_code_sizes() const { return m_code_sizes.empty() ? NULL : &m_code_sizes[0]; }
1544
1545  public:
1546   uint32 m_total_syms;
1547   crnd::vector<uint8> m_code_sizes;
1548   prefix_coding::decoder_tables* m_pDecode_tables;
1549
1550  private:
1551   bool prepare_decoder_tables();
1552   uint compute_decoder_table_bits() const;
1553
1554   friend class symbol_codec;
1555 };
1556
1557 class symbol_codec {
1558  public:
1559   symbol_codec();
1560
1561   bool start_decoding(const uint8* pBuf, uint32 buf_size);
1562   bool decode_receive_static_data_model(static_huffman_data_model& model);
1563
1564   uint32 decode_bits(uint32 num_bits);
1565   uint32 decode(const static_huffman_data_model& model);
1566
1567   uint64 stop_decoding();
1568
1569  public:
1570   const uint8* m_pDecode_buf;
1571   const uint8* m_pDecode_buf_next;
1572   const uint8* m_pDecode_buf_end;
1573   uint32 m_decode_buf_size;
1574
1575   typedef uint32 bit_buf_type;
1576   enum { cBitBufSize = 32U };
1577   bit_buf_type m_bit_buf;
1578
1579   int m_bit_count;
1580
1581  private:
1582   void get_bits_init();
1583   uint32 get_bits(uint32 num_bits);
1584 };
1585
1586 }  // namespace crnd
1587
1588 namespace crnd {
1589 void crnd_assert(const char* pExp, const char* pFile, unsigned line) {
1590   char buf[512];
1591
1592 #if defined(WIN32) && defined(_MSC_VER)
1593   sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failure: \"%s\"\n", pFile, line, pExp);
1594 #else
1595   sprintf(buf, "%s(%u): Assertion failure: \"%s\"\n", pFile, line, pExp);
1596 #endif
1597
1598   crnd_output_debug_string(buf);
1599
1600   puts(buf);
1601
1602   if (crnd_is_debugger_present())
1603     crnd_debug_break();
1604 }
1605
1606 void crnd_trace(const char* pFmt, va_list args) {
1607   if (crnd_is_debugger_present()) {
1608     char buf[512];
1609 #if defined(WIN32) && defined(_MSC_VER)
1610     vsprintf_s(buf, sizeof(buf), pFmt, args);
1611 #else
1612     vsprintf(buf, pFmt, args);
1613 #endif
1614
1615     crnd_output_debug_string(buf);
1616   }
1617 };
1618
1619 void crnd_trace(const char* pFmt, ...) {
1620   va_list args;
1621   va_start(args, pFmt);
1622   crnd_trace(pFmt, args);
1623   va_end(args);
1624 };
1625
1626 }  // namespace crnd
1627
1628 // File: checksum.cpp
1629 // From the public domain stb.h header.
1630 namespace crnd {
1631 uint16 crc16(const void* pBuf, uint32 len, uint16 crc) {
1632   crc = ~crc;
1633
1634   const uint8* p = reinterpret_cast<const uint8*>(pBuf);
1635   while (len) {
1636     const uint16 q = *p++ ^ (crc >> 8U);
1637     crc <<= 8U;
1638
1639     uint16 r = (q >> 4U) ^ q;
1640     crc ^= r;
1641     r <<= 5U;
1642     crc ^= r;
1643     r <<= 7U;
1644     crc ^= r;
1645
1646     len--;
1647   }
1648
1649   return static_cast<uint16>(~crc);
1650 }
1651
1652 }  // namespace crnd
1653
1654 // File: crnd_vector.cpp
1655 namespace crnd {
1656 bool elemental_vector::increase_capacity(uint32 min_new_capacity, bool grow_hint, uint32 element_size, object_mover pMover) {
1657   CRND_ASSERT(m_size <= m_capacity);
1658   CRND_ASSERT(min_new_capacity < (0x7FFF0000U / element_size));
1659
1660   if (m_capacity >= min_new_capacity)
1661     return true;
1662
1663   uint32 new_capacity = min_new_capacity;
1664   if ((grow_hint) && (!math::is_power_of_2(new_capacity)))
1665     new_capacity = math::next_pow2(new_capacity);
1666
1667   CRND_ASSERT(new_capacity && (new_capacity > m_capacity));
1668
1669   const uint32 desired_size = element_size * new_capacity;
1670   size_t actual_size;
1671   if (!pMover) {
1672     void* new_p = crnd_realloc(m_p, desired_size, &actual_size, true);
1673     if (!new_p)
1674       return false;
1675     m_p = new_p;
1676   } else {
1677     void* new_p = crnd_malloc(desired_size, &actual_size);
1678     if (!new_p)
1679       return false;
1680
1681     (*pMover)(new_p, m_p, m_size);
1682
1683     if (m_p)
1684       crnd_free(m_p);
1685
1686     m_p = new_p;
1687   }
1688
1689   if (actual_size > desired_size)
1690     m_capacity = static_cast<uint32>(actual_size / element_size);
1691   else
1692     m_capacity = new_capacity;
1693
1694   return true;
1695 }
1696
1697 }  // namespace crnd
1698
1699 // File: crnd_utils.cpp
1700 namespace crnd {
1701 namespace utils {
1702 uint32 compute_max_mips(uint32 width, uint32 height) {
1703   if ((width | height) == 0)
1704     return 0;
1705
1706   uint32 num_mips = 1;
1707
1708   while ((width > 1U) || (height > 1U)) {
1709     width >>= 1U;
1710     height >>= 1U;
1711     num_mips++;
1712   }
1713
1714   return num_mips;
1715 }
1716
1717 }  // namespace utils
1718
1719 }  // namespace crnd
1720
1721 // File: crnd_prefix_coding.cpp
1722 namespace crnd {
1723 namespace prefix_coding {
1724 bool decoder_tables::init(uint32 num_syms, const uint8* pCodesizes, uint32 table_bits) {
1725   uint32 min_codes[cMaxExpectedCodeSize];
1726   if ((!num_syms) || (table_bits > cMaxTableBits))
1727     return false;
1728
1729   m_num_syms = num_syms;
1730
1731   uint32 num_codes[cMaxExpectedCodeSize + 1];
1732   utils::zero_object(num_codes);
1733
1734   for (uint32 i = 0; i < num_syms; i++) {
1735     uint32 c = pCodesizes[i];
1736     if (c)
1737       num_codes[c]++;
1738   }
1739
1740   uint32 sorted_positions[cMaxExpectedCodeSize + 1];
1741
1742   uint32 cur_code = 0;
1743
1744   uint32 total_used_syms = 0;
1745   uint32 max_code_size = 0;
1746   uint32 min_code_size = cUINT32_MAX;
1747   for (uint32 i = 1; i <= cMaxExpectedCodeSize; i++) {
1748     const uint32 n = num_codes[i];
1749
1750     if (!n)
1751       m_max_codes[i - 1] = 0;  //UINT_MAX;
1752     else {
1753       min_code_size = math::minimum(min_code_size, i);
1754       max_code_size = math::maximum(max_code_size, i);
1755
1756       min_codes[i - 1] = cur_code;
1757
1758       m_max_codes[i - 1] = cur_code + n - 1;
1759       m_max_codes[i - 1] = 1 + ((m_max_codes[i - 1] << (16 - i)) | ((1 << (16 - i)) - 1));
1760
1761       m_val_ptrs[i - 1] = total_used_syms;
1762
1763       sorted_positions[i] = total_used_syms;
1764
1765       cur_code += n;
1766       total_used_syms += n;
1767     }
1768
1769     cur_code <<= 1;
1770   }
1771
1772   m_total_used_syms = total_used_syms;
1773
1774   if (total_used_syms > m_cur_sorted_symbol_order_size) {
1775     m_cur_sorted_symbol_order_size = total_used_syms;
1776
1777     if (!math::is_power_of_2(total_used_syms))
1778       m_cur_sorted_symbol_order_size = math::minimum<uint32>(num_syms, math::next_pow2(total_used_syms));
1779
1780     if (m_sorted_symbol_order)
1781       crnd_delete_array(m_sorted_symbol_order);
1782
1783     m_sorted_symbol_order = crnd_new_array<uint16>(m_cur_sorted_symbol_order_size);
1784     if (!m_sorted_symbol_order)
1785       return false;
1786   }
1787
1788   m_min_code_size = static_cast<uint8>(min_code_size);
1789   m_max_code_size = static_cast<uint8>(max_code_size);
1790
1791   for (uint32 i = 0; i < num_syms; i++) {
1792     uint32 c = pCodesizes[i];
1793     if (c) {
1794       CRND_ASSERT(num_codes[c]);
1795
1796       uint32 sorted_pos = sorted_positions[c]++;
1797
1798       CRND_ASSERT(sorted_pos < total_used_syms);
1799
1800       m_sorted_symbol_order[sorted_pos] = static_cast<uint16>(i);
1801     }
1802   }
1803
1804   if (table_bits <= m_min_code_size)
1805     table_bits = 0;
1806   m_table_bits = table_bits;
1807
1808   if (table_bits) {
1809     uint32 table_size = 1 << table_bits;
1810     if (table_size > m_cur_lookup_size) {
1811       m_cur_lookup_size = table_size;
1812
1813       if (m_lookup)
1814         crnd_delete_array(m_lookup);
1815
1816       m_lookup = crnd_new_array<uint32>(table_size);
1817       if (!m_lookup)
1818         return false;
1819     }
1820
1821     memset(m_lookup, 0xFF, (uint)sizeof(m_lookup[0]) * (1UL << table_bits));
1822
1823     for (uint32 codesize = 1; codesize <= table_bits; codesize++) {
1824       if (!num_codes[codesize])
1825         continue;
1826
1827       const uint32 fillsize = table_bits - codesize;
1828       const uint32 fillnum = 1 << fillsize;
1829
1830       const uint32 min_code = min_codes[codesize - 1];
1831       const uint32 max_code = get_unshifted_max_code(codesize);
1832       const uint32 val_ptr = m_val_ptrs[codesize - 1];
1833
1834       for (uint32 code = min_code; code <= max_code; code++) {
1835         const uint32 sym_index = m_sorted_symbol_order[val_ptr + code - min_code];
1836         CRND_ASSERT(pCodesizes[sym_index] == codesize);
1837
1838         for (uint32 j = 0; j < fillnum; j++) {
1839           const uint32 t = j + (code << fillsize);
1840
1841           CRND_ASSERT(t < (1U << table_bits));
1842
1843           CRND_ASSERT(m_lookup[t] == cUINT32_MAX);
1844
1845           m_lookup[t] = sym_index | (codesize << 16U);
1846         }
1847       }
1848     }
1849   }
1850
1851   for (uint32 i = 0; i < cMaxExpectedCodeSize; i++)
1852     m_val_ptrs[i] -= min_codes[i];
1853
1854   m_table_max_code = 0;
1855   m_decode_start_code_size = m_min_code_size;
1856
1857   if (table_bits) {
1858     uint32 i;
1859     for (i = table_bits; i >= 1; i--) {
1860       if (num_codes[i]) {
1861         m_table_max_code = m_max_codes[i - 1];
1862         break;
1863       }
1864     }
1865     if (i >= 1) {
1866       m_decode_start_code_size = table_bits + 1;
1867       for (uint32 j = table_bits + 1; j <= max_code_size; j++) {
1868         if (num_codes[j]) {
1869           m_decode_start_code_size = j;
1870           break;
1871         }
1872       }
1873     }
1874   }
1875
1876   // sentinels
1877   m_max_codes[cMaxExpectedCodeSize] = cUINT32_MAX;
1878   m_val_ptrs[cMaxExpectedCodeSize] = 0xFFFFF;
1879
1880   m_table_shift = 32 - m_table_bits;
1881   return true;
1882 }
1883
1884 }  // namespace prefix_codig
1885
1886 }  // namespace crnd
1887
1888 // File: crnd_platform.cpp
1889 namespace crnd {
1890 bool crnd_is_debugger_present() {
1891 #ifdef CRND_DEVEL
1892   return IsDebuggerPresent() != 0;
1893 #else
1894   return false;
1895 #endif
1896 }
1897
1898 void crnd_debug_break() {
1899 #ifdef CRND_DEVEL
1900   DebugBreak();
1901 #endif
1902 }
1903
1904 void crnd_output_debug_string(const char* p) {
1905   (void)p;
1906 #ifdef CRND_DEVEL
1907   OutputDebugStringA(p);
1908 #endif
1909 }
1910
1911 }  // namespace crnd
1912
1913 // File: crnd_mem.cpp
1914 namespace crnd {
1915 const uint32 MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U;
1916
1917 static void* crnd_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void*) {
1918   void* p_new;
1919
1920   if (!p) {
1921     p_new = ::malloc(size);
1922
1923     if (pActual_size) {
1924 #ifdef WIN32
1925       *pActual_size = p_new ? ::_msize(p_new) : 0;
1926 #elif defined(__APPLE__)
1927       *pActual_size = p_new ? malloc_size(p_new) : 0;
1928 #else
1929       *pActual_size = p_new ? malloc_usable_size(p_new) : 0;
1930 #endif
1931     }
1932   } else if (!size) {
1933     ::free(p);
1934     p_new = NULL;
1935
1936     if (pActual_size)
1937       *pActual_size = 0;
1938   } else {
1939     void* p_final_block = p;
1940 #ifdef WIN32
1941     p_new = ::_expand(p, size);
1942 #else
1943     p_new = NULL;
1944 #endif
1945
1946     if (p_new)
1947       p_final_block = p_new;
1948     else if (movable) {
1949       p_new = ::realloc(p, size);
1950
1951       if (p_new)
1952         p_final_block = p_new;
1953     }
1954
1955     if (pActual_size) {
1956 #ifdef WIN32
1957       *pActual_size = ::_msize(p_final_block);
1958 #elif defined(__APPLE__)
1959       *pActual_size = ::malloc_size(p_final_block);
1960 #else
1961       *pActual_size = ::malloc_usable_size(p_final_block);
1962 #endif
1963     }
1964   }
1965
1966   return p_new;
1967 }
1968
1969 static size_t crnd_default_msize(void* p, void* pUser_data) {
1970   (void)pUser_data;
1971 #ifdef WIN32
1972   return p ? _msize(p) : 0;
1973 #elif defined(__APPLE__)
1974   return p ? malloc_size(p) : 0;
1975 #else
1976   return p ? malloc_usable_size(p) : 0;
1977 #endif
1978 }
1979
1980 static crnd_realloc_func g_pRealloc = crnd_default_realloc;
1981 static crnd_msize_func g_pMSize = crnd_default_msize;
1982 static void* g_pUser_data;
1983
1984 void crnd_set_memory_callbacks(crnd_realloc_func pRealloc, crnd_msize_func pMSize, void* pUser_data) {
1985   if ((!pRealloc) || (!pMSize)) {
1986     g_pRealloc = crnd_default_realloc;
1987     g_pMSize = crnd_default_msize;
1988     g_pUser_data = NULL;
1989   } else {
1990     g_pRealloc = pRealloc;
1991     g_pMSize = pMSize;
1992     g_pUser_data = pUser_data;
1993   }
1994 }
1995
1996 static inline void crnd_mem_error(const char* p_msg) {
1997   crnd_assert(p_msg, __FILE__, __LINE__);
1998 }
1999
2000 void* crnd_malloc(size_t size, size_t* pActual_size) {
2001   size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U);
2002   if (!size)
2003     size = sizeof(uint32);
2004
2005   if (size > MAX_POSSIBLE_BLOCK_SIZE) {
2006     crnd_mem_error("crnd_malloc: size too big");
2007     return NULL;
2008   }
2009
2010   size_t actual_size = size;
2011   uint8* p_new = static_cast<uint8*>((*g_pRealloc)(NULL, size, &actual_size, true, g_pUser_data));
2012
2013   if (pActual_size)
2014     *pActual_size = actual_size;
2015
2016   if ((!p_new) || (actual_size < size)) {
2017     crnd_mem_error("crnd_malloc: out of memory");
2018     return NULL;
2019   }
2020
2021   CRND_ASSERT(((uint32) reinterpret_cast<uintptr_t>(p_new) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
2022
2023   return p_new;
2024 }
2025
2026 void* crnd_realloc(void* p, size_t size, size_t* pActual_size, bool movable) {
2027   if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
2028     crnd_mem_error("crnd_realloc: bad ptr");
2029     return NULL;
2030   }
2031
2032   if (size > MAX_POSSIBLE_BLOCK_SIZE) {
2033     crnd_mem_error("crnd_malloc: size too big");
2034     return NULL;
2035   }
2036
2037   size_t actual_size = size;
2038   void* p_new = (*g_pRealloc)(p, size, &actual_size, movable, g_pUser_data);
2039
2040   if (pActual_size)
2041     *pActual_size = actual_size;
2042
2043   CRND_ASSERT(((uint32) reinterpret_cast<uintptr_t>(p_new) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) == 0);
2044
2045   return p_new;
2046 }
2047
2048 void crnd_free(void* p) {
2049   if (!p)
2050     return;
2051
2052   if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
2053     crnd_mem_error("crnd_free: bad ptr");
2054     return;
2055   }
2056
2057   (*g_pRealloc)(p, 0, NULL, true, g_pUser_data);
2058 }
2059
2060 size_t crnd_msize(void* p) {
2061   if (!p)
2062     return 0;
2063
2064   if ((uint32) reinterpret_cast<uintptr_t>(p) & (CRND_MIN_ALLOC_ALIGNMENT - 1)) {
2065     crnd_mem_error("crnd_msize: bad ptr");
2066     return 0;
2067   }
2068
2069   return (*g_pMSize)(p, g_pUser_data);
2070 }
2071
2072 }  // namespace crnd
2073
2074 // File: crnd_math.cpp
2075 namespace crnd {
2076 namespace math {
2077 uint32 g_bitmasks[32] =
2078     {
2079         1U << 0U, 1U << 1U, 1U << 2U, 1U << 3U,
2080         1U << 4U, 1U << 5U, 1U << 6U, 1U << 7U,
2081         1U << 8U, 1U << 9U, 1U << 10U, 1U << 11U,
2082         1U << 12U, 1U << 13U, 1U << 14U, 1U << 15U,
2083         1U << 16U, 1U << 17U, 1U << 18U, 1U << 19U,
2084         1U << 20U, 1U << 21U, 1U << 22U, 1U << 23U,
2085         1U << 24U, 1U << 25U, 1U << 26U, 1U << 27U,
2086         1U << 28U, 1U << 29U, 1U << 30U, 1U << 31U};
2087
2088 }  // namespace math
2089 }  // namespace crnd
2090
2091 // File: crnd_info.cpp
2092 namespace crnd {
2093 #define CRND_FOURCC(a, b, c, d) ((a) | ((b) << 8U) | ((c) << 16U) | ((d) << 24U))
2094
2095 uint32 crnd_crn_format_to_fourcc(crn_format fmt) {
2096   switch (fmt) {
2097     case cCRNFmtDXT1:
2098       return CRND_FOURCC('D', 'X', 'T', '1');
2099     case cCRNFmtDXT3:
2100       return CRND_FOURCC('D', 'X', 'T', '3');
2101     case cCRNFmtDXT5:
2102       return CRND_FOURCC('D', 'X', 'T', '5');
2103     case cCRNFmtDXN_XY:
2104       return CRND_FOURCC('A', '2', 'X', 'Y');
2105     case cCRNFmtDXN_YX:
2106       return CRND_FOURCC('A', 'T', 'I', '2');
2107     case cCRNFmtDXT5A:
2108       return CRND_FOURCC('A', 'T', 'I', '1');
2109     case cCRNFmtDXT5_CCxY:
2110       return CRND_FOURCC('C', 'C', 'x', 'Y');
2111     case cCRNFmtDXT5_xGxR:
2112       return CRND_FOURCC('x', 'G', 'x', 'R');
2113     case cCRNFmtDXT5_xGBR:
2114       return CRND_FOURCC('x', 'G', 'B', 'R');
2115     case cCRNFmtDXT5_AGBR:
2116       return CRND_FOURCC('A', 'G', 'B', 'R');
2117     case cCRNFmtETC1:
2118       return CRND_FOURCC('E', 'T', 'C', '1');
2119     case cCRNFmtETC2:
2120       return CRND_FOURCC('E', 'T', 'C', '2');
2121     case cCRNFmtETC2A:
2122       return CRND_FOURCC('E', 'T', '2', 'A');
2123     default:
2124       break;
2125   }
2126   CRND_ASSERT(false);
2127   return 0;
2128 }
2129
2130 crn_format crnd_get_fundamental_dxt_format(crn_format fmt) {
2131   switch (fmt) {
2132     case cCRNFmtDXT5_CCxY:
2133     case cCRNFmtDXT5_xGxR:
2134     case cCRNFmtDXT5_xGBR:
2135     case cCRNFmtDXT5_AGBR:
2136       return cCRNFmtDXT5;
2137     default:
2138       break;
2139   }
2140   return fmt;
2141 }
2142
2143 uint32 crnd_get_crn_format_bits_per_texel(crn_format fmt) {
2144   switch (fmt) {
2145     case cCRNFmtDXT1:
2146     case cCRNFmtDXT5A:
2147     case cCRNFmtETC1:
2148     case cCRNFmtETC2:
2149       return 4;
2150     case cCRNFmtDXT3:
2151     case cCRNFmtDXT5:
2152     case cCRNFmtDXN_XY:
2153     case cCRNFmtDXN_YX:
2154     case cCRNFmtDXT5_CCxY:
2155     case cCRNFmtDXT5_xGxR:
2156     case cCRNFmtDXT5_xGBR:
2157     case cCRNFmtDXT5_AGBR:
2158     case cCRNFmtETC2A:
2159       return 8;
2160     default:
2161       break;
2162   }
2163   CRND_ASSERT(false);
2164   return 0;
2165 }
2166
2167 uint32 crnd_get_bytes_per_dxt_block(crn_format fmt) {
2168   return (crnd_get_crn_format_bits_per_texel(fmt) << 4) >> 3;
2169 }
2170
2171 // TODO: tmp_header isn't used/This function is a helper to support old headers.
2172 const crn_header* crnd_get_header(const void* pData, uint32 data_size) {
2173   if ((!pData) || (data_size < sizeof(crn_header)))
2174     return NULL;
2175
2176   const crn_header& file_header = *static_cast<const crn_header*>(pData);
2177   if (file_header.m_sig != crn_header::cCRNSigValue)
2178     return NULL;
2179
2180   if ((file_header.m_header_size < sizeof(crn_header)) || (data_size < file_header.m_data_size))
2181     return NULL;
2182
2183   return &file_header;
2184 }
2185
2186 bool crnd_validate_file(const void* pData, uint32 data_size, crn_file_info* pFile_info) {
2187   if (pFile_info) {
2188     if (pFile_info->m_struct_size != sizeof(crn_file_info))
2189       return false;
2190
2191     memset(&pFile_info->m_struct_size + 1, 0, sizeof(crn_file_info) - sizeof(pFile_info->m_struct_size));
2192   }
2193
2194   if ((!pData) || (data_size < cCRNHeaderMinSize))
2195     return false;
2196
2197   const crn_header* pHeader = crnd_get_header(pData, data_size);
2198   if (!pHeader)
2199     return false;
2200
2201   const uint32 header_crc = crc16(&pHeader->m_data_size, (uint32)(pHeader->m_header_size - ((const uint8*)&pHeader->m_data_size - (const uint8*)pHeader)));
2202   if (header_crc != pHeader->m_header_crc16)
2203     return false;
2204
2205   const uint32 data_crc = crc16((const uint8*)pData + pHeader->m_header_size, pHeader->m_data_size - pHeader->m_header_size);
2206   if (data_crc != pHeader->m_data_crc16)
2207     return false;
2208
2209   if ((pHeader->m_faces != 1) && (pHeader->m_faces != 6))
2210     return false;
2211   if ((pHeader->m_width < 1) || (pHeader->m_width > cCRNMaxLevelResolution))
2212     return false;
2213   if ((pHeader->m_height < 1) || (pHeader->m_height > cCRNMaxLevelResolution))
2214     return false;
2215   if ((pHeader->m_levels < 1) || (pHeader->m_levels > utils::compute_max_mips(pHeader->m_width, pHeader->m_height)))
2216     return false;
2217   if (((int)pHeader->m_format < cCRNFmtDXT1) || ((int)pHeader->m_format >= cCRNFmtTotal))
2218     return false;
2219
2220   if (pFile_info) {
2221     pFile_info->m_actual_data_size = pHeader->m_data_size;
2222     pFile_info->m_header_size = pHeader->m_header_size;
2223     pFile_info->m_total_palette_size = pHeader->m_color_endpoints.m_size + pHeader->m_color_selectors.m_size + pHeader->m_alpha_endpoints.m_size + pHeader->m_alpha_selectors.m_size;
2224     pFile_info->m_tables_size = pHeader->m_tables_size;
2225
2226     pFile_info->m_levels = pHeader->m_levels;
2227
2228     for (uint32 i = 0; i < pHeader->m_levels; i++) {
2229       uint32 next_ofs = pHeader->m_data_size;
2230
2231       // assumes the levels are packed together sequentially
2232       if ((i + 1) < pHeader->m_levels)
2233         next_ofs = pHeader->m_level_ofs[i + 1];
2234
2235       pFile_info->m_level_compressed_size[i] = next_ofs - pHeader->m_level_ofs[i];
2236     }
2237
2238     pFile_info->m_color_endpoint_palette_entries = pHeader->m_color_endpoints.m_num;
2239     pFile_info->m_color_selector_palette_entries = pHeader->m_color_selectors.m_num;
2240     ;
2241     pFile_info->m_alpha_endpoint_palette_entries = pHeader->m_alpha_endpoints.m_num;
2242     ;
2243     pFile_info->m_alpha_selector_palette_entries = pHeader->m_alpha_selectors.m_num;
2244     ;
2245   }
2246
2247   return true;
2248 }
2249
2250 bool crnd_get_texture_info(const void* pData, uint32 data_size, crn_texture_info* pInfo) {
2251   if ((!pData) || (data_size < sizeof(crn_header)) || (!pInfo))
2252     return false;
2253
2254   if (pInfo->m_struct_size != sizeof(crn_texture_info))
2255     return false;
2256
2257   const crn_header* pHeader = crnd_get_header(pData, data_size);
2258   if (!pHeader)
2259     return false;
2260
2261   pInfo->m_width = pHeader->m_width;
2262   pInfo->m_height = pHeader->m_height;
2263   pInfo->m_levels = pHeader->m_levels;
2264   pInfo->m_faces = pHeader->m_faces;
2265   pInfo->m_format = static_cast<crn_format>((uint32)pHeader->m_format);
2266   pInfo->m_bytes_per_block = pHeader->m_format == cCRNFmtDXT1 || pHeader->m_format == cCRNFmtDXT5A || pHeader->m_format == cCRNFmtETC1 || pHeader->m_format == cCRNFmtETC2 ? 8 : 16;
2267   pInfo->m_userdata0 = pHeader->m_userdata0;
2268   pInfo->m_userdata1 = pHeader->m_userdata1;
2269
2270   return true;
2271 }
2272
2273 bool crnd_get_level_info(const void* pData, uint32 data_size, uint32 level_index, crn_level_info* pLevel_info) {
2274   if ((!pData) || (data_size < cCRNHeaderMinSize) || (!pLevel_info))
2275     return false;
2276
2277   if (pLevel_info->m_struct_size != sizeof(crn_level_info))
2278     return false;
2279
2280   const crn_header* pHeader = crnd_get_header(pData, data_size);
2281   if (!pHeader)
2282     return false;
2283
2284   if (level_index >= pHeader->m_levels)
2285     return false;
2286
2287   uint32 width = math::maximum<uint32>(1U, pHeader->m_width >> level_index);
2288   uint32 height = math::maximum<uint32>(1U, pHeader->m_height >> level_index);
2289
2290   pLevel_info->m_width = width;
2291   pLevel_info->m_height = height;
2292   pLevel_info->m_faces = pHeader->m_faces;
2293   pLevel_info->m_blocks_x = (width + 3) >> 2;
2294   pLevel_info->m_blocks_y = (height + 3) >> 2;
2295   pLevel_info->m_bytes_per_block = ((pHeader->m_format == cCRNFmtDXT1) || (pHeader->m_format == cCRNFmtDXT5A)) ? 8 : 16;
2296   pLevel_info->m_format = static_cast<crn_format>((uint32)pHeader->m_format);
2297
2298   return true;
2299 }
2300
2301 const void* crnd_get_level_data(const void* pData, uint32 data_size, uint32 level_index, uint32* pSize) {
2302   if (pSize)
2303     *pSize = 0;
2304
2305   if ((!pData) || (data_size < cCRNHeaderMinSize))
2306     return NULL;
2307
2308   const crn_header* pHeader = crnd_get_header(pData, data_size);
2309   if (!pHeader)
2310     return NULL;
2311
2312   if (level_index >= pHeader->m_levels)
2313     return NULL;
2314
2315   uint32 cur_level_ofs = pHeader->m_level_ofs[level_index];
2316
2317   if (pSize) {
2318     uint32 next_level_ofs = data_size;
2319     if ((level_index + 1) < (pHeader->m_levels))
2320       next_level_ofs = pHeader->m_level_ofs[level_index + 1];
2321
2322     *pSize = next_level_ofs - cur_level_ofs;
2323   }
2324
2325   return static_cast<const uint8*>(pData) + cur_level_ofs;
2326 }
2327
2328 uint32 crnd_get_segmented_file_size(const void* pData, uint32 data_size) {
2329   if ((!pData) || (data_size < cCRNHeaderMinSize))
2330     return false;
2331
2332   const crn_header* pHeader = crnd_get_header(pData, data_size);
2333   if (!pHeader)
2334     return false;
2335
2336   uint32 size = pHeader->m_header_size;
2337
2338   size = math::maximum(size, pHeader->m_color_endpoints.m_ofs + pHeader->m_color_endpoints.m_size);
2339   size = math::maximum(size, pHeader->m_color_selectors.m_ofs + pHeader->m_color_selectors.m_size);
2340   size = math::maximum(size, pHeader->m_alpha_endpoints.m_ofs + pHeader->m_alpha_endpoints.m_size);
2341   size = math::maximum(size, pHeader->m_alpha_selectors.m_ofs + pHeader->m_alpha_selectors.m_size);
2342   size = math::maximum(size, pHeader->m_tables_ofs + pHeader->m_tables_size);
2343
2344   return size;
2345 }
2346
2347 bool crnd_create_segmented_file(const void* pData, uint32 data_size, void* pBase_data, uint base_data_size) {
2348   if ((!pData) || (data_size < cCRNHeaderMinSize))
2349     return false;
2350
2351   const crn_header* pHeader = crnd_get_header(pData, data_size);
2352   if (!pHeader)
2353     return false;
2354
2355   if (pHeader->m_flags & cCRNHeaderFlagSegmented)
2356     return false;
2357
2358   const uint actual_base_data_size = crnd_get_segmented_file_size(pData, data_size);
2359   if (base_data_size < actual_base_data_size)
2360     return false;
2361
2362   memcpy(pBase_data, pData, actual_base_data_size);
2363
2364   crn_header& new_header = *static_cast<crn_header*>(pBase_data);
2365   new_header.m_flags = new_header.m_flags | cCRNHeaderFlagSegmented;
2366   new_header.m_data_size = actual_base_data_size;
2367
2368   new_header.m_data_crc16 = crc16((const uint8*)pBase_data + new_header.m_header_size, new_header.m_data_size - new_header.m_header_size);
2369
2370   new_header.m_header_crc16 = crc16(&new_header.m_data_size, new_header.m_header_size - (uint32)((const uint8*)&new_header.m_data_size - (const uint8*)&new_header));
2371
2372   CRND_ASSERT(crnd_validate_file(&new_header, actual_base_data_size, NULL));
2373
2374   return true;
2375 }
2376
2377 }  // namespace crnd
2378
2379 // File: symbol_codec.cpp
2380 namespace crnd {
2381 static_huffman_data_model::static_huffman_data_model()
2382     : m_total_syms(0),
2383       m_pDecode_tables(NULL) {
2384 }
2385
2386 static_huffman_data_model::static_huffman_data_model(const static_huffman_data_model& other)
2387     : m_total_syms(0),
2388       m_pDecode_tables(NULL) {
2389   *this = other;
2390 }
2391
2392 static_huffman_data_model::~static_huffman_data_model() {
2393   if (m_pDecode_tables)
2394     crnd_delete(m_pDecode_tables);
2395 }
2396
2397 static_huffman_data_model& static_huffman_data_model::operator=(const static_huffman_data_model& rhs) {
2398   if (this == &rhs)
2399     return *this;
2400
2401   m_total_syms = rhs.m_total_syms;
2402   m_code_sizes = rhs.m_code_sizes;
2403   if (m_code_sizes.get_alloc_failed()) {
2404     clear();
2405     return *this;
2406   }
2407
2408   if (rhs.m_pDecode_tables) {
2409     if (m_pDecode_tables)
2410       *m_pDecode_tables = *rhs.m_pDecode_tables;
2411     else
2412       m_pDecode_tables = crnd_new<prefix_coding::decoder_tables>(*rhs.m_pDecode_tables);
2413   } else {
2414     crnd_delete(m_pDecode_tables);
2415     m_pDecode_tables = NULL;
2416   }
2417
2418   return *this;
2419 }
2420
2421 void static_huffman_data_model::clear() {
2422   m_total_syms = 0;
2423   m_code_sizes.clear();
2424   if (m_pDecode_tables) {
2425     crnd_delete(m_pDecode_tables);
2426     m_pDecode_tables = NULL;
2427   }
2428 }
2429
2430 bool static_huffman_data_model::init(uint32 total_syms, const uint8* pCode_sizes, uint32 code_size_limit) {
2431   CRND_ASSERT((total_syms >= 1) && (total_syms <= prefix_coding::cMaxSupportedSyms) && (code_size_limit >= 1));
2432
2433   code_size_limit = math::minimum(code_size_limit, prefix_coding::cMaxExpectedCodeSize);
2434
2435   if (!m_code_sizes.resize(total_syms))
2436     return false;
2437
2438   uint32 min_code_size = cUINT32_MAX;
2439   uint32 max_code_size = 0;
2440
2441   for (uint32 i = 0; i < total_syms; i++) {
2442     uint32 s = pCode_sizes[i];
2443     m_code_sizes[i] = static_cast<uint8>(s);
2444     min_code_size = math::minimum(min_code_size, s);
2445     max_code_size = math::maximum(max_code_size, s);
2446   }
2447
2448   if ((max_code_size < 1) || (max_code_size > 32) || (min_code_size > code_size_limit))
2449     return false;
2450
2451   if (max_code_size > code_size_limit)
2452     return false;
2453
2454   if (!m_pDecode_tables)
2455     m_pDecode_tables = crnd_new<prefix_coding::decoder_tables>();
2456
2457   if (!m_pDecode_tables->init(m_total_syms, &m_code_sizes[0], compute_decoder_table_bits()))
2458     return false;
2459
2460   return true;
2461 }
2462
2463 bool static_huffman_data_model::prepare_decoder_tables() {
2464   uint32 total_syms = m_code_sizes.size();
2465
2466   CRND_ASSERT((total_syms >= 1) && (total_syms <= prefix_coding::cMaxSupportedSyms));
2467
2468   m_total_syms = total_syms;
2469
2470   if (!m_pDecode_tables)
2471     m_pDecode_tables = crnd_new<prefix_coding::decoder_tables>();
2472
2473   return m_pDecode_tables->init(m_total_syms, &m_code_sizes[0], compute_decoder_table_bits());
2474 }
2475
2476 uint static_huffman_data_model::compute_decoder_table_bits() const {
2477 #if CRND_PREFIX_CODING_USE_FIXED_TABLE_SIZE
2478   return prefix_coding::cMaxTableBits;
2479 #else
2480   uint32 decoder_table_bits = 0;
2481   if (m_total_syms > 16)
2482     decoder_table_bits = static_cast<uint8>(math::minimum(1 + math::ceil_log2i(m_total_syms), prefix_coding::cMaxTableBits));
2483   return decoder_table_bits;
2484 #endif
2485 }
2486
2487 symbol_codec::symbol_codec()
2488     : m_pDecode_buf(NULL),
2489       m_pDecode_buf_next(NULL),
2490       m_pDecode_buf_end(NULL),
2491       m_decode_buf_size(0),
2492       m_bit_buf(0),
2493       m_bit_count(0) {
2494 }
2495
2496 // Code length encoding symbols:
2497 // 0-16 - actual code lengths
2498 const uint32 cMaxCodelengthCodes = 21;
2499
2500 const uint32 cSmallZeroRunCode = 17;
2501 const uint32 cLargeZeroRunCode = 18;
2502 const uint32 cSmallRepeatCode = 19;
2503 const uint32 cLargeRepeatCode = 20;
2504
2505 const uint32 cMinSmallZeroRunSize = 3;
2506 const uint32 cMaxSmallZeroRunSize = 10;
2507 const uint32 cMinLargeZeroRunSize = 11;
2508 const uint32 cMaxLargeZeroRunSize = 138;
2509
2510 const uint32 cSmallMinNonZeroRunSize = 3;
2511 const uint32 cSmallMaxNonZeroRunSize = 6;
2512 const uint32 cLargeMinNonZeroRunSize = 7;
2513 const uint32 cLargeMaxNonZeroRunSize = 70;
2514
2515 const uint32 cSmallZeroRunExtraBits = 3;
2516 const uint32 cLargeZeroRunExtraBits = 7;
2517 const uint32 cSmallNonZeroRunExtraBits = 2;
2518 const uint32 cLargeNonZeroRunExtraBits = 6;
2519
2520 static const uint8 g_most_probable_codelength_codes[] =
2521     {
2522         cSmallZeroRunCode, cLargeZeroRunCode,
2523         cSmallRepeatCode, cLargeRepeatCode,
2524
2525         0, 8,
2526         7, 9,
2527         6, 10,
2528         5, 11,
2529         4, 12,
2530         3, 13,
2531         2, 14,
2532         1, 15,
2533         16};
2534 const uint32 cNumMostProbableCodelengthCodes = sizeof(g_most_probable_codelength_codes) / sizeof(g_most_probable_codelength_codes[0]);
2535
2536 bool symbol_codec::decode_receive_static_data_model(static_huffman_data_model& model) {
2537   const uint32 total_used_syms = decode_bits(math::total_bits(prefix_coding::cMaxSupportedSyms));
2538
2539   if (!total_used_syms) {
2540     model.clear();
2541     return true;
2542   }
2543
2544   if (!model.m_code_sizes.resize(total_used_syms))
2545     return false;
2546
2547   memset(&model.m_code_sizes[0], 0, sizeof(model.m_code_sizes[0]) * total_used_syms);
2548
2549   const uint32 num_codelength_codes_to_send = decode_bits(5);
2550   if ((num_codelength_codes_to_send < 1) || (num_codelength_codes_to_send > cMaxCodelengthCodes))
2551     return false;
2552
2553   static_huffman_data_model dm;
2554   if (!dm.m_code_sizes.resize(cMaxCodelengthCodes))
2555     return false;
2556
2557   for (uint32 i = 0; i < num_codelength_codes_to_send; i++)
2558     dm.m_code_sizes[g_most_probable_codelength_codes[i]] = static_cast<uint8>(decode_bits(3));
2559
2560   if (!dm.prepare_decoder_tables())
2561     return false;
2562
2563   uint32 ofs = 0;
2564   while (ofs < total_used_syms) {
2565     const uint32 num_remaining = total_used_syms - ofs;
2566
2567     uint32 code = decode(dm);
2568     if (code <= 16)
2569       model.m_code_sizes[ofs++] = static_cast<uint8>(code);
2570     else if (code == cSmallZeroRunCode) {
2571       uint32 len = decode_bits(cSmallZeroRunExtraBits) + cMinSmallZeroRunSize;
2572       if (len > num_remaining)
2573         return false;
2574       ofs += len;
2575     } else if (code == cLargeZeroRunCode) {
2576       uint32 len = decode_bits(cLargeZeroRunExtraBits) + cMinLargeZeroRunSize;
2577       if (len > num_remaining)
2578         return false;
2579       ofs += len;
2580     } else if ((code == cSmallRepeatCode) || (code == cLargeRepeatCode)) {
2581       uint32 len;
2582       if (code == cSmallRepeatCode)
2583         len = decode_bits(cSmallNonZeroRunExtraBits) + cSmallMinNonZeroRunSize;
2584       else
2585         len = decode_bits(cLargeNonZeroRunExtraBits) + cLargeMinNonZeroRunSize;
2586
2587       if ((!ofs) || (len > num_remaining))
2588         return false;
2589       const uint32 prev = model.m_code_sizes[ofs - 1];
2590       if (!prev)
2591         return false;
2592       const uint32 end = ofs + len;
2593       while (ofs < end)
2594         model.m_code_sizes[ofs++] = static_cast<uint8>(prev);
2595     } else {
2596       CRND_ASSERT(0);
2597       return false;
2598     }
2599   }
2600
2601   if (ofs != total_used_syms)
2602     return false;
2603
2604   return model.prepare_decoder_tables();
2605 }
2606
2607 bool symbol_codec::start_decoding(const uint8* pBuf, uint32 buf_size) {
2608   if (!buf_size)
2609     return false;
2610
2611   m_pDecode_buf = pBuf;
2612   m_pDecode_buf_next = pBuf;
2613   m_decode_buf_size = buf_size;
2614   m_pDecode_buf_end = pBuf + buf_size;
2615
2616   get_bits_init();
2617
2618   return true;
2619 }
2620
2621 void symbol_codec::get_bits_init() {
2622   m_bit_buf = 0;
2623   m_bit_count = 0;
2624 }
2625
2626 uint32 symbol_codec::decode_bits(uint32 num_bits) {
2627   if (!num_bits)
2628     return 0;
2629
2630   if (num_bits > 16) {
2631     uint32 a = get_bits(num_bits - 16);
2632     uint32 b = get_bits(16);
2633
2634     return (a << 16) | b;
2635   } else
2636     return get_bits(num_bits);
2637 }
2638
2639 uint32 symbol_codec::get_bits(uint32 num_bits) {
2640   CRND_ASSERT(num_bits <= 32U);
2641
2642   while (m_bit_count < (int)num_bits) {
2643     bit_buf_type c = 0;
2644     if (m_pDecode_buf_next != m_pDecode_buf_end)
2645       c = *m_pDecode_buf_next++;
2646
2647     m_bit_count += 8;
2648     CRND_ASSERT(m_bit_count <= cBitBufSize);
2649
2650     m_bit_buf |= (c << (cBitBufSize - m_bit_count));
2651   }
2652
2653   uint32 result = static_cast<uint32>(m_bit_buf >> (cBitBufSize - num_bits));
2654
2655   m_bit_buf <<= num_bits;
2656   m_bit_count -= num_bits;
2657
2658   return result;
2659 }
2660
2661 uint32 symbol_codec::decode(const static_huffman_data_model& model) {
2662   const prefix_coding::decoder_tables* pTables = model.m_pDecode_tables;
2663
2664   if (m_bit_count < 24) {
2665     if (m_bit_count < 16) {
2666       uint32 c0 = 0, c1 = 0;
2667       const uint8* p = m_pDecode_buf_next;
2668       if (p < m_pDecode_buf_end)
2669         c0 = *p++;
2670       if (p < m_pDecode_buf_end)
2671         c1 = *p++;
2672       m_pDecode_buf_next = p;
2673       m_bit_count += 16;
2674       uint32 c = (c0 << 8) | c1;
2675       m_bit_buf |= (c << (32 - m_bit_count));
2676     } else {
2677       uint32 c = (m_pDecode_buf_next < m_pDecode_buf_end) ? *m_pDecode_buf_next++ : 0;
2678       m_bit_count += 8;
2679       m_bit_buf |= (c << (32 - m_bit_count));
2680     }
2681   }
2682
2683   uint32 k = (m_bit_buf >> 16) + 1;
2684   uint32 sym, len;
2685
2686   if (k <= pTables->m_table_max_code) {
2687     uint32 t = pTables->m_lookup[m_bit_buf >> (32 - pTables->m_table_bits)];
2688
2689     CRND_ASSERT(t != cUINT32_MAX);
2690     sym = t & cUINT16_MAX;
2691     len = t >> 16;
2692
2693     CRND_ASSERT(model.m_code_sizes[sym] == len);
2694   } else {
2695     len = pTables->m_decode_start_code_size;
2696
2697     for (;;) {
2698       if (k <= pTables->m_max_codes[len - 1])
2699         break;
2700       len++;
2701     }
2702
2703     int val_ptr = pTables->m_val_ptrs[len - 1] + (m_bit_buf >> (32 - len));
2704
2705     if (((uint32)val_ptr >= model.m_total_syms)) {
2706       // corrupted stream, or a bug
2707       CRND_ASSERT(0);
2708       return 0;
2709     }
2710
2711     sym = pTables->m_sorted_symbol_order[val_ptr];
2712   }
2713
2714   m_bit_buf <<= len;
2715   m_bit_count -= len;
2716
2717   return sym;
2718 }
2719
2720 uint64 symbol_codec::stop_decoding() {
2721   return static_cast<uint64>(m_pDecode_buf_next - m_pDecode_buf);
2722 }
2723
2724 }  // namespace crnd
2725
2726 // File: crnd_dxt.cpp
2727 namespace crnd {
2728 const uint8 g_dxt1_to_linear[cDXT1SelectorValues] = {0U, 3U, 1U, 2U};
2729 const uint8 g_dxt1_from_linear[cDXT1SelectorValues] = {0U, 2U, 3U, 1U};
2730 const uint8 g_etc1_from_linear[cDXT1SelectorValues] = {3U, 2U, 0U, 1U};
2731
2732 const uint8 g_dxt5_to_linear[cDXT5SelectorValues] = {0U, 7U, 1U, 2U, 3U, 4U, 5U, 6U};
2733 const uint8 g_dxt5_from_linear[cDXT5SelectorValues] = {0U, 2U, 3U, 4U, 5U, 6U, 7U, 1U};
2734
2735 const uint8 g_six_alpha_invert_table[cDXT5SelectorValues] = {1, 0, 5, 4, 3, 2, 6, 7};
2736 const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues] = {1, 0, 7, 6, 5, 4, 3, 2};
2737
2738 uint16 dxt1_block::pack_color(const color_quad_u8& color, bool scaled, uint32 bias) {
2739   uint32 r = color.r;
2740   uint32 g = color.g;
2741   uint32 b = color.b;
2742
2743   if (scaled) {
2744     r = (r * 31U + bias) / 255U;
2745     g = (g * 63U + bias) / 255U;
2746     b = (b * 31U + bias) / 255U;
2747   }
2748
2749   r = math::minimum(r, 31U);
2750   g = math::minimum(g, 63U);
2751   b = math::minimum(b, 31U);
2752
2753   return static_cast<uint16>(b | (g << 5U) | (r << 11U));
2754 }
2755
2756 uint16 dxt1_block::pack_color(uint32 r, uint32 g, uint32 b, bool scaled, uint32 bias) {
2757   return pack_color(color_quad_u8(r, g, b, 0), scaled, bias);
2758 }
2759
2760 color_quad_u8 dxt1_block::unpack_color(uint16 packed_color, bool scaled, uint32 alpha) {
2761   uint32 b = packed_color & 31U;
2762   uint32 g = (packed_color >> 5U) & 63U;
2763   uint32 r = (packed_color >> 11U) & 31U;
2764
2765   if (scaled) {
2766     b = (b << 3U) | (b >> 2U);
2767     g = (g << 2U) | (g >> 4U);
2768     r = (r << 3U) | (r >> 2U);
2769   }
2770
2771   return color_quad_u8(r, g, b, alpha);
2772 }
2773
2774 void dxt1_block::unpack_color(uint32& r, uint32& g, uint32& b, uint16 packed_color, bool scaled) {
2775   color_quad_u8 c(unpack_color(packed_color, scaled, 0));
2776   r = c.r;
2777   g = c.g;
2778   b = c.b;
2779 }
2780
2781 uint32 dxt1_block::get_block_colors3(color_quad_u8* pDst, uint16 color0, uint16 color1) {
2782   color_quad_u8 c0(unpack_color(color0, true));
2783   color_quad_u8 c1(unpack_color(color1, true));
2784
2785   pDst[0] = c0;
2786   pDst[1] = c1;
2787   pDst[2].set((c0.r + c1.r) >> 1U, (c0.g + c1.g) >> 1U, (c0.b + c1.b) >> 1U, 255U);
2788   pDst[3].set(0, 0, 0, 0);
2789
2790   return 3;
2791 }
2792
2793 uint32 dxt1_block::get_block_colors4(color_quad_u8* pDst, uint16 color0, uint16 color1) {
2794   color_quad_u8 c0(unpack_color(color0, true));
2795   color_quad_u8 c1(unpack_color(color1, true));
2796
2797   pDst[0] = c0;
2798   pDst[1] = c1;
2799
2800   // 12/14/09 - Supposed to round according to DX docs, but this conflicts with the OpenGL S3TC spec. ?
2801   // Turns out some GPU's round and some don't. Great.
2802   //pDst[2].set( (c0.r * 2 + c1.r + 1) / 3, (c0.g * 2 + c1.g + 1) / 3, (c0.b * 2 + c1.b + 1) / 3, 255U);
2803   //pDst[3].set( (c1.r * 2 + c0.r + 1) / 3, (c1.g * 2 + c0.g + 1) / 3, (c1.b * 2 + c0.b + 1) / 3, 255U);
2804
2805   pDst[2].set((c0.r * 2 + c1.r) / 3, (c0.g * 2 + c1.g) / 3, (c0.b * 2 + c1.b) / 3, 255U);
2806   pDst[3].set((c1.r * 2 + c0.r) / 3, (c1.g * 2 + c0.g) / 3, (c1.b * 2 + c0.b) / 3, 255U);
2807
2808   return 4;
2809 }
2810
2811 uint32 dxt1_block::get_block_colors(color_quad_u8* pDst, uint16 color0, uint16 color1) {
2812   if (color0 > color1)
2813     return get_block_colors4(pDst, color0, color1);
2814   else
2815     return get_block_colors3(pDst, color0, color1);
2816 }
2817
2818 color_quad_u8 dxt1_block::unpack_endpoint(uint32 endpoints, uint32 index, bool scaled, uint32 alpha) {
2819   CRND_ASSERT(index < 2);
2820   return unpack_color(static_cast<uint16>((endpoints >> (index * 16U)) & 0xFFFFU), scaled, alpha);
2821 }
2822
2823 uint32 dxt1_block::pack_endpoints(uint32 lo, uint32 hi) {
2824   CRND_ASSERT((lo <= 0xFFFFU) && (hi <= 0xFFFFU));
2825   return lo | (hi << 16U);
2826 }
2827
2828 void dxt3_block::set_alpha(uint32 x, uint32 y, uint32 value, bool scaled) {
2829   CRND_ASSERT((x < cDXTBlockSize) && (y < cDXTBlockSize));
2830
2831   if (scaled) {
2832     CRND_ASSERT(value <= 0xFF);
2833     value = (value * 15U + 128U) / 255U;
2834   } else {
2835     CRND_ASSERT(value <= 0xF);
2836   }
2837
2838   uint32 ofs = (y << 1U) + (x >> 1U);
2839   uint32 c = m_alpha[ofs];
2840
2841   c &= ~(0xF << ((x & 1U) << 2U));
2842   c |= (value << ((x & 1U) << 2U));
2843
2844   m_alpha[ofs] = static_cast<uint8>(c);
2845 }
2846
2847 uint32 dxt3_block::get_alpha(uint32 x, uint32 y, bool scaled) const {
2848   CRND_ASSERT((x < cDXTBlockSize) && (y < cDXTBlockSize));
2849
2850   uint32 value = m_alpha[(y << 1U) + (x >> 1U)];
2851   if (x & 1)
2852     value >>= 4;
2853   value &= 0xF;
2854
2855   if (scaled)
2856     value = (value << 4U) | value;
2857
2858   return value;
2859 }
2860
2861 uint32 dxt5_block::get_block_values6(color_quad_u8* pDst, uint32 l, uint32 h) {
2862   pDst[0].a = static_cast<uint8>(l);
2863   pDst[1].a = static_cast<uint8>(h);
2864   pDst[2].a = static_cast<uint8>((l * 4 + h) / 5);
2865   pDst[3].a = static_cast<uint8>((l * 3 + h * 2) / 5);
2866   pDst[4].a = static_cast<uint8>((l * 2 + h * 3) / 5);
2867   pDst[5].a = static_cast<uint8>((l + h * 4) / 5);
2868   pDst[6].a = 0;
2869   pDst[7].a = 255;
2870   return 6;
2871 }
2872
2873 uint32 dxt5_block::get_block_values8(color_quad_u8* pDst, uint32 l, uint32 h) {
2874   pDst[0].a = static_cast<uint8>(l);
2875   pDst[1].a = static_cast<uint8>(h);
2876   pDst[2].a = static_cast<uint8>((l * 6 + h) / 7);
2877   pDst[3].a = static_cast<uint8>((l * 5 + h * 2) / 7);
2878   pDst[4].a = static_cast<uint8>((l * 4 + h * 3) / 7);
2879   pDst[5].a = static_cast<uint8>((l * 3 + h * 4) / 7);
2880   pDst[6].a = static_cast<uint8>((l * 2 + h * 5) / 7);
2881   pDst[7].a = static_cast<uint8>((l + h * 6) / 7);
2882   return 8;
2883 }
2884
2885 uint32 dxt5_block::get_block_values(color_quad_u8* pDst, uint32 l, uint32 h) {
2886   if (l > h)
2887     return get_block_values8(pDst, l, h);
2888   else
2889     return get_block_values6(pDst, l, h);
2890 }
2891
2892 uint32 dxt5_block::get_block_values6(uint32* pDst, uint32 l, uint32 h) {
2893   pDst[0] = l;
2894   pDst[1] = h;
2895   pDst[2] = (l * 4 + h) / 5;
2896   pDst[3] = (l * 3 + h * 2) / 5;
2897   pDst[4] = (l * 2 + h * 3) / 5;
2898   pDst[5] = (l + h * 4) / 5;
2899   pDst[6] = 0;
2900   pDst[7] = 255;
2901   return 6;
2902 }
2903
2904 uint32 dxt5_block::get_block_values8(uint32* pDst, uint32 l, uint32 h) {
2905   pDst[0] = l;
2906   pDst[1] = h;
2907   pDst[2] = (l * 6 + h) / 7;
2908   pDst[3] = (l * 5 + h * 2) / 7;
2909   pDst[4] = (l * 4 + h * 3) / 7;
2910   pDst[5] = (l * 3 + h * 4) / 7;
2911   pDst[6] = (l * 2 + h * 5) / 7;
2912   pDst[7] = (l + h * 6) / 7;
2913   return 8;
2914 }
2915
2916 uint32 dxt5_block::unpack_endpoint(uint32 packed, uint32 index) {
2917   CRND_ASSERT(index < 2);
2918   return (packed >> (8 * index)) & 0xFF;
2919 }
2920
2921 uint32 dxt5_block::pack_endpoints(uint32 lo, uint32 hi) {
2922   CRND_ASSERT((lo <= 0xFF) && (hi <= 0xFF));
2923   return lo | (hi << 8U);
2924 }
2925
2926 uint32 dxt5_block::get_block_values(uint32* pDst, uint32 l, uint32 h) {
2927   if (l > h)
2928     return get_block_values8(pDst, l, h);
2929   else
2930     return get_block_values6(pDst, l, h);
2931 }
2932
2933 }  // namespace crnd
2934
2935 // File: crnd_decode.cpp
2936
2937 namespace crnd {
2938
2939 class crn_unpacker {
2940  public:
2941   inline crn_unpacker()
2942       : m_magic(cMagicValue),
2943         m_pData(NULL),
2944         m_data_size(0),
2945         m_pHeader(NULL) {
2946   }
2947
2948   inline ~crn_unpacker() {
2949     m_magic = 0;
2950   }
2951
2952   inline bool is_valid() const { return m_magic == cMagicValue; }
2953
2954   bool init(const void* pData, uint32 data_size) {
2955     m_pHeader = crnd_get_header(pData, data_size);
2956     if (!m_pHeader)
2957       return false;
2958
2959     m_pData = static_cast<const uint8*>(pData);
2960     m_data_size = data_size;
2961
2962     if (!init_tables())
2963       return false;
2964
2965     if (!decode_palettes())
2966       return false;
2967
2968     return true;
2969   }
2970
2971   bool unpack_level(
2972       void** pDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes,
2973       uint32 level_index) {
2974     uint32 cur_level_ofs = m_pHeader->m_level_ofs[level_index];
2975
2976     uint32 next_level_ofs = m_data_size;
2977     if ((level_index + 1) < (m_pHeader->m_levels))
2978       next_level_ofs = m_pHeader->m_level_ofs[level_index + 1];
2979
2980     CRND_ASSERT(next_level_ofs > cur_level_ofs);
2981
2982     return unpack_level(m_pData + cur_level_ofs, next_level_ofs - cur_level_ofs, pDst, dst_size_in_bytes, row_pitch_in_bytes, level_index);
2983   }
2984
2985   bool unpack_level(
2986       const void* pSrc, uint32 src_size_in_bytes,
2987       void** pDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes,
2988       uint32 level_index) {
2989
2990 #ifdef CRND_BUILD_DEBUG
2991     for (uint32 f = 0; f < m_pHeader->m_faces; f++)
2992       if (!pDst[f])
2993         return false;
2994 #endif
2995
2996     const uint32 width = math::maximum(m_pHeader->m_width >> level_index, 1U);
2997     const uint32 height = math::maximum(m_pHeader->m_height >> level_index, 1U);
2998     const uint32 blocks_x = (width + 3U) >> 2U;
2999     const uint32 blocks_y = (height + 3U) >> 2U;
3000     const uint32 block_size = m_pHeader->m_format == cCRNFmtDXT1 || m_pHeader->m_format == cCRNFmtDXT5A || m_pHeader->m_format == cCRNFmtETC1 || m_pHeader->m_format == cCRNFmtETC2 ? 8 : 16;
3001
3002     uint32 minimal_row_pitch = block_size * blocks_x;
3003     if (!row_pitch_in_bytes)
3004       row_pitch_in_bytes = minimal_row_pitch;
3005     else if ((row_pitch_in_bytes < minimal_row_pitch) || (row_pitch_in_bytes & 3))
3006       return false;
3007     if (dst_size_in_bytes < row_pitch_in_bytes * blocks_y)
3008       return false;
3009
3010     if (!m_codec.start_decoding(static_cast<const crnd::uint8*>(pSrc), src_size_in_bytes))
3011       return false;
3012
3013     bool status = false;
3014     switch (m_pHeader->m_format) {
3015       case cCRNFmtDXT1:
3016         status = unpack_dxt1((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3017         break;
3018       case cCRNFmtDXT5:
3019       case cCRNFmtDXT5_CCxY:
3020       case cCRNFmtDXT5_xGBR:
3021       case cCRNFmtDXT5_AGBR:
3022       case cCRNFmtDXT5_xGxR:
3023         status = unpack_dxt5((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3024         break;
3025       case cCRNFmtDXT5A:
3026         status = unpack_dxt5a((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3027         break;
3028       case cCRNFmtDXN_XY:
3029       case cCRNFmtDXN_YX:
3030         status = unpack_dxn((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3031         break;
3032       case cCRNFmtETC1:
3033         status = unpack_etc1((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3034         break;
3035       case cCRNFmtETC2:
3036         status = unpack_etc1((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3037         break;
3038       case cCRNFmtETC2A:
3039         status = unpack_etc2a((uint8**)pDst, row_pitch_in_bytes, blocks_x, blocks_y);
3040         break;
3041       default:
3042         return false;
3043     }
3044     if (!status)
3045       return false;
3046
3047     m_codec.stop_decoding();
3048     return true;
3049   }
3050
3051   inline const void* get_data() const { return m_pData; }
3052   inline uint32 get_data_size() const { return m_data_size; }
3053
3054  private:
3055   enum { cMagicValue = 0x1EF9CABD };
3056   uint32 m_magic;
3057
3058   const uint8* m_pData;
3059   uint32 m_data_size;
3060   const crn_header* m_pHeader;
3061
3062   symbol_codec m_codec;
3063
3064   static_huffman_data_model m_reference_encoding_dm;
3065   static_huffman_data_model m_endpoint_delta_dm[2];
3066   static_huffman_data_model m_selector_delta_dm[2];
3067
3068   crnd::vector<uint32> m_color_endpoints;
3069   crnd::vector<uint32> m_color_selectors;
3070
3071   crnd::vector<uint16> m_alpha_endpoints;
3072   crnd::vector<uint16> m_alpha_selectors;
3073   
3074   struct block_buffer_element {
3075     uint16 endpoint_reference;
3076     uint16 color_endpoint_index;
3077     uint16 alpha0_endpoint_index;
3078     uint16 alpha1_endpoint_index;
3079   };
3080   crnd::vector<block_buffer_element> m_block_buffer;
3081
3082   bool init_tables() {
3083     if (!m_codec.start_decoding(m_pData + m_pHeader->m_tables_ofs, m_pHeader->m_tables_size))
3084       return false;
3085
3086     if (!m_codec.decode_receive_static_data_model(m_reference_encoding_dm))
3087       return false;
3088
3089     if ((!m_pHeader->m_color_endpoints.m_num) && (!m_pHeader->m_alpha_endpoints.m_num))
3090       return false;
3091
3092     if (m_pHeader->m_color_endpoints.m_num) {
3093       if (!m_codec.decode_receive_static_data_model(m_endpoint_delta_dm[0]))
3094         return false;
3095       if (!m_codec.decode_receive_static_data_model(m_selector_delta_dm[0]))
3096         return false;
3097     }
3098
3099     if (m_pHeader->m_alpha_endpoints.m_num) {
3100       if (!m_codec.decode_receive_static_data_model(m_endpoint_delta_dm[1]))
3101         return false;
3102       if (!m_codec.decode_receive_static_data_model(m_selector_delta_dm[1]))
3103         return false;
3104     }
3105
3106     m_codec.stop_decoding();
3107
3108     return true;
3109   }
3110
3111   bool decode_palettes() {
3112     if (m_pHeader->m_color_endpoints.m_num) {
3113       if (!decode_color_endpoints())
3114         return false;
3115       if (!decode_color_selectors())
3116         return false;
3117     }
3118
3119     if (m_pHeader->m_alpha_endpoints.m_num) {
3120       if (!decode_alpha_endpoints())
3121         return false;
3122       if (!(m_pHeader->m_format == cCRNFmtETC2A ? decode_alpha_selectors_etc() : decode_alpha_selectors()))
3123         return false;
3124     }
3125
3126     return true;
3127   }
3128
3129   bool decode_color_endpoints() {
3130     const uint32 num_color_endpoints = m_pHeader->m_color_endpoints.m_num;
3131     const bool has_etc_color_blocks = m_pHeader->m_format == cCRNFmtETC1 || m_pHeader->m_format == cCRNFmtETC2 || m_pHeader->m_format == cCRNFmtETC2A;
3132
3133     if (!m_color_endpoints.resize(num_color_endpoints))
3134       return false;
3135
3136     if (!m_codec.start_decoding(m_pData + m_pHeader->m_color_endpoints.m_ofs, m_pHeader->m_color_endpoints.m_size))
3137       return false;
3138
3139     static_huffman_data_model dm[2];
3140     for (uint32 i = 0; i < (has_etc_color_blocks ? 1 : 2); i++)
3141       if (!m_codec.decode_receive_static_data_model(dm[i]))
3142         return false;
3143
3144     uint32 a = 0, b = 0, c = 0;
3145     uint32 d = 0, e = 0, f = 0;
3146
3147     uint32* CRND_RESTRICT pDst = &m_color_endpoints[0];
3148
3149     for (uint32 i = 0; i < num_color_endpoints; i++) {
3150       if (has_etc_color_blocks) {
3151         for (b = 0; b < 32; b += 8)
3152           a += m_codec.decode(dm[0]) << b;
3153         *pDst++ = a &= 0x1F1F1F1F;
3154       } else {
3155         a = (a + m_codec.decode(dm[0])) & 31;
3156         b = (b + m_codec.decode(dm[1])) & 63;
3157         c = (c + m_codec.decode(dm[0])) & 31;
3158         d = (d + m_codec.decode(dm[0])) & 31;
3159         e = (e + m_codec.decode(dm[1])) & 63;
3160         f = (f + m_codec.decode(dm[0])) & 31;
3161         *pDst++ = c | (b << 5U) | (a << 11U) | (f << 16U) | (e << 21U) | (d << 27U);
3162       }
3163     }
3164
3165     m_codec.stop_decoding();
3166
3167     return true;
3168   }
3169
3170   bool decode_color_selectors() {
3171     const bool has_etc_color_blocks = m_pHeader->m_format == cCRNFmtETC1 || m_pHeader->m_format == cCRNFmtETC2 || m_pHeader->m_format == cCRNFmtETC2A;
3172     m_codec.start_decoding(m_pData + m_pHeader->m_color_selectors.m_ofs, m_pHeader->m_color_selectors.m_size);
3173     static_huffman_data_model dm;
3174     m_codec.decode_receive_static_data_model(dm);
3175     m_color_selectors.resize(m_pHeader->m_color_selectors.m_num << (has_etc_color_blocks ? 1 : 0));
3176     for (uint32 s = 0, i = 0; i < m_pHeader->m_color_selectors.m_num; i++) {
3177       for (uint32 j = 0; j < 32; j += 4)
3178         s ^= m_codec.decode(dm) << j;
3179       if (has_etc_color_blocks) {
3180         for (uint32 selector = (~s & 0xAAAAAAAA) | (~(s ^ s >> 1) & 0x55555555), t = 8, h = 0; h < 4; h++, t -= 15) {
3181           for (uint32 w = 0; w < 4; w++, t += 4) {
3182             uint32 s0 = selector >> (w << 3 | h << 1);
3183             m_color_selectors[i << 1] |= ((s0 >> 1 & 1) | (s0 & 1) << 16) << (t & 15);
3184             uint32 s1 = selector >> (h << 3 | w << 1);
3185             m_color_selectors[i << 1 | 1] |= ((s1 >> 1 & 1) | (s1 & 1) << 16) << (t & 15);
3186           }
3187         }
3188       } else {
3189         m_color_selectors[i] = ((s ^ s << 1) & 0xAAAAAAAA) | (s >> 1 & 0x55555555);
3190       }
3191     }
3192     m_codec.stop_decoding();
3193     return true;
3194   }
3195
3196   bool decode_alpha_endpoints() {
3197     const uint32 num_alpha_endpoints = m_pHeader->m_alpha_endpoints.m_num;
3198
3199     if (!m_codec.start_decoding(m_pData + m_pHeader->m_alpha_endpoints.m_ofs, m_pHeader->m_alpha_endpoints.m_size))
3200       return false;
3201
3202     static_huffman_data_model dm;
3203     if (!m_codec.decode_receive_static_data_model(dm))
3204       return false;
3205
3206     if (!m_alpha_endpoints.resize(num_alpha_endpoints))
3207       return false;
3208
3209     uint16* CRND_RESTRICT pDst = &m_alpha_endpoints[0];
3210     uint32 a = 0, b = 0;
3211
3212     for (uint32 i = 0; i < num_alpha_endpoints; i++) {
3213       a = (a + m_codec.decode(dm)) & 255;
3214       b = (b + m_codec.decode(dm)) & 255;
3215       *pDst++ = (uint16)(a | (b << 8));
3216     }
3217
3218     m_codec.stop_decoding();
3219
3220     return true;
3221   }
3222
3223   bool decode_alpha_selectors() {
3224     m_codec.start_decoding(m_pData + m_pHeader->m_alpha_selectors.m_ofs, m_pHeader->m_alpha_selectors.m_size);
3225     static_huffman_data_model dm;
3226     m_codec.decode_receive_static_data_model(dm);
3227     m_alpha_selectors.resize(m_pHeader->m_alpha_selectors.m_num * 3);
3228     uint8 dxt5_from_linear[64];
3229     for (uint32 i = 0; i < 64; i++)
3230       dxt5_from_linear[i] = g_dxt5_from_linear[i & 7] | g_dxt5_from_linear[i >> 3] << 3;
3231     for (uint32 s0_linear = 0, s1_linear = 0, i = 0; i < m_alpha_selectors.size();) {
3232       uint32 s0 = 0, s1 = 0;
3233       for (uint32 j = 0; j < 24; s0 |= dxt5_from_linear[s0_linear >> j & 0x3F] << j, j += 6)
3234         s0_linear ^= m_codec.decode(dm) << j;
3235       for (uint32 j = 0; j < 24; s1 |= dxt5_from_linear[s1_linear >> j & 0x3F] << j, j += 6)
3236         s1_linear ^= m_codec.decode(dm) << j;
3237       m_alpha_selectors[i++] = s0;
3238       m_alpha_selectors[i++] = s0 >> 16 | s1 << 8;
3239       m_alpha_selectors[i++] = s1 >> 8;
3240     }
3241     m_codec.stop_decoding();
3242     return true;
3243   }
3244
3245   bool decode_alpha_selectors_etc() {
3246     m_codec.start_decoding(m_pData + m_pHeader->m_alpha_selectors.m_ofs, m_pHeader->m_alpha_selectors.m_size);
3247     static_huffman_data_model dm;
3248     m_codec.decode_receive_static_data_model(dm);
3249     m_alpha_selectors.resize(m_pHeader->m_alpha_selectors.m_num * 6);
3250     uint8 s_linear[8] = {};
3251     uint8* data = (uint8*)m_alpha_selectors.begin();
3252     for (uint i = 0; i < m_alpha_selectors.size(); i += 6, data += 12) {
3253       for (uint s_group = 0, p = 0; p < 16; p++) {
3254         s_group = p & 1 ? s_group >> 3 : s_linear[p >> 1] ^= m_codec.decode(dm);
3255         uint8 s = s_group & 7;
3256         if (s <= 3)
3257           s = 3 - s;
3258         uint8 d = 3 * (p + 1);
3259         uint8 byte_offset = d >> 3;
3260         uint8 bit_offset = d & 7;
3261         data[byte_offset] |= s << (8 - bit_offset);
3262         if (bit_offset < 3)
3263           data[byte_offset - 1] |= s >> bit_offset;
3264         d += 9 * ((p & 3) - (p >> 2));
3265         byte_offset = d >> 3;
3266         bit_offset = d & 7;
3267         data[byte_offset + 6] |= s << (8 - bit_offset);
3268         if (bit_offset < 3)
3269           data[byte_offset + 5] |= s >> bit_offset;
3270       }
3271     }
3272     m_codec.stop_decoding();
3273     return true;
3274   }
3275   
3276   static inline uint32 tiled_offset_2d_outer(uint32 y, uint32 AlignedWidth, uint32 LogBpp) {
3277     uint32 Macro = ((y >> 5) * (AlignedWidth >> 5)) << (LogBpp + 7);
3278     uint32 Micro = ((y & 6) << 2) << LogBpp;
3279
3280     return Macro +
3281            ((Micro & ~15) << 1) +
3282            (Micro & 15) +
3283            ((y & 8) << (3 + LogBpp)) + ((y & 1) << 4);
3284   }
3285
3286   static inline uint32 tiled_offset_2d_inner(uint32 x, uint32 y, uint32 LogBpp, uint32 BaseOffset) {
3287     uint32 Macro = (x >> 5) << (LogBpp + 7);
3288     uint32 Micro = (x & 7) << LogBpp;
3289     uint32 Offset = BaseOffset + Macro + ((Micro & ~15) << 1) + (Micro & 15);
3290
3291     return ((Offset & ~511) << 3) + ((Offset & 448) << 2) + (Offset & 63) +
3292            ((y & 16) << 7) +
3293            (((((y & 8) >> 2) + (x >> 3)) & 3) << 6);
3294   }
3295
3296   static inline void limit(uint& x, uint n) {
3297     int v = x - n;
3298     int msk = (v >> 31);
3299     x = (x & msk) | (v & ~msk);
3300   }
3301
3302   bool unpack_dxt1(uint8** pDst, uint32 output_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3303     const uint32 num_color_endpoints = m_color_endpoints.size();
3304     const uint32 width = (output_width + 1) & ~1;
3305     const uint32 height = (output_height + 1) & ~1;
3306     const int32 delta_pitch_in_dwords = (output_pitch_in_bytes >> 2) - (width << 1);
3307
3308     if (m_block_buffer.size() < width)
3309       m_block_buffer.resize(width);
3310
3311     uint32 color_endpoint_index = 0;
3312     uint8 reference_group = 0;
3313
3314     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3315       uint32* pData = (uint32*)pDst[f];
3316       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3317         bool visible = y < output_height;
3318         for (uint32 x = 0; x < width; x++, pData += 2) {
3319           visible = visible && x < output_width;
3320           if (!(y & 1) && !(x & 1))
3321             reference_group = m_codec.decode(m_reference_encoding_dm);
3322           block_buffer_element &buffer = m_block_buffer[x];
3323           uint8 endpoint_reference;
3324           if (y & 1) {
3325             endpoint_reference = buffer.endpoint_reference;
3326           } else {
3327             endpoint_reference = reference_group & 3;
3328             reference_group >>= 2;
3329             buffer.endpoint_reference = reference_group & 3;
3330             reference_group >>= 2;
3331           }
3332           if (!endpoint_reference) {
3333             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3334             if (color_endpoint_index >= num_color_endpoints)
3335               color_endpoint_index -= num_color_endpoints;
3336             buffer.color_endpoint_index = color_endpoint_index;
3337           } else if (endpoint_reference == 1) {
3338             buffer.color_endpoint_index = color_endpoint_index;
3339           } else {
3340             color_endpoint_index = buffer.color_endpoint_index;
3341           }
3342           uint32 color_selector_index = m_codec.decode(m_selector_delta_dm[0]);
3343           if (visible) {
3344             pData[0] = m_color_endpoints[color_endpoint_index];
3345             pData[1] = m_color_selectors[color_selector_index];
3346           }
3347         }
3348       }
3349     }
3350     return true;
3351   }
3352
3353   bool unpack_dxt5(uint8** pDst, uint32 row_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3354     const uint32 num_color_endpoints = m_color_endpoints.size();
3355     const uint32 num_alpha_endpoints = m_alpha_endpoints.size();
3356     const uint32 width = (output_width + 1) & ~1;
3357     const uint32 height = (output_height + 1) & ~1;
3358     const int32 delta_pitch_in_dwords = (row_pitch_in_bytes >> 2) - (width << 2);
3359
3360     if (m_block_buffer.size() < width)
3361       m_block_buffer.resize(width);
3362
3363     uint32 color_endpoint_index = 0;
3364     uint32 alpha0_endpoint_index = 0;
3365     uint8 reference_group = 0;
3366
3367     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3368       uint32* pData = (uint32*)pDst[f];
3369       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3370         bool visible = y < output_height;
3371         for (uint32 x = 0; x < width; x++, pData += 4) {
3372           visible = visible && x < output_width;
3373           if (!(y & 1) && !(x & 1))
3374             reference_group = m_codec.decode(m_reference_encoding_dm);
3375           block_buffer_element &buffer = m_block_buffer[x];
3376           uint8 endpoint_reference;
3377           if (y & 1) {
3378             endpoint_reference = buffer.endpoint_reference;
3379           } else {
3380             endpoint_reference = reference_group & 3;
3381             reference_group >>= 2;
3382             buffer.endpoint_reference = reference_group & 3;
3383             reference_group >>= 2;
3384           }
3385           if (!endpoint_reference) {
3386             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3387             if (color_endpoint_index >= num_color_endpoints)
3388               color_endpoint_index -= num_color_endpoints;
3389             buffer.color_endpoint_index = color_endpoint_index;
3390             alpha0_endpoint_index += m_codec.decode(m_endpoint_delta_dm[1]);
3391             if (alpha0_endpoint_index >= num_alpha_endpoints)
3392               alpha0_endpoint_index -= num_alpha_endpoints;
3393             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3394           } else if (endpoint_reference == 1) {
3395             buffer.color_endpoint_index = color_endpoint_index;
3396             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3397           } else {
3398             color_endpoint_index = buffer.color_endpoint_index;
3399             alpha0_endpoint_index = buffer.alpha0_endpoint_index;
3400           }
3401           uint32 color_selector_index = m_codec.decode(m_selector_delta_dm[0]);
3402           uint32 alpha0_selector_index = m_codec.decode(m_selector_delta_dm[1]);
3403           if (visible) {
3404             const uint16* pAlpha0_selectors = &m_alpha_selectors[alpha0_selector_index * 3];
3405             pData[0] = m_alpha_endpoints[alpha0_endpoint_index] | (pAlpha0_selectors[0] << 16);
3406             pData[1] = pAlpha0_selectors[1] | (pAlpha0_selectors[2] << 16);
3407             pData[2] = m_color_endpoints[color_endpoint_index];
3408             pData[3] = m_color_selectors[color_selector_index];
3409           }
3410         }
3411       }
3412     }
3413     return true;
3414   }
3415
3416   bool unpack_dxn(uint8** pDst, uint32 row_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3417     const uint32 num_alpha_endpoints = m_alpha_endpoints.size();
3418     const uint32 width = (output_width + 1) & ~1;
3419     const uint32 height = (output_height + 1) & ~1;
3420     const int32 delta_pitch_in_dwords = (row_pitch_in_bytes >> 2) - (width << 2);
3421
3422     if (m_block_buffer.size() < width)
3423       m_block_buffer.resize(width);
3424
3425     uint32 alpha0_endpoint_index = 0;
3426     uint32 alpha1_endpoint_index = 0;
3427     uint8 reference_group = 0;
3428
3429     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3430       uint32* pData = (uint32*)pDst[f];
3431       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3432         bool visible = y < output_height;
3433         for (uint32 x = 0; x < width; x++, pData += 4) {
3434           visible = visible && x < output_width;
3435           if (!(y & 1) && !(x & 1))
3436             reference_group = m_codec.decode(m_reference_encoding_dm);
3437           block_buffer_element &buffer = m_block_buffer[x];
3438           uint8 endpoint_reference;
3439           if (y & 1) {
3440             endpoint_reference = buffer.endpoint_reference;
3441           } else {
3442             endpoint_reference = reference_group & 3;
3443             reference_group >>= 2;
3444             buffer.endpoint_reference = reference_group & 3;
3445             reference_group >>= 2;
3446           }
3447           if (!endpoint_reference) {
3448             alpha0_endpoint_index += m_codec.decode(m_endpoint_delta_dm[1]);
3449             if (alpha0_endpoint_index >= num_alpha_endpoints)
3450               alpha0_endpoint_index -= num_alpha_endpoints;
3451             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3452             alpha1_endpoint_index += m_codec.decode(m_endpoint_delta_dm[1]);
3453             if (alpha1_endpoint_index >= num_alpha_endpoints)
3454               alpha1_endpoint_index -= num_alpha_endpoints;
3455             buffer.alpha1_endpoint_index = alpha1_endpoint_index;
3456           } else if (endpoint_reference == 1) {
3457             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3458             buffer.alpha1_endpoint_index = alpha1_endpoint_index;
3459           } else {
3460             alpha0_endpoint_index = buffer.alpha0_endpoint_index;
3461             alpha1_endpoint_index = buffer.alpha1_endpoint_index;
3462           }
3463           uint32 alpha0_selector_index = m_codec.decode(m_selector_delta_dm[1]);
3464           uint32 alpha1_selector_index = m_codec.decode(m_selector_delta_dm[1]);
3465           if (visible) {
3466             const uint16* pAlpha0_selectors = &m_alpha_selectors[alpha0_selector_index * 3];
3467             const uint16* pAlpha1_selectors = &m_alpha_selectors[alpha1_selector_index * 3];
3468             pData[0] = m_alpha_endpoints[alpha0_endpoint_index] | (pAlpha0_selectors[0] << 16);
3469             pData[1] = pAlpha0_selectors[1] | (pAlpha0_selectors[2] << 16);
3470             pData[2] = m_alpha_endpoints[alpha1_endpoint_index] | (pAlpha1_selectors[0] << 16);
3471             pData[3] = pAlpha1_selectors[1] | (pAlpha1_selectors[2] << 16);
3472           }
3473         }
3474       }
3475     }
3476     return true;
3477   }
3478
3479   bool unpack_dxt5a(uint8** pDst, uint32 row_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3480     const uint32 num_alpha_endpoints = m_alpha_endpoints.size();
3481     const uint32 width = (output_width + 1) & ~1;
3482     const uint32 height = (output_height + 1) & ~1;
3483     const int32 delta_pitch_in_dwords = (row_pitch_in_bytes >> 2) - (width << 1);
3484
3485     if (m_block_buffer.size() < width)
3486       m_block_buffer.resize(width);
3487
3488     uint32 alpha0_endpoint_index = 0;
3489     uint8 reference_group = 0;
3490
3491     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3492       uint32* pData = (uint32*)pDst[f];
3493       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3494         bool visible = y < output_height;
3495         for (uint32 x = 0; x < width; x++, pData += 2) {
3496           visible = visible && x < output_width;
3497           if (!(y & 1) && !(x & 1))
3498             reference_group = m_codec.decode(m_reference_encoding_dm);
3499           block_buffer_element &buffer = m_block_buffer[x];
3500           uint8 endpoint_reference;
3501           if (y & 1) {
3502             endpoint_reference = buffer.endpoint_reference;
3503           } else {
3504             endpoint_reference = reference_group & 3;
3505             reference_group >>= 2;
3506             buffer.endpoint_reference = reference_group & 3;
3507             reference_group >>= 2;
3508           }
3509           if (!endpoint_reference) {
3510             alpha0_endpoint_index += m_codec.decode(m_endpoint_delta_dm[1]);
3511             if (alpha0_endpoint_index >= num_alpha_endpoints)
3512               alpha0_endpoint_index -= num_alpha_endpoints;
3513             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3514           } else if (endpoint_reference == 1) {
3515             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3516           } else {
3517             alpha0_endpoint_index = buffer.alpha0_endpoint_index;
3518           }
3519           uint32 alpha0_selector_index = m_codec.decode(m_selector_delta_dm[1]);
3520           if (visible) {
3521             const uint16* pAlpha0_selectors = &m_alpha_selectors[alpha0_selector_index * 3];
3522             pData[0] = m_alpha_endpoints[alpha0_endpoint_index] | (pAlpha0_selectors[0] << 16);
3523             pData[1] = pAlpha0_selectors[1] | (pAlpha0_selectors[2] << 16);
3524           }
3525         }
3526       }
3527     }
3528     return true;
3529   }
3530
3531   bool unpack_etc1(uint8** pDst, uint32 output_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3532     const uint32 num_color_endpoints = m_color_endpoints.size();
3533     const uint32 width = (output_width + 1) & ~1;
3534     const uint32 height = (output_height + 1) & ~1;
3535     const int32 delta_pitch_in_dwords = (output_pitch_in_bytes >> 2) - (width << 1);
3536
3537     if (m_block_buffer.size() < width << 1)
3538       m_block_buffer.resize(width << 1);
3539
3540     uint32 color_endpoint_index = 0, diagonal_color_endpoint_index = 0;
3541     uint8 reference_group = 0;
3542
3543     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3544       uint32* pData = (uint32*)pDst[f];
3545       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3546         bool visible = y < output_height;
3547         for (uint32 x = 0; x < width; x++, pData += 2) {
3548           visible = visible && x < output_width;
3549           block_buffer_element &buffer = m_block_buffer[x << 1];
3550           uint8 endpoint_reference, block_endpoint[4], e0[4], e1[4];
3551           if (y & 1) {
3552             endpoint_reference = buffer.endpoint_reference;
3553           } else {
3554             reference_group = m_codec.decode(m_reference_encoding_dm);
3555             endpoint_reference = (reference_group & 3) | (reference_group >> 2 & 12);
3556             buffer.endpoint_reference = (reference_group >> 2 & 3) | (reference_group >> 4 & 12);
3557           }
3558           if (!(endpoint_reference & 3)) {
3559             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3560             if (color_endpoint_index >= num_color_endpoints)
3561               color_endpoint_index -= num_color_endpoints;
3562             buffer.color_endpoint_index = color_endpoint_index;
3563           } else if ((endpoint_reference & 3) == 1) {
3564             buffer.color_endpoint_index = color_endpoint_index;
3565           } else if ((endpoint_reference & 3) == 3) {
3566             buffer.color_endpoint_index = color_endpoint_index = diagonal_color_endpoint_index;
3567           } else {
3568             color_endpoint_index = buffer.color_endpoint_index;
3569           }
3570           endpoint_reference >>= 2;
3571           *(uint32*)&e0 = m_color_endpoints[color_endpoint_index];
3572           uint32 selector_index = m_codec.decode(m_selector_delta_dm[0]);
3573           if (endpoint_reference) {
3574             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3575             if (color_endpoint_index >= num_color_endpoints)
3576               color_endpoint_index -= num_color_endpoints;
3577           }
3578           diagonal_color_endpoint_index = m_block_buffer[x << 1 | 1].color_endpoint_index;
3579           m_block_buffer[x << 1 | 1].color_endpoint_index = color_endpoint_index;
3580           *(uint32*)&e1 = m_color_endpoints[color_endpoint_index];
3581           if (visible) {
3582             uint32 flip = endpoint_reference >> 1 ^ 1, diff = 1;
3583             for (uint c = 0; diff && c < 3; c++)
3584               diff = e0[c] + 3 >= e1[c] && e1[c] + 4 >= e0[c] ? diff : 0;
3585             for (uint c = 0; c < 3; c++)
3586               block_endpoint[c] = diff ? e0[c] << 3 | ((e1[c] - e0[c]) & 7) : (e0[c] << 3 & 0xF0) | e1[c] >> 1;
3587             block_endpoint[3] = e0[3] << 5 | e1[3] << 2 | diff << 1 | flip;
3588             pData[0] = *(uint32*)&block_endpoint;
3589             pData[1] = m_color_selectors[selector_index << 1 | flip];
3590           }
3591         }
3592       }
3593     }
3594     return true;
3595   }
3596
3597   bool unpack_etc2a(uint8** pDst, uint32 output_pitch_in_bytes, uint32 output_width, uint32 output_height) {
3598     const uint32 num_color_endpoints = m_color_endpoints.size();
3599     const uint32 num_alpha_endpoints = m_alpha_endpoints.size();
3600     const uint32 width = (output_width + 1) & ~1;
3601     const uint32 height = (output_height + 1) & ~1;
3602     const int32 delta_pitch_in_dwords = (output_pitch_in_bytes >> 2) - (width << 2);
3603
3604     if (m_block_buffer.size() < width << 1)
3605       m_block_buffer.resize(width << 1);
3606
3607     uint32 color_endpoint_index = 0, diagonal_color_endpoint_index = 0, alpha0_endpoint_index = 0, diagonal_alpha0_endpoint_index = 0;
3608     uint8 reference_group = 0;
3609
3610     for (uint32 f = 0; f < m_pHeader->m_faces; f++) {
3611       uint32* pData = (uint32*)pDst[f];
3612       for (uint32 y = 0; y < height; y++, pData += delta_pitch_in_dwords) {
3613         bool visible = y < output_height;
3614         for (uint32 x = 0; x < width; x++, pData += 4) {
3615           visible = visible && x < output_width;
3616           block_buffer_element &buffer = m_block_buffer[x << 1];
3617           uint8 endpoint_reference, block_endpoint[4], e0[4], e1[4];
3618           if (y & 1) {
3619             endpoint_reference = buffer.endpoint_reference;
3620           } else {
3621             reference_group = m_codec.decode(m_reference_encoding_dm);
3622             endpoint_reference = (reference_group & 3) | (reference_group >> 2 & 12);
3623             buffer.endpoint_reference = (reference_group >> 2 & 3) | (reference_group >> 4 & 12);
3624           }
3625           if (!(endpoint_reference & 3)) {
3626             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3627             if (color_endpoint_index >= num_color_endpoints)
3628               color_endpoint_index -= num_color_endpoints;
3629             alpha0_endpoint_index += m_codec.decode(m_endpoint_delta_dm[1]);
3630             if (alpha0_endpoint_index >= num_alpha_endpoints)
3631               alpha0_endpoint_index -= num_alpha_endpoints;
3632             buffer.color_endpoint_index = color_endpoint_index;
3633             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3634           } else if ((endpoint_reference & 3) == 1) {
3635             buffer.color_endpoint_index = color_endpoint_index;
3636             buffer.alpha0_endpoint_index = alpha0_endpoint_index;
3637           } else if ((endpoint_reference & 3) == 3) {
3638             buffer.color_endpoint_index = color_endpoint_index = diagonal_color_endpoint_index;
3639             buffer.alpha0_endpoint_index = alpha0_endpoint_index = diagonal_alpha0_endpoint_index;
3640           } else {
3641             color_endpoint_index = buffer.color_endpoint_index;
3642             alpha0_endpoint_index = buffer.alpha0_endpoint_index;
3643           }
3644           endpoint_reference >>= 2;
3645           *(uint32*)&e0 = m_color_endpoints[color_endpoint_index];
3646           uint32 color_selector_index = m_codec.decode(m_selector_delta_dm[0]);
3647           uint32 alpha0_selector_index = m_codec.decode(m_selector_delta_dm[1]);
3648           if (endpoint_reference) {
3649             color_endpoint_index += m_codec.decode(m_endpoint_delta_dm[0]);
3650             if (color_endpoint_index >= num_color_endpoints)
3651               color_endpoint_index -= num_color_endpoints;
3652           }
3653           *(uint32*)&e1 = m_color_endpoints[color_endpoint_index];
3654           diagonal_color_endpoint_index = m_block_buffer[x << 1 | 1].color_endpoint_index;
3655           diagonal_alpha0_endpoint_index = m_block_buffer[x << 1 | 1].alpha0_endpoint_index;
3656           m_block_buffer[x << 1 | 1].color_endpoint_index = color_endpoint_index;
3657           m_block_buffer[x << 1 | 1].alpha0_endpoint_index = alpha0_endpoint_index;
3658           if (visible) {
3659             uint32 flip = endpoint_reference >> 1 ^ 1, diff = 1;
3660             for (uint c = 0; diff && c < 3; c++)
3661               diff = e0[c] + 3 >= e1[c] && e1[c] + 4 >= e0[c] ? diff : 0;
3662             for (uint c = 0; c < 3; c++)
3663               block_endpoint[c] = diff ? e0[c] << 3 | ((e1[c] - e0[c]) & 7) : (e0[c] << 3 & 0xF0) | e1[c] >> 1;
3664             block_endpoint[3] = e0[3] << 5 | e1[3] << 2 | diff << 1 | flip;
3665             const uint16* pAlpha0_selectors = &m_alpha_selectors[alpha0_selector_index * 6 + (flip ? 3 : 0)];
3666             pData[0] = m_alpha_endpoints[alpha0_endpoint_index] | pAlpha0_selectors[0] << 16;
3667             pData[1] = pAlpha0_selectors[1] | pAlpha0_selectors[2] << 16;
3668             pData[2] = *(uint32*)&block_endpoint;
3669             pData[3] = m_color_selectors[color_selector_index << 1 | flip];
3670           }
3671         }
3672       }
3673     }
3674     return true;
3675   }
3676
3677 };
3678
3679 crnd_unpack_context crnd_unpack_begin(const void* pData, uint32 data_size) {
3680   if ((!pData) || (data_size < cCRNHeaderMinSize))
3681     return NULL;
3682
3683   crn_unpacker* p = crnd_new<crn_unpacker>();
3684   if (!p)
3685     return NULL;
3686
3687   if (!p->init(pData, data_size)) {
3688     crnd_delete(p);
3689     return NULL;
3690   }
3691
3692   return p;
3693 }
3694
3695 bool crnd_get_data(crnd_unpack_context pContext, const void** ppData, uint32* pData_size) {
3696   if (!pContext)
3697     return false;
3698
3699   crn_unpacker* pUnpacker = static_cast<crn_unpacker*>(pContext);
3700
3701   if (!pUnpacker->is_valid())
3702     return false;
3703
3704   if (ppData)
3705     *ppData = pUnpacker->get_data();
3706
3707   if (pData_size)
3708     *pData_size = pUnpacker->get_data_size();
3709
3710   return true;
3711 }
3712
3713 bool crnd_unpack_level(
3714     crnd_unpack_context pContext,
3715     void** pDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes,
3716     uint32 level_index) {
3717   if ((!pContext) || (!pDst) || (dst_size_in_bytes < 8U) || (level_index >= cCRNMaxLevels))
3718     return false;
3719
3720   crn_unpacker* pUnpacker = static_cast<crn_unpacker*>(pContext);
3721
3722   if (!pUnpacker->is_valid())
3723     return false;
3724
3725   return pUnpacker->unpack_level(pDst, dst_size_in_bytes, row_pitch_in_bytes, level_index);