📄 zinflate_8cpp-source.html
字号:
00292 {00293 <span class="keywordflow">if</span> (!blocking)00294 <span class="keywordflow">throw</span> BlockingInputOnly(<span class="stringliteral">"Inflator"</span>);00295 00296 <span class="keywordflow">if</span> (hardFlush)00297 ProcessInput(<span class="keyword">true</span>);00298 FlushOutput();00299 00300 <span class="keywordflow">return</span> <span class="keyword">false</span>;00301 }00302 00303 <span class="keywordtype">void</span> Inflator::ProcessInput(<span class="keywordtype">bool</span> flush)00304 {00305 <span class="keywordflow">while</span> (<span class="keyword">true</span>)00306 {00307 <span class="keywordflow">if</span> (m_inQueue.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera16">IsEmpty</a>())00308 <span class="keywordflow">return</span>;00309 00310 <span class="keywordflow">switch</span> (m_state)00311 {00312 <span class="keywordflow">case</span> PRE_STREAM:00313 <span class="keywordflow">if</span> (!flush && m_inQueue.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera15">CurrentSize</a>() < MaxPrestreamHeaderSize())00314 <span class="keywordflow">return</span>;00315 ProcessPrestreamHeader();00316 m_state = WAIT_HEADER;00317 m_maxDistance = 0;00318 m_current = 0;00319 m_lastFlush = 0;00320 m_window.<a class="code" href="class_sec_block.html#_sec_block_with_hinta19">New</a>(1 << GetLog2WindowSize());00321 <span class="keywordflow">break</span>;00322 <span class="keywordflow">case</span> WAIT_HEADER:00323 {00324 <span class="comment">// maximum number of bytes before actual compressed data starts</span>00325 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MAX_HEADER_SIZE = BitsToBytes(3+5+5+4+19*7+286*15+19*15);00326 <span class="keywordflow">if</span> (m_inQueue.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera15">CurrentSize</a>() < (flush ? 1 : MAX_HEADER_SIZE))00327 <span class="keywordflow">return</span>;00328 DecodeHeader();00329 <span class="keywordflow">break</span>;00330 }00331 <span class="keywordflow">case</span> DECODING_BODY:00332 <span class="keywordflow">if</span> (!DecodeBody())00333 <span class="keywordflow">return</span>;00334 <span class="keywordflow">break</span>;00335 <span class="keywordflow">case</span> POST_STREAM:00336 <span class="keywordflow">if</span> (!flush && m_inQueue.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera15">CurrentSize</a>() < MaxPoststreamTailSize())00337 <span class="keywordflow">return</span>;00338 ProcessPoststreamTail();00339 m_state = m_repeat ? PRE_STREAM : AFTER_END;00340 Output(0, NULL, 0, GetAutoSignalPropagation(), <span class="keyword">true</span>); <span class="comment">// TODO: non-blocking</span>00341 <span class="keywordflow">break</span>;00342 <span class="keywordflow">case</span> AFTER_END:00343 m_inQueue.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(*<a class="code" href="class_filter.html#_zlib_decompressora8">AttachedTransformation</a>());00344 <span class="keywordflow">return</span>;00345 }00346 }00347 }00348 00349 <span class="keywordtype">void</span> Inflator::DecodeHeader()00350 {00351 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(3))00352 <span class="keywordflow">throw</span> UnexpectedEndErr();00353 m_eof = m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(1) != 0;00354 m_blockType = (byte)m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(2);00355 <span class="keywordflow">switch</span> (m_blockType)00356 {00357 <span class="keywordflow">case</span> 0: <span class="comment">// stored</span>00358 {00359 m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera6">SkipBits</a>(m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera2">BitsBuffered</a>() % 8);00360 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(32))00361 <span class="keywordflow">throw</span> UnexpectedEndErr();00362 m_storedLen = (word16)m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(16);00363 word16 nlen = (word16)m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(16);00364 <span class="keywordflow">if</span> (nlen != (word16)~m_storedLen)00365 <span class="keywordflow">throw</span> BadBlockErr();00366 <span class="keywordflow">break</span>;00367 }00368 <span class="keywordflow">case</span> 1: <span class="comment">// fixed codes</span>00369 <span class="keywordflow">if</span> (!m_decodersInitializedWithFixedCodes)00370 {00371 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> codeLengths[288];00372 std::fill(codeLengths + 0, codeLengths + 144, 8);00373 std::fill(codeLengths + 144, codeLengths + 256, 9);00374 std::fill(codeLengths + 256, codeLengths + 280, 7);00375 std::fill(codeLengths + 280, codeLengths + 288, 8);00376 m_literalDecoder.<a class="code" href="class_huffman_decoder.html#_huffman_decodera2">Initialize</a>(codeLengths, 288);00377 std::fill(codeLengths + 0, codeLengths + 32, 5);00378 m_distanceDecoder.<a class="code" href="class_huffman_decoder.html#_huffman_decodera2">Initialize</a>(codeLengths, 32);00379 m_decodersInitializedWithFixedCodes = <span class="keyword">true</span>;00380 }00381 m_nextDecode = LITERAL;00382 <span class="keywordflow">break</span>;00383 <span class="keywordflow">case</span> 2: <span class="comment">// dynamic codes</span>00384 {00385 m_decodersInitializedWithFixedCodes = <span class="keyword">false</span>;00386 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(5+5+4))00387 <span class="keywordflow">throw</span> UnexpectedEndErr();00388 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hlit = m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(5);00389 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hdist = m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(5);00390 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hclen = m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(4);00391 00392 FixedSizeSecBlock<unsigned int, 286+32> codeLengths;00393 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i;00394 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> border[] = { <span class="comment">// Order of the bit length code lengths</span>00395 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};00396 std::fill(codeLengths.<a class="code" href="class_sec_block.html#_sec_block_with_hinta7">begin</a>(), codeLengths+19, 0);00397 <span class="keywordflow">for</span> (i=0; i<hclen+4; i++)00398 codeLengths[border[i]] = m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(3);00399 00400 <span class="keywordflow">try</span>00401 {00402 <a class="code" href="class_huffman_decoder.html">HuffmanDecoder</a> codeLengthDecoder(codeLengths, 19);00403 <span class="keywordflow">for</span> (i = 0; i < hlit+257+hdist+1; )00404 {00405 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> k, count, repeater;00406 <span class="keywordtype">bool</span> result = codeLengthDecoder.<a class="code" href="class_huffman_decoder.html#_huffman_decodera3">Decode</a>(m_reader, k);00407 <span class="keywordflow">if</span> (!result)00408 <span class="keywordflow">throw</span> UnexpectedEndErr();00409 <span class="keywordflow">if</span> (k <= 15)00410 {00411 count = 1;00412 repeater = k;00413 }00414 <span class="keywordflow">else</span> <span class="keywordflow">switch</span> (k)00415 {00416 <span class="keywordflow">case</span> 16:00417 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(2))00418 <span class="keywordflow">throw</span> UnexpectedEndErr();00419 count = 3 + m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(2);00420 <span class="keywordflow">if</span> (i == 0)00421 <span class="keywordflow">throw</span> BadBlockErr();00422 repeater = codeLengths[i-1];00423 <span class="keywordflow">break</span>;00424 <span class="keywordflow">case</span> 17:00425 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(3))00426 <span class="keywordflow">throw</span> UnexpectedEndErr();00427 count = 3 + m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(3);00428 repeater = 0;00429 <span class="keywordflow">break</span>;00430 <span class="keywordflow">case</span> 18:00431 <span class="keywordflow">if</span> (!m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera4">FillBuffer</a>(7))00432 <span class="keywordflow">throw</span> UnexpectedEndErr();00433 count = 11 + m_reader.<a class="code" href="class_low_first_bit_reader.html#_low_first_bit_readera7">GetBits</a>(7);00434 repeater = 0;00435 <span class="keywordflow">break</span>;00436 }00437 <span class="keywordflow">if</span> (i + count > hlit+257+hdist+1)00438 <span class="keywordflow">throw</span> BadBlockErr();00439 std::fill(codeLengths + i, codeLengths + i + count, repeater);00440 i += count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -