TNode * AddToTrie(TNode * root, TReader & bitEncoding, uint32_t numBits) { ReaderSource<TReader> src(bitEncoding); // String size. ReadVarUint<uint32_t, ReaderSource<TReader>>(src); BitReader<ReaderSource<TReader>> bitReader(src); auto cur = root; for (uint32_t i = 0; i < numBits; ++i) { auto nxt = bitReader.Read(1) == 0 ? &cur->l : &cur->r; if (!*nxt) *nxt = new TNode(); cur = *nxt; } return cur; }
/*Table 14: Entry-point layer bitstream for Advanced Profile*/ bool Parser::parseEntryPointHeader(const uint8_t* data, uint32_t size) { uint8_t i; BitReader bitReader(data, size); m_entryPointHdr.broken_link = bitReader.read(1); m_entryPointHdr.closed_entry = bitReader.read(1); m_entryPointHdr.panscan_flag = bitReader.read(1); m_entryPointHdr.reference_distance_flag = bitReader.read(1); m_entryPointHdr.loopfilter = bitReader.read(1); m_entryPointHdr.fastuvmc = bitReader.read(1); m_entryPointHdr.extended_mv = bitReader.read(1); m_entryPointHdr.dquant = bitReader.read(2); m_entryPointHdr.variable_sized_transform_flag = bitReader.read(1); m_entryPointHdr.overlap = bitReader.read(1); m_entryPointHdr.quantizer = bitReader.read(2); if (m_seqHdr.hrd_param_flag) { for (i = 0; i < m_seqHdr.hrd_param.hrd_num_leaky_buckets; i++) m_entryPointHdr.hrd_full[i] = bitReader.read(8); } m_entryPointHdr.coded_size_flag = bitReader.read(1); if (m_entryPointHdr.coded_size_flag) { m_entryPointHdr.coded_width = (bitReader.read(12) + 1) << 1; m_entryPointHdr.coded_height = (bitReader.read(12) + 1) << 1; m_seqHdr.coded_width = m_entryPointHdr.coded_width; m_seqHdr.coded_height = m_entryPointHdr.coded_height; } if (m_entryPointHdr.extended_mv) m_entryPointHdr.extended_dmv_flag = bitReader.read(1); m_entryPointHdr.range_mapy_flag = bitReader.read(1); if (m_entryPointHdr.range_mapy_flag) m_entryPointHdr.range_mapy = bitReader.read(3); m_entryPointHdr.range_mapuv_flag = bitReader.read(1); if (m_entryPointHdr.range_mapy_flag) m_entryPointHdr.range_mapuv = bitReader.read(3); return true; }
/** * Gets a resource from the currently loaded section */ byte *TLib::getResource(uint16 id, bool suppressErrors) { // Scan for an entry for the given Id ResourceEntry *re = NULL; ResourceList::iterator iter; for (iter = _resources.begin(); iter != _resources.end(); ++iter) { if ((*iter).id == id) { re = &(*iter); break; } } if (!re) { if (suppressErrors) return NULL; error("Could not find resource Id #%d", id); } if (!re->isCompressed) { // Read in the resource data and return it byte *dataP = _memoryManager.allocate2(re->size); _file.seek(_sections.fileOffset + re->fileOffset); _file.read(dataP, re->size); return dataP; } /* * Decompress the data block */ _file.seek(_sections.fileOffset + re->fileOffset); Common::ReadStream *compStream = _file.readStream(re->size); BitReader bitReader(*compStream); byte *dataOut = _memoryManager.allocate2(re->uncompressedSize); byte *destP = dataOut; uint bytesWritten = 0; uint16 ctrCurrent = 0x102, ctrMax = 0x200; uint16 word_48050 = 0, currentToken = 0, word_48054 =0; byte byte_49068 = 0, byte_49069 = 0; const uint tableSize = 0x1000; DecodeReference *table = (DecodeReference *)malloc(tableSize * sizeof(DecodeReference)); if (!table) error("[TLib::getResource] Cannot allocate table buffer"); for (uint i = 0; i < tableSize; ++i) { table[i].vByte = table[i].vWord = 0; } Common::Stack<uint16> tokenList; for (;;) { // Get the next decode token uint16 token = bitReader.readToken(); // Handle the token if (token == 0x101) { // End of compressed stream break; } else if (token == 0x100) { // Reset bit-rate bitReader.numBits = 9; ctrMax = 0x200; ctrCurrent = 0x102; // Set variables with next token currentToken = word_48050 = bitReader.readToken(); byte_49069 = byte_49068 = (byte)currentToken; ++bytesWritten; assert(bytesWritten <= re->uncompressedSize); *destP++ = byte_49069; } else { word_48054 = word_48050 = token; if (token >= ctrCurrent) { word_48050 = currentToken; tokenList.push(byte_49068); } while (word_48050 >= 0x100) { assert(word_48050 < 0x1000); tokenList.push(table[word_48050].vByte); word_48050 = table[word_48050].vWord; } byte_49069 = byte_49068 = (byte)word_48050; tokenList.push(word_48050); // Write out any cached tokens while (!tokenList.empty()) { ++bytesWritten; assert(bytesWritten <= re->uncompressedSize); *destP++ = tokenList.pop(); } assert(ctrCurrent < 0x1000); table[ctrCurrent].vByte = byte_49069; table[ctrCurrent].vWord = currentToken; ++ctrCurrent; currentToken = word_48054; if ((ctrCurrent >= ctrMax) && (bitReader.numBits != 12)) { // Move to the next higher bit-rate ++bitReader.numBits; ctrMax <<= 1; } } } free(table); assert(bytesWritten == re->uncompressedSize); delete compStream; return dataOut; }
/*Table 264: Sequence Header Data Structure STRUCT_C for Advanced Profiles*/ bool Parser::parseSequenceHeader(const uint8_t* data, uint32_t size) { uint32_t i; BitReader bitReader(data, size); m_seqHdr.profile = bitReader.read(2); if (m_seqHdr.profile != PROFILE_ADVANCED) { /* skip reserved bits */ bitReader.skip(2); m_seqHdr.frmrtq_postproc = bitReader.read(3); m_seqHdr.bitrtq_postproc = bitReader.read(5); m_seqHdr.loop_filter = bitReader.read(1); /* skip reserved bits */ bitReader.skip(1); m_seqHdr.multires = bitReader.read(1); /* skip reserved bits */ bitReader.skip(1); m_seqHdr.fastuvmc = bitReader.read(1); m_seqHdr.extended_mv = bitReader.read(1); m_seqHdr.dquant = bitReader.read(2); m_seqHdr.variable_sized_transform_flag = bitReader.read(1); /* skip reserved bits */ bitReader.skip(1); m_seqHdr.overlap = bitReader.read(1); m_seqHdr.syncmarker = bitReader.read(1); m_seqHdr.rangered = bitReader.read(1); m_seqHdr.max_b_frames = bitReader.read(3); m_seqHdr.quantizer = bitReader.read(2); m_seqHdr.finterpflag = bitReader.read(1); } else { m_seqHdr.level = bitReader.read(3); m_seqHdr.colordiff_format = bitReader.read(2); m_seqHdr.frmrtq_postproc = bitReader.read(3); m_seqHdr.bitrtq_postproc = bitReader.read(5); m_seqHdr.postprocflag = bitReader.read(1); m_seqHdr.coded_width = (bitReader.read(12) + 1) << 1; m_seqHdr.coded_height = (bitReader.read(12) + 1) << 1; m_seqHdr.pulldown = bitReader.read(1); m_seqHdr.interlace = bitReader.read(1); m_seqHdr.tfcntrflag = bitReader.read(1); m_seqHdr.finterpflag = bitReader.read(1); /* skip reserved bits */ bitReader.skip(1); m_seqHdr.psf = bitReader.read(1); m_seqHdr.display_ext = bitReader.read(1); if (m_seqHdr.display_ext == 1) { m_seqHdr.disp_horiz_size = bitReader.read(14) + 1; m_seqHdr.disp_vert_size = bitReader.read(14) + 1; m_seqHdr.aspect_ratio_flag = bitReader.read(1); if (m_seqHdr.aspect_ratio_flag == 1) { m_seqHdr.aspect_ratio = bitReader.read(4); if (m_seqHdr.aspect_ratio == 15) { m_seqHdr.aspect_horiz_size = bitReader.read(8); m_seqHdr.aspect_vert_size = bitReader.read(8); } } m_seqHdr.framerate_flag = bitReader.read(1); if (m_seqHdr.framerate_flag == 1) { m_seqHdr.framerateind = bitReader.read(1); if (m_seqHdr.framerateind == 0) { m_seqHdr.frameratenr = bitReader.read(8); m_seqHdr.frameratedr = bitReader.read(4); } else { m_seqHdr.framerateexp = bitReader.read(16); } } m_seqHdr.color_format_flag = bitReader.read(1); if (m_seqHdr.color_format_flag == 1) { m_seqHdr.color_prim = bitReader.read(8); m_seqHdr.transfer_char = bitReader.read(8); m_seqHdr.matrix_coef = bitReader.read(8); } } m_seqHdr.hrd_param_flag = bitReader.read(1); /*Table 13: Syntax elements for HRD_PARAM structure*/ if (m_seqHdr.hrd_param_flag == 1) { m_seqHdr.hrd_param.hrd_num_leaky_buckets = bitReader.read(5); m_seqHdr.hrd_param.bit_rate_exponent = bitReader.read(4); m_seqHdr.hrd_param.buffer_size_exponent = bitReader.read(4); for (i = 0; i < m_seqHdr.hrd_param.hrd_num_leaky_buckets; i++) { m_seqHdr.hrd_param.hrd_rate[i] = bitReader.read(16); m_seqHdr.hrd_param.hrd_buffer[i] = bitReader.read(16); } } } return true; }