mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	ConvertWRGBToYUV: use relative pointer offsets
avoids int rollover when working with large input BUG=webp:312 Change-Id: I693cbb295df9cf94aa89294b19c0496bdbe84d18
This commit is contained in:
		| @@ -393,36 +393,42 @@ static WEBP_INLINE uint8_t ConvertRGBToV(int r, int g, int b) { | |||||||
|   return clip_8b(128 + (v >> (YUV_FIX + SFIX))); |   return clip_8b(128 + (v >> (YUV_FIX + SFIX))); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int ConvertWRGBToYUV(const fixed_y_t* const best_y, | static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv, | ||||||
|                             const fixed_t* const best_uv, |  | ||||||
|                             WebPPicture* const picture) { |                             WebPPicture* const picture) { | ||||||
|   int i, j; |   int i, j; | ||||||
|  |   uint8_t* dst_y = picture->y; | ||||||
|  |   uint8_t* dst_u = picture->u; | ||||||
|  |   uint8_t* dst_v = picture->v; | ||||||
|  |   const fixed_t* const best_uv_base = best_uv; | ||||||
|   const int w = (picture->width + 1) & ~1; |   const int w = (picture->width + 1) & ~1; | ||||||
|   const int h = (picture->height + 1) & ~1; |   const int h = (picture->height + 1) & ~1; | ||||||
|   const int uv_w = w >> 1; |   const int uv_w = w >> 1; | ||||||
|   const int uv_h = h >> 1; |   const int uv_h = h >> 1; | ||||||
|   for (j = 0; j < picture->height; ++j) { |   for (best_uv = best_uv_base, j = 0; j < picture->height; ++j) { | ||||||
|     for (i = 0; i < picture->width; ++i) { |     for (i = 0; i < picture->width; ++i) { | ||||||
|       const int off = 3 * ((i >> 1) + (j >> 1) * uv_w); |       const int off = 3 * (i >> 1); | ||||||
|       const int off2 = i + j * picture->y_stride; |       const int W = best_y[i]; | ||||||
|       const int W = best_y[i + j * w]; |  | ||||||
|       const int r = best_uv[off + 0] + W; |       const int r = best_uv[off + 0] + W; | ||||||
|       const int g = best_uv[off + 1] + W; |       const int g = best_uv[off + 1] + W; | ||||||
|       const int b = best_uv[off + 2] + W; |       const int b = best_uv[off + 2] + W; | ||||||
|       picture->y[off2] = ConvertRGBToY(r, g, b); |       dst_y[i] = ConvertRGBToY(r, g, b); | ||||||
|     } |     } | ||||||
|  |     best_y += w; | ||||||
|  |     best_uv += (j & 1) * 3 * uv_w; | ||||||
|  |     dst_y += picture->y_stride; | ||||||
|   } |   } | ||||||
|   for (j = 0; j < uv_h; ++j) { |   for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) { | ||||||
|     uint8_t* const dst_u = picture->u + j * picture->uv_stride; |  | ||||||
|     uint8_t* const dst_v = picture->v + j * picture->uv_stride; |  | ||||||
|     for (i = 0; i < uv_w; ++i) { |     for (i = 0; i < uv_w; ++i) { | ||||||
|       const int off = 3 * (i + j * uv_w); |       const int off = 3 * i; | ||||||
|       const int r = best_uv[off + 0]; |       const int r = best_uv[off + 0]; | ||||||
|       const int g = best_uv[off + 1]; |       const int g = best_uv[off + 1]; | ||||||
|       const int b = best_uv[off + 2]; |       const int b = best_uv[off + 2]; | ||||||
|       dst_u[i] = ConvertRGBToU(r, g, b); |       dst_u[i] = ConvertRGBToU(r, g, b); | ||||||
|       dst_v[i] = ConvertRGBToV(r, g, b); |       dst_v[i] = ConvertRGBToV(r, g, b); | ||||||
|     } |     } | ||||||
|  |     best_uv += 3 * uv_w; | ||||||
|  |     dst_u += picture->uv_stride; | ||||||
|  |     dst_v += picture->uv_stride; | ||||||
|   } |   } | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user