1 // Copyright 2011 Google Inc. All Rights Reserved. 2 // 3 // Use of this source code is governed by a BSD-style license 4 // that can be found in the COPYING file in the root of the source 5 // tree. An additional intellectual property rights grant can be found 6 // in the file PATENTS. All contributing project authors may 7 // be found in the AUTHORS file in the root of the source tree. 8 // ----------------------------------------------------------------------------- 9 // 10 // Internal header for mux library. 11 // 12 // Author: Urvang (urvang (at) google.com) 13 14 #ifndef WEBP_MUX_MUXI_H_ 15 #define WEBP_MUX_MUXI_H_ 16 17 #include <assert.h> 18 #include <stdlib.h> 19 #include "src/dec/vp8i_dec.h" 20 #include "src/dec/vp8li_dec.h" 21 #include "src/webp/mux.h" 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 //------------------------------------------------------------------------------ 28 // Defines and constants. 29 30 #define MUX_MAJ_VERSION 1 31 #define MUX_MIN_VERSION 0 32 #define MUX_REV_VERSION 2 33 34 // Chunk object. 35 typedef struct WebPChunk WebPChunk; 36 struct WebPChunk { 37 uint32_t tag_; 38 int owner_; // True if *data_ memory is owned internally. 39 // VP8X, ANIM, and other internally created chunks 40 // like ANMF are always owned. 41 WebPData data_; 42 WebPChunk* next_; 43 }; 44 45 // MuxImage object. Store a full WebP image (including ANMF chunk, ALPH 46 // chunk and VP8/VP8L chunk), 47 typedef struct WebPMuxImage WebPMuxImage; 48 struct WebPMuxImage { 49 WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF. 50 WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA. 51 WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE. 52 WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN. 53 int width_; 54 int height_; 55 int has_alpha_; // Through ALPH chunk or as part of VP8L. 56 int is_partial_; // True if only some of the chunks are filled. 57 WebPMuxImage* next_; 58 }; 59 60 // Main mux object. Stores data chunks. 61 struct WebPMux { 62 WebPMuxImage* images_; 63 WebPChunk* iccp_; 64 WebPChunk* exif_; 65 WebPChunk* xmp_; 66 WebPChunk* anim_; 67 WebPChunk* vp8x_; 68 69 WebPChunk* unknown_; 70 int canvas_width_; 71 int canvas_height_; 72 }; 73 74 // CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only. 75 // Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to 76 // allow two different chunks to have the same id (e.g. WebPChunkId 77 // 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L'). 78 typedef enum { 79 IDX_VP8X = 0, 80 IDX_ICCP, 81 IDX_ANIM, 82 IDX_ANMF, 83 IDX_ALPHA, 84 IDX_VP8, 85 IDX_VP8L, 86 IDX_EXIF, 87 IDX_XMP, 88 IDX_UNKNOWN, 89 90 IDX_NIL, 91 IDX_LAST_CHUNK 92 } CHUNK_INDEX; 93 94 #define NIL_TAG 0x00000000u // To signal void chunk. 95 96 typedef struct { 97 uint32_t tag; 98 WebPChunkId id; 99 uint32_t size; 100 } ChunkInfo; 101 102 extern const ChunkInfo kChunks[IDX_LAST_CHUNK]; 103 104 //------------------------------------------------------------------------------ 105 // Chunk object management. 106 107 // Initialize. 108 void ChunkInit(WebPChunk* const chunk); 109 110 // Get chunk index from chunk tag. Returns IDX_UNKNOWN if not found. 111 CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag); 112 113 // Get chunk id from chunk tag. Returns WEBP_CHUNK_UNKNOWN if not found. 114 WebPChunkId ChunkGetIdFromTag(uint32_t tag); 115 116 // Convert a fourcc string to a tag. 117 uint32_t ChunkGetTagFromFourCC(const char fourcc[4]); 118 119 // Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown. 120 CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]); 121 122 // Search for nth chunk with given 'tag' in the chunk list. 123 // nth = 0 means "last of the list". 124 WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag); 125 126 // Fill the chunk with the given data. 127 WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data, 128 int copy_data, uint32_t tag); 129 130 // Sets 'chunk' as the only element in 'chunk_list' if it is empty. 131 // On success ownership is transferred from 'chunk' to the 'chunk_list'. 132 WebPMuxError ChunkSetHead(WebPChunk* const chunk, WebPChunk** const chunk_list); 133 // Sets 'chunk' at last position in the 'chunk_list'. 134 // On success ownership is transferred from 'chunk' to the 'chunk_list'. 135 // *chunk_list also points towards the last valid element of the initial 136 // *chunk_list. 137 WebPMuxError ChunkAppend(WebPChunk* const chunk, WebPChunk*** const chunk_list); 138 139 // Releases chunk and returns chunk->next_. 140 WebPChunk* ChunkRelease(WebPChunk* const chunk); 141 142 // Deletes given chunk & returns chunk->next_. 143 WebPChunk* ChunkDelete(WebPChunk* const chunk); 144 145 // Deletes all chunks in the given chunk list. 146 void ChunkListDelete(WebPChunk** const chunk_list); 147 148 // Returns size of the chunk including chunk header and padding byte (if any). 149 static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) { 150 assert(chunk_size <= MAX_CHUNK_PAYLOAD); 151 return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U); 152 } 153 154 // Size of a chunk including header and padding. 155 static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) { 156 const size_t data_size = chunk->data_.size; 157 return SizeWithPadding(data_size); 158 } 159 160 // Total size of a list of chunks. 161 size_t ChunkListDiskSize(const WebPChunk* chunk_list); 162 163 // Write out the given list of chunks into 'dst'. 164 uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst); 165 166 //------------------------------------------------------------------------------ 167 // MuxImage object management. 168 169 // Initialize. 170 void MuxImageInit(WebPMuxImage* const wpi); 171 172 // Releases image 'wpi' and returns wpi->next. 173 WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi); 174 175 // Delete image 'wpi' and return the next image in the list or NULL. 176 // 'wpi' can be NULL. 177 WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi); 178 179 // Count number of images matching the given tag id in the 'wpi_list'. 180 // If id == WEBP_CHUNK_NIL, all images will be matched. 181 int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id); 182 183 // Update width/height/has_alpha info from chunks within wpi. 184 // Also remove ALPH chunk if not needed. 185 int MuxImageFinalize(WebPMuxImage* const wpi); 186 187 // Check if given ID corresponds to an image related chunk. 188 static WEBP_INLINE int IsWPI(WebPChunkId id) { 189 switch (id) { 190 case WEBP_CHUNK_ANMF: 191 case WEBP_CHUNK_ALPHA: 192 case WEBP_CHUNK_IMAGE: return 1; 193 default: return 0; 194 } 195 } 196 197 // Pushes 'wpi' at the end of 'wpi_list'. 198 WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list); 199 200 // Delete nth image in the image list. 201 WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth); 202 203 // Get nth image in the image list. 204 WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth, 205 WebPMuxImage** wpi); 206 207 // Total size of the given image. 208 size_t MuxImageDiskSize(const WebPMuxImage* const wpi); 209 210 // Write out the given image into 'dst'. 211 uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst); 212 213 //------------------------------------------------------------------------------ 214 // Helper methods for mux. 215 216 // Checks if the given image list contains at least one image with alpha. 217 int MuxHasAlpha(const WebPMuxImage* images); 218 219 // Write out RIFF header into 'data', given total data size 'size'. 220 uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size); 221 222 // Returns the list where chunk with given ID is to be inserted in mux. 223 WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id); 224 225 // Validates the given mux object. 226 WebPMuxError MuxValidate(const WebPMux* const mux); 227 228 //------------------------------------------------------------------------------ 229 230 #ifdef __cplusplus 231 } // extern "C" 232 #endif 233 234 #endif // WEBP_MUX_MUXI_H_ 235