1 // Copyright 2012 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 // Demux API. 11 // Enables extraction of image and extended format data from WebP files. 12 13 // Code Example: Demuxing WebP data to extract all the frames, ICC profile 14 // and EXIF/XMP metadata. 15 // 16 // WebPDemuxer* demux = WebPDemux(&webp_data); 17 // 18 // uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 19 // uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 20 // // ... (Get information about the features present in the WebP file). 21 // uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 22 // 23 // // ... (Iterate over all frames). 24 // WebPIterator iter; 25 // if (WebPDemuxGetFrame(demux, 1, &iter)) { 26 // do { 27 // // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 28 // // ... and get other frame properties like width, height, offsets etc. 29 // // ... see 'struct WebPIterator' below for more info). 30 // } while (WebPDemuxNextFrame(&iter)); 31 // WebPDemuxReleaseIterator(&iter); 32 // } 33 // 34 // // ... (Extract metadata). 35 // WebPChunkIterator chunk_iter; 36 // if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); 37 // // ... (Consume the ICC profile in 'chunk_iter.chunk'). 38 // WebPDemuxReleaseChunkIterator(&chunk_iter); 39 // if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); 40 // // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). 41 // WebPDemuxReleaseChunkIterator(&chunk_iter); 42 // if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); 43 // // ... (Consume the XMP metadata in 'chunk_iter.chunk'). 44 // WebPDemuxReleaseChunkIterator(&chunk_iter); 45 // WebPDemuxDelete(demux); 46 47 #ifndef WEBP_WEBP_DEMUX_H_ 48 #define WEBP_WEBP_DEMUX_H_ 49 50 #include "./mux_types.h" 51 52 #if defined(__cplusplus) || defined(c_plusplus) 53 extern "C" { 54 #endif 55 56 #define WEBP_DEMUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b) 57 58 // Note: forward declaring enumerations is not allowed in (strict) C and C++, 59 // the types are left here for reference. 60 // typedef enum WebPDemuxState WebPDemuxState; 61 // typedef enum WebPFormatFeature WebPFormatFeature; 62 typedef struct WebPDemuxer WebPDemuxer; 63 typedef struct WebPIterator WebPIterator; 64 typedef struct WebPChunkIterator WebPChunkIterator; 65 66 //------------------------------------------------------------------------------ 67 68 // Returns the version number of the demux library, packed in hexadecimal using 69 // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 70 WEBP_EXTERN(int) WebPGetDemuxVersion(void); 71 72 //------------------------------------------------------------------------------ 73 // Life of a Demux object 74 75 typedef enum WebPDemuxState { 76 WEBP_DEMUX_PARSING_HEADER, // Not enough data to parse full header. 77 WEBP_DEMUX_PARSED_HEADER, // Header parsing complete, data may be available. 78 WEBP_DEMUX_DONE // Entire file has been parsed. 79 } WebPDemuxState; 80 81 // Internal, version-checked, entry point 82 WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal( 83 const WebPData*, int, WebPDemuxState*, int); 84 85 // Parses the full WebP file given by 'data'. 86 // Returns a WebPDemuxer object on successful parse, NULL otherwise. 87 static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { 88 return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); 89 } 90 91 // Parses the possibly incomplete WebP file given by 'data'. 92 // If 'state' is non-NULL it will be set to indicate the status of the demuxer. 93 // Returns a WebPDemuxer object on successful parse, NULL otherwise. 94 static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( 95 const WebPData* data, WebPDemuxState* state) { 96 return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); 97 } 98 99 // Frees memory associated with 'dmux'. 100 WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux); 101 102 //------------------------------------------------------------------------------ 103 // Data/information extraction. 104 105 typedef enum WebPFormatFeature { 106 WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk. 107 WEBP_FF_CANVAS_WIDTH, 108 WEBP_FF_CANVAS_HEIGHT, 109 WEBP_FF_LOOP_COUNT, 110 WEBP_FF_BACKGROUND_COLOR, 111 WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. 112 // In case of a partial demux, this is the number of 113 // frames seen so far, with the last frame possibly 114 // being partial. 115 } WebPFormatFeature; 116 117 // Get the 'feature' value from the 'dmux'. 118 // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() 119 // returned a state > WEBP_DEMUX_PARSING_HEADER. 120 WEBP_EXTERN(uint32_t) WebPDemuxGetI( 121 const WebPDemuxer* dmux, WebPFormatFeature feature); 122 123 //------------------------------------------------------------------------------ 124 // Frame iteration. 125 126 struct WebPIterator { 127 int frame_num; 128 int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. 129 int fragment_num; 130 int num_fragments; 131 int x_offset, y_offset; // offset relative to the canvas. 132 int width, height; // dimensions of this frame or fragment. 133 int duration; // display duration in milliseconds. 134 WebPMuxAnimDispose dispose_method; // dispose method for the frame. 135 int complete; // true if 'fragment' contains a full frame. partial images 136 // may still be decoded with the WebP incremental decoder. 137 WebPData fragment; // The frame or fragment given by 'frame_num' and 138 // 'fragment_num'. 139 140 uint32_t pad[4]; // padding for later use. 141 void* private_; // for internal use only. 142 }; 143 144 // Retrieves frame 'frame_number' from 'dmux'. 145 // 'iter->fragment' points to the first fragment on return from this function. 146 // Individual fragments may be extracted using WebPDemuxSetFragment(). 147 // Setting 'frame_number' equal to 0 will return the last frame of the image. 148 // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. 149 // Call WebPDemuxReleaseIterator() when use of the iterator is complete. 150 // NOTE: 'dmux' must persist for the lifetime of 'iter'. 151 WEBP_EXTERN(int) WebPDemuxGetFrame( 152 const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); 153 154 // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or 155 // previous ('iter->frame_num' - 1) frame. These functions do not loop. 156 // Returns true on success, false otherwise. 157 WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter); 158 WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter); 159 160 // Sets 'iter->fragment' to reflect fragment number 'fragment_num'. 161 // Returns true if fragment 'fragment_num' is present, false otherwise. 162 WEBP_EXTERN(int) WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num); 163 164 // Releases any memory associated with 'iter'. 165 // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same 166 // iter. Also, must be called before destroying the associated WebPDemuxer with 167 // WebPDemuxDelete(). 168 WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter); 169 170 //------------------------------------------------------------------------------ 171 // Chunk iteration. 172 173 struct WebPChunkIterator { 174 // The current and total number of chunks with the fourcc given to 175 // WebPDemuxGetChunk(). 176 int chunk_num; 177 int num_chunks; 178 WebPData chunk; // The payload of the chunk. 179 180 uint32_t pad[6]; // padding for later use 181 void* private_; 182 }; 183 184 // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from 185 // 'dmux'. 186 // 'fourcc' is a character array containing the fourcc of the chunk to return, 187 // e.g., "ICCP", "XMP ", "EXIF", etc. 188 // Setting 'chunk_number' equal to 0 will return the last chunk in a set. 189 // Returns true if the chunk is found, false otherwise. Image related chunk 190 // payloads are accessed through WebPDemuxGetFrame() and related functions. 191 // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. 192 // NOTE: 'dmux' must persist for the lifetime of the iterator. 193 WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux, 194 const char fourcc[4], int chunk_number, 195 WebPChunkIterator* iter); 196 197 // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous 198 // ('iter->chunk_num' - 1) chunk. These functions do not loop. 199 // Returns true on success, false otherwise. 200 WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter); 201 WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter); 202 203 // Releases any memory associated with 'iter'. 204 // Must be called before destroying the associated WebPDemuxer with 205 // WebPDemuxDelete(). 206 WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); 207 208 //------------------------------------------------------------------------------ 209 210 #if defined(__cplusplus) || defined(c_plusplus) 211 } // extern "C" 212 #endif 213 214 #endif /* WEBP_WEBP_DEMUX_H_ */ 215