diff --git a/makefile.unix b/makefile.unix index 3749e5b1..55bba685 100644 --- a/makefile.unix +++ b/makefile.unix @@ -148,6 +148,7 @@ HDRS = \ src/webp/decode.h \ src/webp/decode_vp8.h \ src/webp/encode.h \ + src/webp/format_constants.h \ src/webp/mux.h \ src/webp/types.h \ diff --git a/src/dec/Makefile.am b/src/dec/Makefile.am index e053b9a1..fceeda8f 100644 --- a/src/dec/Makefile.am +++ b/src/dec/Makefile.am @@ -21,7 +21,7 @@ libwebpdecodeinclude_HEADERS = libwebpdecodeinclude_HEADERS += ../webp/decode.h libwebpdecodeinclude_HEADERS += ../webp/decode_vp8.h libwebpdecodeinclude_HEADERS += ../webp/types.h -noinst_HEADERS = ../webp/mux.h +noinst_HEADERS = ../webp/format_constants.h libwebpdecode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpdecodeincludedir = $(includedir)/webp diff --git a/src/dec/alpha.c b/src/dec/alpha.c index e2bfeee6..6e65de90 100644 --- a/src/dec/alpha.c +++ b/src/dec/alpha.c @@ -14,17 +14,12 @@ #include "./vp8li.h" #include "../utils/filters.h" #include "../utils/quant_levels.h" +#include "../webp/format_constants.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -// TODO(skal): find a common place between enc/ and dec/ for these: -#define ALPHA_HEADER_LEN 1 -#define ALPHA_NO_COMPRESSION 0 -#define ALPHA_LOSSLESS_COMPRESSION 1 -#define ALPHA_PREPROCESSED_LEVELS 1 - // TODO(skal): move to dsp/ ? static void CopyPlane(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width, int height) { diff --git a/src/dec/vp8l.c b/src/dec/vp8l.c index 1b01e4e0..a63c042b 100644 --- a/src/dec/vp8l.c +++ b/src/dec/vp8l.c @@ -20,19 +20,14 @@ extern "C" { #endif -static const size_t kHeaderBytes = 5; -static const int kImageSizeBits = 14; +#define NUM_ARGB_CACHE_ROWS 16 +static const size_t kHeaderBytes = 5; static const int kCodeLengthLiterals = 16; static const int kCodeLengthRepeatCode = 16; static const int kCodeLengthExtraBits[3] = { 2, 3, 7 }; static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 }; -#define NUM_LENGTH_CODES 24 -#define NUM_DISTANCE_CODES 40 -#define DEFAULT_CODE_LENGTH 8 -#define MAX_CACHE_BITS 11 - // ----------------------------------------------------------------------------- // Five Huffman codes are used at each meta code: // 1. green + length prefix codes + color cache codes, @@ -86,12 +81,12 @@ static int DecodeImageStream(int xsize, int ysize, static int ReadImageSize(VP8LBitReader* const br, int* const width, int* const height) { const int signature = VP8LReadBits(br, 8); - if (signature != LOSSLESS_MAGIC_BYTE && - signature != LOSSLESS_MAGIC_BYTE_RSVD) { + if (signature != VP8L_MAGIC_BYTE && + signature != VP8L_MAGIC_BYTE_RSVD) { return 0; } - *width = VP8LReadBits(br, kImageSizeBits) + 1; - *height = VP8LReadBits(br, kImageSizeBits) + 1; + *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; + *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; return 1; } diff --git a/src/dec/vp8li.h b/src/dec/vp8li.h index b0974688..2332b513 100644 --- a/src/dec/vp8li.h +++ b/src/dec/vp8li.h @@ -18,32 +18,18 @@ #include "../utils/bit_reader.h" #include "../utils/color_cache.h" #include "../utils/huffman.h" +#include "../webp/format_constants.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -#define NUM_TRANSFORMS 4 -#define HUFFMAN_CODES_PER_META_CODE 5 -#define ARGB_BLACK 0xff000000 -#define NUM_LITERAL_CODES 256 -#define NUM_ARGB_CACHE_ROWS 16 -#define LOSSLESS_MAGIC_BYTE 0x64 -#define LOSSLESS_MAGIC_BYTE_RSVD 0x65 - typedef enum { READ_DATA = 0, READ_HDR = 1, READ_DIM = 2 } VP8LDecodeState; -typedef enum { - PREDICTOR_TRANSFORM = 0, - CROSS_COLOR_TRANSFORM = 1, - SUBTRACT_GREEN = 2, - COLOR_INDEXING_TRANSFORM = 3 -} VP8LImageTransformType; - typedef struct VP8LTransform VP8LTransform; struct VP8LTransform { VP8LImageTransformType type_; // transform type. diff --git a/src/dec/webp.c b/src/dec/webp.c index d8621203..2b5a5695 100644 --- a/src/dec/webp.c +++ b/src/dec/webp.c @@ -14,8 +14,7 @@ #include "./vp8i.h" #include "./vp8li.h" #include "./webpi.h" -#include "../mux/muxi.h" // For MAX_CHUNK_PAYLOAD. -#include "../webp/mux.h" // For 'ALPHA_FLAG'. +#include "../webp/format_constants.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -552,7 +551,7 @@ static VP8StatusCode GetFeatures(const uint8_t* data, size_t data_size, if (status != VP8_STATUS_OK) { return status; // Wrong VP8X / insufficient data. } - features->has_alpha = !!(flags & ALPHA_FLAG); + features->has_alpha = !!(flags & ALPHA_FLAG_BIT); if (found_vp8x) { return VP8_STATUS_OK; // Return features from VP8X header. } diff --git a/src/dec/webpi.h b/src/dec/webpi.h index d14067a4..9d29e633 100644 --- a/src/dec/webpi.h +++ b/src/dec/webpi.h @@ -16,8 +16,8 @@ extern "C" { #endif -#include "../webp/decode_vp8.h" #include "../utils/rescaler.h" +#include "../webp/decode_vp8.h" //------------------------------------------------------------------------------ // WebPDecParams: Decoding output parameters. Transient internal object. @@ -45,15 +45,6 @@ void WebPResetDecParams(WebPDecParams* const params); //------------------------------------------------------------------------------ // Header parsing helpers -#define TAG_SIZE 4 -#define CHUNK_HEADER_SIZE 8 -#define RIFF_HEADER_SIZE 12 -#define FRAME_CHUNK_SIZE 20 -#define LOOP_CHUNK_SIZE 4 -#define TILE_CHUNK_SIZE 8 -#define VP8X_CHUNK_SIZE 12 -#define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. - // Structure storing a description of the RIFF headers. typedef struct { const uint8_t* data; // input buffer diff --git a/src/dsp/upsampling.c b/src/dsp/upsampling.c index ec9ccfa1..d5fd902c 100644 --- a/src/dsp/upsampling.c +++ b/src/dsp/upsampling.c @@ -11,7 +11,6 @@ #include "./dsp.h" #include "./yuv.h" -#include "../dec/webpi.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/src/dsp/upsampling_sse2.c b/src/dsp/upsampling_sse2.c index c89256ab..6116b0a5 100644 --- a/src/dsp/upsampling_sse2.c +++ b/src/dsp/upsampling_sse2.c @@ -17,7 +17,6 @@ #include #include #include "./yuv.h" -#include "../dec/webpi.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/src/enc/Makefile.am b/src/enc/Makefile.am index de51fa73..02d950dc 100644 --- a/src/enc/Makefile.am +++ b/src/enc/Makefile.am @@ -21,7 +21,9 @@ libwebpencode_la_SOURCES += webpenc.c libwebpencodeinclude_HEADERS = libwebpencodeinclude_HEADERS += ../webp/encode.h libwebpencodeinclude_HEADERS += ../webp/types.h -noinst_HEADERS = ../webp/mux.h +noinst_HEADERS = +noinst_HEADERS += ../webp/format_constants.h +noinst_HEADERS += ../webp/mux.h libwebpencode_la_LDFLAGS = -lm libwebpencode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) diff --git a/src/enc/alpha.c b/src/enc/alpha.c index 371f378a..626c5a41 100644 --- a/src/enc/alpha.c +++ b/src/enc/alpha.c @@ -15,17 +15,12 @@ #include "./vp8enci.h" #include "../utils/filters.h" #include "../utils/quant_levels.h" +#include "../webp/format_constants.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -// TODO(skal): find a common place between enc/ and dec/ for these: -#define ALPHA_HEADER_LEN 1 -#define ALPHA_NO_COMPRESSION 0 -#define ALPHA_LOSSLESS_COMPRESSION 1 -#define ALPHA_PREPROCESSED_LEVELS 1 - // ----------------------------------------------------------------------------- // int EncodeAlpha(const uint8_t* data, int width, int height, int stride, // int quality, int method, int filter, int effort_level, diff --git a/src/enc/syntax.c b/src/enc/syntax.c index 43a283a1..99309c0c 100644 --- a/src/enc/syntax.c +++ b/src/enc/syntax.c @@ -11,22 +11,17 @@ #include +#include "../webp/format_constants.h" #include "./vp8enci.h" -#include "../dec/webpi.h" // For chunk-size constants. -#include "../webp/mux.h" // For 'ALPHA_FLAG' constant. #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -#define KSIGNATURE 0x9d012a -#define MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition -#define MAX_PARTITION_SIZE (1 << 24) // max size for token partition - - //------------------------------------------------------------------------------ // Helper functions +// TODO(later): Move to webp/format_constants.h? static void PutLE32(uint8_t* const data, uint32_t val) { data[0] = (val >> 0) & 0xff; data[1] = (val >> 8) & 0xff; @@ -72,7 +67,7 @@ static WebPEncodingError PutVP8XHeader(const VP8Encoder* const enc) { assert(IsVP8XNeeded(enc)); if (enc->has_alpha_) { - flags |= ALPHA_FLAG; + flags |= ALPHA_FLAG_BIT; } PutLE32(vp8x + TAG_SIZE, VP8X_CHUNK_SIZE); @@ -129,7 +124,7 @@ static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic, uint8_t vp8_frm_hdr[VP8_FRAME_HEADER_SIZE]; uint32_t bits; - if (size0 >= MAX_PARTITION0_SIZE) { // partition #0 is too big to fit + if (size0 >= VP8_MAX_PARTITION0_SIZE) { // partition #0 is too big to fit return VP8_ENC_ERROR_PARTITION0_OVERFLOW; } @@ -142,9 +137,9 @@ static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic, vp8_frm_hdr[1] = (bits >> 8) & 0xff; vp8_frm_hdr[2] = (bits >> 16) & 0xff; // signature - vp8_frm_hdr[3] = (KSIGNATURE >> 16) & 0xff; - vp8_frm_hdr[4] = (KSIGNATURE >> 8) & 0xff; - vp8_frm_hdr[5] = (KSIGNATURE >> 0) & 0xff; + vp8_frm_hdr[3] = (VP8_SIGNATURE >> 16) & 0xff; + vp8_frm_hdr[4] = (VP8_SIGNATURE >> 8) & 0xff; + vp8_frm_hdr[5] = (VP8_SIGNATURE >> 0) & 0xff; // dimensions vp8_frm_hdr[6] = pic->width & 0xff; vp8_frm_hdr[7] = pic->width >> 8; @@ -263,7 +258,7 @@ static int EmitPartitionsSize(const VP8Encoder* const enc, int p; for (p = 0; p < enc->num_parts_ - 1; ++p) { const size_t part_size = VP8BitWriterSize(enc->parts_ + p); - if (part_size >= MAX_PARTITION_SIZE) { + if (part_size >= VP8_MAX_PARTITION_SIZE) { return WebPEncodingSetError(pic, VP8_ENC_ERROR_PARTITION_OVERFLOW); } buf[3 * p + 0] = (part_size >> 0) & 0xff; diff --git a/src/enc/vp8l.c b/src/enc/vp8l.c index 91e8a171..958bbac1 100644 --- a/src/enc/vp8l.c +++ b/src/enc/vp8l.c @@ -27,17 +27,9 @@ extern "C" { #endif +#define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer. #define MAX_HUFF_IMAGE_SIZE (32 * 1024 * 1024) -// TODO(vikas): find a common place between enc and dec for these: -#define PREDICTOR_TRANSFORM 0 -#define CROSS_COLOR_TRANSFORM 1 -#define SUBTRACT_GREEN 2 -#define COLOR_INDEXING_TRANSFORM 3 -#define TRANSFORM_PRESENT 1 - -#define IMAGE_SIZE_BITS 14 - // ----------------------------------------------------------------------------- // Palette @@ -640,9 +632,9 @@ static void PutLE32(uint8_t* const data, uint32_t val) { static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic, size_t riff_size, size_t vp8l_size) { - uint8_t riff[HEADER_SIZE + SIGNATURE_SIZE] = { + uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = { 'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P', - 'V', 'P', '8', 'L', 0, 0, 0, 0, LOSSLESS_MAGIC_BYTE, + 'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE, }; PutLE32(riff + TAG_SIZE, (uint32_t)riff_size); PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size); @@ -658,8 +650,8 @@ static int WriteImageSize(const WebPPicture* const pic, const int height = pic->height -1; assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION); - VP8LWriteBits(bw, IMAGE_SIZE_BITS, width); - VP8LWriteBits(bw, IMAGE_SIZE_BITS, height); + VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width); + VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height); return !bw->error_; } @@ -669,7 +661,7 @@ static WebPEncodingError WriteImage(const WebPPicture* const pic, WebPEncodingError err = VP8_ENC_OK; const uint8_t* const webpll_data = VP8LBitWriterFinish(bw); const size_t webpll_size = VP8LBitWriterNumBytes(bw); - const size_t vp8l_size = SIGNATURE_SIZE + webpll_size; + const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size; const size_t pad = vp8l_size & 1; const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad; diff --git a/src/enc/vp8li.h b/src/enc/vp8li.h index 7532544d..a9b98c13 100644 --- a/src/enc/vp8li.h +++ b/src/enc/vp8li.h @@ -15,24 +15,14 @@ #ifdef USE_LOSSLESS_ENCODER #include "./histogram.h" -#include "../webp/encode.h" #include "../utils/bit_writer.h" +#include "../webp/encode.h" +#include "../webp/format_constants.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -// TODO(vikasa): factorize these with ones used in lossless decoder. -#define TAG_SIZE 4 -#define CHUNK_HEADER_SIZE 8 -#define RIFF_HEADER_SIZE 12 -#define HEADER_SIZE (RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE) -#define SIGNATURE_SIZE 1 -#define LOSSLESS_MAGIC_BYTE 0x64 - -#define MAX_PALETTE_SIZE 256 -#define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer. - typedef struct { const WebPConfig* config_; // user configuration and parameters const WebPPicture* pic_; // input picture. diff --git a/src/mux/muxedit.c b/src/mux/muxedit.c index c876b965..836e940c 100644 --- a/src/mux/muxedit.c +++ b/src/mux/muxedit.c @@ -165,7 +165,7 @@ static WebPMuxError CreateDataFromImageInfo(const WebPImageInfo* image_info, } static int IsLosslessData(const WebPData* const image) { - return (image->size_ >= 1 && image->bytes_[0] == LOSSLESS_MAGIC_BYTE); + return (image->size_ >= 1 && image->bytes_[0] == VP8L_MAGIC_BYTE); } // Outputs image data given data from a webp file (including RIFF header). diff --git a/src/mux/muxi.h b/src/mux/muxi.h index bc5f8534..64794a6e 100644 --- a/src/mux/muxi.h +++ b/src/mux/muxi.h @@ -15,7 +15,7 @@ #include #include "../dec/vp8i.h" #include "../dec/vp8li.h" -#include "../dec/webpi.h" // For chunk-size constants. +#include "../webp/format_constants.h" #include "../webp/mux.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -104,11 +104,6 @@ typedef enum { IDX_LAST_CHUNK } CHUNK_INDEX; -// Maximum chunk payload (data) size such that adding the header and padding -// won't overflow an uint32. -#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) -#define CHUNK_SIZE_BYTES 4 - #define NIL_TAG 0x00000000u // To signal void chunk. #define mktag(c1, c2, c3, c4) \ diff --git a/src/webp/format_constants.h b/src/webp/format_constants.h new file mode 100644 index 00000000..260ef8fc --- /dev/null +++ b/src/webp/format_constants.h @@ -0,0 +1,70 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// 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/ +// ----------------------------------------------------------------------------- +// +// Internal header for constants related to WebP file format. +// +// Author: Urvang (urvang@google.com) + +#ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ +#define WEBP_WEBP_FORMAT_CONSTANTS_H_ + +// VP8 related constants. +#define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. +#define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition +#define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition +#define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. + +// VP8L related constants. +#define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. +#define VP8L_MAGIC_BYTE 0x64 // VP8L signature byte. +#define VP8L_MAGIC_BYTE_RSVD 0x65 // VP8L reserved signature byte. +#define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store + // width and height. + +#define MAX_PALETTE_SIZE 256 +#define MAX_CACHE_BITS 11 +#define HUFFMAN_CODES_PER_META_CODE 5 +#define ARGB_BLACK 0xff000000 +#define DEFAULT_CODE_LENGTH 8 + +#define NUM_LITERAL_CODES 256 +#define NUM_LENGTH_CODES 24 +#define NUM_DISTANCE_CODES 40 + +#define TRANSFORM_PRESENT 1 // The bit to be written when next data + // to be read is a transform. +#define NUM_TRANSFORMS 4 // Maximum number of allowed transform + // in a bitstream. +typedef enum { + PREDICTOR_TRANSFORM = 0, + CROSS_COLOR_TRANSFORM = 1, + SUBTRACT_GREEN = 2, + COLOR_INDEXING_TRANSFORM = 3 +} VP8LImageTransformType; + +// Alpha related constants. +#define ALPHA_HEADER_LEN 1 +#define ALPHA_NO_COMPRESSION 0 +#define ALPHA_LOSSLESS_COMPRESSION 1 +#define ALPHA_PREPROCESSED_LEVELS 1 + +// Mux related constants. +#define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). +#define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. +#define CHUNK_HEADER_SIZE 8 // Size of a chunk header. +#define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). +#define FRAME_CHUNK_SIZE 20 // Size of a FRM chunk. +#define LOOP_CHUNK_SIZE 4 // Size of a LOOP chunk. +#define TILE_CHUNK_SIZE 8 // Size of a LOOP chunk. +#define VP8X_CHUNK_SIZE 12 // Size of a VP8X chunk. +#define ALPHA_FLAG_BIT 0x10 // Should be same as the ALPHA_FLAG in mux.h + +// Maximum chunk payload is such that adding the header and padding won't +// overflow a uint32_t. +#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) + +#endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */