Mux: Allow only some frames/tiles to have alpha.

And related const fixes.

Change-Id: I79f6f1b9f8c6faac8cc4ef24b58edff6d90de045
This commit is contained in:
Urvang Joshi 2012-06-29 17:16:08 +05:30
parent 3ba81bbe8b
commit 97649c8f6b
4 changed files with 17 additions and 26 deletions

View File

@ -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 present at the beginning of each tile for a frame that is represented as
multiple tile images. multiple tile images.
* An optional 'ALPH' chunk with alpha bitstream of the frame/tile. If the * An optional 'ALPH' chunk with alpha bitstream of the frame/tile.
file contains transparency, this chunk MUST be present for each frame/tile
containing a 'VP8 ' chunk. It MUST NOT be present otherwise.
* A 'VP8 ' or a 'VP8L' chunk containing compressed image data of the * A 'VP8 ' or a 'VP8L' chunk containing compressed image data of the
frame/tile. frame/tile.
@ -355,7 +353,8 @@ Metadata (M): 1 bit
Alpha (L): 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 Rotation and Symmetry (R): 3 bits
@ -540,10 +539,10 @@ Alpha bitstream: _Chunk Size_ - `1` bytes
: Encoded alpha bitstream. : Encoded alpha bitstream.
This optional chunk contains encoded alpha data for a single frame/tile. 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, For images with transparency, some of the frames/tiles may contain this chunk.
there is one exception to this rule: a frame/tile containing a 'VP8L' chunk However, a frame/tile containing a 'VP8L' chunk SHOULD NOT contain this chunk.
SHOULD NOT contain this chunk. **Rationale**: the transparency information of **Rationale**: the transparency information of a frame/tile is already part of
a frame/tile is already part of the 'VP8L' chunk. the 'VP8L' chunk.
The alpha channel data is losslessly stored as raw data (when The alpha channel data is losslessly stored as raw data (when
compression method is '0') or compressed using the lossless format compression method is '0') or compressed using the lossless format

View File

@ -613,9 +613,8 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
} }
} }
if (images->alpha_ != NULL && images->alpha_->data_.bytes_ != NULL) { if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) {
// This is an image with alpha channel. flags |= ALPHA_FLAG; // Some images have an alpha channel.
flags |= ALPHA_FLAG;
} }
if (flags == 0) { if (flags == 0) {

View File

@ -194,7 +194,7 @@ WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
void MuxImageDeleteAll(WebPMuxImage** const wpi_list); void MuxImageDeleteAll(WebPMuxImage** const wpi_list);
// Count number of images matching the given tag id in the '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. // Check if given ID corresponds to an image related chunk.
static WEBP_INLINE int IsWPI(WebPChunkId id) { 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. // Get a reference to appropriate chunk list within an image given chunk tag.
static WEBP_INLINE WebPChunk** MuxImageGetListFromId(WebPMuxImage* wpi, static WEBP_INLINE WebPChunk** MuxImageGetListFromId(
WebPChunkId id) { const WebPMuxImage* const wpi, WebPChunkId id) {
assert(wpi != NULL); assert(wpi != NULL);
switch (id) { switch (id) {
case WEBP_CHUNK_FRAME: case WEBP_CHUNK_FRAME:
case WEBP_CHUNK_TILE: return &wpi->header_; case WEBP_CHUNK_TILE: return (WebPChunk**)&wpi->header_;
case WEBP_CHUNK_ALPHA: return &wpi->alpha_; case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_;
case WEBP_CHUNK_IMAGE: return &wpi->img_; case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_;
default: return NULL; default: return NULL;
} }
} }

View File

@ -262,9 +262,9 @@ WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// MuxImage search methods. // MuxImage search methods.
int MuxImageCount(WebPMuxImage* const wpi_list, WebPChunkId id) { int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id) {
int count = 0; int count = 0;
WebPMuxImage* current; const WebPMuxImage* current;
for (current = wpi_list; current != NULL; current = current->next_) { for (current = wpi_list; current != NULL; current = current->next_) {
const WebPChunk* const wpi_chunk = *MuxImageGetListFromId(current, id); const WebPChunk* const wpi_chunk = *MuxImageGetListFromId(current, id);
if (wpi_chunk != NULL) { if (wpi_chunk != NULL) {
@ -558,13 +558,6 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
} else { } else {
err = ValidateChunk(mux, IDX_ALPHA, ALPHA_FLAG, flags, -1, &num_alpha); err = ValidateChunk(mux, IDX_ALPHA, ALPHA_FLAG, flags, -1, &num_alpha);
if (err != WEBP_MUX_OK) return err; 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. // num_tiles & num_images are consistent.