// Copyright 2011 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Internal header for mux library.10//11// Author: Urvang ([email protected])1213#ifndef WEBP_MUX_MUXI_H_14#define WEBP_MUX_MUXI_H_1516#include <assert.h>17#include <stdlib.h>18#include "src/dec/vp8i_dec.h"19#include "src/dec/vp8li_dec.h"20#include "src/webp/mux.h"2122#ifdef __cplusplus23extern "C" {24#endif2526//------------------------------------------------------------------------------27// Defines and constants.2829#define MUX_MAJ_VERSION 130#define MUX_MIN_VERSION 531#define MUX_REV_VERSION 03233// Chunk object.34typedef struct WebPChunk WebPChunk;35struct WebPChunk {36uint32_t tag_;37int owner_; // True if *data_ memory is owned internally.38// VP8X, ANIM, and other internally created chunks39// like ANMF are always owned.40WebPData data_;41WebPChunk* next_;42};4344// MuxImage object. Store a full WebP image (including ANMF chunk, ALPH45// chunk and VP8/VP8L chunk),46typedef struct WebPMuxImage WebPMuxImage;47struct WebPMuxImage {48WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF.49WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA.50WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE.51WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN.52int width_;53int height_;54int has_alpha_; // Through ALPH chunk or as part of VP8L.55int is_partial_; // True if only some of the chunks are filled.56WebPMuxImage* next_;57};5859// Main mux object. Stores data chunks.60struct WebPMux {61WebPMuxImage* images_;62WebPChunk* iccp_;63WebPChunk* exif_;64WebPChunk* xmp_;65WebPChunk* anim_;66WebPChunk* vp8x_;6768WebPChunk* unknown_;69int canvas_width_;70int canvas_height_;71};7273// CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only.74// Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to75// allow two different chunks to have the same id (e.g. WebPChunkId76// 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L').77typedef enum {78IDX_VP8X = 0,79IDX_ICCP,80IDX_ANIM,81IDX_ANMF,82IDX_ALPHA,83IDX_VP8,84IDX_VP8L,85IDX_EXIF,86IDX_XMP,87IDX_UNKNOWN,8889IDX_NIL,90IDX_LAST_CHUNK91} CHUNK_INDEX;9293#define NIL_TAG 0x00000000u // To signal void chunk.9495typedef struct {96uint32_t tag;97WebPChunkId id;98uint32_t size;99} ChunkInfo;100101extern const ChunkInfo kChunks[IDX_LAST_CHUNK];102103//------------------------------------------------------------------------------104// Chunk object management.105106// Initialize.107void ChunkInit(WebPChunk* const chunk);108109// Get chunk index from chunk tag. Returns IDX_UNKNOWN if not found.110CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);111112// Get chunk id from chunk tag. Returns WEBP_CHUNK_UNKNOWN if not found.113WebPChunkId ChunkGetIdFromTag(uint32_t tag);114115// Convert a fourcc string to a tag.116uint32_t ChunkGetTagFromFourCC(const char fourcc[4]);117118// Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown.119CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]);120121// Search for nth chunk with given 'tag' in the chunk list.122// nth = 0 means "last of the list".123WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);124125// Fill the chunk with the given data.126WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,127int copy_data, uint32_t tag);128129// Sets 'chunk' as the only element in 'chunk_list' if it is empty.130// On success ownership is transferred from 'chunk' to the 'chunk_list'.131WebPMuxError ChunkSetHead(WebPChunk* const chunk, WebPChunk** const chunk_list);132// Sets 'chunk' at last position in the 'chunk_list'.133// On success ownership is transferred from 'chunk' to the 'chunk_list'.134// *chunk_list also points towards the last valid element of the initial135// *chunk_list.136WebPMuxError ChunkAppend(WebPChunk* const chunk, WebPChunk*** const chunk_list);137138// Releases chunk and returns chunk->next_.139WebPChunk* ChunkRelease(WebPChunk* const chunk);140141// Deletes given chunk & returns chunk->next_.142WebPChunk* ChunkDelete(WebPChunk* const chunk);143144// Deletes all chunks in the given chunk list.145void ChunkListDelete(WebPChunk** const chunk_list);146147// Returns size of the chunk including chunk header and padding byte (if any).148static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {149assert(chunk_size <= MAX_CHUNK_PAYLOAD);150return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);151}152153// Size of a chunk including header and padding.154static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {155const size_t data_size = chunk->data_.size;156return SizeWithPadding(data_size);157}158159// Total size of a list of chunks.160size_t ChunkListDiskSize(const WebPChunk* chunk_list);161162// Write out the given list of chunks into 'dst'.163uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);164165//------------------------------------------------------------------------------166// MuxImage object management.167168// Initialize.169void MuxImageInit(WebPMuxImage* const wpi);170171// Releases image 'wpi' and returns wpi->next.172WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);173174// Delete image 'wpi' and return the next image in the list or NULL.175// 'wpi' can be NULL.176WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);177178// Count number of images matching the given tag id in the 'wpi_list'.179// If id == WEBP_CHUNK_NIL, all images will be matched.180int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);181182// Update width/height/has_alpha info from chunks within wpi.183// Also remove ALPH chunk if not needed.184int MuxImageFinalize(WebPMuxImage* const wpi);185186// Check if given ID corresponds to an image related chunk.187static WEBP_INLINE int IsWPI(WebPChunkId id) {188switch (id) {189case WEBP_CHUNK_ANMF:190case WEBP_CHUNK_ALPHA:191case WEBP_CHUNK_IMAGE: return 1;192default: return 0;193}194}195196// Pushes 'wpi' at the end of 'wpi_list'.197WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);198199// Delete nth image in the image list.200WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth);201202// Get nth image in the image list.203WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,204WebPMuxImage** wpi);205206// Total size of the given image.207size_t MuxImageDiskSize(const WebPMuxImage* const wpi);208209// Write out the given image into 'dst'.210uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);211212//------------------------------------------------------------------------------213// Helper methods for mux.214215// Checks if the given image list contains at least one image with alpha.216int MuxHasAlpha(const WebPMuxImage* images);217218// Write out RIFF header into 'data', given total data size 'size'.219uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);220221// Returns the list where chunk with given ID is to be inserted in mux.222WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);223224// Validates the given mux object.225WebPMuxError MuxValidate(const WebPMux* const mux);226227//------------------------------------------------------------------------------228229#ifdef __cplusplus230} // extern "C"231#endif232233#endif // WEBP_MUX_MUXI_H_234235236