static WebPMuxError MuxSet(WebPMux* mux, TAG_ID id, uint nth, byte* data, uint size, WebPImageInfo* image_info, int copy_data) { WebPChunk chunk; WebPMuxError err = WEBP_MUX_NOT_FOUND; if (mux == null) return WEBP_MUX_INVALID_ARGUMENT; assert(!IsWPI(id)); ChunkInit(&chunk); 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_); if (id == UNKNOWN_ID && size > TAG_SIZE) { // For raw-data unknown chunk, the first four bytes should be the tag to be // used for the chunk. err = ChunkAssignDataImageInfo(&chunk, data + TAG_SIZE, size - TAG_SIZE, image_info, copy_data, GetLE32(data + 0)); if (err == WEBP_MUX_OK) err = ChunkSetNth(&chunk, &mux.unknown_, nth); } return err; }
static WebPMuxError MuxAddChunk(WebPMux* mux, uint nth, uint tag, byte* data, uint size, WebPImageInfo* image_info, int copy_data) { TAG_ID id; assert(mux != null); assert(size <= MAX_CHUNK_PAYLOAD); id = ChunkGetIdFromTag(tag); if (id == NIL_ID) return WEBP_MUX_INVALID_PARAMETER; return MuxSet(mux, id, nth, data, size, image_info, copy_data); }
static void InitImageInfo(WebPImageInfo* image_info) { assert(image_info); memset(image_info, 0, sizeof(*image_info)); }
// Create data for frame/tile given image_info. static WebPMuxError CreateDataFromImageInfo(WebPImageInfo* image_info, int is_frame, byte** data, uint* size) { assert(data); assert(size); assert(image_info); *size = kChunks[is_frame ? FRAME_ID : TILE_ID].chunkSize; *data = (byte*)malloc(*size); if (*data == null) return WEBP_MUX_MEMORY_ERROR; // Fill in data according to frame/tile chunk format. PutLE32(*data + 0, image_info.x_offset_); PutLE32(*data + 4, image_info.y_offset_); if (is_frame) { PutLE32(*data + 8, image_info.width_); PutLE32(*data + 12, image_info.height_); PutLE32(*data + 16, image_info.duration_); } return WEBP_MUX_OK; }
//------------------------------------------------------------------------------ // Chunk writer methods. WebPMuxError ChunkAssignDataImageInfo(WebPChunk* chunk, byte* data, uint data_size, WebPImageInfo* image_info, int copy_data, uint tag) { // For internally allocated chunks, always copy data & make it owner of data. if ((tag == kChunks[VP8X_ID].chunkTag) || (tag == kChunks[LOOP_ID].chunkTag)) { copy_data = 1; } ChunkRelease(chunk); if (data == null) { data_size = 0; } else if (data_size == 0) { data = null; } if (data != null) { if (copy_data) { // Copy data. chunk.data_ = (byte*)malloc(data_size); if (chunk.data_ == null) return WEBP_MUX_MEMORY_ERROR; memcpy((byte*)chunk.data_, data, data_size); chunk.payload_size_ = data_size; // Chunk is owner of data. chunk.owner_ = 1; } else { // Don't copy data. chunk.data_ = data; chunk.payload_size_ = data_size; } } if (tag == kChunks[IMAGE_ID].chunkTag) { chunk.image_info_ = image_info; } chunk.tag_ = tag; return WEBP_MUX_OK; }