SmartRGBYUV: fix odd-width problem with pixel replication

rightmost pixel was missing a copy, which could lead to invalid read.

Also added a lower dimension of 4, below which we use the regular conversion.
This is to prevent corner cases, in addition to not being overkill.

(cherry picked from commit 2523aa73cb)

Change-Id: Iac12e7a3d74590f12fe8eeb1830b9891e61439f6
This commit is contained in:
skal 2014-08-18 14:29:37 -07:00 committed by James Zern
parent c9ac2041e9
commit ee78e7801d

View File

@ -156,6 +156,7 @@ static int RGBToV(int r, int g, int b, VP8Random* const rg) {
// Smart RGB->YUV conversion // Smart RGB->YUV conversion
static const int kNumIterations = 6; static const int kNumIterations = 6;
static const int kMinDimensionIterativeConversion = 4;
// We use a-priori a different precision for storing RGB and Y/W components // We use a-priori a different precision for storing RGB and Y/W components
// We could use YFIX=0 and only uint8_t for fixed_y_t, but it produces some // We could use YFIX=0 and only uint8_t for fixed_y_t, but it produces some
@ -349,6 +350,9 @@ static void ImportOneRow(const uint8_t* const r_ptr,
dst[3 * i + 1] = UpLift(g_ptr[off]); dst[3 * i + 1] = UpLift(g_ptr[off]);
dst[3 * i + 2] = UpLift(b_ptr[off]); dst[3 * i + 2] = UpLift(b_ptr[off]);
} }
if (pic_width & 1) { // replicate rightmost pixel
memcpy(dst + 3 * pic_width, dst + 3 * (pic_width - 1), 3 * sizeof(*dst));
}
} }
static void InterpolateTwoRows(const fixed_y_t* const best_y, static void InterpolateTwoRows(const fixed_y_t* const best_y,
@ -476,6 +480,8 @@ static int PreprocessARGB(const uint8_t* const r_ptr,
ok = WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); ok = WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
goto End; goto End;
} }
assert(picture->width >= kMinDimensionIterativeConversion);
assert(picture->height >= kMinDimensionIterativeConversion);
// Import RGB samples to W/RGB representation. // Import RGB samples to W/RGB representation.
for (j = 0; j < picture->height; j += 2) { for (j = 0; j < picture->height; j += 2) {
@ -629,6 +635,12 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
picture->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420; picture->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
picture->use_argb = 0; picture->use_argb = 0;
// disable smart conversion if source is too small (overkill).
if (width < kMinDimensionIterativeConversion ||
height < kMinDimensionIterativeConversion) {
use_iterative_conversion = 0;
}
if (!WebPPictureAllocYUVA(picture, width, height)) { if (!WebPPictureAllocYUVA(picture, width, height)) {
return 0; return 0;
} }