removing old file
diff --git a/spec/basis_spec.txt b/spec/basis_spec.txt
deleted file mode 100644
index ba9fa4b..0000000
--- a/spec/basis_spec.txt
+++ /dev/null
@@ -1,865 +0,0 @@
-Note: The latest specification is in the Basis Universal wiki, here:
-https://github.com/BinomialLLC/basis_universal/wiki/.basis-File-Format-and-ETC1S-Texture-Video-Specification
-
-File: basis_spec.txt
-Version 1.01
-
-1.0 Introduction
-----------------
-
-The Basis Universal GPU texture codec supports reading and writing ".basis" files. 
-The .basis file format supports ETC1S or UASTC 4x4 texture data.
-
-* ETC1S is a simplified subset of ETC1.
-
-The mode is always differential (diff bit=1), the Rd, Gd, and Bd color deltas 
-are always (0,0,0), and the flip bit is always set. ETC1S texture data is fully 
-compliant with all existing software and hardware ETC1 decoders. Existing encoders 
-can be easily modified to limit their output to ETC1S.
-
-* UASTC 4x4 is a 19 mode subset of the ASTC texture format. Its specification is 
-[here](https://github.com/BinomialLLC/basis_universal/wiki/UASTC-Texture-Specification). UASTC texture data can always be losslessly transcoded to ASTC.
-
-2.0 High-Level File Structure
------------------------------
-
-A .basis file consists of multiple sections. Apart from the header, which must always
-be at the start of the file, the other sections may appear in any order. 
-
-Here's the high level organization of a typical .basis file:
-
-* The file header
-* Optional ETC1S compressed endpoint/selector codebooks
-* Optional ETC1S Huffman table information
-* A required "slice" description array describing the resolutions and file offset/compressed sizes of each texture slice present in the file
-* 1 or more slices containing ETC1S or UASTC compressed texture data. 
-* For future expansion, the format supports an "extended" header which may be located anywhere in the file. This section contains .PNG-like chunked data. 
-
-3.0 File Enums
---------------
-
-// basis_file_header::m_tex_type
-enum basis_texture_type
-{
-  cBASISTexType2D = 0,     
-  cBASISTexType2DArray = 1,   
-  cBASISTexTypeCubemapArray = 2, 
-  cBASISTexTypeVideoFrames = 3, 
-  cBASISTexTypeVolume = 4,  
-  cBASISTexTypeTotal
-};
-
-// basis_slice_desc::flags
-enum basis_slice_desc_flags
-{
-  cSliceDescFlagsHasAlpha = 1,
-  cSliceDescFlagsFrameIsIFrame = 2   
-};
-
-// basis_file_header::m_tex_format 
-enum basis_tex_format
-{
-  cETC1S = 0,
-  cUASTC4x4 = 1
-};
-
-// basis_file_header::m_flags 
-enum basis_header_flags
-{
-  cBASISHeaderFlagETC1S = 1,
-  cBASISHeaderFlagYFlipped = 2,
-  cBASISHeaderFlagHasAlphaSlices = 4
-};
-
-4.0 File Structures
--------------------
-
-All individual members in all file structures are byte aligned and little endian. The structs 
-have no padding (i.e. they are declared with #pragma pack(1)).
-
-4.1 "basis_file_header" structure
----------------------------------
-
-The file header must always be at the beginning of the file.
-
-struct basis_file_header
-{
-  uint16      m_sig;              // 2 byte file signature
-  uint16      m_ver;              // File version
-  uint16      m_header_size;      // Header size in bytes, sizeof(basis_file_header) or 0x4D
-  uint16      m_header_crc16;     // CRC16/genibus of the remaining header data
-
-  uint32      m_data_size;        // The total size of all data after the header
-  uint16      m_data_crc16;       // The CRC16 of all data after the header
-
-  uint24      m_total_slices;     // The number of compressed slices 
-  uint24      m_total_images;     // The total # of images
-
-  byte        m_tex_format;       // enum basis_tex_format
-  uint16      m_flags;            // enum basis_header_flags
-  byte        m_tex_type;         // enum basis_texture_type
-  uint24      m_us_per_frame;     // Video: microseconds per frame
-
-  uint32      m_reserved;         // For future use
-  uint32      m_userdata0;        // For client use
-  uint32      m_userdata1;        // For client use
-
-  uint16      m_total_endpoints;          // ETC1S: The number of endpoints in the endpoint codebook 
-  uint32      m_endpoint_cb_file_ofs;     // ETC1S: The compressed endpoint codebook's file offset relative to the start of the file
-  uint24      m_endpoint_cb_file_size;    // ETC1S: The compressed endpoint codebook's size in bytes
-
-  uint16      m_total_selectors;          // ETC1S: The number of selectors in the selector codebook 
-  uint32      m_selector_cb_file_ofs;     // ETC1S: The compressed selector codebook's file offset relative to the start of the file
-  uint24      m_selector_cb_file_size;    // ETC1S: The compressed selector codebook's size in bytes
-
-  uint32      m_tables_file_ofs;          // ETC1S: The file offset of the compressed Huffman codelength tables.
-  uint32      m_tables_file_size;         // ETC1S: The file size in bytes of the compressed Huffman codelength tables.
-
-  uint32      m_slice_desc_file_ofs;      // The file offset to the slice description array, usually follows the header
-  uint32      m_extended_file_ofs;        // The file offset of the "extended" header and compressed data, for future use
-  uint32      m_extended_file_size;       // The file size in bytes of the "extended" header and compressed data, for future use
-};
-
-4.1.1 Details:
-
-* m_sig is always 'B' * 256 + 's', or 0x4273.
-* m_ver is currently always 0x10.
-* m_header_size is sizeof(basis_file_header). It's always 0x4D.
-* m_header_crc16 is the CRC-16 of the remaining header data. See the "CRC-16" section 5.0 below for more information.
-* m_data_size, m_data_crc16: The size of all data following the header, and its CRC-16.
-* m_total_slices: The total number of slices, from [1,2^24-1]
-* m_total_images: The total number of images (where one image can contain multiple mipmap levels, and each mipmap level is a different slice).
-* m_tex_format: basis_tex_format. Either cETC1S (0), or cUASTC4x4 (1).
-* m_flags: A combination of flags from the basis_header_flags enum.
-* m_tex_type: The texture type, from enum basis_texture_type
-* m_us_per_frame: Microseconds per frame, only valid for cBASISTexTypeVideoFrames texture types.
-* m_total_endpoints, m_endpoint_cb_file_ofs, m_endpoint_cb_file_size: Information about the compressed ETC1S endpoint codebook: The total # of entries, the offset to the compressed data, and the compressed data's size.
-* m_total_selectors, m_selector_cb_file_ofs, m_selector_cb_file_size: Information about the compressed ETC1S selector codebook: The total # of entries, the offset to the compressed data, and the compressed data's size.
-* m_tables_file_ofs, m_tables_file_size: The file offset and size of the compressed Huffman tables for ETC1S format files. 
-* m_slice_desc_file_ofs: The file offset to the array of slice description structures. There will be m_total_slices structures at this file offset.
-* m_extended_file_ofs, m_extended_file_size: The "extended" header, for future expansion. Currently unused.
-
-4.2 "basis_slice_desc" structure
---------------------------------
-
-struct basis_slice_desc
-{
-    uint24 m_image_index;  
-    uint8 m_level_index;   
-    uint8 m_flags;         
-
-    uint16 m_orig_width;   
-    uint16 m_orig_height;  
-
-    uint16 m_num_blocks_x; 
-    uint16 m_num_blocks_y; 
-
-    uint32 m_file_ofs;     
-    uint32 m_file_size;    
-
-    uint16 m_slice_data_crc16; 
-};
-
-4.2.1 Details:
-
-* m_image_index: The index of the source image provided to the encoder (will always appear in order from first to last, first image index is 0, no skipping allowed)
-* m_level_index: The mipmap level index (mipmaps will always appear from largest to smallest)
-* m_flags: enum basis_slice_desc_flags
-* m_orig_width: The original image width (may not be a multiple of 4 pixels)
-* m_orig_height: The original image height (may not be a multiple of 4 pixels)
-* m_num_blocks_x: The slice's block X dimensions. Each block is 4x4 pixels. The slice's pixel resolution may or may not be a power of 2.
-* m_num_blocks_y: The slice's block Y dimensions. 
-* m_file_ofs: Offset from the start of the file to the start of the slice's data
-* m_file_size: The size of the compressed slice data in bytes
-* m_slice_data_crc16: The CRC16 of the compressed slice data, for extra-paranoid use cases
-
-5.0 CRC-16 Function
--------------------
-
-.basis files use CRC-16/genibus(aka CRC-16 EPC, CRC-16 I-CODE, CRC-16 DARC) format CRC-16's. 
-
-Here's an example function in C++:
-
-uint16_t crc16(const void* r, size_t size, uint16_t crc)
-{
-  crc = ~crc;
-  const uint8_t* p = static_cast<const uint8_t*>(r);
-  for ( ; size; --size)
-  {
-    const uint16_t q = *p++ ^ (crc >> 8);
-    uint16_t k = (q >> 4) ^ q;
-    crc = (((crc << 8) ^ k) ^ (k << 5)) ^ (k << 12);
-  }
-
-  return static_cast<uint16_t>(~crc);
-}
-
-This function is called with 0 in the final "crc" parameter when computing CRC-16's of file data.
-
-6.0 Compressed Huffman Tables
------------------------------
-
-ETC1S format .basis files rely heavily on static [canonical Huffman
-prefix coding](https://en.wikipedia.org/wiki/Canonical_Huffman_code).  Multiple
-Huffman tables are used by each compressed section. Huffman codes are stored in
-each output byte in LSB to MSB order. (This is opposite of the JPEG format,
-which stores the codes in MSB to LSB order.)
-
-Huffman coding in .basis is compatible with the canonical Huffman methods used
-by Deflate encoders/decoders. Section 3.2.2 of [Deflate - RFC
-1951](https://tools.ietf.org/html/rfc1951), which describes how to compute the
-value of each Huffman code given an array of symbol codelengths. This document
-assumes familiarity with how Huffman coding works in Deflate.
-
-First, some enums:
-
-enum
-{
-    // Max supported Huffman code size is 16-bits
-    cHuffmanMaxSupportedCodeSize = 16, 
-
-    // The maximum number of symbols  is 2^14
-    cHuffmanMaxSymsLog2 = 14, 
-    cHuffmanMaxSyms = 1 << cHuffmanMaxSymsLog2,
-
-    // Small zero runs may range from 3-10 entries
-    cHuffmanSmallZeroRunSizeMin = 3, 
-    cHuffmanSmallZeroRunSizeMax = 10, 
-    cHuffmanSmallZeroRunExtraBits = 3,
-
-    // Big zero runs may range from 11-138 entries
-    cHuffmanBigZeroRunSizeMin = 11, 
-    cHuffmanBigZeroRunSizeMax = 138, 
-    cHuffmanBigZeroRunExtraBits = 7,
-
-    // Small non-zero runs may range from 3-6 entries
-    cHuffmanSmallRepeatSizeMin = 3, 
-    cHuffmanSmallRepeatSizeMax = 6, 
-    cHuffmanSmallRepeatExtraBits = 2,
-
-    // Big non-zero run may range from 7-134 entries
-    cHuffmanBigRepeatSizeMin = 7, 
-    cHuffmanBigRepeatSizeMax = 134, 
-    cHuffmanBigRepeatExtraBits = 7,
-
-    // There are a maximum of 21 symbols in a compressed Huffman code length table.
-    cHuffmanTotalCodelengthCodes = 21, 
-    
-    // Symbols [0,16] indicate code sizes. Other symbols indicate zero runs or repeats:
-    cHuffmanSmallZeroRunCode = 17, 
-    cHuffmanBigZeroRunCode = 18, 
-    cHuffmanSmallRepeatCode = 19, 
-    cHuffmanBigRepeatCode = 20
-};
-
-A .basis Huffman table consists of 1 to cHuffmanMaxSyms symbols. Each compressed
-Huffman table is described by an array of symbol code lengths in bits.
-
-The table's symbol code lengths are themselves RLE+Huffman coded, just like
-Deflate. (Note this can be confusing to developers unfamiliar with Deflate.)
-Each table begins with a small fixed header:
-
-    14 bits: total_used_syms [1, cHuffmanMaxSyms]
-    5 bits: num_codelength_codes [1, cHuffmanTotalCodelengthCodes]
-    
-Next, the code lengths for the small Huffman table which is used to send the compressed codelengths (and RLE/repeat codes) are sent uncompressed but in a reordered manner:
-    
-    3*num_codelength_codes bits: Code size of each Huffman symbol for the compressed Huffman codelength table.
-    
-    These code lengths are sent in this order (to help reduce the number that must be sent):
-    
-    { 
-        cHuffmanSmallZeroRunCode, cHuffmanBigZeroRunCode, cHuffmanSmallRepeatCode, cHuffmanBigRepeatCode, 
-        0, 8, 7, 9, 6, 0xA, 5, 0xB, 4, 0xC, 3, 0xD, 2, 0xE, 1, 0xF, 0x10 
-    };
-            
-A canonical Huffman decoding table (of up to 21 symbols) should be built from
-these code lengths. Immediately following this data are the Huffman symbols
-(sometimes intermixed with raw bits) which describe how to unpack the
-codelengths of each symbol in the Huffman table:
-
-    - Symbols [0,16] indicate a specific symbol code length in bits.
-    
-    - Symbol cHuffmanSmallZeroRunCode (17) indicates a short run of symbols with 0 bit code lengths.
-      cHuffmanSmallZeroRunExtraBits (3) bits are sent after this symbol, which indicates the run's size after adding the minimum size (cHuffmanSmallZeroRunSizeMin).
-      
-    - Symbol cHuffmanBigZeroRunCode (18) indicates a long run of symbols with 0 bit code lengths. 
-      cHuffmanBigZeroRunExtraBits (7) bits are sent after this symbol, which indicates the run's size after adding the minimum size (cHuffmanBigZeroRunSizeMin)
-
-    - Symbol cHuffmanSmallRepeatCode (19) indicates a short run of symbols that repeat the previous symbol's code length.
-      cHuffmanSmallRepeatExtraBits (2) bits are sent after this symbol, which indicates the number of times to repeat the previous symbol's code length, 
-      after adding the minimum size (cHuffmanSmallRepeatSizeMin).
-      Cannot be the first symbol, and the previous symbol cannot have a code length of 0.
-      
-    - Symbol cHuffmanBigRepeatCode (20) indicates a short run of symbols that repeat the previous symbol's code length.
-      cHuffmanBigRepeatExtraBits (7) bits are sent after this symbol, which indicates the number of times to repeat the previous symbol's code length,
-      after adding the minimum size (cHuffmanBigRepeatSizeMin).
-      Cannot be the first symbol, and the previous symbol cannot have a code length of 0.
-      
-There should be exactly total_used_syms code lengths stored in the compressed Huffman table. If not the stream is either corrupted or invalid.
-
-After all the symbol codelengths are uncompressed, the symbol codes can be computed and the canonical Huffman decoding tables can be built.
-
-7.0 ETC1S Endpoint Codebooks
-----------------------------
-
-The endpoint codebook section starts at file offset
-basis_file_header::m_endpoint_cb_file_ofs and is m_endpoint_cb_file_size bytes
-long. The endpoint codebook will have basis_file_header::m_total_endpoints total
-entries.
-
-At the beginning of the compressed endpoint codebook section are four compressed
-Huffman tables, stored using the procedure outlined in section 6.0. The Huffman tables
-appear in this order:
-
-    1. color5_delta_model0
-    2. color5_delta_model1
-    3. color5_delta_model2
-    4. inten_delta_model
-
-Following the data for these Huffman tables is a single 1-bit code which
-indicates if the color endpoint codebook is grayscale or not. 
-
-Immediately following this code is the compressed color endpoint codebook data. 
-A simple form of DPCM (Delta Pulse Code Modulation) coding is used to send the
-ETC1S intensity table indices and color values. Here is the procedure to decode
-the endpoint codebook:
-
-    const int COLOR5_PAL0_PREV_HI = 9, COLOR5_PAL0_DELTA_LO = -9, COLOR5_PAL0_DELTA_HI = 31;
-    const int COLOR5_PAL1_PREV_HI = 21, COLOR5_PAL1_DELTA_LO = -21, COLOR5_PAL1_DELTA_HI = 21;
-    const int COLOR5_PAL2_PREV_HI = 31, COLOR5_PAL2_DELTA_LO = -31, COLOR5_PAL2_DELTA_HI = 9;
-
-    // Assume previous endpoint color is (16, 16, 16), and the previous intensity is 0.
-    color32 prev_color5(16, 16, 16, 0);
-    uint32_t prev_inten = 0;
-
-    // For each endpoint codebook entry
-    for (uint32_t i = 0; i < num_endpoints; i++)
-    {
-        // Decode the intensity delta Huffman code
-        uint32_t inten_delta = decode_huffman(inten_delta_model);
-        endpoints[i].m_inten5 = static_cast<uint8_t>((inten_delta + prev_inten) & 7);
-        prev_inten = endpoints[i].m_inten5;
-
-        // Now decode the endpoint entry's color or intensity value
-        for (uint32_t c = 0; c < (endpoints_are_grayscale ? 1U : 3U); c++)
-        {
-            // The Huffman table used to decode the delta depends on the previous color's value
-            int delta;
-            if (prev_color5[c] <= basist::COLOR5_PAL0_PREV_HI)
-                delta = decode_huffman(color5_delta_model0);
-            else if (prev_color5[c] <= basist::COLOR5_PAL1_PREV_HI)
-                delta = decode_huffman(color5_delta_model1);
-            else
-                delta = decode_huffman(color5_delta_model2);
-
-            // Apply the delta
-            int v = (prev_color5[c] + delta) & 31;
-
-            endpoints[i].m_color5[c] = static_cast<uint8_t>(v);
-
-            prev_color5[c] = static_cast<uint8_t>(v);
-        }
-
-        // If the endpoints are grayscale, set G and B to match R.
-        if (endpoints_are_grayscale)
-        {
-            endpoints[i].m_color5[1] = endpoints[i].m_color5[0];
-            endpoints[i].m_color5[2] = endpoints[i].m_color5[0];
-        }
-    }
-
-The rest of the section's data (if any) can be ignored.
-
-8.0 ETC1S Selector Codebooks
-----------------------------
-
-The selector codebook section starts at file offset
-basis_file_header::m_selector_cb_file_ofs and is m_selector_cb_file_size bytes
-long. The selector codebook will have basis_file_header::m_total_selectors total
-entries.
-
-The first bit of this section indicates if "global" selector codebooks are used.
-Basis Universal doesn't currently utilize global selector codebooks, so this bit
-should always be 0.
-
-The second bit of this section indicates if "hybrid" global/local selector
-codebooks are used. Hybrid codebooks are not supported either, so this bit
-should always be 0.
-
-The third bit indicates if the selector codebook has been sent in raw form
-(uncompressed). If it's set, each selector is sent as four 8-bit bytes. Each
-byte corresponds to four 2-bit ETC1S selectors. The first selector of each group
-of 4 selectors starts at the LSB (least significant bit) of each byte, and is
-2-bits wide.
-
-If the third bit is 0, the selectors have been DPCM coded with Huffman coding. 
-The "delta_selector_pal_model" Huffman table will immediately follow the third
-bit, and is stored using the procedure outlined in section 6.0.
-
-Immediately following the Huffman table is the compressed selector codebook. 
-Here is the DPCM decoding procedure:
-
-        uint8_t prev_bytes[4] = { 0, 0, 0, 0 };
-
-        for (uint32_t i = 0; i < num_selectors; i++)
-        {
-            if (!i)
-            {
-                // First selector is sent raw
-                for (uint32_t j = 0; j < 4; j++)
-                {
-                    uint32_t cur_byte = get_bits(8);
-                    prev_bytes[j] = static_cast<uint8_t>(cur_byte);
-
-                    for (uint32_t k = 0; k < 4; k++)
-                        selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
-                }
-                selectors[i].init_flags();
-                continue;
-            }
-
-            // Subsequent selectors are sent with a simple form of byte-wise DPCM coding.
-            for (uint32_t j = 0; j < 4; j++)
-            {
-                int delta_byte = decode_huffman(delta_selector_pal_model);
-
-                uint32_t cur_byte = delta_byte ^ prev_bytes[j];
-                prev_bytes[j] = static_cast<uint8_t>(cur_byte);
-
-                for (uint32_t k = 0; k < 4; k++)
-                    selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
-            }
-        }
-
-Any bytes in this section following the selector codebook bits can be safely ignored.
-
-9.0 ETC1S Compressed Slice Decoding Huffman Tables
---------------------------------------------------
-
-Each ETC1S slice is compressed with four Huffman tables stored using the
-procedure outlined in section 6.0. These Huffman tables are stored at file
-offset basis_file_header::m_tables_file_ofs. This section will be 
-basis_file_header::m_tables_file_size bytes long.
-
-The following four Huffman tables are sent, in this order:
-
-    1. endpoint_pred_model
-    2. delta_endpoint_model
-    3. selector_model
-    4. selector_history_buf_rle_model
-
-Following the last Huffman table are 13-bits indicating the size of the selector
-history buffer. Any remaining bits may be safely ignored.
-
-10. ETC1S Slice Decoding
-------------------------
-
-ETC1S slices consist of a compressed 2D array of ETC1S blocks, always compressed
-in top-down/left-right raster order. For texture video, the previous slice's
-already decoded contents may be referred to when blocks are encoded using
-Conditional Replenishment (also known as "skip blocks"). 
-
-Each ETC1S block is encoded by using references to the color endpoint codebook
-and the selector codebook. Sections 10.1 and 10.2 describe the helper procedures
-using by the decoder, and section 10.3 describes how the array of ETC1S blocks
-is actually decoded.
-
-10.1 ETC1S Approximate Move to Front Routines
----------------------------------------------
-
-An approximate Move to Front (MTF) approach is used to efficiently encode the
-selector codebook references. Here is the C++ example class for approximate MTF
-decoding:
-
-    class approx_move_to_front
-    {
-    public:
-        approx_move_to_front(uint32_t n)
-        {
-            init(n);
-        }
-
-        void init(uint32_t n)
-        {
-            m_values.resize(n);
-            m_rover = n / 2;
-        }
-
-        size_t size() const { return m_values.size(); }
-
-        const int& operator[] (uint32_t index) const { return m_values[index]; }
-              int operator[] (uint32_t index)        { return m_values[index]; }
-
-        void add(int new_value)
-        {
-            m_values[m_rover++] = new_value;
-            if (m_rover == m_values.size())
-                m_rover = (uint32_t)m_values.size() / 2;
-        }
-
-        void use(uint32_t index)
-        {
-            if (index)
-            {
-                int x = m_values[index / 2];
-                int y = m_values[index];
-                m_values[index / 2] = y;
-                m_values[index] = x;
-            }
-        }
-        
-    private:
-        std::vector<int> m_values;
-        uint32_t m_rover;
-    };
-
-10.2 ETC1S VLC Decoding Procedure
----------------------------------
-
-ETC1S slice decoding utilizes a simple Variable Length Coding (VLC) scheme that
-sends raw bits using variable-size chunks. Here is the VLC decoding procedure:
-
-    uint32_t decode_vlc(uint32_t chunk_bits)
-    {
-        assert(chunk_bits);
-
-        const uint32_t chunk_size = 1 << chunk_bits;
-        const uint32_t chunk_mask = chunk_size - 1;
-                
-        uint32_t v = 0;
-        uint32_t ofs = 0;
-
-        for ( ; ; )
-        {
-            uint32_t s = get_bits(chunk_bits + 1);
-            v |= ((s & chunk_mask) << ofs);
-            ofs += chunk_bits;
-
-            if ((s & chunk_size) == 0)
-                break;
-            
-            if (ofs >= 32)
-            {
-                assert(0);
-                break;
-            }
-        }
-
-        return v;
-    }
-
-10.3 ETC1S Slice Block Decoding
--------------------------------
-
-Each slice has a corresponding "basis_slice_desc" structure, described in section
-4.2. The slice's dimensions in ETC1S blocks are stored in
-basis_slice_desc::m_num_blocks_x and basis_slice_desc::m_num_blocks_y. Each
-slice is located at file offset basis_slice_desc::m_file_ofs, and is
-basis_slice_desc::m_file_size bytes long.
-
-The decoder iterates through all the slice blocks in top-down, left-right raster
-order. Each block is represented by an index into the color endpoint codebook
-and another index into the selector endpoint codebook. The endpoint codebook
-contains each ETC1S block's base RGB color and intensity table information, and
-the selector codebook contains the 4x4 texel selector entry (which are 2-bits
-each) information. This is all the information needed to fully represent the
-texels within each block.
-
-The decoding procedure loops over all the blocks in raster order, and decodes
-the endpoint and selector indices used to represent each block. The decoding
-procedure is complex enough that commented code is best used to describe it.
-
-Here's the slice decoding procedure. This block of code shows the block loop,
-and how endpoint codebook indices are decoded. The next block of code shows how
-selector codebook indices are decoded.
-
-    // Constants used by the decoder
-    const uint32_t ENDPOINT_PRED_TOTAL_SYMBOLS = (4 * 4 * 4 * 4) + 1;
-    const uint32_t ENDPOINT_PRED_REPEAT_LAST_SYMBOL = ENDPOINT_PRED_TOTAL_SYMBOLS - 1;
-    const uint32_t ENDPOINT_PRED_MIN_REPEAT_COUNT = 3;
-    const uint32_t ENDPOINT_PRED_COUNT_VLC_BITS = 4;
-
-    const uint32_t NUM_ENDPOINT_PREDS = 3;
-    const uint32_t CR_ENDPOINT_PRED_INDEX = NUM_ENDPOINT_PREDS - 1;
-    const uint32_t NO_ENDPOINT_PRED_INDEX = 3;
-    
-    // Endpoint/selector codebooks - decoded previously. See sections 7.0 and 8.0.
-    endpoint endpoints[endpoint_codebook_size];
-    selector selectors[selector_codebook_size]; 
-    
-    // Array of per-block values used for endpoint index prediction (enough for 2 rows).
-    struct block_preds
-    {
-        uint16_t m_endpoint_index;
-        uint8_t m_pred_bits;
-    };
-    block_preds block_endpoint_preds[2][num_blocks_x];
-    
-    // Some constants and state used during block decoding
-    const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = selector_codebook_size;
-    const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = selector_history_buf_size + SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX;
-    uint32_t cur_selector_rle_count = 0;
-    
-    uint32_t cur_pred_bits = 0;
-    int prev_endpoint_pred_sym = 0;
-    int endpoint_pred_repeat_count = 0;
-    uint32_t prev_endpoint_index = 0;
-
-    // This array is only used for texture video. It holds the previous frame's endpoint and selector indices (each 16-bits, for 32-bits total).
-    uint32_t prev_frame_indices[num_blocks_x][num_blocks_y]; 
-    
-    // Selector history buffer - See section 10.1.
-    // For the selector history buffer's size, see section 9.0. 
-    approx_move_to_front selector_history_buf(selector_history_buf_size);
-
-    // Loop over all slice blocks in raster order
-    for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
-    {
-        // The index into the block_endpoint_preds array
-        const uint32_t cur_block_endpoint_pred_array = block_y & 1;
-
-        for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
-        {
-            // Check if we're at the start of a 2x2 block group.
-            if ((block_x & 1) == 0)
-            {
-                // Are we on an even or odd row of blocks?
-                if ((block_y & 1) == 0)
-                {
-                    // We're on an even row and column of blocks. Decode the combined endpoint index predictor symbols for 2x2 blocks.
-                    // This symbol tells the decoder how the endpoints are decoded for each block in a 2x2 group of blocks.
-                                        
-                    // Are we in an RLE run?
-                    if (endpoint_pred_repeat_count)
-                    {
-                        // Inside a run of endpoint predictor symbols.
-                        endpoint_pred_repeat_count--;
-                        cur_pred_bits = prev_endpoint_pred_sym;
-                    }
-                    else
-                    {
-                        // Decode the endpoint prediction symbol, using the "endpoint pred" Huffman table (see section 9.0).
-                        cur_pred_bits = decode_huffman(m_endpoint_pred_model);
-                        if (cur_pred_bits == ENDPOINT_PRED_REPEAT_LAST_SYMBOL)
-                        {
-                            // It's a run of symbols, so decode the count using VLC decoding (see section 10.2)
-                            endpoint_pred_repeat_count = decode_vlc(ENDPOINT_PRED_COUNT_VLC_BITS) + ENDPOINT_PRED_MIN_REPEAT_COUNT - 1;
-
-                            cur_pred_bits = prev_endpoint_pred_sym;
-                        }
-                        else
-                        {
-                            // It's not a run of symbols
-                            prev_endpoint_pred_sym = cur_pred_bits;
-                        }
-                    }
-
-                    // The symbol has enough endpoint prediction information for 4 blocks (2 bits per block), so 8 bits total. 
-                    // Remember the prediction information we should use for the next row of 2 blocks beneath the current block.
-                    block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x].m_pred_bits = (uint8_t)(cur_pred_bits >> 4);
-                }
-                else
-                {
-                    // We're on an odd row of blocks, so use the endpoint prediction information we previously stored on the previous even row.
-                    cur_pred_bits = block_endpoint_preds[cur_block_endpoint_pred_array][block_x].m_pred_bits;
-                }
-            }
-            
-            // Decode the current block's endpoint and selector indices.
-            uint32_t endpoint_index, selector_index = 0;
-
-            // Get the 2-bit endpoint prediction index for this block.
-            const uint32_t pred = cur_pred_bits & 3;
-
-            // Get the next block's endpoint prediction bits ready.
-            cur_pred_bits >>= 2;            
-            
-            // Now check to see if we should reuse a previously encoded block's endpoints.
-            if (pred == 0)
-            {
-                // Reuse the left block's endpoint index
-                assert(block_x > 0);
-                endpoint_index = prev_endpoint_index;
-            }
-            else if (pred == 1)
-            {
-                // Reuse the upper block's endpoint index
-                assert(block_y > 0)
-                endpoint_index = block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x].m_endpoint_index;
-            }
-            else if (pred == 2)
-            {
-                if (is_video)
-                {
-                    // If it's texture video, reuse the previous frame's endpoint index, at this block.
-                    assert(pred == CR_ENDPOINT_PRED_INDEX);
-                    endpoint_index = prev_frame_indices[block_x][block_y];
-                    selector_index = endpoint_index >> 16;
-                    endpoint_index &= 0xFFFFU;
-                }
-                else
-                {
-                    // Reuse the upper left block's endpoint index.
-                    assert((block_x > 0) && (block_y > 0));
-                    endpoint_index = block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x - 1].m_endpoint_index;
-                }
-            }
-            else
-            {
-                // We need to decode and apply a DPCM encoded delta to the previously used endpoint index.
-                // This uses the delta endpoint Huffman table (see section 9.0).
-                const uint32_t delta_sym = decode_huffman(delta_endpoint_model);
-
-                endpoint_index = delta_sym + prev_endpoint_index;
-                
-                // Wrap around if the index goes beyond the end of the endpoint codebook
-                if (endpoint_index >= endpoints.size())
-                    endpoint_index -= (int)endpoints.size();
-            }
-
-            // Remember the endpoint index we used on this block, so the next row can potentially reuse the index.
-            block_endpoint_preds[cur_block_endpoint_pred_array][block_x].m_endpoint_index = (uint16_t)endpoint_index;
-
-            // Remember the endpoint index used
-            prev_endpoint_index = endpoint_index;
-            
-            // Now we have fully decoded the ETC1S endpoint codebook index, in endpoint_index. 
-            
-            // Now decode the selector index (see the next block of code, below).
-            < selector decoding - see below >
-            
-        } // block_x
-    } // block_y
-
-The compressed format allows the encoder to reuse the endpoint index used by
-the previous block, the block immediately above the current block, or the
-block to the upper left (if the file is not texture video). Alternately, the
-encoder can send a Huffman coded DPCM encoded index relative to the
-previously used endpoint index.
-
-Which type of prediction was used by the encoder is controlled by the "endpoint
-pred" (endpoint prediction) indices, which are sent with Huffman coding (using
-the "endpoint_pred_model" table described in Section 9.0) once every 2x2 blocks.
-
-For texture video, the endpoint prediction symbol normally used to refer to the
-upper left block (endpoint pred index 2) instead indicates that both the
-endpoint and selector indices from the previous frame's block should be reused
-on the current frame's block. The endpoint pred indices are RLE coded, so this
-allows the encoder to efficiently skip over a large number of unchanged blocks
-in a video sequence.
-
-The code to decode the selector codebook index immediately follows the code above for decoding the endpoint indices:
-
-    const uint32_t MAX_SELECTOR_HISTORY_BUF_SIZE = 64;
-    const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH = 3;
-    const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_BITS = 6;
-    const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL = (1 << SELECTOR_HISTORY_BUF_RLE_COUNT_BITS);
-
-    // Decode selector index, unless it's texture video and the endpoint predictor indicated that the 
-    // block's endpoints were reused from the previous frame.
-    if ((!is_video) || (pred != CR_ENDPOINT_PRED_INDEX))
-    {
-        int selector_sym;
-
-        // Are we in a selector RLE run?
-        if (cur_selector_rle_count > 0)
-        {
-            // Handle selector RLE run.
-            cur_selector_rle_count--;
-
-            selector_sym = (int)selectors.size();
-        }
-        else
-        {
-            // Decode the selector symbol, using the selector Huffman table (see section 9.0).
-            selector_sym = decode_huffman(m_selector_model);
-
-            // Is it a run?
-            if (selector_sym == static_cast<int>(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX))
-            {
-                // Decode the selector run's size, using the selector history buf RLE Huffman table (see section 9.0).
-                int run_sym = decode_huffman(selector_history_buf_rle_model);
-
-                // Is it a very long run?
-                if (run_sym == (SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
-                    cur_selector_rle_count = decode_vlc(7) + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
-                else
-                    cur_selector_rle_count = run_sym + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
-
-                selector_sym = (int)selectors.size();
-
-                cur_selector_rle_count--;
-            }
-        }
-
-        // Is it a reference into the selector history buffer?
-        if (selector_sym >= (int)selectors.size())
-        {
-            assert(m_selector_history_buf_size > 0);
-
-            // Compute the history buffer index
-            int history_buf_index = selector_sym - (int)selectors.size();
-
-            assert(history_buf_index < selector_history_buf.size());
-
-            // Access the history buffer
-            selector_index = selector_history_buf[history_buf_index];
-
-            // Update the history buffer
-            if (history_buf_index != 0)
-                selector_history_buf.use(history_buf_index);
-        }
-        else
-        {
-            // It's an index into the selector codebook
-            selector_index = selector_sym;
-
-            // Add it to the selector history buffer
-            if (m_selector_history_buf_size)
-                selector_history_buf.add(selector_index);
-        }
-    }
-        
-    // For texture video, remember the endpoint and selector indices used by the block on this frame, for later reuse on the next frame.
-    if (is_video)
-        prev_frame_indices[block_x][block_y] = endpoint_index | (selector_index << 16);
-
-    // The block is fully decoded here. The codebook indices are endpoint_index and selector_index.
-    // Make sure they are valid
-    assert((endpoint_index < endpoints.size()) && (selector_index < selectors.size()));
-
-At this point, the decoder has decoded each block's endpoint and selector codebook indices.
-It can now fetch the actual ETC1S endpoints/selectors from the codebooks and write out ETC1S
-texture data, or it can immedately transcode the ETC1S data to another GPU texture format.
-
-11.0 Alpha Channels in ETC1S Format Files
------------------------------------------
-
-ETC1S .basis files can have optional alpha channels, stored in odd slices. If any slice needs an alpha channel, 
-all slices must have alpha channels. basis_file_header::m_flags will be logically OR'd with 
-cBASISHeaderFlagHasAlphaSlices. Alpha channel ETC1S files will contain two slices for each mipmap level 
-(or face, or video frame, etc.). The basis_slice_desc::m_flags field will be logically OR'd with 
-cSliceDescFlagsHasAlpha for all odd alpha slices. 
-
-The even slices will contain the RGB data, and the odd slices will contain the alpha data, both stored in ETC1S 
-format. Alpha channel ETC1S files must always have an even total number of slices. A decoder can first decode 
-the RGB data slice, then the next alpha channel slice, or it can decode them in parallel using multithreading. 
-The ETC1S green channel (on the odd slices) contains the alpha values.
-
-12.0 Texture Video
-------------------
-
-Both ETC1S and UASTC format files support texture video. Texture video files can be optionally mipmapped, and can
-contain optional alpha channels (stored as separate slices in ETC1S format files). Currently, the first frame is 
-always an i-frame, and all subsequent frames are p-frames, but the file format and transcoder supports any 
-frame being an i-frame (and the encoder will be enhanced to support this feature). Decoders must track the previously 
-decoded frame's endpoints/selectors for all mipmap levels (if any), not just the top level's.
-
-Skip blocks always refer to the previous frame. i-frames cannot use skip blocks (encoded as endpoint predictor index 2).
-
-12.0 Example Bitstreams
------------------------
-
-This section will include several example .basis file bitstreams, along with their decoded equivalents, which should be helpful for new decoder verification.
-