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

View File

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

View File

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

View File

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