muxi.h 8.11 KB
Newer Older
wester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// 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.
// -----------------------------------------------------------------------------
//
// Internal header for mux library.
//
// Author: Urvang (urvang@google.com)

#ifndef WEBP_MUX_MUXI_H_
#define WEBP_MUX_MUXI_H_

#include <stdlib.h>
a  
Kai Westerkamp committed
18 19
#include "../dec/vp8i.h"
#include "../dec/vp8li.h"
wester committed
20 21
#include "../webp/mux.h"

a  
Kai Westerkamp committed
22
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
23 24 25 26 27 28 29
extern "C" {
#endif

//------------------------------------------------------------------------------
// Defines and constants.

#define MUX_MAJ_VERSION 0
a  
Kai Westerkamp committed
30 31
#define MUX_MIN_VERSION 1
#define MUX_REV_VERSION 1
wester committed
32 33 34 35 36 37 38

// Chunk object.
typedef struct WebPChunk WebPChunk;
struct WebPChunk {
  uint32_t        tag_;
  int             owner_;  // True if *data_ memory is owned internally.
                           // VP8X, ANIM, and other internally created chunks
a  
Kai Westerkamp committed
39
                           // like ANMF/FRGM are always owned.
wester committed
40 41 42 43
  WebPData        data_;
  WebPChunk*      next_;
};

a  
Kai Westerkamp committed
44
// MuxImage object. Store a full WebP image (including ANMF/FRGM chunk, ALPH
wester committed
45 46 47
// chunk and VP8/VP8L chunk),
typedef struct WebPMuxImage WebPMuxImage;
struct WebPMuxImage {
a  
Kai Westerkamp committed
48
  WebPChunk*  header_;      // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM.
wester committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
  WebPChunk*  alpha_;       // Corresponds to WEBP_CHUNK_ALPHA.
  WebPChunk*  img_;         // Corresponds to WEBP_CHUNK_IMAGE.
  int         is_partial_;  // True if only some of the chunks are filled.
  WebPMuxImage* next_;
};

// Main mux object. Stores data chunks.
struct WebPMux {
  WebPMuxImage*   images_;
  WebPChunk*      iccp_;
  WebPChunk*      exif_;
  WebPChunk*      xmp_;
  WebPChunk*      anim_;
  WebPChunk*      vp8x_;

a  
Kai Westerkamp committed
64
  WebPChunk*  unknown_;
wester committed
65 66 67 68 69 70 71 72 73 74 75
};

// CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only.
// Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to
// allow two different chunks to have the same id (e.g. WebPChunkId
// 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L').
typedef enum {
  IDX_VP8X = 0,
  IDX_ICCP,
  IDX_ANIM,
  IDX_ANMF,
a  
Kai Westerkamp committed
76
  IDX_FRGM,
wester committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
  IDX_ALPHA,
  IDX_VP8,
  IDX_VP8L,
  IDX_EXIF,
  IDX_XMP,
  IDX_UNKNOWN,

  IDX_NIL,
  IDX_LAST_CHUNK
} CHUNK_INDEX;

#define NIL_TAG 0x00000000u  // To signal void chunk.

typedef struct {
  uint32_t      tag;
  WebPChunkId   id;
  uint32_t      size;
} ChunkInfo;

extern const ChunkInfo kChunks[IDX_LAST_CHUNK];

//------------------------------------------------------------------------------
// Chunk object management.

// Initialize.
void ChunkInit(WebPChunk* const chunk);

a  
Kai Westerkamp committed
104
// Get chunk index from chunk tag. Returns IDX_NIL if not found.
wester committed
105 106
CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);

a  
Kai Westerkamp committed
107
// Get chunk id from chunk tag. Returns WEBP_CHUNK_NIL if not found.
wester committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
WebPChunkId ChunkGetIdFromTag(uint32_t tag);

// Convert a fourcc string to a tag.
uint32_t ChunkGetTagFromFourCC(const char fourcc[4]);

// Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown.
CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]);

// Search for nth chunk with given 'tag' in the chunk list.
// nth = 0 means "last of the list".
WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);

// Fill the chunk with the given data.
WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
                             int copy_data, uint32_t tag);

// Sets 'chunk' at nth position in the 'chunk_list'.
// nth = 0 has the special meaning "last of the list".
// On success ownership is transferred from 'chunk' to the 'chunk_list'.
WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
                         uint32_t nth);

// Releases chunk and returns chunk->next_.
WebPChunk* ChunkRelease(WebPChunk* const chunk);

// Deletes given chunk & returns chunk->next_.
WebPChunk* ChunkDelete(WebPChunk* const chunk);

// Returns size of the chunk including chunk header and padding byte (if any).
static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
  return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
}

// Size of a chunk including header and padding.
static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
  const size_t data_size = chunk->data_.size;
  assert(data_size < MAX_CHUNK_PAYLOAD);
  return SizeWithPadding(data_size);
}

// Total size of a list of chunks.
a  
Kai Westerkamp committed
149
size_t ChunksListDiskSize(const WebPChunk* chunk_list);
wester committed
150 151 152 153

// Write out the given list of chunks into 'dst'.
uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);

a  
Kai Westerkamp committed
154 155 156 157
// Get the width & height of image stored in 'image_chunk'.
WebPMuxError MuxGetImageWidthHeight(const WebPChunk* const image_chunk,
                                    int* const width, int* const height);

wester committed
158 159 160 161 162 163 164 165 166 167 168 169 170
//------------------------------------------------------------------------------
// MuxImage object management.

// Initialize.
void MuxImageInit(WebPMuxImage* const wpi);

// Releases image 'wpi' and returns wpi->next.
WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);

// Delete image 'wpi' and return the next image in the list or NULL.
// 'wpi' can be NULL.
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);

a  
Kai Westerkamp committed
171 172 173
// Delete all images in 'wpi_list'.
void MuxImageDeleteAll(WebPMuxImage** const wpi_list);

wester committed
174 175 176 177 178 179 180 181
// Count number of images matching the given tag id in the 'wpi_list'.
// If id == WEBP_CHUNK_NIL, all images will be matched.
int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);

// Check if given ID corresponds to an image related chunk.
static WEBP_INLINE int IsWPI(WebPChunkId id) {
  switch (id) {
    case WEBP_CHUNK_ANMF:
a  
Kai Westerkamp committed
182
    case WEBP_CHUNK_FRGM:
wester committed
183 184 185 186 187 188
    case WEBP_CHUNK_ALPHA:
    case WEBP_CHUNK_IMAGE:  return 1;
    default:        return 0;
  }
}

a  
Kai Westerkamp committed
189 190 191 192 193 194 195 196 197 198 199 200 201
// Get a reference to appropriate chunk list within an image given chunk tag.
static WEBP_INLINE WebPChunk** MuxImageGetListFromId(
    const WebPMuxImage* const wpi, WebPChunkId id) {
  assert(wpi != NULL);
  switch (id) {
    case WEBP_CHUNK_ANMF:
    case WEBP_CHUNK_FRGM:  return (WebPChunk**)&wpi->header_;
    case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_;
    case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_;
    default: return NULL;
  }
}

wester committed
202 203 204 205 206 207 208 209 210 211 212 213 214
// Pushes 'wpi' at the end of 'wpi_list'.
WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);

// Delete nth image in the image list.
WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth);

// Get nth image in the image list.
WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
                            WebPMuxImage** wpi);

// Total size of the given image.
size_t MuxImageDiskSize(const WebPMuxImage* const wpi);

a  
Kai Westerkamp committed
215 216 217
// Total size of a list of images.
size_t MuxImageListDiskSize(const WebPMuxImage* wpi_list);

wester committed
218 219 220
// Write out the given image into 'dst'.
uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);

a  
Kai Westerkamp committed
221 222 223
// Write out the given list of images into 'dst'.
uint8_t* MuxImageListEmit(const WebPMuxImage* wpi_list, uint8_t* dst);

wester committed
224 225 226
//------------------------------------------------------------------------------
// Helper methods for mux.

a  
Kai Westerkamp committed
227 228
// Checks if the given image list contains at least one lossless image.
int MuxHasLosslessImages(const WebPMuxImage* images);
wester committed
229 230 231 232 233

// Write out RIFF header into 'data', given total data size 'size'.
uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);

// Returns the list where chunk with given ID is to be inserted in mux.
a  
Kai Westerkamp committed
234 235
// Return value is NULL if this chunk should be inserted in mux->images_ list
// or if 'id' is not known.
wester committed
236 237
WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);

a  
Kai Westerkamp committed
238 239 240
// Validates that the given mux has a single image.
WebPMuxError MuxValidateForImage(const WebPMux* const mux);

wester committed
241 242 243 244 245
// Validates the given mux object.
WebPMuxError MuxValidate(const WebPMux* const mux);

//------------------------------------------------------------------------------

a  
Kai Westerkamp committed
246
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
247 248 249 250
}    // extern "C"
#endif

#endif  /* WEBP_MUX_MUXI_H_ */