mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	Fix bad bit writer initialization.
When re-initializing a bit writer, we could set invalid values because the bit writer was not big enough. Change-Id: Id25ab6712603245a5a12d5f4a86fe35a9a799a5d
This commit is contained in:
		| @@ -1507,12 +1507,12 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, | |||||||
|   int use_delta_palette = 0; |   int use_delta_palette = 0; | ||||||
|   int entropy_idx[kNumEntropyIx]; |   int entropy_idx[kNumEntropyIx]; | ||||||
|   int num_entropy_idx = 0; |   int num_entropy_idx = 0; | ||||||
|   int i; |   int idx; | ||||||
|   int red_and_blue_always_zero = 0; |   int red_and_blue_always_zero = 0; | ||||||
|   size_t best_size = 0; |   size_t best_size = 0; | ||||||
|   VP8LBitWriter bw_init = *bw, bw_best; |   VP8LBitWriter bw_init = *bw, bw_best; | ||||||
|  |  | ||||||
|   if (enc == NULL || !VP8LBitWriterInit(&bw_best, 0)) { |   if (enc == NULL || !VP8LBitWriterClone(bw, &bw_best)) { | ||||||
|     err = VP8_ENC_ERROR_OUT_OF_MEMORY; |     err = VP8_ENC_ERROR_OUT_OF_MEMORY; | ||||||
|     goto Error; |     goto Error; | ||||||
|   } |   } | ||||||
| @@ -1526,12 +1526,12 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, | |||||||
|     goto Error; |     goto Error; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   for (i = 0; i < num_entropy_idx; ++i) { |   for (idx = 0; idx < num_entropy_idx; ++idx) { | ||||||
|     enc->use_palette_ = (entropy_idx[i] == kPalette); |     enc->use_palette_ = (entropy_idx[idx] == kPalette); | ||||||
|     enc->use_subtract_green_ = (entropy_idx[i] == kSubGreen) || |     enc->use_subtract_green_ = (entropy_idx[idx] == kSubGreen) || | ||||||
|                                (entropy_idx[i] == kSpatialSubGreen); |                                (entropy_idx[idx] == kSpatialSubGreen); | ||||||
|     enc->use_predict_ = (entropy_idx[i] == kSpatial) || |     enc->use_predict_ = (entropy_idx[idx] == kSpatial) || | ||||||
|                         (entropy_idx[i] == kSpatialSubGreen); |                         (entropy_idx[idx] == kSpatialSubGreen); | ||||||
|     if (low_effort) { |     if (low_effort) { | ||||||
|       enc->use_cross_color_ = 0; |       enc->use_cross_color_ = 0; | ||||||
|     } else { |     } else { | ||||||
| @@ -1632,7 +1632,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, | |||||||
|     if (err != VP8_ENC_OK) goto Error; |     if (err != VP8_ENC_OK) goto Error; | ||||||
|  |  | ||||||
|     // If we are better than what we already have. |     // If we are better than what we already have. | ||||||
|     if (best_size == 0 || VP8LBitWriterNumBytes(bw) < best_size) { |     if (idx == 0 || VP8LBitWriterNumBytes(bw) < best_size) { | ||||||
|       best_size = VP8LBitWriterNumBytes(bw); |       best_size = VP8LBitWriterNumBytes(bw); | ||||||
|       // Store the BitWriter. |       // Store the BitWriter. | ||||||
|       VP8LBitWriterSwap(bw, &bw_best); |       VP8LBitWriterSwap(bw, &bw_best); | ||||||
| @@ -1648,7 +1648,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, | |||||||
|         stats->transform_bits = enc->transform_bits_; |         stats->transform_bits = enc->transform_bits_; | ||||||
|         stats->cache_bits = enc->cache_bits_; |         stats->cache_bits = enc->cache_bits_; | ||||||
|         stats->palette_size = enc->palette_size_; |         stats->palette_size = enc->palette_size_; | ||||||
|         stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position); |         stats->lossless_size = (int)(best_size - byte_position); | ||||||
|         stats->lossless_hdr_size = hdr_size; |         stats->lossless_hdr_size = hdr_size; | ||||||
|         stats->lossless_data_size = data_size; |         stats->lossless_data_size = data_size; | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -239,6 +239,19 @@ int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) { | |||||||
|   return VP8LBitWriterResize(bw, expected_size); |   return VP8LBitWriterResize(bw, expected_size); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int VP8LBitWriterClone(const VP8LBitWriter* const src, | ||||||
|  |                        VP8LBitWriter* const dst) { | ||||||
|  |   const size_t current_size = src->cur_ - src->buf_; | ||||||
|  |   assert(src->cur_ >= src->buf_ && src->cur_ <= src->end_); | ||||||
|  |   memset(dst, 0, sizeof(*dst)); | ||||||
|  |   if (!VP8LBitWriterResize(dst, current_size)) return 0; | ||||||
|  |   memcpy(dst->buf_, src->buf_, current_size); | ||||||
|  |   dst->bits_ = src->bits_; | ||||||
|  |   dst->used_ = src->used_; | ||||||
|  |   dst->error_ = src->error_; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) { | void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) { | ||||||
|   if (bw != NULL) { |   if (bw != NULL) { | ||||||
|     WebPSafeFree(bw->buf_); |     WebPSafeFree(bw->buf_); | ||||||
| @@ -251,6 +264,7 @@ void VP8LBitWriterReset(const VP8LBitWriter* const bw_init, | |||||||
|   bw->bits_ = bw_init->bits_; |   bw->bits_ = bw_init->bits_; | ||||||
|   bw->used_ = bw_init->used_; |   bw->used_ = bw_init->used_; | ||||||
|   bw->cur_ = bw->buf_ + (bw_init->cur_ - bw_init->buf_); |   bw->cur_ = bw->buf_ + (bw_init->cur_ - bw_init->buf_); | ||||||
|  |   assert(bw->cur_ <= bw->end_); | ||||||
|   bw->error_ = bw_init->error_; |   bw->error_ = bw_init->error_; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -106,6 +106,9 @@ static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) { | |||||||
|  |  | ||||||
| // Returns false in case of memory allocation error. | // Returns false in case of memory allocation error. | ||||||
| int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size); | int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size); | ||||||
|  | // Returns false in case of memory allocation error. | ||||||
|  | int VP8LBitWriterClone(const VP8LBitWriter* const src, | ||||||
|  |                        VP8LBitWriter* const dst); | ||||||
| // Finalize the bitstream coding. Returns a pointer to the internal buffer. | // Finalize the bitstream coding. Returns a pointer to the internal buffer. | ||||||
| uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw); | uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw); | ||||||
| // Release any pending memory and zeroes the object. | // Release any pending memory and zeroes the object. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user