1 // Copyright 2012 Google Inc. All Rights Reserved. 2 // 3 // This code is licensed under the same terms as WebM: 4 // Software License Agreement: http://www.webmproject.org/license/software/ 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 // ----------------------------------------------------------------------------- 7 // 8 // Demux API. 9 // Enables extraction of image and extended format data from WebP files. 10 11 // Code Example: Demuxing WebP data to extract all the frames, ICC profile 12 // and EXIF/XMP metadata. 13 // 14 // WebPDemuxer* demux = WebPDemux(&webp_data); 15 // 16 // uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 17 // uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 18 // // ... (Get information about the features present in the WebP file). 19 // uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 20 // 21 // // ... (Iterate over all frames). 22 // WebPIterator iter; 23 // if (WebPDemuxGetFrame(demux, 1, &iter)) { 24 // do { 25 // // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 26 // // ... and get other frame properties like width, height, offsets etc. 27 // // ... see 'struct WebPIterator' below for more info). 28 // } while (WebPDemuxNextFrame(&iter)); 29 // WebPDemuxReleaseIterator(&iter); 30 // } 31 // 32 // // ... (Extract metadata). 33 // WebPChunkIterator chunk_iter; 34 // if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); 35 // // ... (Consume the ICC profile in 'chunk_iter.chunk'). 36 // WebPDemuxReleaseChunkIterator(&chunk_iter); 37 // if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); 38 // // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). 39 // WebPDemuxReleaseChunkIterator(&chunk_iter); 40 // if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); 41 // // ... (Consume the XMP metadata in 'chunk_iter.chunk'). 42 // WebPDemuxReleaseChunkIterator(&chunk_iter); 43 // WebPDemuxDelete(demux); 44 45 #ifndef WEBP_WEBP_DEMUX_H_ 46 #define WEBP_WEBP_DEMUX_H_ 47 48 #include "./format_constants.h" 49 #include "./mux_types.h" 50 51 #if defined(__cplusplus) || defined(c_plusplus) 52 extern "C" { 53 #endif 54 55 #define WEBP_DEMUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b) 56 57 typedef struct WebPDemuxer WebPDemuxer; 58 #if !(defined(__cplusplus) || defined(c_plusplus)) 59 typedef enum WebPDemuxState WebPDemuxState; 60 typedef enum WebPFormatFeature WebPFormatFeature; 61 #endif 62 typedef struct WebPIterator WebPIterator; 63 typedef struct WebPChunkIterator WebPChunkIterator; 64 65 //------------------------------------------------------------------------------ 66 67 // Returns the version number of the demux library, packed in hexadecimal using 68 // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 69 WEBP_EXTERN(int) WebPGetDemuxVersion(void); 70 71 //------------------------------------------------------------------------------ 72 // Life of a Demux object 73 74 enum WebPDemuxState { 75 WEBP_DEMUX_PARSING_HEADER, // Not enough data to parse full header. 76 WEBP_DEMUX_PARSED_HEADER, // Header parsing complete, data may be available. 77 WEBP_DEMUX_DONE // Entire file has been parsed. 78 }; 79 80 // Internal, version-checked, entry point 81 WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal( 82 const WebPData*, int, WebPDemuxState*, int); 83 84 // Parses the WebP file given by 'data'. 85 // A complete WebP file must be present in 'data' for the function to succeed. 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 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 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 }; 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