#ifndef WEBP_MUX_MUXI_H_
#define WEBP_MUX_MUXI_H_
#include <assert.h>
#include <stdlib.h>
#include "src/dec/vp8i_dec.h"
#include "src/dec/vp8li_dec.h"
#include "src/webp/format_constants.h"
#include "src/webp/mux.h"
#include "src/webp/mux_types.h"
#include "src/webp/types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MUX_MAJ_VERSION 1
#define MUX_MIN_VERSION 6
#define MUX_REV_VERSION 0
typedef struct WebPChunk WebPChunk;
struct WebPChunk {
uint32_t tag;
int owner; WebPData data;
WebPChunk* next;
};
typedef struct WebPMuxImage WebPMuxImage;
struct WebPMuxImage {
WebPChunk* header; WebPChunk* alpha; WebPChunk* img; WebPChunk* unknown; int width;
int height;
int has_alpha; int is_partial; WebPMuxImage* next;
};
struct WebPMux {
WebPMuxImage* images;
WebPChunk* iccp;
WebPChunk* exif;
WebPChunk* xmp;
WebPChunk* anim;
WebPChunk* vp8x;
WebPChunk* unknown;
int canvas_width;
int canvas_height;
};
typedef enum {
IDX_VP8X = 0,
IDX_ICCP,
IDX_ANIM,
IDX_ANMF,
IDX_ALPHA,
IDX_VP8,
IDX_VP8L,
IDX_EXIF,
IDX_XMP,
IDX_UNKNOWN,
IDX_NIL,
IDX_LAST_CHUNK
} CHUNK_INDEX;
#define NIL_TAG 0x00000000u
typedef struct {
uint32_t tag;
WebPChunkId id;
uint32_t size;
} ChunkInfo;
extern const ChunkInfo kChunks[IDX_LAST_CHUNK];
void ChunkInit(WebPChunk* const chunk);
CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);
WebPChunkId ChunkGetIdFromTag(uint32_t tag);
uint32_t ChunkGetTagFromFourCC(const char fourcc[4]);
CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]);
WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);
WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
int copy_data, uint32_t tag);
WebPMuxError ChunkSetHead(WebPChunk* const chunk, WebPChunk** const chunk_list);
WebPMuxError ChunkAppend(WebPChunk* const chunk, WebPChunk*** const chunk_list);
WebPChunk* ChunkRelease(WebPChunk* const chunk);
WebPChunk* ChunkDelete(WebPChunk* const chunk);
void ChunkListDelete(WebPChunk** const chunk_list);
static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
assert(chunk_size <= MAX_CHUNK_PAYLOAD);
return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
}
static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
const size_t data_size = chunk->data.size;
return SizeWithPadding(data_size);
}
size_t ChunkListDiskSize(const WebPChunk* chunk_list);
uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
void MuxImageInit(WebPMuxImage* const wpi);
WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);
int MuxImageFinalize(WebPMuxImage* const wpi);
static WEBP_INLINE int IsWPI(WebPChunkId id) {
switch (id) {
case WEBP_CHUNK_ANMF:
case WEBP_CHUNK_ALPHA:
case WEBP_CHUNK_IMAGE: return 1;
default: return 0;
}
}
WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);
WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth);
WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
WebPMuxImage** wpi);
size_t MuxImageDiskSize(const WebPMuxImage* const wpi);
uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);
int MuxHasAlpha(const WebPMuxImage* images);
uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);
WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);
WebPMuxError MuxValidate(const WebPMux* const mux);
#ifdef __cplusplus
} #endif
#endif