static WebPMuxError MuxGet(WebPMux* mux, TAG_ID id, uint nth, WebPData* data) { assert(mux != null); memset(data, 0, sizeof(*data)); assert(!IsWPI(id)); SWITCH_ID_LIST(VP8X_ID, mux.vp8x_); SWITCH_ID_LIST(ICCP_ID, mux.iccp_); SWITCH_ID_LIST(LOOP_ID, mux.loop_); SWITCH_ID_LIST(META_ID, mux.meta_); SWITCH_ID_LIST(UNKNOWN_ID, mux.unknown_); return WEBP_MUX_NOT_FOUND; }
// Gets a reference to the nth tile from the mux object. // The caller should NOT free the returned data. // 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 tile in the mux object // image - (out) the image data // alpha - (out) the alpha data corresponding to tile image (if present) // x_offset - (out) x-offset of the returned tile // y_offset - (out) y-offset of the returned tile // Returns: // WEBP_MUX_INVALID_ARGUMENT - if either mux, image, x_offset or // y_offset is null // WEBP_MUX_NOT_FOUND - if there are less than nth tiles in the mux object. // WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid. // WEBP_MUX_OK - on success. WebPMuxError WebPMuxGetTile(WebPMux* mux, uint nth, WebPData* image, WebPData* alpha, uint* x_offset, uint* y_offset) { return MuxGetFrameTileInternal(mux, nth, image, alpha, x_offset, y_offset, null, kChunks[TILE_ID].chunkTag); }
// Gets a reference to the nth animation frame from the mux object. // The caller should NOT free the returned data. // 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 // image - (out) the image data // alpha - (out) the alpha data corresponding to frame image (if present) // x_offset - (out) x-offset of the returned frame // y_offset - (out) y-offset of the returned frame // duration - (out) duration of the returned frame (in milliseconds) // Returns: // WEBP_MUX_INVALID_ARGUMENT - if either mux, image, x_offset, // y_offset, or duration 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. WebPMuxError WebPMuxGetFrame(WebPMux* mux, uint nth, WebPData* image, WebPData* alpha, uint* x_offset, uint* y_offset, uint* duration) { return MuxGetFrameTileInternal(mux, nth, image, alpha, x_offset, y_offset, duration, kChunks[FRAME_ID].chunkTag); }
static WebPMuxError MuxGetFrameTileInternal(WebPMux* mux, uint nth, WebPData* image, WebPData* alpha, uint* x_offset, uint* y_offset, uint* duration, uint tag) { byte* frame_tile_data; uint frame_tile_size; WebPMuxError err; WebPMuxImage* wpi; int is_frame = (tag == kChunks[FRAME_ID].chunkTag) ? 1 : 0; TAG_ID id = is_frame ? FRAME_ID : TILE_ID; if (mux == null || image == null || x_offset == null || y_offset == null || (is_frame && duration == null)) { return WEBP_MUX_INVALID_ARGUMENT; } // Get the nth WebPMuxImage. err = MuxImageGetNth((WebPMuxImage**)&mux.images_, nth, id, &wpi); if (err != WEBP_MUX_OK) return err; // Get frame chunk. assert(wpi.header_ != null); // As GetNthImage() already checked header_. frame_tile_data = wpi.header_.data_; frame_tile_size = wpi.header_.payload_size_; if (frame_tile_size < kChunks[id].chunkSize) return WEBP_MUX_BAD_DATA; *x_offset = GetLE32(frame_tile_data + 0); *y_offset = GetLE32(frame_tile_data + 4); if (is_frame) *duration = GetLE32(frame_tile_data + 16); // Get alpha chunk (if present & requested). if (alpha != null) { memset(alpha, 0, sizeof(*alpha)); if (wpi.alpha_ != null) { alpha.bytes_ = wpi.alpha_.data_; alpha.size_ = wpi.alpha_.payload_size_; } } // Get image chunk. memset(image, 0, sizeof(*image)); if (wpi.vp8_ != null) { image.bytes_ = wpi.vp8_.data_; image.size_ = wpi.vp8_.payload_size_; } return WEBP_MUX_OK; }
// Gets a reference to the color profile in the mux object. // The caller should NOT free the returned data. // Parameters: // mux - (in) object from which the color profile data is to be fetched // color_profile - (out) color profile data // Returns: // WEBP_MUX_INVALID_ARGUMENT - if either mux or color_profile is null. // WEBP_MUX_NOT_FOUND - if color profile is not present in mux object. // WEBP_MUX_OK - on success. WebPMuxError WebPMuxGetColorProfile(WebPMux* mux, WebPData* color_profile) { if (mux == null || color_profile == null) { return WEBP_MUX_INVALID_ARGUMENT; } return MuxGet(mux, ICCP_ID, 1, color_profile); }
// Gets a reference to the XMP metadata in the mux object. // The caller should NOT free the returned data. // Parameters: // mux - (in) object from which the XMP metadata is to be fetched // metadata - (out) XMP metadata // Returns: // WEBP_MUX_INVALID_ARGUMENT - if either mux or metadata is null. // WEBP_MUX_NOT_FOUND - if metadata is not present in mux object. // WEBP_MUX_OK - on success. public WebPMuxError WebPMuxGetMetadata(WebPMux* mux, WebPData* metadata) { if (mux == null || metadata == null) { return WEBP_MUX_INVALID_ARGUMENT; } return MuxGet(mux, META_ID, 1, metadata); }
// Gets a reference to the image in the mux object. // The caller should NOT free the returned data. // Parameters: // mux - (in) object from which the image is to be fetched // image - (out) the image data // alpha - (out) the alpha data of the image (if present) // Returns: // WEBP_MUX_INVALID_ARGUMENT - if either mux or image is null // OR if mux contains animation/tiling. // WEBP_MUX_NOT_FOUND - if image is not present in mux object. // WEBP_MUX_OK - on success. public WebPMuxError WebPMuxGetImage(WebPMux* mux, WebPData* image, WebPData* alpha) { WebPMuxError err; WebPMuxImage* wpi = null; if (mux == null || image == null) { return WEBP_MUX_INVALID_ARGUMENT; } memset(image, 0, sizeof(*image)); err = ValidateForImage(mux); if (err != WEBP_MUX_OK) return err; // All well. Get the image. err = MuxImageGetNth((WebPMuxImage**)&mux.images_, 1, IMAGE_ID, &wpi); assert(err == WEBP_MUX_OK); // Already tested above. // Get alpha chunk (if present & requested). if (alpha != null) { memset(alpha, 0, sizeof(*alpha)); if (wpi.alpha_ != null) { alpha.bytes_ = wpi.alpha_.data_; alpha.size_ = wpi.alpha_.payload_size_; } } // Get image chunk. if (wpi.vp8_ != null) { image.bytes_ = wpi.vp8_.data_; image.size_ = wpi.vp8_.payload_size_; } return WEBP_MUX_OK; }
// Outputs image data given data from a webp file (including RIFF header). static WebPMuxError GetImageData(byte* data, uint size, WebPData* image, WebPData* alpha) { if (size < TAG_SIZE || memcmp(data, "RIFF", TAG_SIZE)) { // It is NOT webp file data. Return input data as is. image.bytes_ = data; image.size_ = size; return WEBP_MUX_OK; } else { // It is webp file data. Extract image data from it. WebPMuxError err; WebPMuxState mux_state; WebPMux* mux = WebPMuxCreate(data, size, 0, &mux_state); if (mux == null || mux_state != WEBP_MUX_STATE_COMPLETE) { return WEBP_MUX_BAD_DATA; } err = WebPMuxGetImage(mux, image, alpha); WebPMuxDelete(mux); return err; } }