mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
Chunk fourCCs for XMP/EXIF
Use separate fourCCs "XMP " and "EXIF" instead of a common "META" Also, some refactorization in webpmux.c Change-Id: Iad3337e5c1b81e785c60670ce28b1f536dd7ee31
This commit is contained in:
parent
52ad1979d2
commit
f903cbab9a
43
README.mux
43
README.mux
@ -8,7 +8,7 @@ Description:
|
|||||||
============
|
============
|
||||||
|
|
||||||
WebP Mux: library to create a WebP container object for features like
|
WebP Mux: library to create a WebP container object for features like
|
||||||
color profile, metadata, animation & tiling. A reference command line
|
color profile, metadata, animation and tiling. A reference command line
|
||||||
tool 'webpmux' and WebP container specification 'doc/webp-container-spec.txt'
|
tool 'webpmux' and WebP container specification 'doc/webp-container-spec.txt'
|
||||||
are also provided in this package.
|
are also provided in this package.
|
||||||
|
|
||||||
@ -32,56 +32,63 @@ Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
|||||||
|
|
||||||
GET_OPTIONS:
|
GET_OPTIONS:
|
||||||
Extract relevant data.
|
Extract relevant data.
|
||||||
icc Get ICCP Color profile.
|
icc Get ICC profile.
|
||||||
meta Get XMP/EXIF metadata.
|
exif Get EXIF metadata.
|
||||||
|
xmp Get XMP metadata.
|
||||||
tile n Get nth tile.
|
tile n Get nth tile.
|
||||||
frame n Get nth frame.
|
frame n Get nth frame.
|
||||||
|
|
||||||
SET_OPTIONS:
|
SET_OPTIONS:
|
||||||
Set color profile/metadata.
|
Set color profile/metadata.
|
||||||
icc file.icc Set ICC Color profile.
|
icc file.icc Set ICC profile.
|
||||||
meta file.meta Set XMP/EXIF metadata.
|
exif file.exif Set EXIF metadata.
|
||||||
where: 'file.icc' contains the color profile to be set,
|
xmp file.xmp Set XMP metadata.
|
||||||
'file.meta' contains the metadata to be set
|
where: 'file.icc' contains the ICC profile to be set,
|
||||||
|
'file.exif' contains the EXIF metadata to be set and
|
||||||
|
'file.xmp' contains the XMP metadata to be set
|
||||||
|
|
||||||
STRIP_OPTIONS:
|
STRIP_OPTIONS:
|
||||||
Strip color profile/metadata.
|
Strip color profile/metadata.
|
||||||
icc Strip ICCP color profile.
|
icc Strip ICC profile.
|
||||||
meta Strip XMP/EXIF metadata.
|
exif Strip EXIF metadata.
|
||||||
|
xmp Strip XMP metadata.
|
||||||
|
|
||||||
TILE_OPTIONS(i):
|
TILE_OPTIONS(i):
|
||||||
Create tiled image.
|
Create tiled image.
|
||||||
file_i +xi+yi
|
file_i +xi+yi
|
||||||
where: 'file_i' is the i'th tile (webp format),
|
where: 'file_i' is the i'th tile (WebP format),
|
||||||
'xi','yi' specify the image offset for this tile.
|
'xi','yi' specify the image offset for this tile.
|
||||||
|
|
||||||
FRAME_OPTIONS(i):
|
FRAME_OPTIONS(i):
|
||||||
Create animation.
|
Create animation.
|
||||||
file_i +xi+yi+di
|
file_i +xi+yi+di
|
||||||
where: 'file_i' is the i'th animation frame (webp format),
|
where: 'file_i' is the i'th animation frame (WebP format),
|
||||||
'xi','yi' specify the image offset for this frame.
|
'xi','yi' specify the image offset for this frame.
|
||||||
'di' is the pause duration before next frame.
|
'di' is the pause duration before next frame.
|
||||||
|
|
||||||
INPUT & OUTPUT are in webp format.
|
INPUT and OUTPUT are in WebP format.
|
||||||
|
|
||||||
|
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
|
||||||
|
valid.
|
||||||
|
|
||||||
WebP Mux API:
|
WebP Mux API:
|
||||||
==============
|
==============
|
||||||
The WebP Mux API contains methods for adding data to and reading data from
|
The WebP Mux API contains methods for adding data to and reading data from
|
||||||
WebPMux (a WebP container object). This API currently supports XMP/EXIF
|
WebPMux (a WebP container object). This API currently supports XMP/EXIF
|
||||||
metadata, ICC color profile, animation & tiling. Other features will be added in
|
metadata, ICC profile, animation and tiling. Other features will be added
|
||||||
subsequent releases.
|
in subsequent releases.
|
||||||
|
|
||||||
Example#1 (pseudo code): Creating a WebPMux object with image data, color
|
Example#1 (pseudo code): Creating a WebPMux object with image data, color
|
||||||
profile & XMP metadata.
|
profile and XMP metadata.
|
||||||
|
|
||||||
int copy_data = 0;
|
int copy_data = 0;
|
||||||
WebPMux* mux = WebPMuxNew();
|
WebPMux* mux = WebPMuxNew();
|
||||||
// ... (Prepare image data).
|
// ... (Prepare image data).
|
||||||
WebPMuxSetImage(mux, &image, copy_data);
|
WebPMuxSetImage(mux, &image, copy_data);
|
||||||
// ... (Prepare ICCP color profile data).
|
// ... (Prepare ICC profile data).
|
||||||
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
||||||
// ... (Prepare XMP metadata).
|
// ... (Prepare XMP metadata).
|
||||||
WebPMuxSetChunk(mux, "META", &xmp, copy_data);
|
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
|
||||||
// Get data from mux in WebP RIFF format.
|
// Get data from mux in WebP RIFF format.
|
||||||
WebPMuxAssemble(mux, &output_data);
|
WebPMuxAssemble(mux, &output_data);
|
||||||
WebPMuxDelete(mux);
|
WebPMuxDelete(mux);
|
||||||
@ -89,7 +96,7 @@ profile & XMP metadata.
|
|||||||
WebPDataClear(&output_data);
|
WebPDataClear(&output_data);
|
||||||
|
|
||||||
|
|
||||||
Example#2 (pseudo code): Get image & color profile data from a WebP file.
|
Example#2 (pseudo code): Get image and color profile data from a WebP file.
|
||||||
|
|
||||||
int copy_data = 0;
|
int copy_data = 0;
|
||||||
// ... (Read data from file).
|
// ... (Read data from file).
|
||||||
|
@ -31,17 +31,20 @@
|
|||||||
-o out_animation_container.webp
|
-o out_animation_container.webp
|
||||||
|
|
||||||
webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
|
webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
|
||||||
webpmux -set meta image_metadata.meta in.webp -o out_meta_container.webp
|
webpmux -set exif image_metadata.exif in.webp -o out_exif_container.webp
|
||||||
|
webpmux -set xmp image_metadata.xmp in.webp -o out_xmp_container.webp
|
||||||
|
|
||||||
Extract relevant data from WebP container file:
|
Extract relevant data from WebP container file:
|
||||||
webpmux -get tile n in.webp -o out_tile.webp
|
webpmux -get tile n in.webp -o out_tile.webp
|
||||||
webpmux -get frame n in.webp -o out_frame.webp
|
webpmux -get frame n in.webp -o out_frame.webp
|
||||||
webpmux -get icc in.webp -o image_profile.icc
|
webpmux -get icc in.webp -o image_profile.icc
|
||||||
webpmux -get meta in.webp -o image_metadata.meta
|
webpmux -get exif in.webp -o image_metadata.exif
|
||||||
|
webpmux -get xmp in.webp -o image_metadata.xmp
|
||||||
|
|
||||||
Strip data from WebP Container file:
|
Strip data from WebP Container file:
|
||||||
webpmux -strip icc in.webp -o out.webp
|
webpmux -strip icc in.webp -o out.webp
|
||||||
webpmux -strip meta in.webp -o out.webp
|
webpmux -strip exif in.webp -o out.webp
|
||||||
|
webpmux -strip xmp in.webp -o out.webp
|
||||||
|
|
||||||
Misc:
|
Misc:
|
||||||
webpmux -info in.webp
|
webpmux -info in.webp
|
||||||
@ -81,12 +84,23 @@ typedef struct {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NIL_FEATURE = 0,
|
NIL_FEATURE = 0,
|
||||||
FEATURE_META,
|
FEATURE_EXIF,
|
||||||
|
FEATURE_XMP,
|
||||||
FEATURE_ICCP,
|
FEATURE_ICCP,
|
||||||
FEATURE_FRM,
|
FEATURE_FRM,
|
||||||
FEATURE_TILE
|
FEATURE_TILE,
|
||||||
|
LAST_FEATURE
|
||||||
} FeatureType;
|
} FeatureType;
|
||||||
|
|
||||||
|
static const char* const kFourccList[LAST_FEATURE] = {
|
||||||
|
NULL, "EXIF", "XMP ", "ICCP", "ANMF", "FRGM"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* const kDescriptions[LAST_FEATURE] = {
|
||||||
|
NULL, "EXIF metadata", "XMP metadata", "ICC profile",
|
||||||
|
"Animation frame", "Tile fragment"
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FeatureType type_;
|
FeatureType type_;
|
||||||
FeatureArg* args_;
|
FeatureArg* args_;
|
||||||
@ -185,7 +199,8 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
|
|||||||
if (flag & ANIMATION_FLAG) printf(" animation");
|
if (flag & ANIMATION_FLAG) printf(" animation");
|
||||||
if (flag & TILE_FLAG) printf(" tiling");
|
if (flag & TILE_FLAG) printf(" tiling");
|
||||||
if (flag & ICCP_FLAG) printf(" icc profile");
|
if (flag & ICCP_FLAG) printf(" icc profile");
|
||||||
if (flag & META_FLAG) printf(" metadata");
|
if (flag & EXIF_FLAG) printf(" EXIF metadata");
|
||||||
|
if (flag & XMP_FLAG) printf(" XMP metadata");
|
||||||
if (flag & ALPHA_FLAG) printf(" transparency");
|
if (flag & ALPHA_FLAG) printf(" transparency");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
@ -226,15 +241,22 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
|
|||||||
if (flag & ICCP_FLAG) {
|
if (flag & ICCP_FLAG) {
|
||||||
WebPData icc_profile;
|
WebPData icc_profile;
|
||||||
err = WebPMuxGetChunk(mux, "ICCP", &icc_profile);
|
err = WebPMuxGetChunk(mux, "ICCP", &icc_profile);
|
||||||
RETURN_IF_ERROR("Failed to retrieve the color profile\n");
|
RETURN_IF_ERROR("Failed to retrieve the ICC profile\n");
|
||||||
printf("Size of the color profile data: %zu\n", icc_profile.size);
|
printf("Size of the ICC profile data: %zu\n", icc_profile.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag & META_FLAG) {
|
if (flag & EXIF_FLAG) {
|
||||||
WebPData metadata;
|
WebPData exif;
|
||||||
err = WebPMuxGetChunk(mux, "META", &metadata);
|
err = WebPMuxGetChunk(mux, "EXIF", &exif);
|
||||||
RETURN_IF_ERROR("Failed to retrieve the metadata\n");
|
RETURN_IF_ERROR("Failed to retrieve the EXIF metadata\n");
|
||||||
printf("Size of the metadata: %zu\n", metadata.size);
|
printf("Size of the EXIF metadata: %zu\n", exif.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & XMP_FLAG) {
|
||||||
|
WebPData xmp;
|
||||||
|
err = WebPMuxGetChunk(mux, "XMP ", &xmp);
|
||||||
|
RETURN_IF_ERROR("Failed to retrieve the XMP metadata\n");
|
||||||
|
printf("Size of the XMP metadata: %zu\n", xmp.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flag & ALPHA_FLAG) && !(flag & (ANIMATION_FLAG | TILE_FLAG))) {
|
if ((flag & ALPHA_FLAG) && !(flag & (ANIMATION_FLAG | TILE_FLAG))) {
|
||||||
@ -260,41 +282,48 @@ static void PrintHelp(void) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
printf("GET_OPTIONS:\n");
|
printf("GET_OPTIONS:\n");
|
||||||
printf(" Extract relevant data.\n");
|
printf(" Extract relevant data.\n");
|
||||||
printf(" icc Get ICCP Color profile.\n");
|
printf(" icc Get ICC profile.\n");
|
||||||
printf(" meta Get XMP/EXIF metadata.\n");
|
printf(" exif Get EXIF metadata.\n");
|
||||||
|
printf(" xmp Get XMP metadata.\n");
|
||||||
printf(" tile n Get nth tile.\n");
|
printf(" tile n Get nth tile.\n");
|
||||||
printf(" frame n Get nth frame.\n");
|
printf(" frame n Get nth frame.\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("SET_OPTIONS:\n");
|
printf("SET_OPTIONS:\n");
|
||||||
printf(" Set color profile/metadata.\n");
|
printf(" Set color profile/metadata.\n");
|
||||||
printf(" icc file.icc Set ICC Color profile.\n");
|
printf(" icc file.icc Set ICC profile.\n");
|
||||||
printf(" meta file.meta Set XMP/EXIF metadata.\n");
|
printf(" exif file.exif Set EXIF metadata.\n");
|
||||||
printf(" where: 'file.icc' contains the color profile to be set,\n");
|
printf(" xmp file.xmp Set XMP metadata.\n");
|
||||||
printf(" 'file.meta' contains the metadata to be set\n");
|
printf(" where: 'file.icc' contains the ICC profile to be set,\n");
|
||||||
|
printf(" 'file.exif' contains the EXIF metadata to be set\n");
|
||||||
|
printf(" 'file.xmp' contains the XMP metadata to be set\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("STRIP_OPTIONS:\n");
|
printf("STRIP_OPTIONS:\n");
|
||||||
printf(" Strip color profile/metadata.\n");
|
printf(" Strip color profile/metadata.\n");
|
||||||
printf(" icc Strip ICCP color profile.\n");
|
printf(" icc Strip ICC profile.\n");
|
||||||
printf(" meta Strip XMP/EXIF metadata.\n");
|
printf(" exif Strip EXIF metadata.\n");
|
||||||
|
printf(" xmp Strip XMP metadata.\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("TILE_OPTIONS(i):\n");
|
printf("TILE_OPTIONS(i):\n");
|
||||||
printf(" Create tiled image.\n");
|
printf(" Create tiled image.\n");
|
||||||
printf(" file_i +xi+yi\n");
|
printf(" file_i +xi+yi\n");
|
||||||
printf(" where: 'file_i' is the i'th tile (webp format),\n");
|
printf(" where: 'file_i' is the i'th tile (WebP format),\n");
|
||||||
printf(" 'xi','yi' specify the image offset for this tile.\n");
|
printf(" 'xi','yi' specify the image offset for this tile.\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("FRAME_OPTIONS(i):\n");
|
printf("FRAME_OPTIONS(i):\n");
|
||||||
printf(" Create animation.\n");
|
printf(" Create animation.\n");
|
||||||
printf(" file_i +xi+yi+di\n");
|
printf(" file_i +xi+yi+di\n");
|
||||||
printf(" where: 'file_i' is the i'th animation frame (webp format),\n");
|
printf(" where: 'file_i' is the i'th animation frame (WebP format),\n");
|
||||||
printf(" 'xi','yi' specify the image offset for this frame.\n");
|
printf(" 'xi','yi' specify the image offset for this frame.\n");
|
||||||
printf(" 'di' is the pause duration before next frame.\n");
|
printf(" 'di' is the pause duration before next frame.\n");
|
||||||
|
|
||||||
printf("\nINPUT & OUTPUT are in webp format.\n");
|
printf("\nINPUT & OUTPUT are in WebP format.\n");
|
||||||
|
|
||||||
|
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked and is "
|
||||||
|
"assumed to be valid.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ReadFileToWebPData(const char* const filename,
|
static int ReadFileToWebPData(const char* const filename,
|
||||||
@ -421,7 +450,7 @@ static int ValidateCommandLine(int argc, const char* argv[],
|
|||||||
|
|
||||||
assert(ok == 1);
|
assert(ok == 1);
|
||||||
if (num_frame_args == 0 && num_tile_args == 0) {
|
if (num_frame_args == 0 && num_tile_args == 0) {
|
||||||
// Single argument ('set' action for META or ICCP, OR a 'get' action).
|
// Single argument ('set' action for ICCP/EXIF/XMP, OR a 'get' action).
|
||||||
*num_feature_args = 1;
|
*num_feature_args = 1;
|
||||||
} else {
|
} else {
|
||||||
// Multiple arguments ('set' action for animation or tiling).
|
// Multiple arguments ('set' action for animation or tiling).
|
||||||
@ -561,10 +590,11 @@ static int ParseCommandLine(int argc, const char* argv[],
|
|||||||
ERROR_GOTO1("ERROR: Action must be specified before other arguments.\n",
|
ERROR_GOTO1("ERROR: Action must be specified before other arguments.\n",
|
||||||
ErrParse);
|
ErrParse);
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "meta")) {
|
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
||||||
|
!strcmp(argv[i], "xmp")) {
|
||||||
if (FEATURETYPE_IS_NIL) {
|
if (FEATURETYPE_IS_NIL) {
|
||||||
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||||
FEATURE_META;
|
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@ -723,7 +753,7 @@ static int GetFrameTile(const WebPMux* mux,
|
|||||||
// Read and process config.
|
// Read and process config.
|
||||||
static int Process(const WebPMuxConfig* config) {
|
static int Process(const WebPMuxConfig* config) {
|
||||||
WebPMux* mux = NULL;
|
WebPMux* mux = NULL;
|
||||||
WebPData metadata, color_profile;
|
WebPData chunk;
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
@ -735,28 +765,20 @@ static int Process(const WebPMuxConfig* config) {
|
|||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
switch (feature->type_) {
|
switch (feature->type_) {
|
||||||
case FEATURE_FRM:
|
case FEATURE_FRM:
|
||||||
ok = GetFrameTile(mux, config, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FEATURE_TILE:
|
case FEATURE_TILE:
|
||||||
ok = GetFrameTile(mux, config, 0);
|
ok = GetFrameTile(mux, config,
|
||||||
|
(feature->type_ == FEATURE_FRM) ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FEATURE_ICCP:
|
case FEATURE_ICCP:
|
||||||
err = WebPMuxGetChunk(mux, "ICCP", &color_profile);
|
case FEATURE_EXIF:
|
||||||
|
case FEATURE_XMP:
|
||||||
|
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO2("ERROR (%s): Could not get color profile.\n",
|
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
||||||
ErrorString(err), Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
ok = WriteData(config->output_, &color_profile);
|
ok = WriteData(config->output_, &chunk);
|
||||||
break;
|
|
||||||
case FEATURE_META:
|
|
||||||
err = WebPMuxGetChunk(mux, "META", &metadata);
|
|
||||||
if (err != WEBP_MUX_OK) {
|
|
||||||
ERROR_GOTO2("ERROR (%s): Could not get the metadata.\n",
|
|
||||||
ErrorString(err), Err2);
|
|
||||||
}
|
|
||||||
ok = WriteData(config->output_, &metadata);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -834,28 +856,17 @@ static int Process(const WebPMuxConfig* config) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FEATURE_ICCP:
|
case FEATURE_ICCP:
|
||||||
|
case FEATURE_EXIF:
|
||||||
|
case FEATURE_XMP:
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
ok = ReadFileToWebPData(feature->args_[0].filename_, &color_profile);
|
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
err = WebPMuxSetChunk(mux, "ICCP", &color_profile, 1);
|
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
|
||||||
free((void*)color_profile.bytes);
|
free((void*)chunk.bytes);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO2("ERROR (%s): Could not set color profile.\n",
|
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
||||||
ErrorString(err), Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FEATURE_META:
|
|
||||||
ok = CreateMux(config->input_, &mux);
|
|
||||||
if (!ok) goto Err2;
|
|
||||||
ok = ReadFileToWebPData(feature->args_[0].filename_, &metadata);
|
|
||||||
if (!ok) goto Err2;
|
|
||||||
err = WebPMuxSetChunk(mux, "META", &metadata, 1);
|
|
||||||
free((void*)metadata.bytes);
|
|
||||||
if (err != WEBP_MUX_OK) {
|
|
||||||
ERROR_GOTO2("ERROR (%s): Could not set the metadata.\n",
|
|
||||||
ErrorString(err), Err2);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -869,22 +880,14 @@ static int Process(const WebPMuxConfig* config) {
|
|||||||
case ACTION_STRIP:
|
case ACTION_STRIP:
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
switch (feature->type_) {
|
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
|
||||||
case FEATURE_ICCP:
|
feature->type_ == FEATURE_XMP) {
|
||||||
err = WebPMuxDeleteChunk(mux, "ICCP");
|
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO2("ERROR (%s): Could not delete color profile.\n",
|
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
||||||
ErrorString(err), Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case FEATURE_META:
|
|
||||||
err = WebPMuxDeleteChunk(mux, "META");
|
|
||||||
if (err != WEBP_MUX_OK) {
|
|
||||||
ERROR_GOTO2("ERROR (%s): Could not delete the metadata.\n",
|
|
||||||
ErrorString(err), Err2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,13 @@ and extract/strip relevant data from the container file.
|
|||||||
.SS GET_OPTIONS (\-get):
|
.SS GET_OPTIONS (\-get):
|
||||||
.TP
|
.TP
|
||||||
.B icc
|
.B icc
|
||||||
Get ICC Color profile.
|
Get ICC profile.
|
||||||
.TP
|
.TP
|
||||||
.B meta
|
.B exif
|
||||||
Get XMP/EXIF metadata.
|
Get EXIF metadata.
|
||||||
|
.TP
|
||||||
|
.B xmp
|
||||||
|
Get XMP metadata.
|
||||||
.TP
|
.TP
|
||||||
.B tile n
|
.B tile n
|
||||||
Get nth tile.
|
Get nth tile.
|
||||||
@ -62,33 +65,41 @@ Get nth frame.
|
|||||||
.SS SET_OPTIONS (\-set)
|
.SS SET_OPTIONS (\-set)
|
||||||
.TP
|
.TP
|
||||||
.B icc file.icc
|
.B icc file.icc
|
||||||
Set ICC Color profile.
|
Set ICC profile.
|
||||||
.P
|
.P
|
||||||
Where: 'file.icc' contains the color profile to be set.
|
Where: 'file.icc' contains the ICC profile to be set.
|
||||||
.TP
|
.TP
|
||||||
.B meta file.meta
|
.B exif file.exif
|
||||||
Set XMP/EXIF metadata.
|
Set EXIF metadata.
|
||||||
.P
|
.P
|
||||||
Where: 'file.meta' contains the metadata to be set.
|
Where: 'file.exif' contains the EXIF metadata to be set.
|
||||||
|
.TP
|
||||||
|
.B xmp file.xmp
|
||||||
|
Set XMP metadata.
|
||||||
|
.P
|
||||||
|
Where: 'file.xmp' contains the XMP metadata to be set.
|
||||||
|
|
||||||
.SS STRIP_OPTIONS (\-strip)
|
.SS STRIP_OPTIONS (\-strip)
|
||||||
.TP
|
.TP
|
||||||
.B icc
|
.B icc
|
||||||
Strip ICC Color profile.
|
Strip ICC profile.
|
||||||
.TP
|
.TP
|
||||||
.B meta
|
.B exif
|
||||||
Strip XMP/EXIF metadata.
|
Strip EXIF metadata.
|
||||||
|
.TP
|
||||||
|
.B xmp
|
||||||
|
Strip XMP metadata.
|
||||||
|
|
||||||
.SS TILE_OPTIONS (\-tile)
|
.SS TILE_OPTIONS (\-tile)
|
||||||
.TP
|
.TP
|
||||||
.B file_i +xi+yi
|
.B file_i +xi+yi
|
||||||
Where: 'file_i' is the i'th tile (webp format) and 'xi','yi' specify the image
|
Where: 'file_i' is the i'th tile (WebP format) and 'xi','yi' specify the image
|
||||||
offset for this tile.
|
offset for this tile.
|
||||||
|
|
||||||
.SS FRAME_OPTIONS (\-frame)
|
.SS FRAME_OPTIONS (\-frame)
|
||||||
.TP
|
.TP
|
||||||
.B file_i +xi+yi+di
|
.B file_i +xi+yi+di
|
||||||
Where: 'file_i' is the i'th frame (webp format), 'xi','yi' specify the image
|
Where: 'file_i' is the i'th frame (WebP format), 'xi','yi' specify the image
|
||||||
offset for this frame and 'di' is the pause duration before next frame.
|
offset for this frame and 'di' is the pause duration before next frame.
|
||||||
.TP
|
.TP
|
||||||
.B \-loop n
|
.B \-loop n
|
||||||
@ -102,6 +113,10 @@ Input file in WebP format.
|
|||||||
.TP
|
.TP
|
||||||
Output file in WebP format.
|
Output file in WebP format.
|
||||||
|
|
||||||
|
.SS Note:
|
||||||
|
.TP
|
||||||
|
The nature of EXIF, XMP and ICC data is not checked and is assumed to be valid.
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Please report all bugs to our issue tracker:
|
Please report all bugs to our issue tracker:
|
||||||
http://code.google.com/p/webp/issues
|
http://code.google.com/p/webp/issues
|
||||||
@ -114,14 +129,29 @@ webpmux \-set icc image_profile.icc in.webp \-o icc_container.webp
|
|||||||
.br
|
.br
|
||||||
webpmux \-get icc icc_container.webp \-o image_profile.icc
|
webpmux \-get icc icc_container.webp \-o image_profile.icc
|
||||||
.br
|
.br
|
||||||
webpmux \-set meta image_metadata.meta in.webp \-o meta_container.webp
|
webpmux \-strip icc icc_container.webp \-o without_icc.webp
|
||||||
.br
|
.br
|
||||||
webpmux \-get meta meta_container.webp \-o image_metadata.meta
|
webpmux \-set xmp image_metadata.xmp in.webp \-o xmp_container.webp
|
||||||
|
.br
|
||||||
|
webpmux \-get xmp xmp_container.webp \-o image_metadata.xmp
|
||||||
|
.br
|
||||||
|
webpmux \-strip xmp xmp_container.webp \-o without_xmp.webp
|
||||||
|
.br
|
||||||
|
webpmux \-set exif image_metadata.exif in.webp \-o exif_container.webp
|
||||||
|
.br
|
||||||
|
webpmux \-get exif exif_container.webp \-o image_metadata.exif
|
||||||
|
.br
|
||||||
|
webpmux \-strip exif exif_container.webp \-o without_exif.webp
|
||||||
.br
|
.br
|
||||||
webpmux \-frame anim_1.webp +0+0+0 \-frame anim_2.webp +50+50+0 \-loop 10
|
webpmux \-frame anim_1.webp +0+0+0 \-frame anim_2.webp +50+50+0 \-loop 10
|
||||||
\-o anim_container.webp
|
\-o anim_container.webp
|
||||||
.br
|
.br
|
||||||
webpmux \-get frame 2 anim_container.webp \-o frame_2.webp
|
webpmux \-get frame 2 anim_container.webp \-o frame_2.webp
|
||||||
|
.br
|
||||||
|
webpmux \-tile tile_1.webp +0+0 \-tile tile_2.webp +960+0 \-tile tile_3.webp
|
||||||
|
+0+576 \-tile tile_4.webp +960+576 \-o tile_container.webp
|
||||||
|
.br
|
||||||
|
webpmux \-get tile 2 tile_container.webp \-o tile_2.webp
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBwebpmux\fP is written by the WebP team.
|
\fBwebpmux\fP is written by the WebP team.
|
||||||
|
@ -41,7 +41,7 @@ extern "C" {
|
|||||||
// 24..26 Width of the Canvas Image.
|
// 24..26 Width of the Canvas Image.
|
||||||
// 27..29 Height of the Canvas Image.
|
// 27..29 Height of the Canvas Image.
|
||||||
// There can be extra chunks after the "VP8X" chunk (ICCP, TILE, FRM, VP8,
|
// There can be extra chunks after the "VP8X" chunk (ICCP, TILE, FRM, VP8,
|
||||||
// META ...)
|
// XMP, EXIF ...)
|
||||||
// All sizes are in little-endian order.
|
// All sizes are in little-endian order.
|
||||||
// Note: chunk data size must be padded to multiple of 2 when written.
|
// Note: chunk data size must be padded to multiple of 2 when written.
|
||||||
|
|
||||||
|
@ -514,8 +514,12 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
|||||||
store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
|
store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
|
||||||
goto Skip;
|
goto Skip;
|
||||||
}
|
}
|
||||||
case MKFOURCC('M', 'E', 'T', 'A'): {
|
case MKFOURCC('X', 'M', 'P', ' '): {
|
||||||
store_chunk = !!(dmux->feature_flags_ & META_FLAG);
|
store_chunk = !!(dmux->feature_flags_ & XMP_FLAG);
|
||||||
|
goto Skip;
|
||||||
|
}
|
||||||
|
case MKFOURCC('E', 'X', 'I', 'F'): {
|
||||||
|
store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG);
|
||||||
goto Skip;
|
goto Skip;
|
||||||
}
|
}
|
||||||
Skip:
|
Skip:
|
||||||
|
@ -48,7 +48,8 @@ static void MuxRelease(WebPMux* const mux) {
|
|||||||
DeleteAllChunks(&mux->vp8x_);
|
DeleteAllChunks(&mux->vp8x_);
|
||||||
DeleteAllChunks(&mux->iccp_);
|
DeleteAllChunks(&mux->iccp_);
|
||||||
DeleteAllChunks(&mux->loop_);
|
DeleteAllChunks(&mux->loop_);
|
||||||
DeleteAllChunks(&mux->meta_);
|
DeleteAllChunks(&mux->exif_);
|
||||||
|
DeleteAllChunks(&mux->xmp_);
|
||||||
DeleteAllChunks(&mux->unknown_);
|
DeleteAllChunks(&mux->unknown_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +83,8 @@ static WebPMuxError MuxSet(WebPMux* const mux, CHUNK_INDEX idx, uint32_t nth,
|
|||||||
SWITCH_ID_LIST(IDX_VP8X, &mux->vp8x_);
|
SWITCH_ID_LIST(IDX_VP8X, &mux->vp8x_);
|
||||||
SWITCH_ID_LIST(IDX_ICCP, &mux->iccp_);
|
SWITCH_ID_LIST(IDX_ICCP, &mux->iccp_);
|
||||||
SWITCH_ID_LIST(IDX_LOOP, &mux->loop_);
|
SWITCH_ID_LIST(IDX_LOOP, &mux->loop_);
|
||||||
SWITCH_ID_LIST(IDX_META, &mux->meta_);
|
SWITCH_ID_LIST(IDX_EXIF, &mux->exif_);
|
||||||
|
SWITCH_ID_LIST(IDX_XMP, &mux->xmp_);
|
||||||
if (idx == IDX_UNKNOWN && data->size > TAG_SIZE) {
|
if (idx == IDX_UNKNOWN && data->size > TAG_SIZE) {
|
||||||
// For raw-data unknown chunk, the first four bytes should be the tag to be
|
// For raw-data unknown chunk, the first four bytes should be the tag to be
|
||||||
// used for the chunk.
|
// used for the chunk.
|
||||||
@ -529,11 +531,12 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
|
|||||||
if (mux->iccp_ != NULL && mux->iccp_->data_.bytes != NULL) {
|
if (mux->iccp_ != NULL && mux->iccp_->data_.bytes != NULL) {
|
||||||
flags |= ICCP_FLAG;
|
flags |= ICCP_FLAG;
|
||||||
}
|
}
|
||||||
|
if (mux->exif_ != NULL && mux->exif_->data_.bytes != NULL) {
|
||||||
if (mux->meta_ != NULL && mux->meta_->data_.bytes != NULL) {
|
flags |= EXIF_FLAG;
|
||||||
flags |= META_FLAG;
|
}
|
||||||
|
if (mux->xmp_ != NULL && mux->xmp_->data_.bytes != NULL) {
|
||||||
|
flags |= XMP_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (images->header_ != NULL) {
|
if (images->header_ != NULL) {
|
||||||
if (images->header_->tag_ == kChunks[IDX_FRGM].tag) {
|
if (images->header_->tag_ == kChunks[IDX_FRGM].tag) {
|
||||||
// This is a tiled image.
|
// This is a tiled image.
|
||||||
@ -543,7 +546,6 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
|
|||||||
flags |= ANIMATION_FLAG;
|
flags |= ANIMATION_FLAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) {
|
if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) {
|
||||||
flags |= ALPHA_FLAG; // Some images have an alpha channel.
|
flags |= ALPHA_FLAG; // Some images have an alpha channel.
|
||||||
}
|
}
|
||||||
@ -610,8 +612,8 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
|||||||
// Allocate data.
|
// Allocate data.
|
||||||
size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_)
|
size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_)
|
||||||
+ ChunksListDiskSize(mux->loop_) + MuxImageListDiskSize(mux->images_)
|
+ ChunksListDiskSize(mux->loop_) + MuxImageListDiskSize(mux->images_)
|
||||||
+ ChunksListDiskSize(mux->meta_) + ChunksListDiskSize(mux->unknown_)
|
+ ChunksListDiskSize(mux->exif_) + ChunksListDiskSize(mux->xmp_)
|
||||||
+ RIFF_HEADER_SIZE;
|
+ ChunksListDiskSize(mux->unknown_) + RIFF_HEADER_SIZE;
|
||||||
|
|
||||||
data = (uint8_t*)malloc(size);
|
data = (uint8_t*)malloc(size);
|
||||||
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
@ -622,7 +624,8 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
|||||||
dst = ChunkListEmit(mux->iccp_, dst);
|
dst = ChunkListEmit(mux->iccp_, dst);
|
||||||
dst = ChunkListEmit(mux->loop_, dst);
|
dst = ChunkListEmit(mux->loop_, dst);
|
||||||
dst = MuxImageListEmit(mux->images_, dst);
|
dst = MuxImageListEmit(mux->images_, dst);
|
||||||
dst = ChunkListEmit(mux->meta_, dst);
|
dst = ChunkListEmit(mux->exif_, dst);
|
||||||
|
dst = ChunkListEmit(mux->xmp_, dst);
|
||||||
dst = ChunkListEmit(mux->unknown_, dst);
|
dst = ChunkListEmit(mux->unknown_, dst);
|
||||||
assert(dst == data + size);
|
assert(dst == data + size);
|
||||||
|
|
||||||
|
@ -51,7 +51,8 @@ struct WebPMuxImage {
|
|||||||
struct WebPMux {
|
struct WebPMux {
|
||||||
WebPMuxImage* images_;
|
WebPMuxImage* images_;
|
||||||
WebPChunk* iccp_;
|
WebPChunk* iccp_;
|
||||||
WebPChunk* meta_;
|
WebPChunk* exif_;
|
||||||
|
WebPChunk* xmp_;
|
||||||
WebPChunk* loop_;
|
WebPChunk* loop_;
|
||||||
WebPChunk* vp8x_;
|
WebPChunk* vp8x_;
|
||||||
|
|
||||||
@ -71,7 +72,8 @@ typedef enum {
|
|||||||
IDX_ALPHA,
|
IDX_ALPHA,
|
||||||
IDX_VP8,
|
IDX_VP8,
|
||||||
IDX_VP8L,
|
IDX_VP8L,
|
||||||
IDX_META,
|
IDX_EXIF,
|
||||||
|
IDX_XMP,
|
||||||
IDX_UNKNOWN,
|
IDX_UNKNOWN,
|
||||||
|
|
||||||
IDX_NIL,
|
IDX_NIL,
|
||||||
|
@ -28,7 +28,8 @@ const ChunkInfo kChunks[] = {
|
|||||||
{ MKFOURCC('A', 'L', 'P', 'H'), WEBP_CHUNK_ALPHA, UNDEFINED_CHUNK_SIZE },
|
{ MKFOURCC('A', 'L', 'P', 'H'), WEBP_CHUNK_ALPHA, UNDEFINED_CHUNK_SIZE },
|
||||||
{ MKFOURCC('V', 'P', '8', ' '), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE },
|
{ MKFOURCC('V', 'P', '8', ' '), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE },
|
||||||
{ MKFOURCC('V', 'P', '8', 'L'), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE },
|
{ MKFOURCC('V', 'P', '8', 'L'), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE },
|
||||||
{ MKFOURCC('M', 'E', 'T', 'A'), WEBP_CHUNK_META, UNDEFINED_CHUNK_SIZE },
|
{ MKFOURCC('E', 'X', 'I', 'F'), WEBP_CHUNK_EXIF, UNDEFINED_CHUNK_SIZE },
|
||||||
|
{ MKFOURCC('X', 'M', 'P', ' '), WEBP_CHUNK_XMP, UNDEFINED_CHUNK_SIZE },
|
||||||
{ MKFOURCC('U', 'N', 'K', 'N'), WEBP_CHUNK_UNKNOWN, UNDEFINED_CHUNK_SIZE },
|
{ MKFOURCC('U', 'N', 'K', 'N'), WEBP_CHUNK_UNKNOWN, UNDEFINED_CHUNK_SIZE },
|
||||||
|
|
||||||
{ NIL_TAG, WEBP_CHUNK_NIL, UNDEFINED_CHUNK_SIZE }
|
{ NIL_TAG, WEBP_CHUNK_NIL, UNDEFINED_CHUNK_SIZE }
|
||||||
@ -446,7 +447,8 @@ WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id) {
|
|||||||
case WEBP_CHUNK_VP8X: return (WebPChunk**)&mux->vp8x_;
|
case WEBP_CHUNK_VP8X: return (WebPChunk**)&mux->vp8x_;
|
||||||
case WEBP_CHUNK_ICCP: return (WebPChunk**)&mux->iccp_;
|
case WEBP_CHUNK_ICCP: return (WebPChunk**)&mux->iccp_;
|
||||||
case WEBP_CHUNK_LOOP: return (WebPChunk**)&mux->loop_;
|
case WEBP_CHUNK_LOOP: return (WebPChunk**)&mux->loop_;
|
||||||
case WEBP_CHUNK_META: return (WebPChunk**)&mux->meta_;
|
case WEBP_CHUNK_EXIF: return (WebPChunk**)&mux->exif_;
|
||||||
|
case WEBP_CHUNK_XMP: return (WebPChunk**)&mux->xmp_;
|
||||||
case WEBP_CHUNK_UNKNOWN: return (WebPChunk**)&mux->unknown_;
|
case WEBP_CHUNK_UNKNOWN: return (WebPChunk**)&mux->unknown_;
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
@ -495,7 +497,8 @@ static WebPMuxError ValidateChunk(const WebPMux* const mux, CHUNK_INDEX idx,
|
|||||||
|
|
||||||
WebPMuxError MuxValidate(const WebPMux* const mux) {
|
WebPMuxError MuxValidate(const WebPMux* const mux) {
|
||||||
int num_iccp;
|
int num_iccp;
|
||||||
int num_meta;
|
int num_exif;
|
||||||
|
int num_xmp;
|
||||||
int num_loop_chunks;
|
int num_loop_chunks;
|
||||||
int num_frames;
|
int num_frames;
|
||||||
int num_tiles;
|
int num_tiles;
|
||||||
@ -518,8 +521,12 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
|
|||||||
err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp);
|
err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
|
// At most one EXIF metadata.
|
||||||
|
err = ValidateChunk(mux, IDX_EXIF, EXIF_FLAG, flags, 1, &num_exif);
|
||||||
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
// At most one XMP metadata.
|
// At most one XMP metadata.
|
||||||
err = ValidateChunk(mux, IDX_META, META_FLAG, flags, 1, &num_meta);
|
err = ValidateChunk(mux, IDX_XMP, XMP_FLAG, flags, 1, &num_xmp);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
// Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent.
|
// Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent.
|
||||||
|
@ -42,7 +42,8 @@ static WebPMuxError MuxGet(const WebPMux* const mux, CHUNK_INDEX idx,
|
|||||||
SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_);
|
SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_);
|
||||||
SWITCH_ID_LIST(IDX_ICCP, mux->iccp_);
|
SWITCH_ID_LIST(IDX_ICCP, mux->iccp_);
|
||||||
SWITCH_ID_LIST(IDX_LOOP, mux->loop_);
|
SWITCH_ID_LIST(IDX_LOOP, mux->loop_);
|
||||||
SWITCH_ID_LIST(IDX_META, mux->meta_);
|
SWITCH_ID_LIST(IDX_EXIF, mux->exif_);
|
||||||
|
SWITCH_ID_LIST(IDX_XMP, mux->xmp_);
|
||||||
SWITCH_ID_LIST(IDX_UNKNOWN, mux->unknown_);
|
SWITCH_ID_LIST(IDX_UNKNOWN, mux->unknown_);
|
||||||
return WEBP_MUX_NOT_FOUND;
|
return WEBP_MUX_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,14 @@ typedef enum {
|
|||||||
#define FRGM_CHUNK_SIZE 6 // Size of a FRGM chunk.
|
#define FRGM_CHUNK_SIZE 6 // Size of a FRGM chunk.
|
||||||
#define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk.
|
#define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk.
|
||||||
|
|
||||||
#define TILING_FLAG_BIT 0x01 // Set if tiles are possibly used.
|
// VP8X Feature Flags. These should be the same as the corresponding values in
|
||||||
#define ANIMATION_FLAG_BIT 0x02 // Set if some animation is expected
|
// the 'WebPFeatureFlags' enum defined in mux.h.
|
||||||
#define ICC_FLAG_BIT 0x04 // Whether ICC is present or not.
|
#define FRAGMENTS_FLAG_BIT 0x01
|
||||||
#define METADATA_FLAG_BIT 0x08 // Set if some META chunk is possibly present.
|
#define ANIMATION_FLAG_BIT 0x02
|
||||||
#define ALPHA_FLAG_BIT 0x10 // Should be same as the ALPHA_FLAG in mux.h
|
#define XMP_FLAG_BIT 0x04
|
||||||
#define ROTATION_FLAG_BITS 0xe0 // all 3 bits for rotation + symmetry
|
#define EXIF_FLAG_BIT 0x08
|
||||||
|
#define ALPHA_FLAG_BIT 0x10
|
||||||
|
#define ICC_FLAG_BIT 0x20
|
||||||
|
|
||||||
#define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height.
|
#define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height.
|
||||||
#define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height.
|
#define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height.
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// Vikas (vikasa@google.com)
|
// Vikas (vikasa@google.com)
|
||||||
|
|
||||||
// This API allows manipulation of WebP container images containing features
|
// This API allows manipulation of WebP container images containing features
|
||||||
// like Color profile, XMP metadata, Animation and Tiling.
|
// like color profile, metadata, animation and tiling.
|
||||||
//
|
//
|
||||||
// Code Example#1: Creating a MUX with image data, color profile and XMP
|
// Code Example#1: Creating a MUX with image data, color profile and XMP
|
||||||
// metadata.
|
// metadata.
|
||||||
@ -23,7 +23,7 @@
|
|||||||
// // ... (Prepare ICCP color profile data).
|
// // ... (Prepare ICCP color profile data).
|
||||||
// WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
// WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
||||||
// // ... (Prepare XMP metadata).
|
// // ... (Prepare XMP metadata).
|
||||||
// WebPMuxSetChunk(mux, "META", &xmp, copy_data);
|
// WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
|
||||||
// // Get data from mux in WebP RIFF format.
|
// // Get data from mux in WebP RIFF format.
|
||||||
// WebPMuxAssemble(mux, &output_data);
|
// WebPMuxAssemble(mux, &output_data);
|
||||||
// WebPMuxDelete(mux);
|
// WebPMuxDelete(mux);
|
||||||
@ -84,9 +84,10 @@ enum WebPMuxError {
|
|||||||
enum WebPFeatureFlags {
|
enum WebPFeatureFlags {
|
||||||
TILE_FLAG = 0x00000001,
|
TILE_FLAG = 0x00000001,
|
||||||
ANIMATION_FLAG = 0x00000002,
|
ANIMATION_FLAG = 0x00000002,
|
||||||
ICCP_FLAG = 0x00000004,
|
XMP_FLAG = 0x00000004,
|
||||||
META_FLAG = 0x00000008,
|
EXIF_FLAG = 0x00000008,
|
||||||
ALPHA_FLAG = 0x00000010
|
ALPHA_FLAG = 0x00000010,
|
||||||
|
ICCP_FLAG = 0x00000020
|
||||||
};
|
};
|
||||||
|
|
||||||
// IDs for different types of chunks.
|
// IDs for different types of chunks.
|
||||||
@ -98,7 +99,8 @@ enum WebPChunkId {
|
|||||||
WEBP_CHUNK_FRGM, // FRGM
|
WEBP_CHUNK_FRGM, // FRGM
|
||||||
WEBP_CHUNK_ALPHA, // ALPH
|
WEBP_CHUNK_ALPHA, // ALPH
|
||||||
WEBP_CHUNK_IMAGE, // VP8/VP8L
|
WEBP_CHUNK_IMAGE, // VP8/VP8L
|
||||||
WEBP_CHUNK_META, // META
|
WEBP_CHUNK_EXIF, // EXIF
|
||||||
|
WEBP_CHUNK_XMP, // XMP
|
||||||
WEBP_CHUNK_UNKNOWN, // Other chunks.
|
WEBP_CHUNK_UNKNOWN, // Other chunks.
|
||||||
WEBP_CHUNK_NIL
|
WEBP_CHUNK_NIL
|
||||||
};
|
};
|
||||||
@ -174,7 +176,7 @@ static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// mux - (in/out) object to which the chunk is to be added
|
// mux - (in/out) object to which the chunk is to be added
|
||||||
// fourcc - (in) a character array containing the fourcc of the given chunk;
|
// fourcc - (in) a character array containing the fourcc of the given chunk;
|
||||||
// e.g., "ICCP", "META" etc.
|
// e.g., "ICCP", "XMP ", "EXIF" etc.
|
||||||
// chunk_data - (in) the chunk data to be added
|
// chunk_data - (in) the chunk data to be added
|
||||||
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
|
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
|
||||||
// and value 0 indicates data will NOT be copied.
|
// and value 0 indicates data will NOT be copied.
|
||||||
@ -192,7 +194,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk(
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// mux - (in) object from which the chunk data is to be fetched
|
// mux - (in) object from which the chunk data is to be fetched
|
||||||
// fourcc - (in) a character array containing the fourcc of the chunk;
|
// fourcc - (in) a character array containing the fourcc of the chunk;
|
||||||
// e.g., "ICCP", "META" etc.
|
// e.g., "ICCP", "XMP ", "EXIF" etc.
|
||||||
// chunk_data - (out) returned chunk data
|
// chunk_data - (out) returned chunk data
|
||||||
// Returns:
|
// Returns:
|
||||||
// WEBP_MUX_INVALID_ARGUMENT - if either mux, fourcc or chunk_data is NULL
|
// WEBP_MUX_INVALID_ARGUMENT - if either mux, fourcc or chunk_data is NULL
|
||||||
@ -206,7 +208,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk(
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// mux - (in/out) object from which the chunk is to be deleted
|
// mux - (in/out) object from which the chunk is to be deleted
|
||||||
// fourcc - (in) a character array containing the fourcc of the chunk;
|
// fourcc - (in) a character array containing the fourcc of the chunk;
|
||||||
// e.g., "ICCP", "META" etc.
|
// e.g., "ICCP", "XMP ", "EXIF" etc.
|
||||||
// Returns:
|
// Returns:
|
||||||
// WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
|
// WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
|
||||||
// or if fourcc corresponds to an image chunk.
|
// or if fourcc corresponds to an image chunk.
|
||||||
@ -481,7 +483,7 @@ struct WebPChunkIterator {
|
|||||||
// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
|
// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
|
||||||
// 'dmux'.
|
// 'dmux'.
|
||||||
// 'fourcc' is a character array containing the fourcc of the chunk to return,
|
// 'fourcc' is a character array containing the fourcc of the chunk to return,
|
||||||
// e.g., "ICCP", "META", "EXIF", etc.
|
// e.g., "ICCP", "XMP ", "EXIF", etc.
|
||||||
// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
|
// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
|
||||||
// Returns true if the chunk is found, false otherwise. Image related chunk
|
// Returns true if the chunk is found, false otherwise. Image related chunk
|
||||||
// payloads are accessed through WebPDemuxGetFrame() and related functions.
|
// payloads are accessed through WebPDemuxGetFrame() and related functions.
|
||||||
|
Loading…
Reference in New Issue
Block a user