diff options
author | fbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-20 01:29:30 +0000 |
---|---|---|
committer | fbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-20 01:29:30 +0000 |
commit | 33253151fc54626224cd40cf9435ebe1c0cbd53e (patch) | |
tree | 6c0f972a7cf0d877e0c283330bd98437f6d9bd6d /third_party/libwebp | |
parent | 5eb4be2a0f9036b9b300f3f1d1764b506c9abefa (diff) | |
download | chromium_src-33253151fc54626224cd40cf9435ebe1c0cbd53e.zip chromium_src-33253151fc54626224cd40cf9435ebe1c0cbd53e.tar.gz chromium_src-33253151fc54626224cd40cf9435ebe1c0cbd53e.tar.bz2 |
webp update to use standard C, not c99 or c++ to make it build without warnings
BUG=59833
TEST=devenv -build Release chrome.sln -project libwebp
Review URL: http://codereview.chromium.org/3901001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/libwebp')
-rw-r--r-- | third_party/libwebp/dsp.c | 93 | ||||
-rw-r--r-- | third_party/libwebp/frame.c | 258 | ||||
-rw-r--r-- | third_party/libwebp/libwebp.gyp | 16 | ||||
-rw-r--r-- | third_party/libwebp/quant.c | 24 | ||||
-rw-r--r-- | third_party/libwebp/tree.c | 15 | ||||
-rw-r--r-- | third_party/libwebp/vp8.c | 110 | ||||
-rw-r--r-- | third_party/libwebp/webp.c | 153 | ||||
-rw-r--r-- | third_party/libwebp/yuv.c | 9 |
8 files changed, 383 insertions, 295 deletions
diff --git a/third_party/libwebp/dsp.c b/third_party/libwebp/dsp.c index 2730b78..420b3b0 100644 --- a/third_party/libwebp/dsp.c +++ b/third_party/libwebp/dsp.c @@ -32,17 +32,18 @@ static int tables_ok = 0; void VP8DspInitTables() { if (!tables_ok) { - for (int i = -255; i <= 255; ++i) { + int i; + for (i = -255; i <= 255; ++i) { abs0[255 + i] = (i < 0) ? -i : i; abs1[255 + i] = abs0[255 + i] >> 1; } - for (int i = -1020; i <= 1020; ++i) { + for (i = -1020; i <= 1020; ++i) { sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i; } - for (int i = -112; i <= 112; ++i) { + for (i = -112; i <= 112; ++i) { sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i; } - for (int i = -255; i <= 255 + 255; ++i) { + for (i = -255; i <= 255 + 255; ++i) { clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i; } tables_ok = 1; @@ -66,8 +67,9 @@ static const int kC2 = 35468; static void Transform(const int16_t* in, uint8_t* dst) { int C[4 * 4], *tmp; + int i; tmp = C; - for (int i = 0; i < 4; ++i) { // vertical pass + for (i = 0; i < 4; ++i) { // vertical pass const int a = in[0] + in[8]; const int b = in[0] - in[8]; const int c = MUL(in[4], kC2) - MUL(in[12], kC1); @@ -81,7 +83,7 @@ static void Transform(const int16_t* in, uint8_t* dst) { } tmp = C; - for (int i = 0; i < 4; ++i) { // horizontal pass + for (i = 0; i < 4; ++i) { // horizontal pass const int dc = tmp[0] + 4; const int a = dc + tmp[8]; const int b = dc - tmp[8]; @@ -106,8 +108,9 @@ static void TransformUV(const int16_t* in, uint8_t* dst) { static void TransformDC(const int16_t *in, uint8_t* dst) { const int DC = in[0] + 4; - for (int j = 0; j < 4; ++j) { - for (int i = 0; i < 4; ++i) { + int i, j; + for (j = 0; j < 4; ++j) { + for (i = 0; i < 4; ++i) { STORE(i, j, DC); } } @@ -133,7 +136,8 @@ VP8Idct VP8TransformDCUV = TransformDCUV; static void TransformWHT(const int16_t* in, int16_t* out) { int tmp[16]; - for (int i = 0; i < 4; ++i) { + int i; + for (i = 0; i < 4; ++i) { const int a0 = in[0 + i] + in[12 + i]; const int a1 = in[4 + i] + in[ 8 + i]; const int a2 = in[4 + i] - in[ 8 + i]; @@ -143,7 +147,7 @@ static void TransformWHT(const int16_t* in, int16_t* out) { tmp[4 + i] = a3 + a2; tmp[12 + i] = a3 - a2; } - for (int i = 0; i < 4; ++i) { + for (i = 0; i < 4; ++i) { const int dc = tmp[0 + i * 4] + 3; // w/ rounder const int a0 = dc + tmp[3 + i * 4]; const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4]; @@ -167,9 +171,11 @@ void (*VP8TransformWHT)(const int16_t* in, int16_t* out) = TransformWHT; static inline void TrueMotion(uint8_t *dst, int size) { const uint8_t* top = dst - BPS; const int tl = top[-1]; - for (int y = 0; y < size; ++y) { + int x, y; + + for (y = 0; y < size; ++y) { const uint8_t* const clip = clip1 + 255 + dst[-1] - tl; - for (int x = 0; x < size; ++x) { + for (x = 0; x < size; ++x) { dst[x] = clip[top[x]]; } dst += BPS; @@ -183,27 +189,31 @@ static void TM16(uint8_t *dst) { TrueMotion(dst, 16); } // 16x16 static void V16(uint8_t *dst) { // vertical - for (int j = 0; j < 16; ++j) { + int j; + for (j = 0; j < 16; ++j) { memcpy(dst + j * BPS, dst - BPS, 16); } } static void H16(uint8_t *dst) { // horizontal - for (int j = 16; j > 0; --j) { + int j; + for (j = 16; j > 0; --j) { memset(dst, dst[-1], 16); dst += BPS; } } static inline void Put16(int v, uint8_t* dst) { - for (int j = 0; j < 16; ++j) { + int j; + for (j = 0; j < 16; ++j) { memset(dst + j * BPS, v, 16); } } static void DC16(uint8_t *dst) { // DC int DC = 16; - for (int j = 0; j < 16; ++j) { + int j; + for (j = 0; j < 16; ++j) { DC += dst[-1 + j * BPS] + dst[j - BPS]; } Put16(DC >> 5, dst); @@ -235,7 +245,8 @@ static void DC16NoTopLeft(uint8_t *dst) { // DC with no top and left samples // 4x4 static inline void Put4(uint32_t v, uint8_t* dst) { - for (int i = 4; i > 0; --i) { + int i; + for (i = 4; i > 0; --i) { *(uint32_t*)dst = v; dst += BPS; } @@ -270,7 +281,8 @@ static void H4(uint8_t *dst) { // horizontal static void DC4(uint8_t *dst) { // DC uint32_t dc = 4; - for (int i = 0; i < 4; ++i) { + int i; + for (i = 0; i < 4; ++i) { dc += dst[i - BPS] + dst[-1 + i * BPS]; } Put4((dc >> 3) * 0x01010101U, dst); @@ -402,13 +414,15 @@ static void HD4(uint8_t *dst) { // Horizontal-Down // Chroma static void V8uv(uint8_t *dst) { // vertical - for (int j = 0; j < 8; ++j) { + int j; + for (j = 0; j < 8; ++j) { memcpy(dst + j * BPS, dst - BPS, 8); } } static void H8uv(uint8_t *dst) { // horizontal - for (int j = 0; j < 8; ++j) { + int j; + for (j = 0; j < 8; ++j) { memset(dst, dst[-1], 8); dst += BPS; } @@ -416,36 +430,37 @@ static void H8uv(uint8_t *dst) { // horizontal // helper for chroma-DC predictions static inline void Put8x8uv(uint64_t v, uint8_t* dst) { - for (int j = 0; j < 8; ++j) { + int j; + for (j = 0; j < 8; ++j) { *(uint64_t*)(dst + j * BPS) = v; } } static void DC8uv(uint8_t *dst) { // DC int dc0 = 8; - for (int i = 0; i < 8; ++i) { + int i; + for (i = 0; i < 8; ++i) { dc0 += dst[i - BPS] + dst[-1 + i * BPS]; } - const uint64_t t = (dc0 >> 4) * 0x0101010101010101ULL; - Put8x8uv(t, dst); + Put8x8uv((uint64_t)((dc0 >> 4) * 0x0101010101010101ULL), dst); } static void DC8uvNoLeft(uint8_t *dst) { // DC with no left samples int dc0 = 4; - for (int i = 0; i < 8; ++i) { + int i; + for (i = 0; i < 8; ++i) { dc0 += dst[i - BPS]; } - const uint64_t v = (dc0 >> 3) * 0x0101010101010101ULL; - Put8x8uv(v, dst); + Put8x8uv((uint64_t)((dc0 >> 3) * 0x0101010101010101ULL), dst); } static void DC8uvNoTop(uint8_t *dst) { // DC with no top samples int dc0 = 4; - for (int i = 0; i < 8; ++i) { + int i; + for (i = 0; i < 8; ++i) { dc0 += dst[-1 + i * BPS]; } - const uint64_t v = (dc0 >> 3) * 0x0101010101010101ULL; - Put8x8uv(v, dst); + Put8x8uv((uint64_t)((dc0 >> 3) * 0x0101010101010101ULL), dst); } static void DC8uvNoTopLeft(uint8_t *dst) { // DC with nothing @@ -535,7 +550,8 @@ static inline int needs_filter2(const uint8_t* p, int step, int t, int it) { // Simple In-loop filtering (Paragraph 15.2) static void SimpleVFilter16(uint8_t* p, int stride, int thresh) { - for (int i = 0; i < 16; ++i) { + int i; + for (i = 0; i < 16; ++i) { if (needs_filter(p + i, stride, thresh)) { do_filter2(p + i, stride); } @@ -543,7 +559,8 @@ static void SimpleVFilter16(uint8_t* p, int stride, int thresh) { } static void SimpleHFilter16(uint8_t* p, int stride, int thresh) { - for (int i = 0; i < 16; ++i) { + int i; + for (i = 0; i < 16; ++i) { if (needs_filter(p + i * stride, 1, thresh)) { do_filter2(p + i * stride, 1); } @@ -551,14 +568,16 @@ static void SimpleHFilter16(uint8_t* p, int stride, int thresh) { } static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) { - for (int k = 3; k > 0; --k) { + int k; + for (k = 3; k > 0; --k) { p += 4 * stride; SimpleVFilter16(p, stride, thresh); } } static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) { - for (int k = 3; k > 0; --k) { + int k; + for (k = 3; k > 0; --k) { p += 4; SimpleHFilter16(p, stride, thresh); } @@ -609,7 +628,8 @@ static void HFilter16(uint8_t* p, int stride, // on three inner edges static void VFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { - for (int k = 3; k > 0; --k) { + int k; + for (k = 3; k > 0; --k) { p += 4 * stride; FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh); } @@ -617,7 +637,8 @@ static void VFilter16i(uint8_t* p, int stride, static void HFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { - for (int k = 3; k > 0; --k) { + int k; + for (k = 3; k > 0; --k) { p += 4; FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh); } diff --git a/third_party/libwebp/frame.c b/third_party/libwebp/frame.c index ef8eab5..2386db2 100644 --- a/third_party/libwebp/frame.c +++ b/third_party/libwebp/frame.c @@ -38,6 +38,8 @@ int VP8InitFrame(VP8Decoder* const dec, VP8Io* io) { + top_size + info_size + yuv_size + coeffs_size + cache_size + ALIGN_MASK; + uint8_t* mem; + if (needed > dec->mem_size_) { free(dec->mem_); dec->mem_size_ = 0; @@ -48,7 +50,7 @@ int VP8InitFrame(VP8Decoder* const dec, VP8Io* io) { dec->mem_size_ = needed; } - uint8_t* mem = (uint8_t*)dec->mem_; + mem = (uint8_t*)dec->mem_; dec->intra_t_ = (uint8_t*)mem; mem += intra_pred_mode_size; @@ -198,65 +200,71 @@ void VP8StoreBlock(VP8Decoder* const dec) { level = 9 - dec->filter_hdr_.sharpness_; } } + info->f_ilevel_ = (level < 1) ? 1 : level; info->f_inner_ = (!info->skip_ || dec->is_i4x4_); - - // Transfer samples to row cache - uint8_t* const ydst = dec->cache_y_ + dec->mb_x_ * 16; - uint8_t* const udst = dec->cache_u_ + dec->mb_x_ * 8; - uint8_t* const vdst = dec->cache_v_ + dec->mb_x_ * 8; - for (int y = 0; y < 16; ++y) { - memcpy(ydst + y * dec->cache_y_stride_, - dec->yuv_b_ + Y_OFF + y * BPS, 16); - } - for (int y = 0; y < 8; ++y) { - memcpy(udst + y * dec->cache_uv_stride_, + { + // Transfer samples to row cache + int y; + uint8_t* const ydst = dec->cache_y_ + dec->mb_x_ * 16; + uint8_t* const udst = dec->cache_u_ + dec->mb_x_ * 8; + uint8_t* const vdst = dec->cache_v_ + dec->mb_x_ * 8; + for (y = 0; y < 16; ++y) { + memcpy(ydst + y * dec->cache_y_stride_, + dec->yuv_b_ + Y_OFF + y * BPS, 16); + } + for (y = 0; y < 8; ++y) { + memcpy(udst + y * dec->cache_uv_stride_, dec->yuv_b_ + U_OFF + y * BPS, 8); - memcpy(vdst + y * dec->cache_uv_stride_, + memcpy(vdst + y * dec->cache_uv_stride_, dec->yuv_b_ + V_OFF + y * BPS, 8); + } } } void VP8FilterRow(VP8Decoder* const dec, VP8Io* io) { - for (int mb_x = 0; mb_x < dec->mb_w_; ++mb_x) { + int mb_x; + for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) { DoFilter(dec, mb_x, dec->mb_y_); } - const int extra_y_rows = kFilterExtraRows[dec->filter_type_]; - const int ysize = extra_y_rows * dec->cache_y_stride_; - const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_; - uint8_t* const ydst = dec->cache_y_ - ysize; - uint8_t* const udst = dec->cache_u_ - uvsize; - uint8_t* const vdst = dec->cache_v_ - uvsize; - if (io->put) { - int y_end; - if (dec->mb_y_ > 0) { - io->mb_y = dec->mb_y_ * 16 - extra_y_rows; - io->y = ydst; - io->u = udst; - io->v = vdst; - if (dec->mb_y_ < dec->mb_h_ - 1) { - y_end = io->mb_y + 16; - } else { - y_end = io->height; // last macroblock row. + { + const int extra_y_rows = kFilterExtraRows[dec->filter_type_]; + const int ysize = extra_y_rows * dec->cache_y_stride_; + const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_; + uint8_t* const ydst = dec->cache_y_ - ysize; + uint8_t* const udst = dec->cache_u_ - uvsize; + uint8_t* const vdst = dec->cache_v_ - uvsize; + if (io->put) { + int y_end; + if (dec->mb_y_ > 0) { + io->mb_y = dec->mb_y_ * 16 - extra_y_rows; + io->y = ydst; + io->u = udst; + io->v = vdst; + if (dec->mb_y_ < dec->mb_h_ - 1) { + y_end = io->mb_y + 16; + } else { + y_end = io->height; // last macroblock row. + } + } else { // first macroblock row. + io->mb_y = 0; + y_end = 16 - extra_y_rows; + io->y = dec->cache_y_; + io->u = dec->cache_u_; + io->v = dec->cache_v_; } - } else { // first macroblock row. - io->mb_y = 0; - y_end = 16 - extra_y_rows; - io->y = dec->cache_y_; - io->u = dec->cache_u_; - io->v = dec->cache_v_; + if (y_end > io->height) { + y_end = io->height; + } + io->mb_h = y_end - io->mb_y; + io->put(io); } - if (y_end > io->height) { - y_end = io->height; + // rotate top samples + if (dec->mb_y_ < dec->mb_h_ - 1) { + memcpy(ydst, ydst + 16 * dec->cache_y_stride_, ysize); + memcpy(udst, udst + 8 * dec->cache_uv_stride_, uvsize); + memcpy(vdst, vdst + 8 * dec->cache_uv_stride_, uvsize); } - io->mb_h = y_end - io->mb_y; - io->put(io); - } - // rotate top samples - if (dec->mb_y_ < dec->mb_h_ - 1) { - memcpy(ydst, ydst + 16 * dec->cache_y_stride_, ysize); - memcpy(udst, udst + 8 * dec->cache_uv_stride_, uvsize); - memcpy(vdst, vdst + 8 * dec->cache_uv_stride_, uvsize); } } @@ -294,18 +302,20 @@ void VP8ReconstructBlock(VP8Decoder* const dec) { // Rotate in the left samples from previously decoded block. We move four // pixels at a time for alignment reason, and because of in-loop filter. if (dec->mb_x_ > 0) { - for (int j = -1; j < 16; ++j) { + int j; + for (j = -1; j < 16; ++j) { Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]); } - for (int j = -1; j < 8; ++j) { + for (j = -1; j < 8; ++j) { Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]); Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]); } } else { - for (int j = 0; j < 16; ++j) { + int j; + for (j = 0; j < 16; ++j) { y_dst[j * BPS - 1] = 129; } - for (int j = 0; j < 8; ++j) { + for (j = 0; j < 8; ++j) { u_dst[j * BPS - 1] = 129; v_dst[j * BPS - 1] = 129; } @@ -314,90 +324,96 @@ void VP8ReconstructBlock(VP8Decoder* const dec) { y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129; } } + { + // bring top samples into the cache + uint8_t* const top_y = dec->y_t_ + dec->mb_x_ * 16; + uint8_t* const top_u = dec->u_t_ + dec->mb_x_ * 8; + uint8_t* const top_v = dec->v_t_ + dec->mb_x_ * 8; + const int16_t* coeffs = dec->coeffs_; + int n; - // bring top samples into the cache - uint8_t* const top_y = dec->y_t_ + dec->mb_x_ * 16; - uint8_t* const top_u = dec->u_t_ + dec->mb_x_ * 8; - uint8_t* const top_v = dec->v_t_ + dec->mb_x_ * 8; - if (dec->mb_y_ > 0) { - memcpy(y_dst - BPS, top_y, 16); - memcpy(u_dst - BPS, top_u, 8); - memcpy(v_dst - BPS, top_v, 8); - } else if (dec->mb_x_ == 0) { - // we only need to do this init once at block (0,0). - // Afterward, it remains valid for the whole topmost row. - memset(y_dst - BPS - 1, 127, 16 + 4 + 1); - memset(u_dst - BPS - 1, 127, 8 + 1); - memset(v_dst - BPS - 1, 127, 8 + 1); - } - - // predict and add residuals - const int16_t* coeffs = dec->coeffs_; - if (dec->is_i4x4_) { // 4x4 - uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16); if (dec->mb_y_ > 0) { - if (dec->mb_x_ >= dec->mb_w_ - 1) { // on rightmost border - top_right[0] = top_y[15] * 0x01010101u; - } else { - memcpy(top_right, top_y + 16, sizeof(*top_right)); - } + memcpy(y_dst - BPS, top_y, 16); + memcpy(u_dst - BPS, top_u, 8); + memcpy(v_dst - BPS, top_v, 8); + } else if (dec->mb_x_ == 0) { + // we only need to do this init once at block (0,0). + // Afterward, it remains valid for the whole topmost row. + memset(y_dst - BPS - 1, 127, 16 + 4 + 1); + memset(u_dst - BPS - 1, 127, 8 + 1); + memset(v_dst - BPS - 1, 127, 8 + 1); } - // replicate the top-right pixels below - top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0]; - - // predict and add residues for all 4x4 blocks in turn. - for (int n = 0; n < 16; n++) { - uint8_t* const dst = y_dst + kScan[n]; - VP8PredLuma4[dec->imodes_[n]](dst); - if (dec->non_zero_ & (1 << n)) { - VP8Transform(coeffs + n * 16, dst); - } else if (dec->non_zero_ & (1 << n)) { // only DC is present - VP8TransformDC(coeffs + n * 16, dst); + + // predict and add residuals + + if (dec->is_i4x4_) { // 4x4 + uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16); + + if (dec->mb_y_ > 0) { + if (dec->mb_x_ >= dec->mb_w_ - 1) { // on rightmost border + top_right[0] = top_y[15] * 0x01010101u; + } else { + memcpy(top_right, top_y + 16, sizeof(*top_right)); + } } - } - } else { // 16x16 - const int pred_func = CheckMode(dec, dec->imodes_[0]); - VP8PredLuma16[pred_func](y_dst); - if (dec->non_zero_) { - for (int n = 0; n < 16; n++) { + // replicate the top-right pixels below + top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0]; + + // predict and add residues for all 4x4 blocks in turn. + for (n = 0; n < 16; n++) { uint8_t* const dst = y_dst + kScan[n]; - if (dec->non_zero_ac_ & (1 << n)) { + VP8PredLuma4[dec->imodes_[n]](dst); + if (dec->non_zero_ & (1 << n)) { VP8Transform(coeffs + n * 16, dst); } else if (dec->non_zero_ & (1 << n)) { // only DC is present VP8TransformDC(coeffs + n * 16, dst); } } + } else { // 16x16 + const int pred_func = CheckMode(dec, dec->imodes_[0]); + VP8PredLuma16[pred_func](y_dst); + if (dec->non_zero_) { + for (n = 0; n < 16; n++) { + uint8_t* const dst = y_dst + kScan[n]; + if (dec->non_zero_ac_ & (1 << n)) { + VP8Transform(coeffs + n * 16, dst); + } else if (dec->non_zero_ & (1 << n)) { // only DC is present + VP8TransformDC(coeffs + n * 16, dst); + } + } + } } - } - - // Chroma - const int pred_func = CheckMode(dec, dec->uvmode_); - VP8PredChroma8[pred_func](u_dst); - VP8PredChroma8[pred_func](v_dst); + { + // Chroma + const int pred_func = CheckMode(dec, dec->uvmode_); + VP8PredChroma8[pred_func](u_dst); + VP8PredChroma8[pred_func](v_dst); + + if (dec->non_zero_ & 0x0f0000) { // chroma-U + const int16_t* const u_coeffs = dec->coeffs_ + 16 * 16; + if (dec->non_zero_ac_ & 0x0f0000) { + VP8TransformUV(u_coeffs, u_dst); + } else { + VP8TransformDCUV(u_coeffs, u_dst); + } + } + if (dec->non_zero_ & 0xf00000) { // chroma-V + const int16_t* const v_coeffs = dec->coeffs_ + 20 * 16; + if (dec->non_zero_ac_ & 0xf00000) { + VP8TransformUV(v_coeffs, v_dst); + } else { + VP8TransformDCUV(v_coeffs, v_dst); + } + } - if (dec->non_zero_ & 0x0f0000) { // chroma-U - const int16_t* const u_coeffs = dec->coeffs_ + 16 * 16; - if (dec->non_zero_ac_ & 0x0f0000) { - VP8TransformUV(u_coeffs, u_dst); - } else { - VP8TransformDCUV(u_coeffs, u_dst); - } - } - if (dec->non_zero_ & 0xf00000) { // chroma-V - const int16_t* const v_coeffs = dec->coeffs_ + 20 * 16; - if (dec->non_zero_ac_ & 0xf00000) { - VP8TransformUV(v_coeffs, v_dst); - } else { - VP8TransformDCUV(v_coeffs, v_dst); + // stash away top samples for next block + if (dec->mb_y_ < dec->mb_h_ - 1) { + memcpy(top_y, y_dst + 15 * BPS, 16); + memcpy(top_u, u_dst + 7 * BPS, 8); + memcpy(top_v, v_dst + 7 * BPS, 8); + } } } - - // stash away top samples for next block - if (dec->mb_y_ < dec->mb_h_ - 1) { - memcpy(top_y, y_dst + 15 * BPS, 16); - memcpy(top_u, u_dst + 7 * BPS, 8); - memcpy(top_v, v_dst + 7 * BPS, 8); - } } //----------------------------------------------------------------------------- diff --git a/third_party/libwebp/libwebp.gyp b/third_party/libwebp/libwebp.gyp index 42510a5..7fb1cbb 100644 --- a/third_party/libwebp/libwebp.gyp +++ b/third_party/libwebp/libwebp.gyp @@ -14,8 +14,8 @@ 'type': '<(library)', 'sources': [ 'bits.c', - 'frame.c', 'dsp.c', + 'frame.c', 'quant.c', 'tree.c', 'vp8.c', @@ -28,19 +28,7 @@ ], }, 'conditions': [ - ['OS!="win"', { - 'product_name': 'webp', - 'cflags': [ - '-std=c99', - ],}, - ], - ['OS=="win"', { - 'msvs_settings': { - 'VCCLCompilerTool': { - 'AdditionalOptions': ['/TP'], # compile as C++ to get C99 - }, - }, - }], + ['OS!="win"', {'product_name': 'webp'}], ], }, ], diff --git a/third_party/libwebp/quant.c b/third_party/libwebp/quant.c index 557467e..3699392 100644 --- a/third_party/libwebp/quant.c +++ b/third_party/libwebp/quant.c @@ -71,7 +71,9 @@ void VP8ParseQuant(VP8Decoder* const dec) { const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const VP8SegmentHeader* const hdr = &dec->segment_hdr_; - for (int i = 0; i < NUM_MB_SEGMENTS; ++i) { + int i; + + for (i = 0; i < NUM_MB_SEGMENTS; ++i) { int q; if (hdr->use_segment_) { q = hdr->quantizer_[i]; @@ -86,17 +88,19 @@ void VP8ParseQuant(VP8Decoder* const dec) { q = base_q0; } } - VP8QuantMatrix* const m = &dec->dqm_[i]; - m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)]; - m->y1_mat_[1] = kAcTable[clip(q + 0, 127)]; + { + VP8QuantMatrix* const m = &dec->dqm_[i]; + m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)]; + m->y1_mat_[1] = kAcTable[clip(q + 0, 127)]; - m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2; - // TODO(skal): make it another table? - m->y2_mat_[1] = kAcTable[clip(q + dqy2_ac, 127)] * 155 / 100; - if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8; + m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2; + // TODO(skal): make it another table? + m->y2_mat_[1] = kAcTable[clip(q + dqy2_ac, 127)] * 155 / 100; + if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8; - m->uv_mat_[0] = kDcTable[clip(q + dquv_ac, 117)]; - m->uv_mat_[1] = kAcTable[clip(q + dquv_dc, 127)]; + m->uv_mat_[0] = kDcTable[clip(q + dquv_dc, 117)]; + m->uv_mat_[1] = kAcTable[clip(q + dquv_ac, 127)]; + } } } diff --git a/third_party/libwebp/tree.c b/third_party/libwebp/tree.c index be9951d..1d5c422 100644 --- a/third_party/libwebp/tree.c +++ b/third_party/libwebp/tree.c @@ -343,9 +343,11 @@ void VP8ParseIntraMode(VP8BitReader* const br, VP8Decoder* const dec) { memset(left, ymode, 4 * sizeof(left[0])); } else { uint8_t* modes = dec->imodes_; - for (int y = 0; y < 4; ++y) { + int y; + for (y = 0; y < 4; ++y) { int ymode = left[y]; - for (int x = 0; x < 4; ++x) { + int x; + for (x = 0; x < 4; ++x) { const uint8_t* const prob = kBModesProba[top[x]][ymode]; #ifdef USE_GENERIC_TREE // Generic tree-parsing @@ -531,10 +533,11 @@ static const uint8_t MVUpdateProba[2][NUM_MV_PROBAS] = { // Paragraph 9.9 void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) { VP8Proba* const proba = &dec->proba_; - for (int t = 0; t < NUM_TYPES; ++t) { - for (int b = 0; b < NUM_BANDS; ++b) { - for (int c = 0; c < NUM_CTX; ++c) { - for (int p = 0; p < NUM_PROBAS; ++p) { + int t, b, c, p; + for (t = 0; t < NUM_TYPES; ++t) { + for (b = 0; b < NUM_BANDS; ++b) { + for (c = 0; c < NUM_CTX; ++c) { + for (p = 0; p < NUM_PROBAS; ++p) { if (VP8GetBit(br, CoeffsUpdateProba[t][b][c][p])) { proba->coeffs_[t][b][c][p] = VP8GetValue(br, 8); } diff --git a/third_party/libwebp/vp8.c b/third_party/libwebp/vp8.c index ddfe189..76fc74e 100644 --- a/third_party/libwebp/vp8.c +++ b/third_party/libwebp/vp8.c @@ -80,18 +80,19 @@ static int ParseSegmentHeader(VP8BitReader* br, hdr->use_segment_ = VP8Get(br); if (hdr->use_segment_) { hdr->update_map_ = VP8Get(br); - const int update_data = VP8Get(br); - if (update_data) { + if (VP8Get(br)) { // update data + int s; hdr->absolute_delta_ = VP8Get(br); - for (int s = 0; s < NUM_MB_SEGMENTS; ++s) { + for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; } - for (int s = 0; s < NUM_MB_SEGMENTS; ++s) { + for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; } } if (hdr->update_map_) { - for (int s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { + int s; + for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; } } @@ -105,14 +106,19 @@ static int ParseSegmentHeader(VP8BitReader* br, static int ParsePartitions(VP8Decoder* const dec, const uint8_t* buf, uint32_t size) { VP8BitReader* const br = &dec->br_; - dec->num_parts_ = 1 << VP8GetValue(br, 2); const uint8_t* sz = buf; - const int last_part = dec->num_parts_ - 1; - uint32_t offset = last_part * 3; + int last_part; + uint32_t offset; + int p; + + dec->num_parts_ = 1 << VP8GetValue(br, 2); + last_part = dec->num_parts_ - 1; + offset = last_part * 3; + if (size <= offset) { return 0; } - for (int p = 0; p < last_part; ++p) { + for (p = 0; p < last_part; ++p) { const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); if (offset + psize > size) { return 0; @@ -135,12 +141,13 @@ static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { hdr->use_lf_delta_ = VP8Get(br); if (hdr->use_lf_delta_) { if (VP8Get(br)) { // update lf-delta? - for (int i = 0; i < NUM_REF_LF_DELTAS; ++i) { + int i; + for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); } } - for (int i = 0; i < NUM_MODE_LF_DELTAS; ++i) { + for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); } @@ -150,7 +157,8 @@ static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2; if (dec->filter_type_ > 0) { // precompute filter levels per segment if (dec->segment_hdr_.use_segment_) { - for (int s = 0; s < NUM_MB_SEGMENTS; ++s) { + int s; + for (s = 0; s < NUM_MB_SEGMENTS; ++s) { int strength = dec->segment_hdr_.filter_strength_[s]; if (!dec->segment_hdr_.absolute_delta_) { strength += hdr->level_; @@ -170,6 +178,12 @@ static inline uint32_t get_le32(const uint8_t* const data) { // Topmost call int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { + uint8_t* buf; + uint32_t buf_size; + VP8FrameHeader* frm_hdr; + VP8PictureHeader* pic_hdr; + VP8BitReader* br; + if (dec == NULL) { return 0; } @@ -177,25 +191,28 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { if (io == NULL || io->data == NULL || io->data_size <= 4) { return VP8SetError(dec, 2, "null VP8Io passed to VP8GetHeaders()"); } - const uint8_t* buf = io->data; - uint32_t buf_size = io->data_size; + + buf = (uint8_t *)io->data; + buf_size = io->data_size; if (buf_size < 4) { return VP8SetError(dec, 2, "Not enough data to parse frame header"); } // Skip over valid RIFF headers if (!memcmp(buf, "RIFF", 4)) { + uint32_t riff_size; + uint32_t chunk_size; if (buf_size < 20 + 4) { return VP8SetError(dec, 2, "RIFF: Truncated header."); } if (memcmp(buf + 8, "WEBP", 4)) { // wrong image file signature return VP8SetError(dec, 2, "RIFF: WEBP signature not found."); } - const uint32_t riff_size = get_le32(buf + 4); + riff_size = get_le32(buf + 4); if (memcmp(buf + 12, "VP8 ", 4)) { return VP8SetError(dec, 2, "RIFF: Invalid compression format."); } - const uint32_t chunk_size = get_le32(buf + 16); + chunk_size = get_le32(buf + 16); if ((chunk_size > riff_size + 8) || (chunk_size & 1)) { return VP8SetError(dec, 2, "RIFF: Inconsistent size information."); } @@ -204,16 +221,18 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { } // Paragraph 9.1 - VP8FrameHeader* const frm_hdr = &dec->frm_hdr_; - const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); - frm_hdr->key_frame_ = !(bits & 1); - frm_hdr->profile_ = (bits >> 1) & 7; - frm_hdr->show_ = (bits >> 4) & 1; - frm_hdr->partition_length_ = (bits >> 5); - buf += 3; - buf_size -= 3; - - VP8PictureHeader* const pic_hdr = &dec->pic_hdr_; + { + const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); + frm_hdr = &dec->frm_hdr_; + frm_hdr->key_frame_ = !(bits & 1); + frm_hdr->profile_ = (bits >> 1) & 7; + frm_hdr->show_ = (bits >> 4) & 1; + frm_hdr->partition_length_ = (bits >> 5); + buf += 3; + buf_size -= 3; + } + + pic_hdr = &dec->pic_hdr_; if (frm_hdr->key_frame_) { // Paragraph 9.2 if (buf_size < 7) { @@ -239,7 +258,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { dec->segment_ = 0; // default for intra } - VP8BitReader* const br = &dec->br_; + br = &dec->br_; VP8Init(br, buf, buf_size); buf += frm_hdr->partition_length_; buf_size -= frm_hdr->partition_length_; @@ -333,7 +352,7 @@ static int GetCoeffs(VP8BitReader* const br, if (!VP8GetBit(br, p[1])) { p = prob[kBands[n]][0]; } else { // non zero coeff - int v; + int v, j; if (!VP8GetBit(br, p[2])) { p = prob[kBands[n]][1]; v = 1; @@ -352,11 +371,12 @@ static int GetCoeffs(VP8BitReader* const br, v = 7 + 2 * VP8GetBit(br, 165) + VP8GetBit(br, 145); } } else { + uint8_t* tab; const int bit1 = VP8GetBit(br, p[8]); const int bit0 = VP8GetBit(br, p[9 + bit1]); const int cat = 2 * bit1 + bit0; v = 0; - for (const uint8_t* tab = kCat3456[cat]; *tab; ++tab) { + for (tab = (uint8_t*)kCat3456[cat]; *tab; ++tab) { v += v + VP8GetBit(br, *tab); } v += 3 + (8 << cat); @@ -364,7 +384,7 @@ static int GetCoeffs(VP8BitReader* const br, } p = prob[kBands[n]][2]; } - const int j = kZigzag[n - 1]; + j = kZigzag[n - 1]; out[j] = VP8GetSigned(br, v) * dq[j > 0]; if (n == 16) break; if (!VP8GetBit(br, p[0])) { // EOB @@ -394,6 +414,12 @@ static int ParseResiduals(VP8Decoder* const dec, const VP8QuantMatrix* q = &dec->dqm_[dec->segment_]; int16_t* dst = dec->coeffs_; VP8MB* const left_mb = dec->mb_info_ - 1; + uint8_t nz_ac[4], nz_dc[4]; + uint32_t non_zero_ac = 0; + uint32_t non_zero_dc = 0; + uint8_t tnz[4], lnz[4]; + int x, y, ch; + memset(dst, 0, 384 * sizeof(*dst)); if (!dec->is_i4x4_) { // parse DC int16_t dc[16] = { 0 }; @@ -409,16 +435,12 @@ static int ParseResiduals(VP8Decoder* const dec, ac_prob = (Proba_t)dec->proba_.coeffs_[3]; } - uint8_t nz_ac[4], nz_dc[4]; - uint32_t non_zero_ac = 0; - uint32_t non_zero_dc = 0; - - uint8_t tnz[4], lnz[4]; memcpy(tnz, kUnpackTab[mb->nz_ & 0xf], sizeof(tnz)); memcpy(lnz, kUnpackTab[left_mb->nz_ & 0xf], sizeof(lnz)); - for (int y = 0; y < 4; ++y) { + for (y = 0; y < 4; ++y) { int l = lnz[y]; - for (int x = 0; x < 4; ++x) { + + for (x = 0; x < 4; ++x) { const int ctx = l + tnz[x]; const int last = GetCoeffs(token_br, ac_prob, ctx, q->y1_mat_, first, dst); @@ -436,10 +458,10 @@ static int ParseResiduals(VP8Decoder* const dec, memcpy(tnz, kUnpackTab[mb->nz_ >> 4], sizeof(tnz)); memcpy(lnz, kUnpackTab[left_mb->nz_ >> 4], sizeof(lnz)); - for (int ch = 0; ch < 4; ch += 2) { - for (int y = 0; y < 2; ++y) { + for (ch = 0; ch < 4; ch += 2) { + for (y = 0; y < 2; ++y) { int l = lnz[ch + y]; - for (int x = 0; x < 2; ++x) { + for (x = 0; x < 2; ++x) { const int ctx = l + tnz[ch + x]; const int last = GetCoeffs(token_br, (Proba_t)dec->proba_.coeffs_[2], @@ -485,13 +507,17 @@ static void SendBlock(VP8Decoder* const dec, VP8Io* io) { static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { int ok = 1; VP8BitReader* const br = &dec->br_; + VP8BitReader* token_br; for (dec->mb_y_ = 0; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) { - memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); VP8MB* const left = dec->mb_info_ - 1; + + memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); + left->nz_ = 0; left->dc_nz_ = 0; - VP8BitReader* token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; + token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; + for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) { VP8MB* const info = dec->mb_info_ + dec->mb_x_; diff --git a/third_party/libwebp/webp.c b/third_party/libwebp/webp.c index 4c13fd2..5234a4d 100644 --- a/third_party/libwebp/webp.c +++ b/third_party/libwebp/webp.c @@ -35,25 +35,28 @@ static inline uint32_t get_le32(const uint8_t* const data) { } // If a RIFF container is detected, validate it and skip over it. -static int CheckRIFFHeader(const uint8_t** data_ptr, uint32_t *data_size_ptr) { +static uint32_t CheckRIFFHeader(const uint8_t** data_ptr, + uint32_t *data_size_ptr) { uint32_t chunk_size = 0xffffffffu; if (*data_size_ptr >= 10 + 20 && !memcmp(*data_ptr, "RIFF", 4)) { if (memcmp(*data_ptr + 8, "WEBP", 4)) { return 0; // wrong image file signature + } else { + const uint32_t riff_size = get_le32(*data_ptr + 4); + if (memcmp(*data_ptr + 12, "VP8 ", 4)) { + return 0; // invalid compression format + } + chunk_size = get_le32(*data_ptr + 16); + if ((chunk_size > riff_size + 8) || (chunk_size & 1)) { + return 0; // inconsistent size information. + } + // We have a IFF container. Skip it. + *data_ptr += 20; + *data_size_ptr -= 20; } - const uint32_t riff_size = get_le32(*data_ptr + 4); - if (memcmp(*data_ptr + 12, "VP8 ", 4)) { - return 0; // invalid compression format - } - chunk_size = get_le32(*data_ptr + 16); - if ((chunk_size > riff_size + 8) || (chunk_size & 1)) { - return 0; // inconsistent size information. - } - // We have a IFF container. Skip it. - *data_ptr += 20; - *data_size_ptr -= 20; + return chunk_size; } - return chunk_size; + return *data_size_ptr; } //----------------------------------------------------------------------------- @@ -75,24 +78,32 @@ static void CustomPut(const VP8Io* io) { Params *p = (Params*)io->opaque; const int mb_w = io->mb_w; const int mb_h = io->mb_h; + int j; + if (p->mode == MODE_YUV) { uint8_t* const y_dst = p->output + io->mb_x + io->mb_y * p->stride; - for (int j = 0; j < mb_h; ++j) { + uint8_t* u_dst; + uint8_t* v_dst; + int uv_w; + + for (j = 0; j < mb_h; ++j) { memcpy(y_dst + j * p->stride, io->y + j * io->y_stride, mb_w); } - uint8_t* const u_dst = p->u + (io->mb_x / 2) + (io->mb_y / 2) * p->u_stride; - uint8_t* const v_dst = p->v + (io->mb_x / 2) + (io->mb_y / 2) * p->v_stride; - const int uv_w = (mb_w + 1) / 2; - for (int j = 0; j < (mb_h + 1) / 2; ++j) { + u_dst = p->u + (io->mb_x / 2) + (io->mb_y / 2) * p->u_stride; + v_dst = p->v + (io->mb_x / 2) + (io->mb_y / 2) * p->v_stride; + uv_w = (mb_w + 1) / 2; + for (j = 0; j < (mb_h + 1) / 2; ++j) { memcpy(u_dst + j * p->u_stride, io->u + j * io->uv_stride, uv_w); memcpy(v_dst + j * p->v_stride, io->v + j * io->uv_stride, uv_w); } } else { const int psize = (p->mode == MODE_RGB || p->mode == MODE_BGR) ? 3 : 4; uint8_t* dst = p->output + psize * io->mb_x + io->mb_y * p->stride; - for (int j = 0; j < mb_h; ++j) { + int i; + + for (j = 0; j < mb_h; ++j) { const uint8_t* y_src = io->y + j * io->y_stride; - for (int i = 0; i < mb_w; ++i) { + for (i = 0; i < mb_w; ++i) { const int y = y_src[i]; const int u = io->u[(j / 2) * io->uv_stride + (i / 2)]; const int v = io->v[(j / 2) * io->uv_stride + (i / 2)]; @@ -120,11 +131,13 @@ static uint8_t* DecodeInto(CSP_MODE mode, Params* params, int output_size, int output_u_size, int output_v_size) { VP8Decoder* dec = VP8New(); + VP8Io io; + int ok = 1; + if (dec == NULL) { return NULL; } - VP8Io io; VP8InitIo(&io); io.data = data; io.data_size = data_size; @@ -138,17 +151,17 @@ static uint8_t* DecodeInto(CSP_MODE mode, return NULL; } // check output buffers - int ok = 1; + ok &= (params->stride * io.height <= output_size); if (mode == MODE_RGB || mode == MODE_BGR) { ok &= (params->stride >= io.width * 3); } else if (mode == MODE_RGBA || mode == MODE_BGRA) { ok &= (params->stride >= io.width * 4); } else { - ok &= (params->stride >= io.width); // some extra checks for U/V const int u_size = params->u_stride * ((io.height + 1) / 2); const int v_size = params->v_stride * ((io.height + 1) / 2); + ok &= (params->stride >= io.width); ok &= (params->u_stride >= (io.width + 1) / 2) && (params->v_stride >= (io.width + 1) / 2); ok &= (u_size <= output_u_size && v_size <= output_v_size); @@ -170,10 +183,12 @@ static uint8_t* DecodeInto(CSP_MODE mode, uint8_t* WebPDecodeRGBInto(const uint8_t* data, uint32_t data_size, uint8_t* output, int output_size, int output_stride) { + Params params; + if (output == NULL) { return NULL; } - Params params; + params.output = output; params.stride = output_stride; return DecodeInto(MODE_RGB, data, data_size, ¶ms, output_size, 0, 0); @@ -182,10 +197,12 @@ uint8_t* WebPDecodeRGBInto(const uint8_t* data, uint32_t data_size, uint8_t* WebPDecodeRGBAInto(const uint8_t* data, uint32_t data_size, uint8_t* output, int output_size, int output_stride) { + Params params; + if (output == NULL) { return NULL; } - Params params; + params.output = output; params.stride = output_stride; return DecodeInto(MODE_RGBA, data, data_size, ¶ms, output_size, 0, 0); @@ -194,10 +211,12 @@ uint8_t* WebPDecodeRGBAInto(const uint8_t* data, uint32_t data_size, uint8_t* WebPDecodeBGRInto(const uint8_t* data, uint32_t data_size, uint8_t* output, int output_size, int output_stride) { + Params params; + if (output == NULL) { return NULL; } - Params params; + params.output = output; params.stride = output_stride; return DecodeInto(MODE_BGR, data, data_size, ¶ms, output_size, 0, 0); @@ -206,10 +225,12 @@ uint8_t* WebPDecodeBGRInto(const uint8_t* data, uint32_t data_size, uint8_t* WebPDecodeBGRAInto(const uint8_t* data, uint32_t data_size, uint8_t* output, int output_size, int output_stride) { + Params params; + if (output == NULL) { return NULL; } - Params params; + params.output = output; params.stride = output_stride; return DecodeInto(MODE_BGRA, data, data_size, ¶ms, output_size, 0, 0); @@ -219,10 +240,12 @@ uint8_t* WebPDecodeYUVInto(const uint8_t* data, uint32_t data_size, uint8_t* luma, int luma_size, int luma_stride, uint8_t* u, int u_size, int u_stride, uint8_t* v, int v_size, int v_stride) { + Params params; + if (luma == NULL) { return NULL; } - Params params; + params.output = luma; params.stride = luma_stride; params.u = u; @@ -237,7 +260,13 @@ uint8_t* WebPDecodeYUVInto(const uint8_t* data, uint32_t data_size, static uint8_t* Decode(CSP_MODE mode, const uint8_t* data, uint32_t data_size, int* width, int* height, Params* params_out) { - int w, h; + int w, h, stride; + int uv_size = 0; + int uv_stride = 0; + int size; + uint8_t* output; + Params params = { 0 }; + if (!WebPGetInfo(data, data_size, &w, &h)) { return NULL; } @@ -245,21 +274,21 @@ static uint8_t* Decode(CSP_MODE mode, const uint8_t* data, uint32_t data_size, if (height) *height = h; // initialize output buffer, now that dimensions are known. - int stride = (mode == MODE_RGB || mode == MODE_BGR) ? 3 * w + stride = (mode == MODE_RGB || mode == MODE_BGR) ? 3 * w : (mode == MODE_RGBA || mode == MODE_BGRA) ? 4 * w : w; - const int size = stride * h; - int uv_size = 0; - int uv_stride = 0; + size = stride * h; + if (mode == MODE_YUV) { uv_stride = (w + 1) / 2; uv_size = uv_stride * ((h + 1) / 2); } - uint8_t* const output = (uint8_t*)malloc(size + 2 * uv_size); + + output = (uint8_t*)malloc(size + 2 * uv_size); if (!output) { return NULL; } - Params params = { 0 }; + params.output = output; params.stride = stride; if (mode == MODE_YUV) { @@ -325,35 +354,35 @@ int WebPGetInfo(const uint8_t* data, uint32_t data_size, // check signature if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) { return 0; // Wrong signature. - } - const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); - const int key_frame = !(bits & 1); - if (!key_frame) { // Not a keyframe. - return 0; - } - const int profile = (bits >> 1) & 7; - const int show_frame = (bits >> 4) & 1; - const uint32_t partition_length = (bits >> 5); - if (profile > 3) { - return 0; // unknown profile - } - if (!show_frame) { - return 0; // first frame is invisible! - } - if (partition_length >= chunk_size) { - return 0; // inconsistent size information. - } + } else { + const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); + const int key_frame = !(bits & 1); + const int w = ((data[7] << 8) | data[6]) & 0x3fff; + const int h = ((data[9] << 8) | data[8]) & 0x3fff; - const int w = ((data[7] << 8) | data[6]) & 0x3fff; - const int h = ((data[9] << 8) | data[8]) & 0x3fff; - if (width) { - *width = w; - } - if (height) { - *height = h; - } + if (!key_frame) { // Not a keyframe. + return 0; + } - return 1; + if (((bits >> 1) & 7) > 3) { + return 0; // unknown profile + } + if (!((bits >> 4) & 1)) { + return 0; // first frame is invisible! + } + if (((bits >> 5)) >= chunk_size) { // partition_length + return 0; // inconsistent size information. + } + + if (width) { + *width = w; + } + if (height) { + *height = h; + } + + return 1; + } } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/third_party/libwebp/yuv.c b/third_party/libwebp/yuv.c index 32927fb..30f59c1 100644 --- a/third_party/libwebp/yuv.c +++ b/third_party/libwebp/yuv.c @@ -24,18 +24,19 @@ uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN]; static int done = 0; void VP8YUVInit() { + int i; if (done) { return; } - for (int i = 0; i < 256; ++i) { + for (i = 0; i < 256; ++i) { VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX; VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF; VP8kVToG[i] = -45773 * (i - 128); VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX; } - for (int i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) { - const int j = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX; - VP8kClip[i - YUV_RANGE_MIN] = (j < 0) ? 0 : (j > 255) ? 255 : j; + for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) { + const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX; + VP8kClip[i - YUV_RANGE_MIN] = (k < 0) ? 0 : (k > 255) ? 255 : k; } done = 1; } |