diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-02-10 22:37:07 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-02-10 22:37:07 -0300 |
commit | abb985e755ccf858149294868eff8a9a9feca67e (patch) | |
tree | 2a82fd9f87ddecfb14b08d8599bb2417b3cea7ff /drivers/webp/utils | |
parent | 1c7726820ec53b486e946bb42cac98a600c5bdb5 (diff) |
Reverted to older version of WebP, newer one crashed on Android.
Diffstat (limited to 'drivers/webp/utils')
26 files changed, 391 insertions, 1045 deletions
diff --git a/drivers/webp/utils/alpha_processing.c b/drivers/webp/utils/alpha_processing.c deleted file mode 100644 index 7362ff94a5..0000000000 --- a/drivers/webp/utils/alpha_processing.c +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Utilities for processing transparent channel. -// -// Author: Skal (pascal.massimino@gmail.com) - -#include <assert.h> -#include "./alpha_processing.h" - -// Tables can be faster on some platform but incur some extra binary size (~2k). -// #define USE_TABLES_FOR_ALPHA_MULT - -// ----------------------------------------------------------------------------- - -#define MFIX 24 // 24bit fixed-point arithmetic -#define HALF ((1u << MFIX) >> 1) -#define KINV_255 ((1u << MFIX) / 255u) - -static uint32_t Mult(uint8_t x, uint32_t mult) { - const uint32_t v = (x * mult + HALF) >> MFIX; - assert(v <= 255); // <- 24bit precision is enough to ensure that. - return v; -} - -#ifdef USE_TABLES_FOR_ALPHA_MULT - -static const uint32_t kMultTables[2][256] = { - { // (255u << MFIX) / alpha - 0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000, - 0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2, - 0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000, - 0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8, - 0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3, - 0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492, - 0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3, - 0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8, - 0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7, - 0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0, - 0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4, - 0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6, - 0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace, - 0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a, - 0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf, - 0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b, - 0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d, - 0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec, - 0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9, - 0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249, - 0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70, - 0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213, - 0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10, - 0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5, - 0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed, - 0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a, - 0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741, - 0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0, - 0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e, - 0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157, - 0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67, - 0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4, - 0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc, - 0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b, - 0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830, - 0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be, - 0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276, - 0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc, - 0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2, - 0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358, - 0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0, - 0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465, - 0x01030c30, 0x01020612, 0x01010204, 0x01000000 }, - { // alpha * KINV_255 - 0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, - 0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b, - 0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111, - 0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717, - 0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d, - 0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323, - 0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929, - 0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f, - 0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535, - 0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b, - 0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141, - 0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747, - 0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d, - 0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353, - 0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959, - 0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f, - 0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565, - 0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b, - 0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171, - 0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777, - 0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d, - 0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383, - 0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989, - 0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f, - 0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595, - 0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b, - 0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1, - 0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7, - 0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad, - 0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3, - 0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9, - 0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf, - 0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5, - 0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb, - 0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1, - 0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7, - 0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd, - 0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3, - 0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9, - 0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef, - 0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5, - 0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb, - 0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff } -}; - -static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { - return kMultTables[!inverse][a]; -} - -#else - -static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { - return inverse ? (255u << MFIX) / a : a * KINV_255; -} - -#endif // USE_TABLES_FOR_ALPHA_MULT - -void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse) { - int x; - for (x = 0; x < width; ++x) { - const uint32_t argb = ptr[x]; - if (argb < 0xff000000u) { // alpha < 255 - if (argb <= 0x00ffffffu) { // alpha == 0 - ptr[x] = 0; - } else { - const uint32_t alpha = (argb >> 24) & 0xff; - const uint32_t scale = GetScale(alpha, inverse); - uint32_t out = argb & 0xff000000u; - out |= Mult(argb >> 0, scale) << 0; - out |= Mult(argb >> 8, scale) << 8; - out |= Mult(argb >> 16, scale) << 16; - ptr[x] = out; - } - } - } -} - -void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, - int inverse) { - int n; - for (n = 0; n < num_rows; ++n) { - WebPMultARGBRow((uint32_t*)ptr, width, inverse); - ptr += stride; - } -} - -void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha, - int width, int inverse) { - int x; - for (x = 0; x < width; ++x) { - const uint32_t a = alpha[x]; - if (a != 255) { - if (a == 0) { - ptr[x] = 0; - } else { - const uint32_t scale = GetScale(a, inverse); - ptr[x] = Mult(ptr[x], scale); - } - } - } -} - -void WebPMultRows(uint8_t* ptr, int stride, - const uint8_t* alpha, int alpha_stride, - int width, int num_rows, int inverse) { - int n; - for (n = 0; n < num_rows; ++n) { - WebPMultRow(ptr, alpha, width, inverse); - ptr += stride; - alpha += alpha_stride; - } -} - -#undef KINV_255 -#undef HALF -#undef MFIX - diff --git a/drivers/webp/utils/alpha_processing.h b/drivers/webp/utils/alpha_processing.h deleted file mode 100644 index 80e1ae45dd..0000000000 --- a/drivers/webp/utils/alpha_processing.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Utilities for processing transparent channel. -// -// Author: Skal (pascal.massimino@gmail.com) - -#ifndef WEBP_UTILS_ALPHA_PROCESSING_H_ -#define WEBP_UTILS_ALPHA_PROCESSING_H_ - -#include "../webp/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B). -// Un-Multiply operation transforms x into x * 255 / A. - -// Pre-Multiply or Un-Multiply (if 'inverse' is true) argb values in a row. -void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse); - -// Same a WebPMultARGBRow(), but for several rows. -void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, - int inverse); - -// Same for a row of single values, with side alpha values. -void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha, - int width, int inverse); - -// Same a WebPMultRow(), but for several 'num_rows' rows. -void WebPMultRows(uint8_t* ptr, int stride, - const uint8_t* alpha, int alpha_stride, - int width, int num_rows, int inverse); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // WEBP_UTILS_ALPHA_PROCESSING_H_ diff --git a/drivers/webp/utils/bit_reader.c b/drivers/webp/utils/bit_reader.c index bfa4d7d2e2..1afb1db890 100644 --- a/drivers/webp/utils/bit_reader.c +++ b/drivers/webp/utils/bit_reader.c @@ -1,10 +1,8 @@ // Copyright 2010 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Boolean decoder @@ -13,12 +11,12 @@ #include "./bit_reader.h" -#ifndef USE_RIGHT_JUSTIFY -#define MK(X) (((range_t)(X) << (BITS)) | (MASK)) -#else -#define MK(X) ((range_t)(X)) +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { #endif +#define MK(X) (((bit_t)(X) << (BITS)) | (MASK)) + //------------------------------------------------------------------------------ // VP8BitReader @@ -31,7 +29,7 @@ void VP8InitBitReader(VP8BitReader* const br, br->buf_ = start; br->buf_end_ = end; br->value_ = 0; - br->bits_ = -8; // to load the very first 8bits + br->missing_ = 8; // to load the very first 8bits br->eof_ = 0; } @@ -48,7 +46,7 @@ const uint8_t kVP8Log2Range[128] = { }; // range = (range << kVP8Log2Range[range]) + trailing 1's -const range_t kVP8NewRange[128] = { +const bit_t kVP8NewRange[128] = { MK(127), MK(127), MK(191), MK(127), MK(159), MK(191), MK(223), MK(127), MK(143), MK(159), MK(175), MK(191), MK(207), MK(223), MK(239), MK(127), MK(135), MK(143), MK(151), MK(159), MK(167), MK(175), MK(183), MK(191), @@ -73,19 +71,9 @@ void VP8LoadFinalBytes(VP8BitReader* const br) { assert(br != NULL && br->buf_ != NULL); // Only read 8bits at a time if (br->buf_ < br->buf_end_) { -#ifndef USE_RIGHT_JUSTIFY - br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 - br->bits_); -#else - br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8); -#endif - br->bits_ += 8; - } else if (!br->eof_) { -#ifdef USE_RIGHT_JUSTIFY - // These are not strictly needed, but it makes the behaviour - // consistent for both USE_RIGHT_JUSTIFY and !USE_RIGHT_JUSTIFY. - br->value_ <<= 8; - br->bits_ += 8; -#endif + br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 + br->missing_); + br->missing_ -= 8; + } else { br->eof_ = 1; } } @@ -111,10 +99,6 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { #define MAX_NUM_BIT_READ 25 -#define LBITS 64 // Number of bits prefetched. -#define WBITS 32 // Minimum number of bytes needed after VP8LFillBitWindow. -#define LOG8_WBITS 4 // Number of bytes needed to store WBITS bits. - static const uint32_t kBitMask[MAX_NUM_BIT_READ] = { 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215 @@ -136,7 +120,7 @@ void VP8LInitBitReader(VP8LBitReader* const br, br->eos_ = 0; br->error_ = 0; for (i = 0; i < sizeof(br->val_) && i < br->len_; ++i) { - br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (8 * i); + br->val_ |= ((uint64_t)br->buf_[br->pos_]) << (8 * i); ++br->pos_; } } @@ -151,57 +135,95 @@ void VP8LBitReaderSetBuffer(VP8LBitReader* const br, br->len_ = len; } -// If not at EOS, reload up to LBITS byte-by-byte static void ShiftBytes(VP8LBitReader* const br) { while (br->bit_pos_ >= 8 && br->pos_ < br->len_) { br->val_ >>= 8; - br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (LBITS - 8); + br->val_ |= ((uint64_t)br->buf_[br->pos_]) << 56; ++br->pos_; br->bit_pos_ -= 8; } } void VP8LFillBitWindow(VP8LBitReader* const br) { - if (br->bit_pos_ >= WBITS) { -#if (defined(__x86_64__) || defined(_M_X64)) - if (br->pos_ + sizeof(br->val_) < br->len_) { - br->val_ >>= WBITS; - br->bit_pos_ -= WBITS; + if (br->bit_pos_ >= 32) { +#if defined(__x86_64__) || defined(_M_X64) + if (br->pos_ + 8 < br->len_) { + br->val_ >>= 32; // The expression below needs a little-endian arch to work correctly. // This gives a large speedup for decoding speed. - br->val_ |= *(const vp8l_val_t*)(br->buf_ + br->pos_) << (LBITS - WBITS); - br->pos_ += LOG8_WBITS; - return; + br->val_ |= *(const uint64_t *)(br->buf_ + br->pos_) << 32; + br->pos_ += 4; + br->bit_pos_ -= 32; + } else { + // Slow path. + ShiftBytes(br); } +#else + // Always the slow path. + ShiftBytes(br); #endif - ShiftBytes(br); // Slow path. - if (br->pos_ == br->len_ && br->bit_pos_ >= LBITS) { + } + if (br->pos_ == br->len_ && br->bit_pos_ == 64) { + br->eos_ = 1; + } +} + +uint32_t VP8LReadOneBit(VP8LBitReader* const br) { + const uint32_t val = (br->val_ >> br->bit_pos_) & 1; + // Flag an error at end_of_stream. + if (!br->eos_) { + ++br->bit_pos_; + if (br->bit_pos_ >= 32) { + ShiftBytes(br); + } + // After this last bit is read, check if eos needs to be flagged. + if (br->pos_ == br->len_ && br->bit_pos_ == 64) { br->eos_ = 1; } + } else { + br->error_ = 1; } + return val; } uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) { + uint32_t val = 0; assert(n_bits >= 0); // Flag an error if end_of_stream or n_bits is more than allowed limit. if (!br->eos_ && n_bits < MAX_NUM_BIT_READ) { - const uint32_t val = - (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits]; - const int new_bits = br->bit_pos_ + n_bits; - br->bit_pos_ = new_bits; // If this read is going to cross the read buffer, set the eos flag. if (br->pos_ == br->len_) { - if (new_bits >= LBITS) { + if ((br->bit_pos_ + n_bits) >= 64) { br->eos_ = 1; + if ((br->bit_pos_ + n_bits) > 64) return val; + } + } + val = (br->val_ >> br->bit_pos_) & kBitMask[n_bits]; + br->bit_pos_ += n_bits; + if (br->bit_pos_ >= 40) { + if (br->pos_ + 5 < br->len_) { + br->val_ >>= 40; + br->val_ |= + (((uint64_t)br->buf_[br->pos_ + 0]) << 24) | + (((uint64_t)br->buf_[br->pos_ + 1]) << 32) | + (((uint64_t)br->buf_[br->pos_ + 2]) << 40) | + (((uint64_t)br->buf_[br->pos_ + 3]) << 48) | + (((uint64_t)br->buf_[br->pos_ + 4]) << 56); + br->pos_ += 5; + br->bit_pos_ -= 40; + } + if (br->bit_pos_ >= 8) { + ShiftBytes(br); } } - ShiftBytes(br); - return val; } else { br->error_ = 1; - return 0; } + return val; } //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/bit_reader.h b/drivers/webp/utils/bit_reader.h index 98df98a767..36fc13e2da 100644 --- a/drivers/webp/utils/bit_reader.h +++ b/drivers/webp/utils/bit_reader.h @@ -1,10 +1,8 @@ // Copyright 2010 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Boolean decoder @@ -19,86 +17,18 @@ #ifdef _MSC_VER #include <stdlib.h> // _byteswap_ulong #endif +#include <string.h> // For memcpy #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -// The Boolean decoder needs to maintain infinite precision on the value_ field. -// However, since range_ is only 8bit, we only need an active window of 8 bits -// for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls -// below 128, range_ is updated, and fresh bits read from the bitstream are -// brought in as LSB. -// To avoid reading the fresh bits one by one (slow), we cache a few of them -// ahead (actually, we cache BITS of them ahead. See below). There's two -// strategies regarding how to shift these looked-ahead fresh bits into the -// 8bit window of value_: either we shift them in, while keeping the position of -// the window fixed. Or we slide the window to the right while keeping the cache -// bits at a fixed, right-justified, position. -// -// Example, for BITS=16: here is the content of value_ for both strategies: -// -// !USE_RIGHT_JUSTIFY || USE_RIGHT_JUSTIFY -// || -// <- 8b -><- 8b -><- BITS bits -> || <- 8b+3b -><- 8b -><- 13 bits -> -// [unused][value_][cached bits][0] || [unused...][value_][cached bits] -// [........00vvvvvvBBBBBBBBBBBBB000]LSB || [...........00vvvvvvBBBBBBBBBBBBB] -// || -// After calling VP8Shift(), where we need to shift away two zeros: -// [........vvvvvvvvBBBBBBBBBBB00000]LSB || [.............vvvvvvvvBBBBBBBBBBB] -// || -// Just before we need to call VP8LoadNewBytes(), the situation is: -// [........vvvvvv000000000000000000]LSB || [..........................vvvvvv] -// || -// And just after calling VP8LoadNewBytes(): -// [........vvvvvvvvBBBBBBBBBBBBBBBB]LSB || [........vvvvvvvvBBBBBBBBBBBBBBBB] -// -// -> we're back to eight active 'value_' bits (marked 'v') and BITS cached -// bits (marked 'B') -// -// The right-justify strategy tends to use less shifts and is often faster. - -//------------------------------------------------------------------------------ -// BITS can be any multiple of 8 from 8 to 56 (inclusive). -// Pick values that fit natural register size. - -#if !defined(WEBP_REFERENCE_IMPLEMENTATION) - -#define USE_RIGHT_JUSTIFY - -#if defined(__i386__) || defined(_M_IX86) // x86 32bit -#define BITS 16 -#elif defined(__x86_64__) || defined(_M_X64) // x86 64bit -#define BITS 56 -#elif defined(__arm__) || defined(_M_ARM) // ARM -#define BITS 24 -#else // reasonable default -#define BITS 24 -#endif - -#else // reference choices - -#define USE_RIGHT_JUSTIFY -#define BITS 8 - -#endif - -//------------------------------------------------------------------------------ -// Derived types and constants - -// bit_t = natural register type -// lbit_t = natural type for memory I/O - -#if (BITS > 32) -typedef uint64_t bit_t; -typedef uint64_t lbit_t; -#elif (BITS == 32) -typedef uint64_t bit_t; -typedef uint32_t lbit_t; -#elif (BITS == 24) -typedef uint32_t bit_t; -typedef uint32_t lbit_t; +#define BITS 32 // can be 32, 16 or 8 +#define MASK ((((bit_t)1) << (BITS)) - 1) +#if (BITS == 32) +typedef uint64_t bit_t; // natural register type +typedef uint32_t lbit_t; // natural type for memory I/O #elif (BITS == 16) typedef uint32_t bit_t; typedef uint16_t lbit_t; @@ -107,15 +37,8 @@ typedef uint32_t bit_t; typedef uint8_t lbit_t; #endif -#ifndef USE_RIGHT_JUSTIFY -typedef bit_t range_t; // type for storing range_ -#define MASK ((((bit_t)1) << (BITS)) - 1) -#else -typedef uint32_t range_t; // range_ only uses 8bits here. No need for bit_t. -#endif - //------------------------------------------------------------------------------ -// Bitreader +// Bitreader and code-tree reader typedef struct VP8BitReader VP8BitReader; struct VP8BitReader { @@ -124,9 +47,9 @@ struct VP8BitReader { int eof_; // true if input is exhausted // boolean decoder - range_t range_; // current range minus 1. In [127, 254] interval. - bit_t value_; // current value - int bits_; // number of valid bits left + bit_t range_; // current range minus 1. In [127, 254] interval. + bit_t value_; // current value + int missing_; // number of missing bits in value_ (8bit) }; // Initialize the bit reader and the boolean decoder. @@ -144,160 +67,98 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); // Read a bit with proba 'prob'. Speed-critical function! extern const uint8_t kVP8Log2Range[128]; -extern const range_t kVP8NewRange[128]; +extern const bit_t kVP8NewRange[128]; void VP8LoadFinalBytes(VP8BitReader* const br); // special case for the tail static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) { - assert(br != NULL && br->buf_ != NULL); + assert(br && br->buf_); // Read 'BITS' bits at a time if possible. if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) { // convert memory type to register type (with some zero'ing!) bit_t bits; - const lbit_t in_bits = *(const lbit_t*)br->buf_; + lbit_t in_bits = *(lbit_t*)br->buf_; br->buf_ += (BITS) >> 3; #if !defined(__BIG_ENDIAN__) -#if (BITS > 32) -// gcc 4.3 has builtin functions for swap32/swap64 -#if defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - bits = (bit_t)__builtin_bswap64(in_bits); -#elif defined(_MSC_VER) - bits = (bit_t)_byteswap_uint64(in_bits); -#elif defined(__x86_64__) - __asm__ volatile("bswapq %0" : "=r"(bits) : "0"(in_bits)); -#else // generic code for swapping 64-bit values (suggested by bdb@) - bits = (bit_t)in_bits; - bits = ((bits & 0xffffffff00000000ull) >> 32) | - ((bits & 0x00000000ffffffffull) << 32); - bits = ((bits & 0xffff0000ffff0000ull) >> 16) | - ((bits & 0x0000ffff0000ffffull) << 16); - bits = ((bits & 0xff00ff00ff00ff00ull) >> 8) | - ((bits & 0x00ff00ff00ff00ffull) << 8); -#endif - bits >>= 64 - BITS; -#elif (BITS >= 24) +#if (BITS == 32) #if defined(__i386__) || defined(__x86_64__) - { - lbit_t swapped_in_bits; - __asm__ volatile("bswap %k0" : "=r"(swapped_in_bits) : "0"(in_bits)); - bits = (bit_t)swapped_in_bits; // 24b/32b -> 32b/64b zero-extension - } + __asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits)); + bits = (bit_t)in_bits; // 32b -> 64b zero-extension #elif defined(_MSC_VER) - bits = (bit_t)_byteswap_ulong(in_bits); + bits = _byteswap_ulong(in_bits); #else bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00) | ((in_bits << 8) & 0xff0000) | (in_bits << 24); #endif // x86 - bits >>= (32 - BITS); #elif (BITS == 16) // gcc will recognize a 'rorw $8, ...' here: bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8); -#else // BITS == 8 - bits = (bit_t)in_bits; #endif -#else // BIG_ENDIAN +#else // LITTLE_ENDIAN bits = (bit_t)in_bits; - if (BITS != 8 * sizeof(bit_t)) bits >>= (8 * sizeof(bit_t) - BITS); -#endif -#ifndef USE_RIGHT_JUSTIFY - br->value_ |= bits << (-br->bits_); -#else - br->value_ = bits | (br->value_ << (BITS)); #endif - br->bits_ += (BITS); + br->value_ |= bits << br->missing_; + br->missing_ -= (BITS); } else { VP8LoadFinalBytes(br); // no need to be inlined } } -static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, range_t split) { - if (br->bits_ < 0) { // Make sure we have a least BITS bits in 'value_' +static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, bit_t split) { + const bit_t value_split = split | (MASK); + if (br->missing_ > 0) { // Make sure we have a least BITS bits in 'value_' VP8LoadNewBytes(br); } -#ifndef USE_RIGHT_JUSTIFY - split |= (MASK); - if (br->value_ > split) { - br->range_ -= split + 1; - br->value_ -= split + 1; + if (br->value_ > value_split) { + br->range_ -= value_split + 1; + br->value_ -= value_split + 1; return 1; } else { - br->range_ = split; + br->range_ = value_split; return 0; } -#else - { - const int pos = br->bits_; - const range_t value = (range_t)(br->value_ >> pos); - if (value > split) { - br->range_ -= split + 1; - br->value_ -= (bit_t)(split + 1) << pos; - return 1; - } else { - br->range_ = split; - return 0; - } - } -#endif } static WEBP_INLINE void VP8Shift(VP8BitReader* const br) { -#ifndef USE_RIGHT_JUSTIFY // range_ is in [0..127] interval here. - const bit_t idx = br->range_ >> (BITS); + const int idx = br->range_ >> (BITS); const int shift = kVP8Log2Range[idx]; br->range_ = kVP8NewRange[idx]; br->value_ <<= shift; - br->bits_ -= shift; -#else - const int shift = kVP8Log2Range[br->range_]; - assert(br->range_ < (range_t)128); - br->range_ = kVP8NewRange[br->range_]; - br->bits_ -= shift; -#endif + br->missing_ += shift; } static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { -#ifndef USE_RIGHT_JUSTIFY // It's important to avoid generating a 64bit x 64bit multiply here. // We just need an 8b x 8b after all. - const range_t split = - (range_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8); + const bit_t split = + (bit_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8); const int bit = VP8BitUpdate(br, split); - if (br->range_ <= (((range_t)0x7e << (BITS)) | (MASK))) { + if (br->range_ <= (((bit_t)0x7e << (BITS)) | (MASK))) { VP8Shift(br); } return bit; -#else - const range_t split = (br->range_ * prob) >> 8; - const int bit = VP8BitUpdate(br, split); - if (br->range_ <= (range_t)0x7e) { - VP8Shift(br); - } - return bit; -#endif } static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) { - const range_t split = (br->range_ >> 1); + const bit_t split = (br->range_ >> 1); const int bit = VP8BitUpdate(br, split); VP8Shift(br); return bit ? -v : v; } -// ----------------------------------------------------------------------------- -// Bitreader for lossless format -typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit. +// ----------------------------------------------------------------------------- +// Bitreader typedef struct { - vp8l_val_t val_; // pre-fetched bits - const uint8_t* buf_; // input byte buffer - size_t len_; // buffer length - size_t pos_; // byte position in buf_ - int bit_pos_; // current bit-reading position in val_ - int eos_; // bitstream is finished - int error_; // an error occurred (buffer overflow attempt...) + uint64_t val_; + const uint8_t* buf_; + size_t len_; + size_t pos_; + int bit_pos_; + int eos_; + int error_; } VP8LBitReader; void VP8LInitBitReader(VP8LBitReader* const br, @@ -313,21 +174,23 @@ void VP8LBitReaderSetBuffer(VP8LBitReader* const br, // Flags eos if this read attempt is going to cross the read buffer. uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits); -// Return the prefetched bits, so they can be looked up. -static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) { - return (uint32_t)(br->val_ >> br->bit_pos_); -} - -// For jumping over a number of bits in the bit stream when accessed with -// VP8LPrefetchBits and VP8LFillBitWindow. -static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) { - br->bit_pos_ = val; +// Reads one bit from Read Buffer. Flags an error in case end_of_stream. +// Flags eos after reading last bit from the buffer. +uint32_t VP8LReadOneBit(VP8LBitReader* const br); + +// VP8LReadOneBitUnsafe is faster than VP8LReadOneBit, but it can be called only +// 32 times after the last VP8LFillBitWindow. Any subsequent calls +// (without VP8LFillBitWindow) will return invalid data. +static WEBP_INLINE uint32_t VP8LReadOneBitUnsafe(VP8LBitReader* const br) { + const uint32_t val = (br->val_ >> br->bit_pos_) & 1; + ++br->bit_pos_; + return val; } -// Advances the read buffer by 4 bytes to make room for reading next 32 bits. +// Advances the Read buffer by 4 bytes to make room for reading next 32 bits. void VP8LFillBitWindow(VP8LBitReader* const br); -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/bit_writer.c b/drivers/webp/utils/bit_writer.c index 29810a1749..671159cacd 100644 --- a/drivers/webp/utils/bit_writer.c +++ b/drivers/webp/utils/bit_writer.c @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Bit writing and boolean coder @@ -17,6 +15,10 @@ #include <stdlib.h> #include "./bit_writer.h" +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + //------------------------------------------------------------------------------ // VP8BitWriter @@ -39,10 +41,7 @@ static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) { bw->error_ = 1; return 0; } - if (bw->pos_ > 0) { - assert(bw->buf_ != NULL); - memcpy(new_buf, bw->buf_, bw->pos_); - } + memcpy(new_buf, bw->buf_, bw->pos_); free(bw->buf_); bw->buf_ = new_buf; bw->max_pos_ = new_size; @@ -252,7 +251,7 @@ void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) { uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3]; const int bits_reserved_in_first_byte = bw->bit_pos_ & 7; const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte; - // implicit & 0xff is assumed for uint8_t arithmetic + // implicit & 0xff is assumed for uint8_t arithmetics *p++ |= bits << bits_reserved_in_first_byte; bits >>= 8 - bits_reserved_in_first_byte; if (bits_left_to_write >= 1) { @@ -280,3 +279,6 @@ void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) { //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/bit_writer.h b/drivers/webp/utils/bit_writer.h index 89a9ead488..f7ca08497f 100644 --- a/drivers/webp/utils/bit_writer.h +++ b/drivers/webp/utils/bit_writer.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Bit writing and boolean coder @@ -16,7 +14,7 @@ #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -118,7 +116,7 @@ void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits); //------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/color_cache.c b/drivers/webp/utils/color_cache.c index 66a44647fd..560f81db10 100644 --- a/drivers/webp/utils/color_cache.c +++ b/drivers/webp/utils/color_cache.c @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Color Cache for WebP Lossless @@ -16,6 +14,10 @@ #include "./color_cache.h" #include "../utils/utils.h" +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + //------------------------------------------------------------------------------ // VP8LColorCache. @@ -37,3 +39,6 @@ void VP8LColorCacheClear(VP8LColorCache* const cc) { } } +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif diff --git a/drivers/webp/utils/color_cache.h b/drivers/webp/utils/color_cache.h index 0f824ed457..13be629f36 100644 --- a/drivers/webp/utils/color_cache.h +++ b/drivers/webp/utils/color_cache.h @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Color Cache for WebP Lossless @@ -17,7 +15,7 @@ #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -63,7 +61,7 @@ void VP8LColorCacheClear(VP8LColorCache* const color_cache); //------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/drivers/webp/utils/filters.c b/drivers/webp/utils/filters.c index 2d15bd0e4a..08f52a3d20 100644 --- a/drivers/webp/utils/filters.c +++ b/drivers/webp/utils/filters.c @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Spatial prediction using various filters @@ -16,17 +14,20 @@ #include <stdlib.h> #include <string.h> +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + //------------------------------------------------------------------------------ // Helpful macro. -# define SANITY_CHECK(in, out) \ - assert(in != NULL); \ - assert(out != NULL); \ - assert(width > 0); \ - assert(height > 0); \ - assert(stride >= width); \ - assert(row >= 0 && num_rows > 0 && row + num_rows <= height); \ - (void)height; // Silence unused warning. +# define SANITY_CHECK(in, out) \ + assert(in != NULL); \ + assert(out != NULL); \ + assert(width > 0); \ + assert(height > 0); \ + assert(bpp > 0); \ + assert(stride >= width * bpp); static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred, uint8_t* dst, int length, int inverse) { @@ -42,33 +43,20 @@ static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred, // Horizontal filter. static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in, - int width, int height, int stride, - int row, int num_rows, - int inverse, uint8_t* out) { - const uint8_t* preds; - const size_t start_offset = row * stride; - const int last_row = row + num_rows; + int width, int height, int bpp, int stride, int inverse, uint8_t* out) { + int h; + const uint8_t* preds = (inverse ? out : in); SANITY_CHECK(in, out); - in += start_offset; - out += start_offset; - preds = inverse ? out : in; - - if (row == 0) { - // Leftmost pixel is the same as input for topmost scanline. - out[0] = in[0]; - PredictLine(in + 1, preds, out + 1, width - 1, inverse); - row = 1; - preds += stride; - in += stride; - out += stride; - } // Filter line-by-line. - while (row < last_row) { - // Leftmost pixel is predicted from above. - PredictLine(in, preds - stride, out, 1, inverse); - PredictLine(in + 1, preds, out + 1, width - 1, inverse); - ++row; + for (h = 0; h < height; ++h) { + // Leftmost pixel is predicted from above (except for topmost scanline). + if (h == 0) { + memcpy((void*)out, (const void*)in, bpp); + } else { + PredictLine(in, preds - stride, out, bpp, inverse); + } + PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse); preds += stride; in += stride; out += stride; @@ -76,61 +64,46 @@ static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in, } static void HorizontalFilter(const uint8_t* data, int width, int height, - int stride, uint8_t* filtered_data) { - DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data); + int bpp, int stride, uint8_t* filtered_data) { + DoHorizontalFilter(data, width, height, bpp, stride, 0, filtered_data); } -static void HorizontalUnfilter(int width, int height, int stride, int row, - int num_rows, uint8_t* data) { - DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data); +static void HorizontalUnfilter(const uint8_t* data, int width, int height, + int bpp, int stride, uint8_t* recon_data) { + DoHorizontalFilter(data, width, height, bpp, stride, 1, recon_data); } //------------------------------------------------------------------------------ // Vertical filter. static WEBP_INLINE void DoVerticalFilter(const uint8_t* in, - int width, int height, int stride, - int row, int num_rows, - int inverse, uint8_t* out) { - const uint8_t* preds; - const size_t start_offset = row * stride; - const int last_row = row + num_rows; + int width, int height, int bpp, int stride, int inverse, uint8_t* out) { + int h; + const uint8_t* preds = (inverse ? out : in); SANITY_CHECK(in, out); - in += start_offset; - out += start_offset; - preds = inverse ? out : in; - - if (row == 0) { - // Very first top-left pixel is copied. - out[0] = in[0]; - // Rest of top scan-line is left-predicted. - PredictLine(in + 1, preds, out + 1, width - 1, inverse); - row = 1; - in += stride; - out += stride; - } else { - // We are starting from in-between. Make sure 'preds' points to prev row. - preds -= stride; - } + + // Very first top-left pixel is copied. + memcpy((void*)out, (const void*)in, bpp); + // Rest of top scan-line is left-predicted. + PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse); // Filter line-by-line. - while (row < last_row) { - PredictLine(in, preds, out, width, inverse); - ++row; - preds += stride; + for (h = 1; h < height; ++h) { in += stride; out += stride; + PredictLine(in, preds, out, bpp * width, inverse); + preds += stride; } } static void VerticalFilter(const uint8_t* data, int width, int height, - int stride, uint8_t* filtered_data) { - DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data); + int bpp, int stride, uint8_t* filtered_data) { + DoVerticalFilter(data, width, height, bpp, stride, 0, filtered_data); } -static void VerticalUnfilter(int width, int height, int stride, int row, - int num_rows, uint8_t* data) { - DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data); +static void VerticalUnfilter(const uint8_t* data, int width, int height, + int bpp, int stride, uint8_t* recon_data) { + DoVerticalFilter(data, width, height, bpp, stride, 1, recon_data); } //------------------------------------------------------------------------------ @@ -138,63 +111,52 @@ static void VerticalUnfilter(int width, int height, int stride, int row, static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) { const int g = a + b - c; - return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit + return (g < 0) ? 0 : (g > 255) ? 255 : g; } -static WEBP_INLINE void DoGradientFilter(const uint8_t* in, - int width, int height, int stride, - int row, int num_rows, - int inverse, uint8_t* out) { - const uint8_t* preds; - const size_t start_offset = row * stride; - const int last_row = row + num_rows; +static WEBP_INLINE +void DoGradientFilter(const uint8_t* in, int width, int height, + int bpp, int stride, int inverse, uint8_t* out) { + const uint8_t* preds = (inverse ? out : in); + int h; SANITY_CHECK(in, out); - in += start_offset; - out += start_offset; - preds = inverse ? out : in; // left prediction for top scan-line - if (row == 0) { - out[0] = in[0]; - PredictLine(in + 1, preds, out + 1, width - 1, inverse); - row = 1; - preds += stride; - in += stride; - out += stride; - } + memcpy((void*)out, (const void*)in, bpp); + PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse); // Filter line-by-line. - while (row < last_row) { + for (h = 1; h < height; ++h) { int w; + preds += stride; + in += stride; + out += stride; // leftmost pixel: predict from above. - PredictLine(in, preds - stride, out, 1, inverse); - for (w = 1; w < width; ++w) { - const int pred = GradientPredictor(preds[w - 1], + PredictLine(in, preds - stride, out, bpp, inverse); + for (w = bpp; w < width * bpp; ++w) { + const int pred = GradientPredictor(preds[w - bpp], preds[w - stride], - preds[w - stride - 1]); + preds[w - stride - bpp]); out[w] = in[w] + (inverse ? pred : -pred); } - ++row; - preds += stride; - in += stride; - out += stride; } } static void GradientFilter(const uint8_t* data, int width, int height, - int stride, uint8_t* filtered_data) { - DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data); + int bpp, int stride, uint8_t* filtered_data) { + DoGradientFilter(data, width, height, bpp, stride, 0, filtered_data); } -static void GradientUnfilter(int width, int height, int stride, int row, - int num_rows, uint8_t* data) { - DoGradientFilter(data, width, height, stride, row, num_rows, 1, data); +static void GradientUnfilter(const uint8_t* data, int width, int height, + int bpp, int stride, uint8_t* recon_data) { + DoGradientFilter(data, width, height, bpp, stride, 1, recon_data); } #undef SANITY_CHECK // ----------------------------------------------------------------------------- -// Quick estimate of a potentially interesting filter mode to try. +// Quick estimate of a potentially interesting filter mode to try, in addition +// to the default NONE. #define SMAX 16 #define SDIFF(a, b) (abs((a) - (b)) >> 4) // Scoring diff, in [0..SMAX) @@ -204,7 +166,6 @@ WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, int i, j; int bins[WEBP_FILTER_LAST][SMAX]; memset(bins, 0, sizeof(bins)); - // We only sample every other pixels. That's enough. for (j = 2; j < height - 1; j += 2) { const uint8_t* const p = data + j * stride; @@ -224,8 +185,7 @@ WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, } } { - int filter; - WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE; + WEBP_FILTER_TYPE filter, best_filter = WEBP_FILTER_NONE; int best_score = 0x7fffffff; for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) { int score = 0; @@ -236,7 +196,7 @@ WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, } if (score < best_score) { best_score = score; - best_filter = (WEBP_FILTER_TYPE)filter; + best_filter = filter; } } return best_filter; @@ -255,7 +215,7 @@ const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST] = { GradientFilter // WEBP_FILTER_GRADIENT }; -const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST] = { +const WebPFilterFunc WebPUnfilters[WEBP_FILTER_LAST] = { NULL, // WEBP_FILTER_NONE HorizontalUnfilter, // WEBP_FILTER_HORIZONTAL VerticalUnfilter, // WEBP_FILTER_VERTICAL @@ -264,3 +224,6 @@ const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST] = { //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/filters.h b/drivers/webp/utils/filters.h index dde39cb5c4..c5cdbd6deb 100644 --- a/drivers/webp/utils/filters.h +++ b/drivers/webp/utils/filters.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Spatial prediction using various filters @@ -16,7 +14,7 @@ #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -32,27 +30,24 @@ typedef enum { } WEBP_FILTER_TYPE; typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height, - int stride, uint8_t* out); -typedef void (*WebPUnfilterFunc)(int width, int height, int stride, - int row, int num_rows, uint8_t* data); + int bpp, int stride, uint8_t* out); // Filter the given data using the given predictor. // 'in' corresponds to a 2-dimensional pixel array of size (stride * height) // in raster order. +// 'bpp' is number of bytes per pixel, and // 'stride' is number of bytes per scan line (with possible padding). // 'out' should be pre-allocated. extern const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST]; -// In-place reconstruct the original data from the given filtered data. -// The reconstruction will be done for 'num_rows' rows starting from 'row' -// (assuming rows upto 'row - 1' are already reconstructed). -extern const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST]; +// Reconstruct the original data from the given filtered data. +extern const WebPFilterFunc WebPUnfilters[WEBP_FILTER_LAST]; // Fast estimate of a potentially good filter. -WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, - int width, int height, int stride); +extern WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, + int width, int height, int stride); -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/huffman.c b/drivers/webp/utils/huffman.c index 8c5739f633..41529cc9da 100644 --- a/drivers/webp/utils/huffman.c +++ b/drivers/webp/utils/huffman.c @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Utilities for building and looking up Huffman trees. @@ -13,14 +11,13 @@ #include <assert.h> #include <stdlib.h> -#include <string.h> #include "./huffman.h" #include "../utils/utils.h" #include "../webp/format_constants.h" -// Uncomment the following to use look-up table for ReverseBits() -// (might be faster on some platform) -// #define USE_LUT_REVERSE_BITS +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif #define NON_EXISTENT_SYMBOL (-1) @@ -53,14 +50,11 @@ static int TreeInit(HuffmanTree* const tree, int num_leaves) { // Note that a Huffman tree is a full binary tree; and in a full binary tree // with L leaves, the total number of nodes N = 2 * L - 1. tree->max_nodes_ = 2 * num_leaves - 1; - assert(tree->max_nodes_ < (1 << 16)); // limit for the lut_jump_ table tree->root_ = (HuffmanTreeNode*)WebPSafeMalloc((uint64_t)tree->max_nodes_, sizeof(*tree->root_)); if (tree->root_ == NULL) return 0; TreeNodeInit(tree->root_); // Initialize root. tree->num_nodes_ = 1; - memset(tree->lut_bits_, 255, sizeof(tree->lut_bits_)); - memset(tree->lut_jump_, 0, sizeof(tree->lut_jump_)); return 1; } @@ -121,54 +115,10 @@ int HuffmanCodeLengthsToCodes(const int* const code_lengths, return 1; } -#ifndef USE_LUT_REVERSE_BITS - -static int ReverseBitsShort(int bits, int num_bits) { - int retval = 0; - int i; - assert(num_bits <= 8); // Not a hard requirement, just for coherency. - for (i = 0; i < num_bits; ++i) { - retval <<= 1; - retval |= bits & 1; - bits >>= 1; - } - return retval; -} - -#else - -static const uint8_t kReversedBits[16] = { // Pre-reversed 4-bit values. - 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, - 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf -}; - -static int ReverseBitsShort(int bits, int num_bits) { - const uint8_t v = (kReversedBits[bits & 0xf] << 4) | kReversedBits[bits >> 4]; - assert(num_bits <= 8); - return v >> (8 - num_bits); -} - -#endif - static int TreeAddSymbol(HuffmanTree* const tree, int symbol, int code, int code_length) { - int step = HUFF_LUT_BITS; - int base_code; HuffmanTreeNode* node = tree->root_; const HuffmanTreeNode* const max_node = tree->root_ + tree->max_nodes_; - assert(symbol == (int16_t)symbol); - if (code_length <= HUFF_LUT_BITS) { - int i; - base_code = ReverseBitsShort(code, code_length); - for (i = 0; i < (1 << (HUFF_LUT_BITS - code_length)); ++i) { - const int idx = base_code | (i << code_length); - tree->lut_symbol_[idx] = (int16_t)symbol; - tree->lut_bits_[idx] = code_length; - } - } else { - base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)), - HUFF_LUT_BITS); - } while (code_length-- > 0) { if (node >= max_node) { return 0; @@ -176,17 +126,14 @@ static int TreeAddSymbol(HuffmanTree* const tree, if (NodeIsEmpty(node)) { if (IsFull(tree)) return 0; // error: too many symbols. AssignChildren(tree, node); - } else if (!HuffmanTreeNodeIsNotLeaf(node)) { + } else if (HuffmanTreeNodeIsLeaf(node)) { return 0; // leaf is already occupied. } node += node->children_ + ((code >> code_length) & 1); - if (--step == 0) { - tree->lut_jump_[base_code] = (int16_t)(node - tree->root_); - } } if (NodeIsEmpty(node)) { node->children_ = 0; // turn newly created node into a leaf. - } else if (HuffmanTreeNodeIsNotLeaf(node)) { + } else if (!HuffmanTreeNodeIsLeaf(node)) { return 0; // trying to assign a symbol to already used code. } node->symbol_ = symbol; // Add symbol in this node. @@ -286,3 +233,6 @@ int HuffmanTreeBuildExplicit(HuffmanTree* const tree, return ok; } +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/huffman.h b/drivers/webp/utils/huffman.h index e8afd27f24..70220a67fb 100644 --- a/drivers/webp/utils/huffman.h +++ b/drivers/webp/utils/huffman.h @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Utilities for building and looking up Huffman trees. @@ -17,7 +15,7 @@ #include <assert.h> #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -28,24 +26,17 @@ typedef struct { } HuffmanTreeNode; // Huffman Tree. -#define HUFF_LUT_BITS 7 -#define HUFF_LUT (1U << HUFF_LUT_BITS) typedef struct HuffmanTree HuffmanTree; struct HuffmanTree { - // Fast lookup for short bit lengths. - uint8_t lut_bits_[HUFF_LUT]; - int16_t lut_symbol_[HUFF_LUT]; - int16_t lut_jump_[HUFF_LUT]; - // Complete tree for lookups. HuffmanTreeNode* root_; // all the nodes, starting at root. int max_nodes_; // max number of nodes int num_nodes_; // number of currently occupied nodes }; -// Returns true if the given node is not a leaf of the Huffman tree. -static WEBP_INLINE int HuffmanTreeNodeIsNotLeaf( +// Returns true if the given node is a leaf of the Huffman tree. +static WEBP_INLINE int HuffmanTreeNodeIsLeaf( const HuffmanTreeNode* const node) { - return node->children_; + return (node->children_ == 0); } // Go down one level. Most critical function. 'right_child' must be 0 or 1. @@ -80,7 +71,7 @@ int HuffmanCodeLengthsToCodes(const int* const code_lengths, int code_lengths_size, int* const huff_codes); -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/huffman_encode.c b/drivers/webp/utils/huffman_encode.c index 9c5986738d..8ccd291d22 100644 --- a/drivers/webp/utils/huffman_encode.c +++ b/drivers/webp/utils/huffman_encode.c @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) @@ -27,7 +25,7 @@ static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) { } // Change the population counts in a way that the consequent -// Huffman tree compression, especially its RLE-part, give smaller output. +// Hufmann tree compression, especially its RLE-part, give smaller output. static int OptimizeHuffmanForRle(int length, int* const counts) { uint8_t* good_for_rle; // 1) Let's make the Huffman code more compatible with rle encoding. @@ -140,8 +138,13 @@ static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) { } else if (t1->total_count_ < t2->total_count_) { return 1; } else { - assert(t1->value_ != t2->value_); - return (t1->value_ < t2->value_) ? -1 : 1; + if (t1->value_ < t2->value_) { + return -1; + } + if (t1->value_ > t2->value_) { + return 1; + } + return 0; } } @@ -190,10 +193,6 @@ static int GenerateOptimalTree(const int* const histogram, int histogram_size, } } - if (tree_size_orig == 0) { // pretty optimal already! - return 1; - } - // 3 * tree_size is enough to cover all the nodes representing a // population and all the inserted nodes combining two existing nodes. // The tree pool needs 2 * (tree_size_orig - 1) entities, and the @@ -235,7 +234,7 @@ static int GenerateOptimalTree(const int* const histogram, int histogram_size, tree_pool[tree_pool_size++] = tree[tree_size - 1]; tree_pool[tree_pool_size++] = tree[tree_size - 2]; count = tree_pool[tree_pool_size - 1].total_count_ + - tree_pool[tree_pool_size - 2].total_count_; + tree_pool[tree_pool_size - 2].total_count_; tree_size -= 2; { // Search for the insertion point. diff --git a/drivers/webp/utils/huffman_encode.h b/drivers/webp/utils/huffman_encode.h index ee51c68c9f..cc3b38d330 100644 --- a/drivers/webp/utils/huffman_encode.h +++ b/drivers/webp/utils/huffman_encode.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) @@ -16,7 +14,7 @@ #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -42,7 +40,7 @@ int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit, HuffmanTreeCode* const tree); -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/drivers/webp/utils/quant_levels.c b/drivers/webp/utils/quant_levels.c index d7c8aab922..f6884392aa 100644 --- a/drivers/webp/utils/quant_levels.c +++ b/drivers/webp/utils/quant_levels.c @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Quantize levels for specified number of quantization-levels ([2, 256]). @@ -16,6 +14,10 @@ #include "./quant_levels.h" +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + #define NUM_SYMBOLS 256 #define MAX_ITER 6 // Maximum number of convergence steps. @@ -138,3 +140,15 @@ int QuantizeLevels(uint8_t* const data, int width, int height, return 1; } +int DequantizeLevels(uint8_t* const data, int width, int height) { + if (data == NULL || width <= 0 || height <= 0) return 0; + // TODO(skal): implement gradient smoothing. + (void)data; + (void)width; + (void)height; + return 1; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/quant_levels.h b/drivers/webp/utils/quant_levels.h index 1cb5a32cae..89ccafe40d 100644 --- a/drivers/webp/utils/quant_levels.h +++ b/drivers/webp/utils/quant_levels.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Alpha plane quantization utility @@ -18,7 +16,7 @@ #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -29,7 +27,12 @@ extern "C" { int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels, uint64_t* const sse); -#ifdef __cplusplus +// Apply post-processing to input 'data' of size 'width'x'height' assuming +// that the source was quantized to a reduced number of levels. +// Returns false in case of error (data is NULL, invalid parameters, ...). +int DequantizeLevels(uint8_t* const data, int width, int height); + +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/quant_levels_dec.c b/drivers/webp/utils/quant_levels_dec.c deleted file mode 100644 index 8489705a2d..0000000000 --- a/drivers/webp/utils/quant_levels_dec.c +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// TODO(skal): implement gradient smoothing. -// -// Author: Skal (pascal.massimino@gmail.com) - -#include "./quant_levels_dec.h" - -int DequantizeLevels(uint8_t* const data, int width, int height, - int row, int num_rows) { - if (data == NULL || width <= 0 || height <= 0 || row < 0 || num_rows < 0 || - row + num_rows > height) { - return 0; - } - return 1; -} - diff --git a/drivers/webp/utils/quant_levels_dec.h b/drivers/webp/utils/quant_levels_dec.h deleted file mode 100644 index 0288383aeb..0000000000 --- a/drivers/webp/utils/quant_levels_dec.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Alpha plane de-quantization utility -// -// Author: Vikas Arora (vikasa@google.com) - -#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_ -#define WEBP_UTILS_QUANT_LEVELS_DEC_H_ - -#include "../webp/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Apply post-processing to input 'data' of size 'width'x'height' assuming that -// the source was quantized to a reduced number of levels. The post-processing -// will be applied to 'num_rows' rows of 'data' starting from 'row'. -// Returns false in case of error (data is NULL, invalid parameters, ...). -int DequantizeLevels(uint8_t* const data, int width, int height, - int row, int num_rows); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* WEBP_UTILS_QUANT_LEVELS_DEC_H_ */ diff --git a/drivers/webp/utils/random.c b/drivers/webp/utils/random.c deleted file mode 100644 index 24e96ad648..0000000000 --- a/drivers/webp/utils/random.c +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Pseudo-random utilities -// -// Author: Skal (pascal.massimino@gmail.com) - -#include <string.h> -#include "./random.h" - -//------------------------------------------------------------------------------ - -// 31b-range values -static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = { - 0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828, - 0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da, - 0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f, - 0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2, - 0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c, - 0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd, - 0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3, - 0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b, - 0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494, - 0x27e5ed3c -}; - -void VP8InitRandom(VP8Random* const rg, float dithering) { - memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_)); - rg->index1_ = 0; - rg->index2_ = 31; - rg->amp_ = (dithering < 0.0) ? 0 - : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX) - : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering); -} - -//------------------------------------------------------------------------------ - diff --git a/drivers/webp/utils/random.h b/drivers/webp/utils/random.h deleted file mode 100644 index 08a83e9674..0000000000 --- a/drivers/webp/utils/random.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Pseudo-random utilities -// -// Author: Skal (pascal.massimino@gmail.com) - -#ifndef WEBP_UTILS_RANDOM_H_ -#define WEBP_UTILS_RANDOM_H_ - -#include <assert.h> -#include "../webp/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering -#define VP8_RANDOM_TABLE_SIZE 55 - -typedef struct { - int index1_, index2_; - uint32_t tab_[VP8_RANDOM_TABLE_SIZE]; - int amp_; -} VP8Random; - -// Initializes random generator with an amplitude 'dithering' in range [0..1]. -void VP8InitRandom(VP8Random* const rg, float dithering); - -// Returns a centered pseudo-random number with 'num_bits' amplitude. -// (uses D.Knuth's Difference-based random generator). -// 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision. -static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits, - int amp) { - int diff; - assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31); - diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_]; - if (diff < 0) diff += (1u << 31); - rg->tab_[rg->index1_] = diff; - if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0; - if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0; - diff = (diff << 1) >> (32 - num_bits); // sign-extend, 0-center - diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range - diff += 1 << (num_bits - 1); // shift back to 0.5-center - return diff; -} - -static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) { - return VP8RandomBits2(rg, num_bits, rg->amp_); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* WEBP_UTILS_RANDOM_H_ */ diff --git a/drivers/webp/utils/rescaler.c b/drivers/webp/utils/rescaler.c index 7061246024..9825dcbc5f 100644 --- a/drivers/webp/utils/rescaler.c +++ b/drivers/webp/utils/rescaler.c @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Rescaling functions @@ -17,8 +15,12 @@ //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + #define RFIX 30 -#define MULT_FIX(x, y) (((int64_t)(x) * (y) + (1 << (RFIX - 1))) >> RFIX) +#define MULT_FIX(x,y) (((int64_t)(x) * (y) + (1 << (RFIX - 1))) >> RFIX) void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height, uint8_t* const dst, int dst_width, int dst_height, @@ -119,11 +121,6 @@ uint8_t* WebPRescalerExportRow(WebPRescaler* const wrk) { //------------------------------------------------------------------------------ // all-in-one calls -int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) { - const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub; - return (num_lines > max_num_lines) ? max_num_lines : num_lines; -} - int WebPRescalerImport(WebPRescaler* const wrk, int num_lines, const uint8_t* src, int src_stride) { int total_imported = 0; @@ -150,3 +147,6 @@ int WebPRescalerExport(WebPRescaler* const rescaler) { //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/rescaler.h b/drivers/webp/utils/rescaler.h index 68e49cee55..ef93d465f0 100644 --- a/drivers/webp/utils/rescaler.h +++ b/drivers/webp/utils/rescaler.h @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Rescaling functions @@ -14,7 +12,7 @@ #ifndef WEBP_UTILS_RESCALER_H_ #define WEBP_UTILS_RESCALER_H_ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -38,8 +36,7 @@ typedef struct { } WebPRescaler; // Initialize a rescaler given scratch area 'work' and dimensions of src & dst. -void WebPRescalerInit(WebPRescaler* const rescaler, - int src_width, int src_height, +void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height, uint8_t* const dst, int dst_width, int dst_height, int dst_stride, int num_channels, @@ -47,11 +44,6 @@ void WebPRescalerInit(WebPRescaler* const rescaler, int y_add, int y_sub, int32_t* const work); -// Returns the number of input lines needed next to produce one output line, -// considering that the maximum available input lines are 'max_num_lines'. -int WebPRescaleNeededLines(const WebPRescaler* const rescaler, - int max_num_lines); - // Import a row of data and save its contribution in the rescaler. // 'channel' denotes the channel number to be imported. void WebPRescalerImportRow(WebPRescaler* const rescaler, @@ -70,14 +62,14 @@ int WebPRescalerHasPendingOutput(const WebPRescaler* const rescaler) { // Export one row from rescaler. Returns the pointer where output was written, // or NULL if no row was pending. -uint8_t* WebPRescalerExportRow(WebPRescaler* const rescaler); +uint8_t* WebPRescalerExportRow(WebPRescaler* const wrk); // Export as many rows as possible. Return the numbers of rows written. -int WebPRescalerExport(WebPRescaler* const rescaler); +int WebPRescalerExport(WebPRescaler* const wrk); //------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/thread.c b/drivers/webp/utils/thread.c index a9e3fae8de..ce89cf9dc7 100644 --- a/drivers/webp/utils/thread.c +++ b/drivers/webp/utils/thread.c @@ -1,20 +1,26 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Multi-threaded worker // // Author: Skal (pascal.massimino@gmail.com) +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <assert.h> #include <string.h> // for memset() #include "./thread.h" +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + #ifdef WEBP_USE_THREAD #if defined(_WIN32) @@ -122,14 +128,14 @@ static int pthread_cond_wait(pthread_cond_t* const condition, return !ok; } -#else // !_WIN32 +#else // _WIN32 # define THREADFN void* # define THREAD_RETURN(val) val -#endif // _WIN32 +#endif //------------------------------------------------------------------------------ -static THREADFN ThreadLoop(void* ptr) { +static THREADFN WebPWorkerThreadLoop(void *ptr) { // thread loop WebPWorker* const worker = (WebPWorker*)ptr; int done = 0; while (!done) { @@ -138,7 +144,9 @@ static THREADFN ThreadLoop(void* ptr) { pthread_cond_wait(&worker->condition_, &worker->mutex_); } if (worker->status_ == WORK) { - WebPWorkerExecute(worker); + if (worker->hook) { + worker->had_error |= !worker->hook(worker->data1, worker->data2); + } worker->status_ = OK; } else if (worker->status_ == NOT_OK) { // finish the worker done = 1; @@ -151,8 +159,8 @@ static THREADFN ThreadLoop(void* ptr) { } // main thread state control -static void ChangeState(WebPWorker* const worker, - WebPWorkerStatus new_status) { +static void WebPWorkerChangeState(WebPWorker* const worker, + WebPWorkerStatus new_status) { // no-op when attempting to change state on a thread that didn't come up if (worker->status_ < OK) return; @@ -169,7 +177,7 @@ static void ChangeState(WebPWorker* const worker, pthread_mutex_unlock(&worker->mutex_); } -#endif // WEBP_USE_THREAD +#endif //------------------------------------------------------------------------------ @@ -180,7 +188,7 @@ void WebPWorkerInit(WebPWorker* const worker) { int WebPWorkerSync(WebPWorker* const worker) { #ifdef WEBP_USE_THREAD - ChangeState(worker, OK); + WebPWorkerChangeState(worker, OK); #endif assert(worker->status_ <= OK); return !worker->had_error; @@ -196,7 +204,7 @@ int WebPWorkerReset(WebPWorker* const worker) { return 0; } pthread_mutex_lock(&worker->mutex_); - ok = !pthread_create(&worker->thread_, NULL, ThreadLoop, worker); + ok = !pthread_create(&worker->thread_, NULL, WebPWorkerThreadLoop, worker); if (ok) worker->status_ = OK; pthread_mutex_unlock(&worker->mutex_); #else @@ -209,24 +217,19 @@ int WebPWorkerReset(WebPWorker* const worker) { return ok; } -void WebPWorkerExecute(WebPWorker* const worker) { - if (worker->hook != NULL) { - worker->had_error |= !worker->hook(worker->data1, worker->data2); - } -} - void WebPWorkerLaunch(WebPWorker* const worker) { #ifdef WEBP_USE_THREAD - ChangeState(worker, WORK); + WebPWorkerChangeState(worker, WORK); #else - WebPWorkerExecute(worker); + if (worker->hook) + worker->had_error |= !worker->hook(worker->data1, worker->data2); #endif } void WebPWorkerEnd(WebPWorker* const worker) { if (worker->status_ >= OK) { #ifdef WEBP_USE_THREAD - ChangeState(worker, NOT_OK); + WebPWorkerChangeState(worker, NOT_OK); pthread_join(worker->thread_, NULL); pthread_mutex_destroy(&worker->mutex_); pthread_cond_destroy(&worker->condition_); @@ -239,3 +242,6 @@ void WebPWorkerEnd(WebPWorker* const worker) { //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/thread.h b/drivers/webp/utils/thread.h index aef33bdaf2..3191890b76 100644 --- a/drivers/webp/utils/thread.h +++ b/drivers/webp/utils/thread.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Multi-threaded worker @@ -14,15 +12,11 @@ #ifndef WEBP_UTILS_THREAD_H_ #define WEBP_UTILS_THREAD_H_ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -#ifdef WEBP_USE_THREAD +#if WEBP_USE_THREAD #if defined(_WIN32) @@ -55,7 +49,7 @@ typedef int (*WebPWorkerHook)(void*, void*); // Synchronize object used to launch job in the worker thread typedef struct { -#ifdef WEBP_USE_THREAD +#if WEBP_USE_THREAD pthread_mutex_t mutex_; pthread_cond_t condition_; pthread_t thread_; @@ -69,28 +63,23 @@ typedef struct { // Must be called first, before any other method. void WebPWorkerInit(WebPWorker* const worker); -// Must be called to initialize the object and spawn the thread. Re-entrant. +// Must be called initialize the object and spawn the thread. Re-entrant. // Will potentially launch the thread. Returns false in case of error. int WebPWorkerReset(WebPWorker* const worker); -// Makes sure the previous work is finished. Returns true if worker->had_error -// was not set and no error condition was triggered by the working thread. +// Make sure the previous work is finished. Returns true if worker->had_error +// was not set and not error condition was triggered by the working thread. int WebPWorkerSync(WebPWorker* const worker); -// Triggers the thread to call hook() with data1 and data2 argument. These +// Trigger the thread to call hook() with data1 and data2 argument. These // hook/data1/data2 can be changed at any time before calling this function, // but not be changed afterward until the next call to WebPWorkerSync(). void WebPWorkerLaunch(WebPWorker* const worker); -// This function is similar to WebPWorkerLaunch() except that it calls the -// hook directly instead of using a thread. Convenient to bypass the thread -// mechanism while still using the WebPWorker structs. WebPWorkerSync() must -// still be called afterward (for error reporting). -void WebPWorkerExecute(WebPWorker* const worker); // Kill the thread and terminate the object. To use the object again, one // must call WebPWorkerReset() again. void WebPWorkerEnd(WebPWorker* const worker); //------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/drivers/webp/utils/utils.c b/drivers/webp/utils/utils.c index 5592538988..673b7e284c 100644 --- a/drivers/webp/utils/utils.c +++ b/drivers/webp/utils/utils.c @@ -1,10 +1,8 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Misc. common utility functions @@ -14,11 +12,14 @@ #include <stdlib.h> #include "./utils.h" +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + //------------------------------------------------------------------------------ // Checked memory allocation -// Returns 0 in case of overflow of nmemb * size. -static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) { +static int CheckSizeArguments(uint64_t nmemb, size_t size) { const uint64_t total_size = nmemb * size; if (nmemb == 0) return 1; if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0; @@ -27,16 +28,17 @@ static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) { } void* WebPSafeMalloc(uint64_t nmemb, size_t size) { - if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; - assert(nmemb * size > 0); + if (!CheckSizeArguments(nmemb, size)) return NULL; return malloc((size_t)(nmemb * size)); } void* WebPSafeCalloc(uint64_t nmemb, size_t size) { - if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; - assert(nmemb * size > 0); + if (!CheckSizeArguments(nmemb, size)) return NULL; return calloc((size_t)nmemb, size); } //------------------------------------------------------------------------------ +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif diff --git a/drivers/webp/utils/utils.h b/drivers/webp/utils/utils.h index 8bdf0f03db..a034762556 100644 --- a/drivers/webp/utils/utils.h +++ b/drivers/webp/utils/utils.h @@ -1,25 +1,20 @@ // Copyright 2012 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // Misc. common utility functions // -// Authors: Skal (pascal.massimino@gmail.com) -// Urvang (urvang@google.com) +// Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_UTILS_H_ #define WEBP_UTILS_UTILS_H_ -#include <assert.h> - #include "../webp/types.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -41,42 +36,8 @@ void* WebPSafeMalloc(uint64_t nmemb, size_t size); void* WebPSafeCalloc(uint64_t nmemb, size_t size); //------------------------------------------------------------------------------ -// Reading/writing data. - -// Read 16, 24 or 32 bits stored in little-endian order. -static WEBP_INLINE int GetLE16(const uint8_t* const data) { - return (int)(data[0] << 0) | (data[1] << 8); -} - -static WEBP_INLINE int GetLE24(const uint8_t* const data) { - return GetLE16(data) | (data[2] << 16); -} - -static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) { - return (uint32_t)GetLE16(data) | (GetLE16(data + 2) << 16); -} - -// Store 16, 24 or 32 bits in little-endian order. -static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { - assert(val < (1 << 16)); - data[0] = (val >> 0); - data[1] = (val >> 8); -} - -static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { - assert(val < (1 << 24)); - PutLE16(data, val & 0xffff); - data[2] = (val >> 16); -} - -static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { - PutLE16(data, (int)(val & 0xffff)); - PutLE16(data + 2, (int)(val >> 16)); -} - -//------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif |