Remove support for partial files in Mux.

Change-Id: Ie084f308c79a3cfaf2ea13e800397debc2643470
This commit is contained in:
Urvang Joshi 2012-06-07 13:45:06 +05:30
parent f1df5587d9
commit 6d5c797cee
6 changed files with 18 additions and 73 deletions

View File

@ -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);

View File

@ -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_)

View File

@ -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_;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------