mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
Remove support for partial files in Mux.
Change-Id: Ie084f308c79a3cfaf2ea13e800397debc2643470
This commit is contained in:
parent
f1df5587d9
commit
6d5c797cee
@ -325,17 +325,13 @@ static int ReadFileToWebPData(const char* const filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int CreateMux(const char* const filename, WebPMux** mux) {
|
static int CreateMux(const char* const filename, WebPMux** mux) {
|
||||||
WebPMuxState mux_state;
|
|
||||||
WebPData bitstream;
|
WebPData bitstream;
|
||||||
|
|
||||||
assert(mux != NULL);
|
assert(mux != NULL);
|
||||||
|
|
||||||
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||||
*mux = WebPMuxCreate(&bitstream, 1, &mux_state);
|
*mux = WebPMuxCreate(&bitstream, 1);
|
||||||
free((void*)bitstream.bytes_);
|
free((void*)bitstream.bytes_);
|
||||||
if (*mux != NULL && mux_state == WEBP_MUX_STATE_COMPLETE) return 1;
|
if (*mux != NULL) return 1;
|
||||||
fprintf(stderr, "Failed to create mux object from file %s. mux_state = %d.\n",
|
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||||
filename, mux_state);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,15 +341,12 @@ static int ReadImage(const char* filename,
|
|||||||
WebPMux* mux;
|
WebPMux* mux;
|
||||||
WebPMuxError err;
|
WebPMuxError err;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
WebPMuxState mux_state;
|
|
||||||
|
|
||||||
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||||
mux = WebPMuxCreate(&bitstream, 1, &mux_state);
|
mux = WebPMuxCreate(&bitstream, 1);
|
||||||
free((void*)bitstream.bytes_);
|
free((void*)bitstream.bytes_);
|
||||||
if (mux == NULL || mux_state != WEBP_MUX_STATE_COMPLETE) {
|
if (mux == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||||
"Failed to create mux object from file %s. mux_state = %d.\n",
|
|
||||||
filename, mux_state);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
err = WebPMuxGetImage(mux, &image, &alpha);
|
err = WebPMuxGetImage(mux, &image, &alpha);
|
||||||
|
@ -23,7 +23,6 @@ extern "C" {
|
|||||||
static void MuxInit(WebPMux* const mux) {
|
static void MuxInit(WebPMux* const mux) {
|
||||||
if (mux == NULL) return;
|
if (mux == NULL) return;
|
||||||
memset(mux, 0, sizeof(*mux));
|
memset(mux, 0, sizeof(*mux));
|
||||||
mux->state_ = WEBP_MUX_STATE_PARTIAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPMux* WebPNewInternal(int version) {
|
WebPMux* WebPNewInternal(int version) {
|
||||||
@ -182,11 +181,8 @@ static WebPMuxError GetImageData(const WebPData* const bitstream,
|
|||||||
} else {
|
} else {
|
||||||
// It is webp file data. Extract image data from it.
|
// It is webp file data. Extract image data from it.
|
||||||
WebPMuxError err;
|
WebPMuxError err;
|
||||||
WebPMuxState mux_state;
|
WebPMux* const mux = WebPMuxCreate(bitstream, 0);
|
||||||
WebPMux* const mux = WebPMuxCreate(bitstream, 0, &mux_state);
|
if (mux == NULL) return WEBP_MUX_BAD_DATA;
|
||||||
if (mux == NULL || mux_state != WEBP_MUX_STATE_COMPLETE) {
|
|
||||||
return WEBP_MUX_BAD_DATA;
|
|
||||||
}
|
|
||||||
err = WebPMuxGetImage(mux, image, alpha);
|
err = WebPMuxGetImage(mux, image, alpha);
|
||||||
WebPMuxDelete(mux);
|
WebPMuxDelete(mux);
|
||||||
*is_lossless = VP8LCheckSignature(image->bytes_, image->size_);
|
*is_lossless = VP8LCheckSignature(image->bytes_, image->size_);
|
||||||
@ -676,9 +672,6 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux,
|
|||||||
err = CreateVP8XChunk(mux);
|
err = CreateVP8XChunk(mux);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
// Mark mux as complete.
|
|
||||||
mux->state_ = WEBP_MUX_STATE_COMPLETE;
|
|
||||||
|
|
||||||
// Allocate data.
|
// Allocate data.
|
||||||
size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_)
|
size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_)
|
||||||
+ ChunksListDiskSize(mux->loop_) + MuxImageListDiskSize(mux->images_)
|
+ ChunksListDiskSize(mux->loop_) + MuxImageListDiskSize(mux->images_)
|
||||||
|
@ -60,7 +60,6 @@ struct WebPMuxImage {
|
|||||||
|
|
||||||
// Main mux object. Stores data chunks.
|
// Main mux object. Stores data chunks.
|
||||||
struct WebPMux {
|
struct WebPMux {
|
||||||
WebPMuxState state_;
|
|
||||||
WebPMuxImage* images_;
|
WebPMuxImage* images_;
|
||||||
WebPChunk* iccp_;
|
WebPChunk* iccp_;
|
||||||
WebPChunk* meta_;
|
WebPChunk* meta_;
|
||||||
|
@ -507,12 +507,7 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
|
|||||||
WebPMuxError err;
|
WebPMuxError err;
|
||||||
|
|
||||||
// Verify mux is not NULL.
|
// Verify mux is not NULL.
|
||||||
if (mux == NULL || mux->state_ == WEBP_MUX_STATE_ERROR) {
|
if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
||||||
return WEBP_MUX_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No further checks if mux is partial.
|
|
||||||
if (mux->state_ == WEBP_MUX_STATE_PARTIAL) return WEBP_MUX_OK;
|
|
||||||
|
|
||||||
// Verify mux has at least one image.
|
// Verify mux has at least one image.
|
||||||
if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
||||||
|
@ -78,7 +78,7 @@ static WebPMuxError ChunkAssignData(WebPChunk* chunk, const uint8_t* data,
|
|||||||
// Create a mux object from WebP-RIFF data.
|
// Create a mux object from WebP-RIFF data.
|
||||||
|
|
||||||
WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
||||||
WebPMuxState* const mux_state, int version) {
|
int version) {
|
||||||
size_t riff_size;
|
size_t riff_size;
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
const uint8_t* end;
|
const uint8_t* end;
|
||||||
@ -87,8 +87,6 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
|||||||
const uint8_t* data;
|
const uint8_t* data;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (mux_state) *mux_state = WEBP_MUX_STATE_PARTIAL;
|
|
||||||
|
|
||||||
// Sanity checks.
|
// Sanity checks.
|
||||||
if (version != WEBP_MUX_ABI_VERSION) goto Err; // version mismatch
|
if (version != WEBP_MUX_ABI_VERSION) goto Err; // version mismatch
|
||||||
if (bitstream == NULL) goto Err;
|
if (bitstream == NULL) goto Err;
|
||||||
@ -106,10 +104,7 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
|||||||
mux = WebPMuxNew();
|
mux = WebPMuxNew();
|
||||||
if (mux == NULL) goto Err;
|
if (mux == NULL) goto Err;
|
||||||
|
|
||||||
if (size < RIFF_HEADER_SIZE + TAG_SIZE) {
|
if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err;
|
||||||
mux->state_ = WEBP_MUX_STATE_PARTIAL;
|
|
||||||
goto Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
tag = GetLE32(data + RIFF_HEADER_SIZE);
|
tag = GetLE32(data + RIFF_HEADER_SIZE);
|
||||||
if (tag != kChunks[IDX_VP8].tag &&
|
if (tag != kChunks[IDX_VP8].tag &&
|
||||||
@ -119,12 +114,9 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
|
riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
|
||||||
if (riff_size > MAX_CHUNK_PAYLOAD) {
|
if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) {
|
||||||
goto Err;
|
goto Err;
|
||||||
} else if (riff_size > size) {
|
|
||||||
mux->state_ = WEBP_MUX_STATE_PARTIAL;
|
|
||||||
} else {
|
} else {
|
||||||
mux->state_ = WEBP_MUX_STATE_COMPLETE;
|
|
||||||
if (riff_size < size) { // Redundant data after last chunk.
|
if (riff_size < size) { // Redundant data after last chunk.
|
||||||
size = riff_size; // To make sure we don't read any data beyond mux_size.
|
size = riff_size; // To make sure we don't read any data beyond mux_size.
|
||||||
}
|
}
|
||||||
@ -146,14 +138,7 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
|||||||
|
|
||||||
ChunkInit(&chunk);
|
ChunkInit(&chunk);
|
||||||
err = ChunkAssignData(&chunk, data, size, riff_size, copy_data);
|
err = ChunkAssignData(&chunk, data, size, riff_size, copy_data);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
if (err == WEBP_MUX_NOT_ENOUGH_DATA &&
|
|
||||||
mux->state_ == WEBP_MUX_STATE_PARTIAL) {
|
|
||||||
goto Ok;
|
|
||||||
} else {
|
|
||||||
goto Err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id = ChunkGetIdFromTag(chunk.tag_);
|
id = ChunkGetIdFromTag(chunk.tag_);
|
||||||
|
|
||||||
@ -191,15 +176,12 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
|||||||
// Validate mux if complete.
|
// Validate mux if complete.
|
||||||
if (MuxValidate(mux) != WEBP_MUX_OK) goto Err;
|
if (MuxValidate(mux) != WEBP_MUX_OK) goto Err;
|
||||||
|
|
||||||
Ok:
|
|
||||||
MuxImageDelete(wpi);
|
MuxImageDelete(wpi);
|
||||||
if (mux_state) *mux_state = mux->state_;
|
|
||||||
return mux; // All OK;
|
return mux; // All OK;
|
||||||
|
|
||||||
Err: // Something bad happened.
|
Err: // Something bad happened.
|
||||||
MuxImageDelete(wpi);
|
MuxImageDelete(wpi);
|
||||||
WebPMuxDelete(mux);
|
WebPMuxDelete(mux);
|
||||||
if (mux_state) *mux_state = WEBP_MUX_STATE_ERROR;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,13 +199,7 @@ WebPMuxError WebPMuxGetFeatures(const WebPMux* const mux, uint32_t* flags) {
|
|||||||
err = MuxGet(mux, IDX_VP8X, 1, &data);
|
err = MuxGet(mux, IDX_VP8X, 1, &data);
|
||||||
if (err == WEBP_MUX_NOT_FOUND) {
|
if (err == WEBP_MUX_NOT_FOUND) {
|
||||||
// Check if VP8/VP8L chunk is present.
|
// Check if VP8/VP8L chunk is present.
|
||||||
err = WebPMuxGetImage(mux, &data, NULL);
|
return WebPMuxGetImage(mux, &data, NULL);
|
||||||
if (err == WEBP_MUX_NOT_FOUND && // Data not available (yet).
|
|
||||||
mux->state_ == WEBP_MUX_STATE_PARTIAL) { // Incremental case.
|
|
||||||
return WEBP_MUX_NOT_ENOUGH_DATA;
|
|
||||||
} else {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
} else if (err != WEBP_MUX_OK) {
|
} else if (err != WEBP_MUX_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
//
|
//
|
||||||
// int copy_data = 0;
|
// int copy_data = 0;
|
||||||
// // ... (Read data from file).
|
// // ... (Read data from file).
|
||||||
// WebPMux* mux = WebPMuxCreate(&data, copy_data, NULL);
|
// WebPMux* mux = WebPMuxCreate(&data, copy_data);
|
||||||
// WebPMuxGetImage(mux, &image, &alpha);
|
// WebPMuxGetImage(mux, &image, &alpha);
|
||||||
// // ... (Consume image; e.g. call WebPDecode() to decode the data).
|
// // ... (Consume image; e.g. call WebPDecode() to decode the data).
|
||||||
// WebPMuxGetColorProfile(mux, &icc_profile);
|
// WebPMuxGetColorProfile(mux, &icc_profile);
|
||||||
@ -64,12 +64,6 @@ typedef enum {
|
|||||||
WEBP_MUX_NOT_ENOUGH_DATA = -6
|
WEBP_MUX_NOT_ENOUGH_DATA = -6
|
||||||
} WebPMuxError;
|
} WebPMuxError;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WEBP_MUX_STATE_PARTIAL = 0,
|
|
||||||
WEBP_MUX_STATE_COMPLETE = 1,
|
|
||||||
WEBP_MUX_STATE_ERROR = -1
|
|
||||||
} WebPMuxState;
|
|
||||||
|
|
||||||
// Flag values for different features used in VP8X chunk.
|
// Flag values for different features used in VP8X chunk.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TILE_FLAG = 0x00000001,
|
TILE_FLAG = 0x00000001,
|
||||||
@ -117,24 +111,19 @@ WEBP_EXTERN(void) WebPMuxDelete(WebPMux* const mux);
|
|||||||
// Mux creation.
|
// Mux creation.
|
||||||
|
|
||||||
// Internal, version-checked, entry point
|
// Internal, version-checked, entry point
|
||||||
WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData* const,
|
WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData* const, int, int);
|
||||||
int, WebPMuxState* const, int);
|
|
||||||
|
|
||||||
// Creates a mux object from raw data given in WebP RIFF format.
|
// Creates a mux object from raw data given in WebP RIFF format.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// bitstream - (in) the bitstream data in WebP RIFF format
|
// bitstream - (in) the bitstream data in WebP RIFF format
|
||||||
// copy_data - (in) value 1 indicates given data WILL copied to the mux, and
|
// copy_data - (in) value 1 indicates given data WILL copied to the mux, and
|
||||||
// value 0 indicates data will NOT be copied.
|
// value 0 indicates data will NOT be copied.
|
||||||
// mux_state - (out) indicates the state of the mux returned. Can be passed
|
|
||||||
// NULL if not required.
|
|
||||||
// Returns:
|
// Returns:
|
||||||
// A pointer to the mux object created from given data - on success.
|
// A pointer to the mux object created from given data - on success.
|
||||||
// NULL - In case of invalid data or memory error.
|
// NULL - In case of invalid data or memory error.
|
||||||
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* const bitstream,
|
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* const bitstream,
|
||||||
int copy_data,
|
int copy_data) {
|
||||||
WebPMuxState* const mux_state) {
|
return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
|
||||||
return WebPMuxCreateInternal(
|
|
||||||
bitstream, copy_data, mux_state, WEBP_MUX_ABI_VERSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user