mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:52:46 +00:00 
			
		
		
		
	LibGfx/JPEG: Introduce peek_bits and use it in read_bits
				
					
				
			While already providing a performance improvement by removing the loop in `read_bits`, this method was introduced to optimize `next_symbol`.
This commit is contained in:
		
							parent
							
								
									86ce9cc30f
								
							
						
					
					
						commit
						5ec2aa4dcc
					
				
					 1 changed files with 30 additions and 18 deletions
				
			
		|  | @ -12,6 +12,7 @@ | |||
| #include <AK/HashMap.h> | ||||
| #include <AK/Math.h> | ||||
| #include <AK/MemoryStream.h> | ||||
| #include <AK/NumericLimits.h> | ||||
| #include <AK/String.h> | ||||
| #include <AK/Try.h> | ||||
| #include <AK/Vector.h> | ||||
|  | @ -253,27 +254,38 @@ public: | |||
|             return Error::from_string_literal("Reading too much huffman bits at once"); | ||||
|         } | ||||
| 
 | ||||
|         u16 value = 0; | ||||
|         while (count--) { | ||||
|             if (m_byte_offset >= m_stream.size()) { | ||||
|                 dbgln_if(JPEG_DEBUG, "Huffman stream exhausted. This could be an error!"); | ||||
|                 return Error::from_string_literal("Huffman stream exhausted."); | ||||
|             } | ||||
| 
 | ||||
|             u8 const current_byte = m_stream[m_byte_offset]; | ||||
|             u8 const current_bit = 1u & (current_byte >> (7 - m_bit_offset)); // MSB first.
 | ||||
| 
 | ||||
|             m_bit_offset++; | ||||
|             value = (value << 1) | current_bit; | ||||
| 
 | ||||
|             if (m_bit_offset == 8) { | ||||
|                 m_byte_offset++; | ||||
|                 m_bit_offset = 0; | ||||
|             } | ||||
|         } | ||||
|         u16 const value = peek_bits(count); | ||||
|         discard_bits(count); | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     u16 peek_bits(u8 count) const | ||||
|     { | ||||
|         using BufferType = u32; | ||||
| 
 | ||||
|         constexpr static auto max = NumericLimits<BufferType>::max(); | ||||
| 
 | ||||
|         auto const mask = max >> (8 + m_bit_offset); | ||||
| 
 | ||||
|         BufferType msb_buffer {}; | ||||
|         if (m_byte_offset + 0 < m_stream.size()) | ||||
|             msb_buffer |= (static_cast<BufferType>(m_stream[m_byte_offset + 0]) << (2 * 8)); | ||||
|         if (m_byte_offset + 1 < m_stream.size()) | ||||
|             msb_buffer |= (static_cast<BufferType>(m_stream[m_byte_offset + 1]) << (1 * 8)); | ||||
|         if (m_byte_offset + 2 < m_stream.size()) | ||||
|             msb_buffer |= (static_cast<BufferType>(m_stream[m_byte_offset + 2]) << (0 * 8)); | ||||
| 
 | ||||
|         return (mask & msb_buffer) >> (3 * 8 - m_bit_offset - count); | ||||
|     } | ||||
| 
 | ||||
|     void discard_bits(u8 count) | ||||
|     { | ||||
|         m_bit_offset += count; | ||||
|         auto const carry = m_bit_offset / 8; | ||||
|         m_bit_offset -= 8 * carry; | ||||
|         m_byte_offset += carry; | ||||
|     } | ||||
| 
 | ||||
|     void advance_to_byte_boundary() | ||||
|     { | ||||
|         if (m_bit_offset > 0) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lucas CHOLLET
						Lucas CHOLLET