mux.h 14.8 KB
Newer Older
wester committed
1 2 3 4 5 6 7 8 9
// 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.
// -----------------------------------------------------------------------------
//
a  
Kai Westerkamp committed
10
//  RIFF container manipulation for WEBP images.
wester committed
11 12 13 14
//
// Authors: Urvang (urvang@google.com)
//          Vikas (vikasa@google.com)

a  
Kai Westerkamp committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
// This API allows manipulation of WebP container images containing features
// like color profile, metadata, animation and fragmented images.
//
// Code Example#1: Creating a MUX with image data, color profile and XMP
// metadata.
//
//   int copy_data = 0;
//   WebPMux* mux = WebPMuxNew();
//   // ... (Prepare image data).
//   WebPMuxSetImage(mux, &image, copy_data);
//   // ... (Prepare ICCP color profile data).
//   WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
//   // ... (Prepare XMP metadata).
//   WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
//   // Get data from mux in WebP RIFF format.
//   WebPMuxAssemble(mux, &output_data);
//   WebPMuxDelete(mux);
//   // ... (Consume output_data; e.g. write output_data.bytes to file).
//   WebPDataClear(&output_data);
//
// Code Example#2: Get image and color profile data from a WebP file.
//
//   int copy_data = 0;
//   // ... (Read data from file).
//   WebPMux* mux = WebPMuxCreate(&data, copy_data);
//   WebPMuxGetFrame(mux, 1, &image);
//   // ... (Consume image; e.g. call WebPDecode() to decode the data).
//   WebPMuxGetChunk(mux, "ICCP", &icc_profile);
//   // ... (Consume icc_data).
//   WebPMuxDelete(mux);
//   free(data);

wester committed
47 48 49 50 51
#ifndef WEBP_WEBP_MUX_H_
#define WEBP_WEBP_MUX_H_

#include "./mux_types.h"

a  
Kai Westerkamp committed
52
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
53 54 55
extern "C" {
#endif

a  
Kai Westerkamp committed
56
#define WEBP_MUX_ABI_VERSION 0x0100        // MAJOR(8b) + MINOR(8b)
wester committed
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum WebPMuxError WebPMuxError;
// typedef enum WebPChunkId WebPChunkId;
typedef struct WebPMux WebPMux;   // main opaque object.
typedef struct WebPMuxFrameInfo WebPMuxFrameInfo;
typedef struct WebPMuxAnimParams WebPMuxAnimParams;

// Error codes
typedef enum WebPMuxError {
  WEBP_MUX_OK                 =  1,
  WEBP_MUX_NOT_FOUND          =  0,
  WEBP_MUX_INVALID_ARGUMENT   = -1,
  WEBP_MUX_BAD_DATA           = -2,
  WEBP_MUX_MEMORY_ERROR       = -3,
  WEBP_MUX_NOT_ENOUGH_DATA    = -4
} WebPMuxError;

// IDs for different types of chunks.
typedef enum WebPChunkId {
a  
Kai Westerkamp committed
78 79 80 81 82 83 84 85 86 87
  WEBP_CHUNK_VP8X,     // VP8X
  WEBP_CHUNK_ICCP,     // ICCP
  WEBP_CHUNK_ANIM,     // ANIM
  WEBP_CHUNK_ANMF,     // ANMF
  WEBP_CHUNK_FRGM,     // FRGM
  WEBP_CHUNK_ALPHA,    // ALPH
  WEBP_CHUNK_IMAGE,    // VP8/VP8L
  WEBP_CHUNK_EXIF,     // EXIF
  WEBP_CHUNK_XMP,      // XMP
  WEBP_CHUNK_UNKNOWN,  // Other chunks.
wester committed
88 89 90 91 92 93
  WEBP_CHUNK_NIL
} WebPChunkId;

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

// Returns the version number of the mux library, packed in hexadecimal using
a  
Kai Westerkamp committed
94
// 8bits or each of major/minor/revision. E.g: v2.5.7 is 0x020507.
wester committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
WEBP_EXTERN(int) WebPGetMuxVersion(void);

//------------------------------------------------------------------------------
// Life of a Mux object

// Internal, version-checked, entry point
WEBP_EXTERN(WebPMux*) WebPNewInternal(int);

// Creates an empty mux object.
// Returns:
//   A pointer to the newly created empty mux object.
static WEBP_INLINE WebPMux* WebPMuxNew(void) {
  return WebPNewInternal(WEBP_MUX_ABI_VERSION);
}

// Deletes the mux object.
// Parameters:
//   mux - (in/out) object to be deleted
WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux);

//------------------------------------------------------------------------------
// Mux creation.

// Internal, version-checked, entry point
WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int);

// Creates a mux object from raw data given in WebP RIFF format.
// Parameters:
//   bitstream - (in) the bitstream data in WebP RIFF format
//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
a  
Kai Westerkamp committed
125
//               and value 0 indicates data will NOT be copied.
wester committed
126 127 128 129 130 131 132 133 134 135 136 137
// Returns:
//   A pointer to the mux object created from given data - on success.
//   NULL - In case of invalid data or memory error.
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
                                          int copy_data) {
  return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
}

//------------------------------------------------------------------------------
// Non-image chunks.

// Note: Only non-image related chunks should be managed through chunk APIs.
a  
Kai Westerkamp committed
138 139 140
// (Image related chunks are: "ANMF", "FRGM", "VP8 ", "VP8L" and "ALPH").
// To add, get and delete images, use APIs WebPMuxSetImage(),
// WebPMuxPushFrame(), WebPMuxGetFrame() and WebPMuxDeleteFrame().
wester committed
141 142 143 144 145 146 147 148 149

// Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object.
// Any existing chunk(s) with the same id will be removed.
// Parameters:
//   mux - (in/out) object to which the chunk is to be added
//   fourcc - (in) a character array containing the fourcc of the given chunk;
//                 e.g., "ICCP", "XMP ", "EXIF" etc.
//   chunk_data - (in) the chunk data to be added
//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
a  
Kai Westerkamp committed
150
//               and value 0 indicates data will NOT be copied.
wester committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
//                               or if fourcc corresponds to an image chunk.
//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk(
    WebPMux* mux, const char fourcc[4], const WebPData* chunk_data,
    int copy_data);

// Gets a reference to the data of the chunk with id 'fourcc' in the mux object.
// The caller should NOT free the returned data.
// Parameters:
//   mux - (in) object from which the chunk data is to be fetched
//   fourcc - (in) a character array containing the fourcc of the chunk;
//                 e.g., "ICCP", "XMP ", "EXIF" etc.
//   chunk_data - (out) returned chunk data
// Returns:
a  
Kai Westerkamp committed
168
//   WEBP_MUX_INVALID_ARGUMENT - if either mux, fourcc or chunk_data is NULL
wester committed
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
//                               or if fourcc corresponds to an image chunk.
//   WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk(
    const WebPMux* mux, const char fourcc[4], WebPData* chunk_data);

// Deletes the chunk with the given 'fourcc' from the mux object.
// Parameters:
//   mux - (in/out) object from which the chunk is to be deleted
//   fourcc - (in) a character array containing the fourcc of the chunk;
//                 e.g., "ICCP", "XMP ", "EXIF" etc.
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
//                               or if fourcc corresponds to an image chunk.
//   WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk(
    WebPMux* mux, const char fourcc[4]);

//------------------------------------------------------------------------------
// Images.

a  
Kai Westerkamp committed
191
// Encapsulates data about a single frame/fragment.
wester committed
192
struct WebPMuxFrameInfo {
a  
Kai Westerkamp committed
193
  WebPData    bitstream;  // image data: can either be a raw VP8/VP8L bitstream
wester committed
194 195 196 197 198
                          // or a single-image WebP file.
  int         x_offset;   // x-offset of the frame.
  int         y_offset;   // y-offset of the frame.
  int         duration;   // duration of the frame (in milliseconds).

a  
Kai Westerkamp committed
199 200
  WebPChunkId id;         // frame type: should be one of WEBP_CHUNK_ANMF,
                          // WEBP_CHUNK_FRGM or WEBP_CHUNK_IMAGE
wester committed
201
  WebPMuxAnimDispose dispose_method;  // Disposal method for the frame.
a  
Kai Westerkamp committed
202
  uint32_t    pad[2];     // padding for later use
wester committed
203 204
};

a  
Kai Westerkamp committed
205 206
// Sets the (non-animated and non-fragmented) image in the mux object.
// Note: Any existing images (including frames/fragments) will be removed.
wester committed
207 208
// Parameters:
//   mux - (in/out) object in which the image is to be set
a  
Kai Westerkamp committed
209 210
//   bitstream - (in) can either be a raw VP8/VP8L bitstream or a single-image
//               WebP file (non-animated and non-fragmented)
wester committed
211
//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
a  
Kai Westerkamp committed
212
//               and value 0 indicates data will NOT be copied.
wester committed
213 214 215 216 217 218 219 220
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(
    WebPMux* mux, const WebPData* bitstream, int copy_data);

// Adds a frame at the end of the mux object.
a  
Kai Westerkamp committed
221 222 223
// Notes: (1) frame.id should be one of WEBP_CHUNK_ANMF or WEBP_CHUNK_FRGM
//        (2) For setting a non-animated non-fragmented image, use
//            WebPMuxSetImage() instead.
wester committed
224 225 226 227 228 229 230
//        (3) Type of frame being pushed must be same as the frames in mux.
//        (4) As WebP only supports even offsets, any odd offset will be snapped
//            to an even location using: offset &= ~1
// Parameters:
//   mux - (in/out) object to which the frame is to be added
//   frame - (in) frame data.
//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
a  
Kai Westerkamp committed
231
//               and value 0 indicates data will NOT be copied.
wester committed
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL
//                               or if content of 'frame' is invalid.
//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
    WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);

// Gets the nth frame from the mux object.
// The content of 'frame->bitstream' is allocated using malloc(), and NOT
// owned by the 'mux' object. It MUST be deallocated by the caller by calling
// WebPDataClear().
// nth=0 has a special meaning - last position.
// Parameters:
//   mux - (in) object from which the info is to be fetched
//   nth - (in) index of the frame in the mux object
//   frame - (out) data of the returned frame
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL.
//   WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
//   WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
    const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame);

// Deletes a frame from the mux object.
// nth=0 has a special meaning - last position.
// Parameters:
//   mux - (in/out) object from which a frame is to be deleted
//   nth - (in) The position from which the frame is to be deleted
// Returns:
//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL.
//   WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
//                        before deletion.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);

//------------------------------------------------------------------------------
// Animation.

// Animation parameters.
struct WebPMuxAnimParams {
  uint32_t bgcolor;  // Background color of the canvas stored (in MSB order) as:
                     // Bits 00 to 07: Alpha.
                     // Bits 08 to 15: Red.
                     // Bits 16 to 23: Green.
                     // Bits 24 to 31: Blue.
  int loop_count;    // Number of times to repeat the animation [0 = infinite].
};

// Sets the animation parameters in the mux object. Any existing ANIM chunks
// will be removed.
// Parameters:
//   mux - (in/out) object in which ANIM chunk is to be set/added
//   params - (in) animation parameters.
// Returns:
a  
Kai Westerkamp committed
288
//   WEBP_MUX_INVALID_ARGUMENT - if either mux or params is NULL
wester committed
289 290 291 292 293 294 295 296 297 298
//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxSetAnimationParams(
    WebPMux* mux, const WebPMuxAnimParams* params);

// Gets the animation parameters from the mux object.
// Parameters:
//   mux - (in) object from which the animation parameters to be fetched
//   params - (out) animation parameters extracted from the ANIM chunk
// Returns:
a  
Kai Westerkamp committed
299
//   WEBP_MUX_INVALID_ARGUMENT - if either of mux or params is NULL
wester committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
//   WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object.
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams(
    const WebPMux* mux, WebPMuxAnimParams* params);

//------------------------------------------------------------------------------
// Misc Utilities.

// Gets the feature flags from the mux object.
// Parameters:
//   mux - (in) object from which the features are to be fetched
//   flags - (out) the flags specifying which features are present in the
//           mux object. This will be an OR of various flag values.
//           Enum 'WebPFeatureFlags' can be used to test individual flag values.
// Returns:
a  
Kai Westerkamp committed
315 316 317
//   WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL
//   WEBP_MUX_NOT_FOUND - if VP8X chunk is not present in mux object.
//   WEBP_MUX_BAD_DATA - if VP8X chunk in mux is invalid.
wester committed
318 319 320 321
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux,
                                             uint32_t* flags);

a  
Kai Westerkamp committed
322
// Gets number of chunks having tag value tag in the mux object.
wester committed
323 324 325 326 327
// Parameters:
//   mux - (in) object from which the info is to be fetched
//   id - (in) chunk id specifying the type of chunk
//   num_elements - (out) number of chunks with the given chunk id
// Returns:
a  
Kai Westerkamp committed
328
//   WEBP_MUX_INVALID_ARGUMENT - if either mux, or num_elements is NULL
wester committed
329 330 331 332 333 334 335 336 337
//   WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux,
                                           WebPChunkId id, int* num_elements);

// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
// This function also validates the mux object.
// Note: The content of 'assembled_data' will be ignored and overwritten.
// Also, the content of 'assembled_data' is allocated using malloc(), and NOT
// owned by the 'mux' object. It MUST be deallocated by the caller by calling
a  
Kai Westerkamp committed
338
// WebPDataClear().
wester committed
339 340 341 342 343
// Parameters:
//   mux - (in/out) object whose chunks are to be assembled
//   assembled_data - (out) assembled WebP data
// Returns:
//   WEBP_MUX_BAD_DATA - if mux object is invalid.
a  
Kai Westerkamp committed
344 345
//   WEBP_MUX_INVALID_ARGUMENT - if either mux, output_data or output_size is
//                               NULL.
wester committed
346
//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
a  
Kai Westerkamp committed
347
//   WEBP_MUX_OK - on success
wester committed
348 349 350 351 352
WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
                                          WebPData* assembled_data);

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

a  
Kai Westerkamp committed
353
#if defined(__cplusplus) || defined(c_plusplus)
wester committed
354 355 356 357
}    // extern "C"
#endif

#endif  /* WEBP_WEBP_MUX_H_ */