mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 02:15:42 +01:00 
			
		
		
		
	lossless: bit writer optimization
valgrind --tool=callgrind shows a 9 % speedup: 1021201984 ticks before vs. 927917709 after -q 0 -m 0 -lossless ~/alpi/1.png 22.040 MP/s before 24.796 MP/s after Change-Id: Iaab928167b3e20fb0d9401c6f8317a26c5a610b4
This commit is contained in:
		
				
					committed by
					
						 James Zern
						James Zern
					
				
			
			
				
	
			
			
			
						parent
						
							d97b9ff755
						
					
				
				
					commit
					f3a7a5bf76
				
			| @@ -250,12 +250,28 @@ void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) { | void VP8LPutBitsFlushBits(VP8LBitWriter* const bw) { | ||||||
|  |   // If needed, make some room by flushing some bits out. | ||||||
|  |   if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { | ||||||
|  |     const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; | ||||||
|  |     if (extra_size != (size_t)extra_size || | ||||||
|  |         !VP8LBitWriterResize(bw, (size_t)extra_size)) { | ||||||
|  |       bw->cur_ = bw->buf_; | ||||||
|  |       bw->error_ = 1; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)bw->bits_); | ||||||
|  |   bw->cur_ += VP8L_WRITER_BYTES; | ||||||
|  |   bw->bits_ >>= VP8L_WRITER_BITS; | ||||||
|  |   bw->used_ -= VP8L_WRITER_BITS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) { | ||||||
|   assert(n_bits <= 32); |   assert(n_bits <= 32); | ||||||
|   // That's the max we can handle: |   // That's the max we can handle: | ||||||
|   assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS); |   assert(sizeof(vp8l_wtype_t) == 2); | ||||||
|   if (n_bits > 0) { |   if (n_bits > 0) { | ||||||
|     // Local field copy. |  | ||||||
|     vp8l_atype_t lbits = bw->bits_; |     vp8l_atype_t lbits = bw->bits_; | ||||||
|     int used = bw->used_; |     int used = bw->used_; | ||||||
|     // Special case of overflow handling for 32bit accumulator (2-steps flush). |     // Special case of overflow handling for 32bit accumulator (2-steps flush). | ||||||
| @@ -286,7 +302,6 @@ void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) { | |||||||
|       lbits >>= VP8L_WRITER_BITS; |       lbits >>= VP8L_WRITER_BITS; | ||||||
|       used -= VP8L_WRITER_BITS; |       used -= VP8L_WRITER_BITS; | ||||||
|     } |     } | ||||||
|     // Eventually, insert new bits. |  | ||||||
|     bw->bits_ = lbits | ((vp8l_atype_t)bits << used); |     bw->bits_ = lbits | ((vp8l_atype_t)bits << used); | ||||||
|     bw->used_ = used + n_bits; |     bw->used_ = used + n_bits; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -104,12 +104,31 @@ uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw); | |||||||
| // Release any pending memory and zeroes the object. | // Release any pending memory and zeroes the object. | ||||||
| void VP8LBitWriterWipeOut(VP8LBitWriter* const bw); | void VP8LBitWriterWipeOut(VP8LBitWriter* const bw); | ||||||
|  |  | ||||||
|  | // Internal function for VP8LPutBits flushing 32 bits from the written state. | ||||||
|  | void VP8LPutBitsFlushBits(VP8LBitWriter* const bw); | ||||||
|  |  | ||||||
|  | // PutBits internal function used in the 16 bit vp8l_wtype_t case. | ||||||
|  | void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits); | ||||||
|  |  | ||||||
| // This function writes bits into bytes in increasing addresses (little endian), | // This function writes bits into bytes in increasing addresses (little endian), | ||||||
| // and within a byte least-significant-bit first. | // and within a byte least-significant-bit first. | ||||||
| // This function can write up to 32 bits in one go, but VP8LBitReader can only | // This function can write up to 32 bits in one go, but VP8LBitReader can only | ||||||
| // read 24 bits max (VP8L_MAX_NUM_BIT_READ). | // read 24 bits max (VP8L_MAX_NUM_BIT_READ). | ||||||
| // VP8LBitWriter's error_ flag is set in case of  memory allocation error. | // VP8LBitWriter's error_ flag is set in case of  memory allocation error. | ||||||
| void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits); | static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw, | ||||||
|  |                                     uint32_t bits, int n_bits) { | ||||||
|  |   if (sizeof(vp8l_wtype_t) == 4) { | ||||||
|  |     if (n_bits > 0) { | ||||||
|  |       if (bw->used_ >= 32) { | ||||||
|  |         VP8LPutBitsFlushBits(bw); | ||||||
|  |       } | ||||||
|  |       bw->bits_ |= (vp8l_atype_t)bits << bw->used_; | ||||||
|  |       bw->used_ += n_bits; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     VP8LPutBitsInternal(bw, bits, n_bits); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user