From 873d7e0e632645e67fdfd0e35fb27d477b11307a Mon Sep 17 00:00:00 2001 From: Tom Butterworth Date: Thu, 7 May 2015 16:17:10 +0100 Subject: [PATCH] avcodec/s3tc: fix decoding when dimensions are not a multiple of 4 Image dimensions were rounded down causing rows to wrap early if dimensions were not a multiple of 4. Signed-off-by: Michael Niedermayer --- libavcodec/s3tc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c index 4743d784fc..9886b1dc9c 100644 --- a/libavcodec/s3tc.c +++ b/libavcodec/s3tc.c @@ -26,6 +26,7 @@ #include "s3tc.h" static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d, + unsigned int w, unsigned int h, unsigned int qstride, unsigned int flag, uint64_t alpha) { unsigned int x, y, c0, c1, a = (!flag * 255u) << 24; @@ -62,14 +63,16 @@ static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d, colors[2] = rb2 + g2 + a; pixels = bytestream2_get_le32(gb); - for (y=0; y<4; y++) { - for (x=0; x<4; x++) { + for (y=0; y> 4; d[x] = a + colors[pixels&3]; pixels >>= 2; alpha >>= 4; } + for (; x<4; x++) + pixels >>= 2; d += qstride; } } @@ -77,21 +80,21 @@ static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d, void ff_decode_dxt1(GetByteContext *gb, uint8_t *dst, const unsigned int w, const unsigned int h, const unsigned int stride) { - unsigned int bx, by, qstride = stride/4; + unsigned int x, y, qstride = stride/4; uint32_t *d = (uint32_t *) dst; - for (by=0; by < h/4; by++, d += stride-w) - for (bx = 0; bx < w / 4; bx++, d += 4) - dxt1_decode_pixels(gb, d, qstride, 0, 0LL); + for (y=0; y < h; y += 4, d += stride-w) + for (x = 0; x < w; d += FFMIN(4, w-x), x += 4) + dxt1_decode_pixels(gb, d, FFMIN(4, w-x), FFMIN(4, h-y), qstride, 0, 0LL); } void ff_decode_dxt3(GetByteContext *gb, uint8_t *dst, const unsigned int w, const unsigned int h, const unsigned int stride) { - unsigned int bx, by, qstride = stride/4; + unsigned int x, y, qstride = stride/4; uint32_t *d = (uint32_t *) dst; - for (by=0; by < h/4; by++, d += stride-w) - for (bx = 0; bx < w / 4; bx++, d += 4) - dxt1_decode_pixels(gb, d, qstride, 1, bytestream2_get_le64(gb)); + for (y=0; y < h; y += 4, d += stride-w) + for (x = 0; x < w; d += FFMIN(4, w-x), x += 4) + dxt1_decode_pixels(gb, d, FFMIN(4, w-x), FFMIN(4, h-y), qstride, 1, bytestream2_get_le64(gb)); }