diff --git a/doc/webp-container-spec.txt b/doc/webp-container-spec.txt index 87b68a68..5689c5db 100644 --- a/doc/webp-container-spec.txt +++ b/doc/webp-container-spec.txt @@ -300,9 +300,7 @@ multiple frames. Data for each frame consists of: present at the beginning of each tile for a frame that is represented as multiple tile images. - * An optional 'ALPH' chunk with alpha bitstream of the frame/tile. If the - file contains transparency, this chunk MUST be present for each frame/tile - containing a 'VP8 ' chunk. It MUST NOT be present otherwise. + * An optional 'ALPH' chunk with alpha bitstream of the frame/tile. * A 'VP8 ' or a 'VP8L' chunk containing compressed image data of the frame/tile. @@ -355,7 +353,8 @@ Metadata (M): 1 bit Alpha (L): 1 bit -: Set if the file contains images with transparency information ("alpha"). +: Set if the file contains some (or all) images with transparency information +("alpha"). Rotation and Symmetry (R): 3 bits @@ -540,10 +539,10 @@ Alpha bitstream: _Chunk Size_ - `1` bytes : Encoded alpha bitstream. This optional chunk contains encoded alpha data for a single frame/tile. -Either **ALL or NONE** of the frame/tiles must contain this chunk. However, -there is one exception to this rule: a frame/tile containing a 'VP8L' chunk -SHOULD NOT contain this chunk. **Rationale**: the transparency information of -a frame/tile is already part of the 'VP8L' chunk. +For images with transparency, some of the frames/tiles may contain this chunk. +However, a frame/tile containing a 'VP8L' chunk SHOULD NOT contain this chunk. +**Rationale**: the transparency information of a frame/tile is already part of +the 'VP8L' chunk. The alpha channel data is losslessly stored as raw data (when compression method is '0') or compressed using the lossless format diff --git a/src/mux/muxedit.c b/src/mux/muxedit.c index 00ca9ac6..e63d2cee 100644 --- a/src/mux/muxedit.c +++ b/src/mux/muxedit.c @@ -613,9 +613,8 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) { } } - if (images->alpha_ != NULL && images->alpha_->data_.bytes_ != NULL) { - // This is an image with alpha channel. - flags |= ALPHA_FLAG; + if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) { + flags |= ALPHA_FLAG; // Some images have an alpha channel. } if (flags == 0) { diff --git a/src/mux/muxi.h b/src/mux/muxi.h index cf8b9692..6e80849d 100644 --- a/src/mux/muxi.h +++ b/src/mux/muxi.h @@ -194,7 +194,7 @@ WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi); void MuxImageDeleteAll(WebPMuxImage** const wpi_list); // Count number of images matching the given tag id in the 'wpi_list'. -int MuxImageCount(WebPMuxImage* const wpi_list, WebPChunkId id); +int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id); // Check if given ID corresponds to an image related chunk. static WEBP_INLINE int IsWPI(WebPChunkId id) { @@ -208,14 +208,14 @@ static WEBP_INLINE int IsWPI(WebPChunkId id) { } // Get a reference to appropriate chunk list within an image given chunk tag. -static WEBP_INLINE WebPChunk** MuxImageGetListFromId(WebPMuxImage* wpi, - WebPChunkId id) { +static WEBP_INLINE WebPChunk** MuxImageGetListFromId( + const WebPMuxImage* const wpi, WebPChunkId id) { assert(wpi != NULL); switch (id) { case WEBP_CHUNK_FRAME: - case WEBP_CHUNK_TILE: return &wpi->header_; - case WEBP_CHUNK_ALPHA: return &wpi->alpha_; - case WEBP_CHUNK_IMAGE: return &wpi->img_; + case WEBP_CHUNK_TILE: return (WebPChunk**)&wpi->header_; + case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_; + case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_; default: return NULL; } } diff --git a/src/mux/muxinternal.c b/src/mux/muxinternal.c index a09f3f35..bbc585b1 100644 --- a/src/mux/muxinternal.c +++ b/src/mux/muxinternal.c @@ -262,9 +262,9 @@ WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { //------------------------------------------------------------------------------ // MuxImage search methods. -int MuxImageCount(WebPMuxImage* const wpi_list, WebPChunkId id) { +int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id) { int count = 0; - WebPMuxImage* current; + const WebPMuxImage* current; for (current = wpi_list; current != NULL; current = current->next_) { const WebPChunk* const wpi_chunk = *MuxImageGetListFromId(current, id); if (wpi_chunk != NULL) { @@ -558,13 +558,6 @@ WebPMuxError MuxValidate(const WebPMux* const mux) { } else { err = ValidateChunk(mux, IDX_ALPHA, ALPHA_FLAG, flags, -1, &num_alpha); if (err != WEBP_MUX_OK) return err; - - // num_images & num_alpha_chunks are consistent. - if (num_alpha > 0 && num_alpha != num_images) { - // Note that "num_alpha > 0" is the correct test but "flags && ALPHA_FLAG" - // is NOT, because ALPHA_FLAG is based on first image only. - return WEBP_MUX_INVALID_ARGUMENT; - } } // num_tiles & num_images are consistent.