Better alpha support in webpmux binary

- Support for adding/getting frames/tiles with alpha in webpmux
- For "-info" option in webpmux binary, add alpha related info

Change-Id: Iccd2fd35ab8453dabd74779f12f2844ab76d0538
This commit is contained in:
Urvang Joshi 2011-12-01 16:11:51 +05:30
parent a0ec9aace9
commit cdf97aa265

View File

@ -157,6 +157,8 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
int nTiles; int nTiles;
const uint8_t* data = NULL; const uint8_t* data = NULL;
uint32_t size = 0; uint32_t size = 0;
const uint8_t* alpha_data;
uint32_t alpha_size;
uint32_t flag; uint32_t flag;
WebPMuxError err = WebPMuxGetFeatures(mux, &flag); WebPMuxError err = WebPMuxGetFeatures(mux, &flag);
@ -173,6 +175,7 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
if (flag & TILE_FLAG) fprintf(stderr, " tiling"); if (flag & TILE_FLAG) fprintf(stderr, " tiling");
if (flag & ICCP_FLAG) fprintf(stderr, " icc profile"); if (flag & ICCP_FLAG) fprintf(stderr, " icc profile");
if (flag & META_FLAG) fprintf(stderr, " metadata"); if (flag & META_FLAG) fprintf(stderr, " metadata");
if (flag & ALPHA_FLAG) fprintf(stderr, " transparency");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (flag & ANIMATION_FLAG) { if (flag & ANIMATION_FLAG) {
@ -188,13 +191,16 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
if (nFrames > 0) { if (nFrames > 0) {
int i; int i;
uint32_t x_offset, y_offset, duration; uint32_t x_offset, y_offset, duration;
fprintf(stderr, "No.: x_offset y_offset duration");
fprintf(stderr, "No.: x_offset y_offset duration\n"); if (flag & ALPHA_FLAG) fprintf(stderr, " alpha_size");
fprintf(stderr, "\n");
for (i = 1; i <= nFrames; i++) { for (i = 1; i <= nFrames; i++) {
err = WebPMuxGetFrame(mux, i, &data, &size, NULL, NULL, err = WebPMuxGetFrame(mux, i, &data, &size, &alpha_data, &alpha_size,
&x_offset, &y_offset, &duration); &x_offset, &y_offset, &duration);
assert(err == WEBP_MUX_OK); RETURN_IF_ERROR2("Failed to retrieve frame#%d\n", i);
fprintf(stderr, "%3d: %8d %8d %8d\n", i, x_offset, y_offset, duration); fprintf(stderr, "%3d: %8d %8d %8d", i, x_offset, y_offset, duration);
if (flag & ALPHA_FLAG) fprintf(stderr, " %10d", alpha_size);
fprintf(stderr, "\n");
} }
} }
} }
@ -207,12 +213,16 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
if (nTiles > 0) { if (nTiles > 0) {
int i; int i;
uint32_t x_offset, y_offset; uint32_t x_offset, y_offset;
fprintf(stderr, "No.: x_offset y_offset\n"); fprintf(stderr, "No.: x_offset y_offset");
if (flag & ALPHA_FLAG) fprintf(stderr, " alpha_size");
fprintf(stderr, "\n");
for (i = 1; i <= nTiles; i++) { for (i = 1; i <= nTiles; i++) {
err = WebPMuxGetTile(mux, i, &data, &size, NULL, NULL, err = WebPMuxGetTile(mux, i, &data, &size, &alpha_data, &alpha_size,
&x_offset, &y_offset); &x_offset, &y_offset);
assert(err == WEBP_MUX_OK); RETURN_IF_ERROR2("Failed to retrieve tile#%d\n", i);
fprintf(stderr, "%3d: %8d %8d\n", i, x_offset, y_offset); fprintf(stderr, "%3d: %8d %8d", i, x_offset, y_offset);
if (flag & ALPHA_FLAG) fprintf(stderr, " %10d", alpha_size);
fprintf(stderr, "\n");
} }
} }
} }
@ -229,6 +239,12 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
fprintf(stderr, "Size of the XMP metadata: %d\n", size); fprintf(stderr, "Size of the XMP metadata: %d\n", size);
} }
if ((flag & ALPHA_FLAG) && !(flag & (ANIMATION_FLAG | TILE_FLAG))) {
err = WebPMuxGetImage(mux, &data, &size, &alpha_data, &alpha_size);
RETURN_IF_ERROR("Failed to retrieve the image\n");
fprintf(stderr, "Size of the alpha data: %d\n", alpha_size);
}
return WEBP_MUX_OK; return WEBP_MUX_OK;
} }
@ -351,6 +367,52 @@ static int ReadFile(const char* const filename, WebPMux** mux) {
return 0; return 0;
} }
static int ReadImage(const char* filename,
const uint8_t** data_ptr, uint32_t* size_ptr,
const uint8_t** alpha_data_ptr, uint32_t* alpha_size_ptr) {
void* data = NULL;
uint32_t size = 0;
const uint8_t* alpha_data = NULL;
uint32_t alpha_size = 0;
WebPMux* mux;
WebPMuxError err;
int ok = 0;
if (!ReadData(filename, &data, &size)) return 0;
mux = WebPMuxCreate((const uint8_t*)data, size, 1);
free(data);
if (mux == NULL) {
fprintf(stderr, "Failed to create mux object from file %s.\n",
filename);
return 0;
}
err = WebPMuxGetImage(mux, (const uint8_t**)&data, &size,
&alpha_data, &alpha_size);
if (err == WEBP_MUX_OK) {
*size_ptr = size;
*alpha_size_ptr = alpha_size;
*data_ptr = (uint8_t*)malloc(*size_ptr);
*alpha_data_ptr = (uint8_t*)malloc(*alpha_size_ptr);
if ((*data_ptr != NULL) && (*alpha_data_ptr != NULL)) {
memcpy((void*)*data_ptr, data, (size_t)size);
memcpy((void*)*alpha_data_ptr, alpha_data, (size_t)alpha_size);
ok = 1;
} else {
free(data_ptr);
free(alpha_data_ptr);
err = WEBP_MUX_MEMORY_ERROR;
fprintf(stderr, "Failed to allocate %d bytes to extract image data from"
" file %s. Error: %d\n", size + alpha_size, filename, err);
}
} else {
fprintf(stderr, "Failed to extract image data from file %s. Error: %d\n",
filename, err);
}
WebPMuxDelete(mux);
return ok;
}
static int WriteData(const char* filename, void* data, uint32_t size) { static int WriteData(const char* filename, void* data, uint32_t size) {
int ok = 0; int ok = 0;
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout; FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout;
@ -718,6 +780,8 @@ static int GetFrameTile(const WebPMux* mux,
const WebPMuxConfig* config, int isFrame) { const WebPMuxConfig* config, int isFrame) {
const uint8_t* data = NULL; const uint8_t* data = NULL;
uint32_t size = 0; uint32_t size = 0;
const uint8_t* alpha_data = NULL;
uint32_t alpha_size = 0;
uint32_t x_offset = 0; uint32_t x_offset = 0;
uint32_t y_offset = 0; uint32_t y_offset = 0;
uint32_t duration = 0; uint32_t duration = 0;
@ -732,13 +796,13 @@ static int GetFrameTile(const WebPMux* mux,
} }
if (isFrame) { if (isFrame) {
err = WebPMuxGetFrame(mux, num, &data, &size, NULL, NULL, err = WebPMuxGetFrame(mux, num, &data, &size, &alpha_data, &alpha_size,
&x_offset, &y_offset, &duration); &x_offset, &y_offset, &duration);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet); ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet);
} }
} else { } else {
err = WebPMuxGetTile(mux, num, &data, &size, NULL, NULL, err = WebPMuxGetTile(mux, num, &data, &size, &alpha_data, &alpha_size,
&x_offset, &y_offset); &x_offset, &y_offset);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet); ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet);
@ -750,7 +814,7 @@ static int GetFrameTile(const WebPMux* mux,
err = WEBP_MUX_MEMORY_ERROR; err = WEBP_MUX_MEMORY_ERROR;
ERROR_GOTO2("ERROR#%d: Could not allocate a mux object.\n", err, ErrGet); ERROR_GOTO2("ERROR#%d: Could not allocate a mux object.\n", err, ErrGet);
} }
err = WebPMuxSetImage(mux_single, data, size, NULL, 0, 1); err = WebPMuxSetImage(mux_single, data, size, alpha_data, alpha_size, 1);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO2("ERROR#%d: Could not create single image mux object.\n", err, ERROR_GOTO2("ERROR#%d: Could not create single image mux object.\n", err,
ErrGet); ErrGet);
@ -767,6 +831,8 @@ static int Process(const WebPMuxConfig* config) {
WebPMux* mux = NULL; WebPMux* mux = NULL;
const uint8_t* data = NULL; const uint8_t* data = NULL;
uint32_t size = 0; uint32_t size = 0;
const uint8_t* alpha_data = NULL;
uint32_t alpha_size = 0;
uint32_t x_offset = 0; uint32_t x_offset = 0;
uint32_t y_offset = 0; uint32_t y_offset = 0;
uint32_t duration = 0; uint32_t duration = 0;
@ -833,18 +899,20 @@ static int Process(const WebPMuxConfig* config) {
ERROR_GOTO2("ERROR#%d: Could not set loop count.\n", err, Err2); ERROR_GOTO2("ERROR#%d: Could not set loop count.\n", err, Err2);
} }
} else if (feature->args_[index].subtype_ == SUBTYPE_FRM) { } else if (feature->args_[index].subtype_ == SUBTYPE_FRM) {
ok = ReadData(feature->args_[index].filename_, ok = ReadImage(feature->args_[index].filename_,
(void**)&data, &size); &data, &size, &alpha_data, &alpha_size);
if (!ok) goto Err2; if (!ok) goto Err2;
ok = ParseFrameArgs(feature->args_[index].params_, ok = ParseFrameArgs(feature->args_[index].params_,
&x_offset, &y_offset, &duration); &x_offset, &y_offset, &duration);
if (!ok) { if (!ok) {
free((void*)data); free((void*)data);
free((void*)alpha_data);
ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2); ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2);
} }
err = WebPMuxAddFrame(mux, 0, data, size, NULL, 0, err = WebPMuxAddFrame(mux, 0, data, size, alpha_data, alpha_size,
x_offset, y_offset, duration, 1); x_offset, y_offset, duration, 1);
free((void*)data); free((void*)data);
free((void*)alpha_data);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n", ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n",
err, index, Err2); err, index, Err2);
@ -862,18 +930,20 @@ static int Process(const WebPMuxConfig* config) {
WEBP_MUX_MEMORY_ERROR, Err2); WEBP_MUX_MEMORY_ERROR, Err2);
} }
for (index = 0; index < feature->arg_count_; ++index) { for (index = 0; index < feature->arg_count_; ++index) {
ok = ReadData(feature->args_[index].filename_, ok = ReadImage(feature->args_[index].filename_,
(void**)&data, &size); &data, &size, &alpha_data, &alpha_size);
if (!ok) goto Err2; if (!ok) goto Err2;
ok = ParseTileArgs(feature->args_[index].params_, &x_offset, ok = ParseTileArgs(feature->args_[index].params_, &x_offset,
&y_offset); &y_offset);
if (!ok) { if (!ok) {
free((void*)data); free((void*)data);
free((void*)alpha_data);
ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2); ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2);
} }
err = WebPMuxAddTile(mux, 0, data, size, NULL, 0, err = WebPMuxAddTile(mux, 0, data, size, alpha_data, alpha_size,
x_offset, y_offset, 1); x_offset, y_offset, 1);
free((void*)data); free((void*)data);
free((void*)alpha_data);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n", ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n",
err, index, Err2); err, index, Err2);