mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
webpmux: make more use of WebPData
Add WebPDataCopy and use it in ReadImage which now returns WebPData*s. Update ReadData prototype variables used with it to avoid unnecessary const casting back and forth from void*. Change-Id: I3f83db6729306eab0db9027b68706c8a7005ec10
This commit is contained in:
parent
974aaff360
commit
0f7820e65c
@ -119,6 +119,27 @@ static int IsNotCompatible(int count1, int count2) {
|
||||
return (count1 > 0) != (count2 > 0);
|
||||
}
|
||||
|
||||
// Allocate necessary storage for dst then copy the contents of src.
|
||||
// Returns 1 on success.
|
||||
static int WebPDataCopy(const WebPData* const src, WebPData* const dst) {
|
||||
if (src == NULL || dst == NULL) return 0;
|
||||
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
if (src->bytes_ != NULL && src->size_ != 0) {
|
||||
dst->bytes_ = (uint8_t*)malloc(src->size_);
|
||||
if (dst->bytes_ == NULL) return 0;
|
||||
memcpy((void*)dst->bytes_, src->bytes_, src->size_);
|
||||
dst->size_ = src->size_;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Frees data allocated by WebPDataCopy.
|
||||
static void WebPDataFree(WebPData* const webpdata) {
|
||||
free((void*)webpdata->bytes_);
|
||||
memset(webpdata, 0, sizeof(*webpdata));
|
||||
}
|
||||
|
||||
#define RETURN_IF_ERROR(ERR_MSG) \
|
||||
if (err != WEBP_MUX_OK) { \
|
||||
fprintf(stderr, ERR_MSG); \
|
||||
@ -210,11 +231,11 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
|
||||
printf("Number of tiles: %d\n", nTiles);
|
||||
if (nTiles > 0) {
|
||||
int i;
|
||||
uint32_t x_offset, y_offset;
|
||||
printf("No.: x_offset y_offset image_size");
|
||||
if (flag & ALPHA_FLAG) printf(" alpha_size");
|
||||
printf("\n");
|
||||
for (i = 1; i <= nTiles; i++) {
|
||||
uint32_t x_offset, y_offset;
|
||||
WebPData image, alpha;
|
||||
err = WebPMuxGetTile(mux, i, &image, &alpha, &x_offset, &y_offset);
|
||||
RETURN_IF_ERROR2("Failed to retrieve tile#%d\n", i);
|
||||
@ -298,7 +319,8 @@ static void PrintHelp(void) {
|
||||
printf("\nINPUT & OUTPUT are in webp format.\n");
|
||||
}
|
||||
|
||||
static int ReadData(const char* filename, void** data_ptr, uint32_t* size_ptr) {
|
||||
static int ReadData(const char* filename,
|
||||
uint8_t** data_ptr, uint32_t* size_ptr) {
|
||||
void* data = NULL;
|
||||
long size = 0;
|
||||
int ok = 0;
|
||||
@ -343,19 +365,19 @@ static int ReadData(const char* filename, void** data_ptr, uint32_t* size_ptr) {
|
||||
Err:
|
||||
if (in != stdin) fclose(in);
|
||||
*size_ptr = (uint32_t)size;
|
||||
*data_ptr = data;
|
||||
*data_ptr = (uint8_t*)data;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int ReadFile(const char* const filename, WebPMux** mux) {
|
||||
uint32_t size = 0;
|
||||
void* data = NULL;
|
||||
uint8_t* data = NULL;
|
||||
WebPMuxState mux_state;
|
||||
|
||||
assert(mux != NULL);
|
||||
|
||||
if (!ReadData(filename, &data, &size)) return 0;
|
||||
*mux = WebPMuxCreate((const uint8_t*)data, size, 1, &mux_state);
|
||||
*mux = WebPMuxCreate(data, size, 1, &mux_state);
|
||||
free(data);
|
||||
if (*mux != NULL && mux_state == WEBP_MUX_STATE_COMPLETE) return 1;
|
||||
fprintf(stderr, "Failed to create mux object from file %s. mux_state = %d.\n",
|
||||
@ -364,9 +386,8 @@ static int ReadFile(const char* const filename, WebPMux** mux) {
|
||||
}
|
||||
|
||||
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;
|
||||
WebPData* const image_ptr, WebPData* const alpha_ptr) {
|
||||
uint8_t* data = NULL;
|
||||
uint32_t size = 0;
|
||||
WebPData image, alpha;
|
||||
WebPMux* mux;
|
||||
@ -376,7 +397,7 @@ static int ReadImage(const char* filename,
|
||||
|
||||
if (!ReadData(filename, &data, &size)) return 0;
|
||||
|
||||
mux = WebPMuxCreate((const uint8_t*)data, size, 1, &mux_state);
|
||||
mux = WebPMuxCreate(data, size, 1, &mux_state);
|
||||
free(data);
|
||||
if (mux == NULL || mux_state != WEBP_MUX_STATE_COMPLETE) {
|
||||
fprintf(stderr,
|
||||
@ -386,23 +407,14 @@ static int ReadImage(const char* filename,
|
||||
}
|
||||
err = WebPMuxGetImage(mux, &image, &alpha);
|
||||
if (err == WEBP_MUX_OK) {
|
||||
uint8_t* const data_mem = (uint8_t*)malloc(image.size_);
|
||||
uint8_t* const alpha_mem = (uint8_t*)malloc(alpha.size_);
|
||||
if ((data_mem != NULL) && (alpha_mem != NULL)) {
|
||||
memcpy(data_mem, image.bytes_, image.size_);
|
||||
memcpy(alpha_mem, alpha.bytes_, alpha.size_);
|
||||
*data_ptr = data_mem;
|
||||
*size_ptr = image.size_;
|
||||
*alpha_data_ptr = alpha_mem;
|
||||
*alpha_size_ptr = alpha.size_;
|
||||
ok = 1;
|
||||
} else {
|
||||
free(data_mem);
|
||||
free(alpha_mem);
|
||||
err = WEBP_MUX_MEMORY_ERROR;
|
||||
fprintf(stderr, "Failed to allocate %u bytes to extract image data from"
|
||||
" file %s. Error: %d\n",
|
||||
image.size_ + alpha.size_, filename, err);
|
||||
ok &= WebPDataCopy(&image, image_ptr);
|
||||
ok &= WebPDataCopy(&alpha, alpha_ptr);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Error allocating storage for image (%u bytes) "
|
||||
"and alpha (%u bytes) data\n", image.size_, alpha.size_);
|
||||
WebPDataFree(image_ptr);
|
||||
WebPDataFree(alpha_ptr);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Failed to extract image data from file %s. Error: %d\n",
|
||||
@ -412,17 +424,17 @@ static int ReadImage(const char* filename,
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int WriteData(const char* filename, const void* data, uint32_t size) {
|
||||
static int WriteData(const char* filename, const WebPData* const webpdata) {
|
||||
int ok = 0;
|
||||
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout;
|
||||
if (!fout) {
|
||||
fprintf(stderr, "Error opening output WebP file %s!\n", filename);
|
||||
return 0;
|
||||
}
|
||||
if (fwrite(data, size, 1, fout) != 1) {
|
||||
if (fwrite(webpdata->bytes_, webpdata->size_, 1, fout) != 1) {
|
||||
fprintf(stderr, "Error writing file %s!\n", filename);
|
||||
} else {
|
||||
fprintf(stderr, "Saved file %s (%d bytes)\n", filename, size);
|
||||
fprintf(stderr, "Saved file %s (%d bytes)\n", filename, webpdata->size_);
|
||||
ok = 1;
|
||||
}
|
||||
if (fout != stdout) fclose(fout);
|
||||
@ -430,17 +442,17 @@ static int WriteData(const char* filename, const void* data, uint32_t size) {
|
||||
}
|
||||
|
||||
static int WriteWebP(WebPMux* const mux, const char* filename) {
|
||||
uint8_t* data = NULL;
|
||||
uint32_t size = 0;
|
||||
WebPData webpdata;
|
||||
int ok;
|
||||
|
||||
WebPMuxError err = WebPMuxAssemble(mux, &data, &size);
|
||||
const WebPMuxError err = WebPMuxAssemble(
|
||||
mux, (uint8_t**)&webpdata.bytes_, &webpdata.size_);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
fprintf(stderr, "Error (%d) assembling the WebP file.\n", err);
|
||||
return 0;
|
||||
}
|
||||
ok = WriteData(filename, data, size);
|
||||
free(data);
|
||||
ok = WriteData(filename, &webpdata);
|
||||
WebPDataFree(&webpdata);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -826,16 +838,11 @@ static int GetFrameTile(const WebPMux* mux,
|
||||
static int Process(const WebPMuxConfig* config) {
|
||||
WebPMux* mux = NULL;
|
||||
WebPData webpdata;
|
||||
const uint8_t* data = NULL;
|
||||
uint8_t* data = NULL;
|
||||
uint32_t size = 0;
|
||||
const uint8_t* alpha_data = NULL;
|
||||
uint32_t alpha_size = 0;
|
||||
uint32_t x_offset = 0;
|
||||
uint32_t y_offset = 0;
|
||||
uint32_t duration = 0;
|
||||
uint32_t loop_count = 0;
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
long num;
|
||||
int index = 0;
|
||||
int ok = 1;
|
||||
const Feature* const feature = &config->feature_;
|
||||
@ -858,14 +865,14 @@ static int Process(const WebPMuxConfig* config) {
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO2("ERROR#%d: Could not get color profile.\n", err, Err2);
|
||||
}
|
||||
ok = WriteData(config->output_, webpdata.bytes_, webpdata.size_);
|
||||
ok = WriteData(config->output_, &webpdata);
|
||||
break;
|
||||
case FEATURE_XMP:
|
||||
err = WebPMuxGetMetadata(mux, &webpdata);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO2("ERROR#%d: Could not get XMP metadata.\n", err, Err2);
|
||||
}
|
||||
ok = WriteData(config->output_, webpdata.bytes_, webpdata.size_);
|
||||
ok = WriteData(config->output_, &webpdata);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -884,31 +891,31 @@ static int Process(const WebPMuxConfig* config) {
|
||||
}
|
||||
for (index = 0; index < feature->arg_count_; ++index) {
|
||||
if (feature->args_[index].subtype_ == SUBTYPE_LOOP) {
|
||||
num = strtol(feature->args_[index].params_, NULL, 10);
|
||||
const long num = strtol(feature->args_[index].params_, NULL, 10);
|
||||
if (num < 0) {
|
||||
ERROR_GOTO1("ERROR: Loop count must be non-negative.\n", Err2);
|
||||
} else {
|
||||
loop_count = num;
|
||||
}
|
||||
err = WebPMuxSetLoopCount(mux, loop_count);
|
||||
err = WebPMuxSetLoopCount(mux, num);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO2("ERROR#%d: Could not set loop count.\n", err, Err2);
|
||||
}
|
||||
} else if (feature->args_[index].subtype_ == SUBTYPE_FRM) {
|
||||
ok = ReadImage(feature->args_[index].filename_,
|
||||
&data, &size, &alpha_data, &alpha_size);
|
||||
WebPData image, alpha;
|
||||
uint32_t duration;
|
||||
ok = ReadImage(feature->args_[index].filename_, &image, &alpha);
|
||||
if (!ok) goto Err2;
|
||||
ok = ParseFrameArgs(feature->args_[index].params_,
|
||||
&x_offset, &y_offset, &duration);
|
||||
if (!ok) {
|
||||
free((void*)data);
|
||||
free((void*)alpha_data);
|
||||
WebPDataFree(&image);
|
||||
WebPDataFree(&alpha);
|
||||
ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2);
|
||||
}
|
||||
err = WebPMuxAddFrame(mux, 0, data, size, alpha_data, alpha_size,
|
||||
err = WebPMuxAddFrame(mux, 0, image.bytes_, image.size_,
|
||||
alpha.bytes_, alpha.size_,
|
||||
x_offset, y_offset, duration, 1);
|
||||
free((void*)data);
|
||||
free((void*)alpha_data);
|
||||
WebPDataFree(&image);
|
||||
WebPDataFree(&alpha);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n",
|
||||
err, index, Err2);
|
||||
@ -926,20 +933,21 @@ static int Process(const WebPMuxConfig* config) {
|
||||
WEBP_MUX_MEMORY_ERROR, Err2);
|
||||
}
|
||||
for (index = 0; index < feature->arg_count_; ++index) {
|
||||
ok = ReadImage(feature->args_[index].filename_,
|
||||
&data, &size, &alpha_data, &alpha_size);
|
||||
WebPData image, alpha;
|
||||
ok = ReadImage(feature->args_[index].filename_, &image, &alpha);
|
||||
if (!ok) goto Err2;
|
||||
ok = ParseTileArgs(feature->args_[index].params_, &x_offset,
|
||||
&y_offset);
|
||||
if (!ok) {
|
||||
free((void*)data);
|
||||
free((void*)alpha_data);
|
||||
WebPDataFree(&image);
|
||||
WebPDataFree(&alpha);
|
||||
ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2);
|
||||
}
|
||||
err = WebPMuxAddTile(mux, 0, data, size, alpha_data, alpha_size,
|
||||
err = WebPMuxAddTile(mux, 0, image.bytes_, image.size_,
|
||||
alpha.bytes_, alpha.size_,
|
||||
x_offset, y_offset, 1);
|
||||
free((void*)data);
|
||||
free((void*)alpha_data);
|
||||
WebPDataFree(&image);
|
||||
WebPDataFree(&alpha);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n",
|
||||
err, index, Err2);
|
||||
@ -950,7 +958,7 @@ static int Process(const WebPMuxConfig* config) {
|
||||
case FEATURE_ICCP:
|
||||
ok = ReadFile(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
ok = ReadData(feature->args_[0].filename_, (void**)&data, &size);
|
||||
ok = ReadData(feature->args_[0].filename_, &data, &size);
|
||||
if (!ok) goto Err2;
|
||||
err = WebPMuxSetColorProfile(mux, data, size, 1);
|
||||
free((void*)data);
|
||||
@ -962,10 +970,10 @@ static int Process(const WebPMuxConfig* config) {
|
||||
case FEATURE_XMP:
|
||||
ok = ReadFile(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
ok = ReadData(feature->args_[0].filename_, (void**)&data, &size);
|
||||
ok = ReadData(feature->args_[0].filename_, &data, &size);
|
||||
if (!ok) goto Err2;
|
||||
err = WebPMuxSetMetadata(mux, data, size, 1);
|
||||
free((void*)data);
|
||||
free(data);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO2("ERROR#%d: Could not set XMP metadata.\n", err, Err2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user