// 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 <stdlib.h>17#include "src/dec/vp8i_dec.h"18#include "src/dec/vp8li_dec.h"19#include "src/webp/mux.h"2021#ifdef __cplusplus22extern "C" {23#endif2425//------------------------------------------------------------------------------26// Defines and constants.2728#define MUX_MAJ_VERSION 129#define MUX_MIN_VERSION 030#define MUX_REV_VERSION 03132// Chunk object.33typedef struct WebPChunk WebPChunk;34struct WebPChunk {35uint32_t tag_;36int owner_; // True if *data_ memory is owned internally.37// VP8X, ANIM, and other internally created chunks38// like ANMF are always owned.39WebPData data_;40WebPChunk* next_;41};4243// MuxImage object. Store a full WebP image (including ANMF chunk, ALPH44// chunk and VP8/VP8L chunk),45typedef struct WebPMuxImage WebPMuxImage;46struct WebPMuxImage {47WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF.48WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA.49WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE.50WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN.51int width_;52int height_;53int has_alpha_; // Through ALPH chunk or as part of VP8L.54int is_partial_; // True if only some of the chunks are filled.55WebPMuxImage* next_;56};5758// Main mux object. Stores data chunks.59struct WebPMux {60WebPMuxImage* images_;61WebPChunk* iccp_;62WebPChunk* exif_;63WebPChunk* xmp_;64WebPChunk* anim_;65WebPChunk* vp8x_;6667WebPChunk* unknown_;68int canvas_width_;69int canvas_height_;70};7172// CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only.73// Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to74// allow two different chunks to have the same id (e.g. WebPChunkId75// 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L').76typedef enum {77IDX_VP8X = 0,78IDX_ICCP,79IDX_ANIM,80IDX_ANMF,81IDX_ALPHA,82IDX_VP8,83IDX_VP8L,84IDX_EXIF,85IDX_XMP,86IDX_UNKNOWN,8788IDX_NIL,89IDX_LAST_CHUNK90} CHUNK_INDEX;9192#define NIL_TAG 0x00000000u // To signal void chunk.9394typedef struct {95uint32_t tag;96WebPChunkId id;97uint32_t size;98} ChunkInfo;99100extern const ChunkInfo kChunks[IDX_LAST_CHUNK];101102//------------------------------------------------------------------------------103// Chunk object management.104105// Initialize.106void ChunkInit(WebPChunk* const chunk);107108// Get chunk index from chunk tag. Returns IDX_UNKNOWN if not found.109CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);110111// Get chunk id from chunk tag. Returns WEBP_CHUNK_UNKNOWN if not found.112WebPChunkId ChunkGetIdFromTag(uint32_t tag);113114// Convert a fourcc string to a tag.115uint32_t ChunkGetTagFromFourCC(const char fourcc[4]);116117// Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown.118CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]);119120// Search for nth chunk with given 'tag' in the chunk list.121// nth = 0 means "last of the list".122WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);123124// Fill the chunk with the given data.125WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,126int copy_data, uint32_t tag);127128// Sets 'chunk' at nth position in the 'chunk_list'.129// nth = 0 has the special meaning "last of the list".130// On success ownership is transferred from 'chunk' to the 'chunk_list'.131WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,132uint32_t nth);133134// Releases chunk and returns chunk->next_.135WebPChunk* ChunkRelease(WebPChunk* const chunk);136137// Deletes given chunk & returns chunk->next_.138WebPChunk* ChunkDelete(WebPChunk* const chunk);139140// Deletes all chunks in the given chunk list.141void ChunkListDelete(WebPChunk** const chunk_list);142143// Returns size of the chunk including chunk header and padding byte (if any).144static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {145return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);146}147148// Size of a chunk including header and padding.149static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {150const size_t data_size = chunk->data_.size;151assert(data_size < MAX_CHUNK_PAYLOAD);152return SizeWithPadding(data_size);153}154155// Total size of a list of chunks.156size_t ChunkListDiskSize(const WebPChunk* chunk_list);157158// Write out the given list of chunks into 'dst'.159uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);160161//------------------------------------------------------------------------------162// MuxImage object management.163164// Initialize.165void MuxImageInit(WebPMuxImage* const wpi);166167// Releases image 'wpi' and returns wpi->next.168WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);169170// Delete image 'wpi' and return the next image in the list or NULL.171// 'wpi' can be NULL.172WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);173174// Count number of images matching the given tag id in the 'wpi_list'.175// If id == WEBP_CHUNK_NIL, all images will be matched.176int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);177178// Update width/height/has_alpha info from chunks within wpi.179// Also remove ALPH chunk if not needed.180int MuxImageFinalize(WebPMuxImage* const wpi);181182// Check if given ID corresponds to an image related chunk.183static WEBP_INLINE int IsWPI(WebPChunkId id) {184switch (id) {185case WEBP_CHUNK_ANMF:186case WEBP_CHUNK_ALPHA:187case WEBP_CHUNK_IMAGE: return 1;188default: return 0;189}190}191192// Pushes 'wpi' at the end of 'wpi_list'.193WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);194195// Delete nth image in the image list.196WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth);197198// Get nth image in the image list.199WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,200WebPMuxImage** wpi);201202// Total size of the given image.203size_t MuxImageDiskSize(const WebPMuxImage* const wpi);204205// Write out the given image into 'dst'.206uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);207208//------------------------------------------------------------------------------209// Helper methods for mux.210211// Checks if the given image list contains at least one image with alpha.212int MuxHasAlpha(const WebPMuxImage* images);213214// Write out RIFF header into 'data', given total data size 'size'.215uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);216217// Returns the list where chunk with given ID is to be inserted in mux.218WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);219220// Validates the given mux object.221WebPMuxError MuxValidate(const WebPMux* const mux);222223//------------------------------------------------------------------------------224225#ifdef __cplusplus226} // extern "C"227#endif228229#endif /* WEBP_MUX_MUXI_H_ */230231232