2012-01-06 23:49:06 +01:00
|
|
|
// Copyright 2011 Google Inc. All Rights Reserved.
|
2011-09-30 07:37:01 +02:00
|
|
|
//
|
2013-06-07 08:05:58 +02:00
|
|
|
// Use of this source code is governed by a BSD-style license
|
|
|
|
// that can be found in the COPYING file in the root of the source
|
|
|
|
// tree. An additional intellectual property rights grant can be found
|
|
|
|
// in the file PATENTS. All contributing project authors may
|
|
|
|
// be found in the AUTHORS file in the root of the source tree.
|
2011-09-30 07:37:01 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Simple command-line to create a WebP container file and to extract or strip
|
|
|
|
// relevant data from the container file.
|
|
|
|
//
|
|
|
|
// Authors: Vikas (vikaas.arora@gmail.com),
|
|
|
|
// Urvang (urvang@google.com)
|
|
|
|
|
|
|
|
/* Usage examples:
|
|
|
|
|
|
|
|
Create container WebP file:
|
2012-11-14 06:19:31 +01:00
|
|
|
webpmux -frame anim_1.webp +100+10+10 \
|
|
|
|
-frame anim_2.webp +100+25+25+1 \
|
|
|
|
-frame anim_3.webp +100+50+50+1 \
|
|
|
|
-frame anim_4.webp +100 \
|
|
|
|
-loop 10 -bgcolor 128,255,255,255 \
|
2011-09-30 07:37:01 +02:00
|
|
|
-o out_animation_container.webp
|
|
|
|
|
|
|
|
webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
|
2012-11-01 00:30:41 +01:00
|
|
|
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
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
Extract relevant data from WebP container file:
|
|
|
|
webpmux -get frame n in.webp -o out_frame.webp
|
|
|
|
webpmux -get icc in.webp -o image_profile.icc
|
2012-11-01 00:30:41 +01:00
|
|
|
webpmux -get exif in.webp -o image_metadata.exif
|
|
|
|
webpmux -get xmp in.webp -o image_metadata.xmp
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
Strip data from WebP Container file:
|
2011-11-04 23:20:08 +01:00
|
|
|
webpmux -strip icc in.webp -o out.webp
|
2012-11-01 00:30:41 +01:00
|
|
|
webpmux -strip exif in.webp -o out.webp
|
|
|
|
webpmux -strip xmp in.webp -o out.webp
|
2011-09-30 07:37:01 +02:00
|
|
|
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
Change duration of frame intervals:
|
|
|
|
webpmux -duration 150 in.webp -o out.webp
|
2016-11-10 08:26:01 +01:00
|
|
|
webpmux -duration 33,2 in.webp -o out.webp
|
|
|
|
webpmux -duration 200,10,0 -duration 150,6,50 in.webp -o out.webp
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
Misc:
|
|
|
|
webpmux -info in.webp
|
2011-11-04 23:20:08 +01:00
|
|
|
webpmux [ -h | -help ]
|
2013-02-26 23:22:06 +01:00
|
|
|
webpmux -version
|
2017-12-01 09:21:13 +01:00
|
|
|
webpmux argument_file_name
|
2011-09-30 07:37:01 +02:00
|
|
|
*/
|
|
|
|
|
2013-03-15 22:46:12 +01:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2014-06-11 02:53:44 +02:00
|
|
|
#include "webp/config.h"
|
2013-03-15 22:46:12 +01:00
|
|
|
#endif
|
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2013-09-17 00:29:24 +02:00
|
|
|
#include "webp/decode.h"
|
2011-09-30 07:37:01 +02:00
|
|
|
#include "webp/mux.h"
|
2016-07-22 01:10:05 +02:00
|
|
|
#include "../examples/example_util.h"
|
2016-07-21 03:25:00 +02:00
|
|
|
#include "../imageio/imageio_util.h"
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
#include "./unicode.h"
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Config object to parse command-line arguments.
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
NIL_ACTION = 0,
|
|
|
|
ACTION_GET,
|
|
|
|
ACTION_SET,
|
|
|
|
ACTION_STRIP,
|
|
|
|
ACTION_INFO,
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
ACTION_HELP,
|
|
|
|
ACTION_DURATION
|
2011-09-30 07:37:01 +02:00
|
|
|
} ActionType;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
NIL_SUBTYPE = 0,
|
2012-11-01 23:34:46 +01:00
|
|
|
SUBTYPE_ANMF,
|
|
|
|
SUBTYPE_LOOP,
|
|
|
|
SUBTYPE_BGCOLOR
|
2011-09-30 07:37:01 +02:00
|
|
|
} FeatureSubType;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
FeatureSubType subtype_;
|
|
|
|
const char* filename_;
|
|
|
|
const char* params_;
|
|
|
|
} FeatureArg;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
NIL_FEATURE = 0,
|
2012-11-01 00:30:41 +01:00
|
|
|
FEATURE_EXIF,
|
|
|
|
FEATURE_XMP,
|
2011-09-30 07:37:01 +02:00
|
|
|
FEATURE_ICCP,
|
2012-11-01 01:49:15 +01:00
|
|
|
FEATURE_ANMF,
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
FEATURE_DURATION,
|
2012-11-01 00:30:41 +01:00
|
|
|
LAST_FEATURE
|
2011-09-30 07:37:01 +02:00
|
|
|
} FeatureType;
|
|
|
|
|
2012-11-01 00:30:41 +01:00
|
|
|
static const char* const kFourccList[LAST_FEATURE] = {
|
2016-09-02 14:26:37 +02:00
|
|
|
NULL, "EXIF", "XMP ", "ICCP", "ANMF"
|
2012-11-01 00:30:41 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static const char* const kDescriptions[LAST_FEATURE] = {
|
|
|
|
NULL, "EXIF metadata", "XMP metadata", "ICC profile",
|
2016-09-02 14:26:37 +02:00
|
|
|
"Animation frame"
|
2012-11-01 00:30:41 +01:00
|
|
|
};
|
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
typedef struct {
|
2018-02-08 08:09:14 +01:00
|
|
|
CommandLineArguments cmd_args_;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
ActionType action_type_;
|
|
|
|
const char* input_;
|
|
|
|
const char* output_;
|
2017-12-01 09:21:13 +01:00
|
|
|
FeatureType type_;
|
|
|
|
FeatureArg* args_;
|
|
|
|
int arg_count_;
|
|
|
|
} Config;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Helper functions.
|
|
|
|
|
2018-02-08 08:09:14 +01:00
|
|
|
static int CountOccurrences(const CommandLineArguments* const args,
|
|
|
|
const char* const arg) {
|
2011-09-30 07:37:01 +02:00
|
|
|
int i;
|
|
|
|
int num_occurences = 0;
|
|
|
|
|
2018-02-08 08:09:14 +01:00
|
|
|
for (i = 0; i < args->argc_; ++i) {
|
|
|
|
if (!strcmp(args->argv_[i], arg)) {
|
2011-09-30 07:37:01 +02:00
|
|
|
++num_occurences;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return num_occurences;
|
|
|
|
}
|
|
|
|
|
2014-07-21 15:44:43 +02:00
|
|
|
static const char* const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
|
2012-07-06 14:03:59 +02:00
|
|
|
"WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA",
|
|
|
|
"WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA"
|
2012-06-27 13:25:01 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static const char* ErrorString(WebPMuxError err) {
|
2012-07-06 14:03:59 +02:00
|
|
|
assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA);
|
2012-06-27 13:25:01 +02:00
|
|
|
return kErrorMessages[-err];
|
|
|
|
}
|
|
|
|
|
2012-01-28 02:39:47 +01:00
|
|
|
#define RETURN_IF_ERROR(ERR_MSG) \
|
|
|
|
if (err != WEBP_MUX_OK) { \
|
|
|
|
fprintf(stderr, ERR_MSG); \
|
|
|
|
return err; \
|
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2012-08-23 12:58:36 +02:00
|
|
|
#define RETURN_IF_ERROR3(ERR_MSG, FORMAT_STR1, FORMAT_STR2) \
|
|
|
|
if (err != WEBP_MUX_OK) { \
|
|
|
|
fprintf(stderr, ERR_MSG, FORMAT_STR1, FORMAT_STR2); \
|
|
|
|
return err; \
|
|
|
|
}
|
|
|
|
|
2012-01-28 02:39:47 +01:00
|
|
|
#define ERROR_GOTO1(ERR_MSG, LABEL) \
|
|
|
|
do { \
|
|
|
|
fprintf(stderr, ERR_MSG); \
|
|
|
|
ok = 0; \
|
|
|
|
goto LABEL; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ERROR_GOTO2(ERR_MSG, FORMAT_STR, LABEL) \
|
|
|
|
do { \
|
|
|
|
fprintf(stderr, ERR_MSG, FORMAT_STR); \
|
|
|
|
ok = 0; \
|
|
|
|
goto LABEL; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ERROR_GOTO3(ERR_MSG, FORMAT_STR1, FORMAT_STR2, LABEL) \
|
2013-04-27 00:55:42 +02:00
|
|
|
do { \
|
|
|
|
fprintf(stderr, ERR_MSG, FORMAT_STR1, FORMAT_STR2); \
|
|
|
|
ok = 0; \
|
|
|
|
goto LABEL; \
|
|
|
|
} while (0)
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
static WebPMuxError DisplayInfo(const WebPMux* mux) {
|
2013-05-02 22:54:25 +02:00
|
|
|
int width, height;
|
2011-09-30 07:37:01 +02:00
|
|
|
uint32_t flag;
|
|
|
|
|
2013-05-02 22:54:25 +02:00
|
|
|
WebPMuxError err = WebPMuxGetCanvasSize(mux, &width, &height);
|
2013-09-18 20:44:24 +02:00
|
|
|
assert(err == WEBP_MUX_OK); // As WebPMuxCreate() was successful earlier.
|
2013-05-02 22:54:25 +02:00
|
|
|
printf("Canvas size: %d x %d\n", width, height);
|
|
|
|
|
|
|
|
err = WebPMuxGetFeatures(mux, &flag);
|
2011-09-30 07:37:01 +02:00
|
|
|
RETURN_IF_ERROR("Failed to retrieve features\n");
|
|
|
|
|
|
|
|
if (flag == 0) {
|
2015-09-26 03:49:08 +02:00
|
|
|
printf("No features present.\n");
|
2011-09-30 07:37:01 +02:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print the features present.
|
2012-01-24 21:46:46 +01:00
|
|
|
printf("Features present:");
|
|
|
|
if (flag & ANIMATION_FLAG) printf(" animation");
|
2013-03-13 22:04:20 +01:00
|
|
|
if (flag & ICCP_FLAG) printf(" ICC profile");
|
2012-11-01 00:30:41 +01:00
|
|
|
if (flag & EXIF_FLAG) printf(" EXIF metadata");
|
|
|
|
if (flag & XMP_FLAG) printf(" XMP metadata");
|
2012-01-24 21:46:46 +01:00
|
|
|
if (flag & ALPHA_FLAG) printf(" transparency");
|
|
|
|
printf("\n");
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2016-09-02 14:26:37 +02:00
|
|
|
if (flag & ANIMATION_FLAG) {
|
|
|
|
const WebPChunkId id = WEBP_CHUNK_ANMF;
|
|
|
|
const char* const type_str = "frame";
|
2012-01-07 21:44:01 +01:00
|
|
|
int nFrames;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2016-09-02 14:26:37 +02:00
|
|
|
WebPMuxAnimParams params;
|
|
|
|
err = WebPMuxGetAnimationParams(mux, ¶ms);
|
|
|
|
assert(err == WEBP_MUX_OK);
|
|
|
|
printf("Background color : 0x%.8X Loop Count : %d\n",
|
|
|
|
params.bgcolor, params.loop_count);
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2012-08-23 12:58:36 +02:00
|
|
|
err = WebPMuxNumChunks(mux, id, &nFrames);
|
2013-09-18 20:44:24 +02:00
|
|
|
assert(err == WEBP_MUX_OK);
|
2012-08-23 12:58:36 +02:00
|
|
|
|
|
|
|
printf("Number of %ss: %d\n", type_str, nFrames);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (nFrames > 0) {
|
|
|
|
int i;
|
2013-09-17 00:29:24 +02:00
|
|
|
printf("No.: width height alpha x_offset y_offset ");
|
2016-09-02 14:26:37 +02:00
|
|
|
printf("duration dispose blend ");
|
2016-07-09 00:44:38 +02:00
|
|
|
printf("image_size compression\n");
|
2011-09-30 07:37:01 +02:00
|
|
|
for (i = 1; i <= nFrames; i++) {
|
2012-08-23 11:48:51 +02:00
|
|
|
WebPMuxFrameInfo frame;
|
|
|
|
err = WebPMuxGetFrame(mux, i, &frame);
|
2013-05-22 00:58:53 +02:00
|
|
|
if (err == WEBP_MUX_OK) {
|
2013-09-17 00:29:24 +02:00
|
|
|
WebPBitstreamFeatures features;
|
|
|
|
const VP8StatusCode status = WebPGetFeatures(
|
|
|
|
frame.bitstream.bytes, frame.bitstream.size, &features);
|
|
|
|
assert(status == VP8_STATUS_OK); // Checked by WebPMuxCreate().
|
|
|
|
(void)status;
|
|
|
|
printf("%3d: %5d %5d %5s %8d %8d ", i, features.width,
|
|
|
|
features.height, features.has_alpha ? "yes" : "no",
|
|
|
|
frame.x_offset, frame.y_offset);
|
2016-09-02 14:26:37 +02:00
|
|
|
{
|
2013-09-17 00:29:24 +02:00
|
|
|
const char* const dispose =
|
|
|
|
(frame.dispose_method == WEBP_MUX_DISPOSE_NONE) ? "none"
|
|
|
|
: "background";
|
|
|
|
const char* const blend =
|
|
|
|
(frame.blend_method == WEBP_MUX_BLEND) ? "yes" : "no";
|
|
|
|
printf("%8d %10s %5s ", frame.duration, dispose, blend);
|
2013-08-27 03:04:52 +02:00
|
|
|
}
|
2016-07-09 00:44:38 +02:00
|
|
|
printf("%10d %11s\n", (int)frame.bitstream.size,
|
|
|
|
(features.format == 1) ? "lossy" :
|
|
|
|
(features.format == 2) ? "lossless" :
|
|
|
|
"undefined");
|
2013-05-22 00:58:53 +02:00
|
|
|
}
|
2012-10-30 22:54:46 +01:00
|
|
|
WebPDataClear(&frame.bitstream);
|
2013-05-22 00:58:53 +02:00
|
|
|
RETURN_IF_ERROR3("Failed to retrieve %s#%d\n", type_str, i);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag & ICCP_FLAG) {
|
2012-01-07 21:44:01 +01:00
|
|
|
WebPData icc_profile;
|
2012-08-23 11:58:20 +02:00
|
|
|
err = WebPMuxGetChunk(mux, "ICCP", &icc_profile);
|
2013-09-18 20:44:24 +02:00
|
|
|
assert(err == WEBP_MUX_OK);
|
2013-03-21 00:59:35 +01:00
|
|
|
printf("Size of the ICC profile data: %d\n", (int)icc_profile.size);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
2012-11-01 00:30:41 +01:00
|
|
|
if (flag & EXIF_FLAG) {
|
|
|
|
WebPData exif;
|
|
|
|
err = WebPMuxGetChunk(mux, "EXIF", &exif);
|
2013-09-18 20:44:24 +02:00
|
|
|
assert(err == WEBP_MUX_OK);
|
2013-03-21 00:59:35 +01:00
|
|
|
printf("Size of the EXIF metadata: %d\n", (int)exif.size);
|
2012-11-01 00:30:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (flag & XMP_FLAG) {
|
|
|
|
WebPData xmp;
|
|
|
|
err = WebPMuxGetChunk(mux, "XMP ", &xmp);
|
2013-09-18 20:44:24 +02:00
|
|
|
assert(err == WEBP_MUX_OK);
|
2013-03-21 00:59:35 +01:00
|
|
|
printf("Size of the XMP metadata: %d\n", (int)xmp.size);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 14:26:37 +02:00
|
|
|
if ((flag & ALPHA_FLAG) && !(flag & ANIMATION_FLAG)) {
|
2012-08-23 12:58:36 +02:00
|
|
|
WebPMuxFrameInfo image;
|
|
|
|
err = WebPMuxGetFrame(mux, 1, &image);
|
2013-05-22 00:58:53 +02:00
|
|
|
if (err == WEBP_MUX_OK) {
|
|
|
|
printf("Size of the image (with alpha): %d\n", (int)image.bitstream.size);
|
|
|
|
}
|
|
|
|
WebPDataClear(&image.bitstream);
|
2011-12-01 11:41:51 +01:00
|
|
|
RETURN_IF_ERROR("Failed to retrieve the image\n");
|
|
|
|
}
|
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
return WEBP_MUX_OK;
|
|
|
|
}
|
|
|
|
|
2011-11-01 14:24:34 +01:00
|
|
|
static void PrintHelp(void) {
|
2012-01-24 21:46:46 +01:00
|
|
|
printf("Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT\n");
|
|
|
|
printf(" webpmux -set SET_OPTIONS INPUT -o OUTPUT\n");
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
printf(" webpmux -duration DURATION_OPTIONS [-duration ...]\n");
|
|
|
|
printf(" INPUT -o OUTPUT\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
printf(" webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT\n");
|
2012-11-01 23:34:46 +01:00
|
|
|
printf(" webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]"
|
|
|
|
"\n");
|
|
|
|
printf(" [-bgcolor BACKGROUND_COLOR] -o OUTPUT\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
printf(" webpmux -info INPUT\n");
|
|
|
|
printf(" webpmux [-h|-help]\n");
|
2013-02-26 23:22:06 +01:00
|
|
|
printf(" webpmux -version\n");
|
2017-12-01 09:21:13 +01:00
|
|
|
printf(" webpmux argument_file_name\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printf("GET_OPTIONS:\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" Extract relevant data:\n");
|
|
|
|
printf(" icc get ICC profile\n");
|
|
|
|
printf(" exif get EXIF metadata\n");
|
|
|
|
printf(" xmp get XMP metadata\n");
|
|
|
|
printf(" frame n get nth frame\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printf("SET_OPTIONS:\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" Set color profile/metadata:\n");
|
|
|
|
printf(" icc file.icc set ICC profile\n");
|
|
|
|
printf(" exif file.exif set EXIF metadata\n");
|
|
|
|
printf(" xmp file.xmp set XMP metadata\n");
|
2012-11-01 00:30:41 +01:00
|
|
|
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");
|
2012-01-24 21:46:46 +01:00
|
|
|
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
printf("\n");
|
|
|
|
printf("DURATION_OPTIONS:\n");
|
2016-11-10 08:26:01 +01:00
|
|
|
printf(" Set duration of selected frames:\n");
|
|
|
|
printf(" duration set duration for each frames\n");
|
|
|
|
printf(" duration,frame set duration of a particular frame\n");
|
|
|
|
printf(" duration,start,end set duration of frames in the\n");
|
|
|
|
printf(" interval [start,end])\n");
|
|
|
|
printf(" where: 'duration' is the duration in milliseconds\n");
|
|
|
|
printf(" 'start' is the start frame index\n");
|
|
|
|
printf(" 'end' is the inclusive end frame index\n");
|
|
|
|
printf(" The special 'end' value '0' means: last frame.\n");
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
|
2012-01-24 21:46:46 +01:00
|
|
|
printf("\n");
|
|
|
|
printf("STRIP_OPTIONS:\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" Strip color profile/metadata:\n");
|
|
|
|
printf(" icc strip ICC profile\n");
|
|
|
|
printf(" exif strip EXIF metadata\n");
|
|
|
|
printf(" xmp strip XMP metadata\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printf("FRAME_OPTIONS(i):\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" Create animation:\n");
|
2013-08-27 03:04:52 +02:00
|
|
|
printf(" file_i +di+[xi+yi[+mi[bi]]]\n");
|
2012-11-01 00:30:41 +01:00
|
|
|
printf(" where: 'file_i' is the i'th animation frame (WebP format),\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" 'di' is the pause duration before next frame,\n");
|
|
|
|
printf(" 'xi','yi' specify the image offset for this frame,\n");
|
|
|
|
printf(" 'mi' is the dispose method for this frame (0 or 1),\n");
|
|
|
|
printf(" 'bi' is the blending method for this frame (+b or -b)"
|
2013-08-27 03:04:52 +02:00
|
|
|
"\n");
|
2012-11-01 23:34:46 +01:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printf("LOOP_COUNT:\n");
|
|
|
|
printf(" Number of times to repeat the animation.\n");
|
|
|
|
printf(" Valid range is 0 to 65535 [Default: 0 (infinite)].\n");
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printf("BACKGROUND_COLOR:\n");
|
|
|
|
printf(" Background color of the canvas.\n");
|
|
|
|
printf(" A,R,G,B\n");
|
|
|
|
printf(" where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 "
|
|
|
|
"specifying\n");
|
|
|
|
printf(" the Alpha, Red, Green and Blue component values "
|
|
|
|
"respectively\n");
|
2014-06-18 16:45:34 +02:00
|
|
|
printf(" [Default: 255,255,255,255]\n");
|
2012-01-24 21:46:46 +01:00
|
|
|
|
2012-11-01 00:30:41 +01:00
|
|
|
printf("\nINPUT & OUTPUT are in WebP format.\n");
|
|
|
|
|
2012-11-01 23:34:46 +01:00
|
|
|
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
|
|
|
printf(" and is assumed to be\nvalid.\n");
|
2017-12-01 09:21:13 +01:00
|
|
|
printf("\nNote: if a single file name is passed as the argument, the "
|
|
|
|
"arguments will be\n");
|
|
|
|
printf("tokenized from this file. The file name must not start with "
|
|
|
|
"the character '-'.\n");
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
2014-06-18 08:21:49 +02:00
|
|
|
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
|
|
|
if ((info->x_offset | info->y_offset) & 1) {
|
|
|
|
fprintf(stderr, "Warning: odd offsets will be snapped to even values"
|
|
|
|
" (%d, %d) -> (%d, %d)\n", info->x_offset, info->y_offset,
|
|
|
|
info->x_offset & ~1, info->y_offset & ~1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-12 01:00:57 +02:00
|
|
|
static int CreateMux(const char* const filename, WebPMux** mux) {
|
2012-06-05 10:50:45 +02:00
|
|
|
WebPData bitstream;
|
2011-09-30 07:37:01 +02:00
|
|
|
assert(mux != NULL);
|
2018-02-08 08:09:14 +01:00
|
|
|
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
|
2012-06-07 10:15:06 +02:00
|
|
|
*mux = WebPMuxCreate(&bitstream, 1);
|
2017-12-01 09:21:13 +01:00
|
|
|
WebPDataClear(&bitstream);
|
2012-06-07 10:15:06 +02:00
|
|
|
if (*mux != NULL) return 1;
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
|
|
|
|
(const W_CHAR*)filename);
|
2011-09-30 07:37:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-01-24 23:08:27 +01:00
|
|
|
static int WriteData(const char* filename, const WebPData* const webpdata) {
|
2011-09-30 07:37:01 +02:00
|
|
|
int ok = 0;
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
|
|
|
|
: ImgIoUtilSetBinaryMode(stdout);
|
2014-08-30 04:11:41 +02:00
|
|
|
if (fout == NULL) {
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
WFPRINTF(stderr, "Error opening output WebP file %s!\n",
|
|
|
|
(const W_CHAR*)filename);
|
2011-09-30 07:37:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2012-10-30 22:54:46 +01:00
|
|
|
if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
WFPRINTF(stderr, "Error writing file %s!\n", (const W_CHAR*)filename);
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
|
|
|
|
(const W_CHAR*)filename, (int)webpdata->size);
|
2011-09-30 07:37:01 +02:00
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
if (fout != stdout) fclose(fout);
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int WriteWebP(WebPMux* const mux, const char* filename) {
|
|
|
|
int ok;
|
2012-06-07 07:34:57 +02:00
|
|
|
WebPData webp_data;
|
|
|
|
const WebPMuxError err = WebPMuxAssemble(mux, &webp_data);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (err != WEBP_MUX_OK) {
|
2012-06-27 13:25:01 +02:00
|
|
|
fprintf(stderr, "Error (%s) assembling the WebP file.\n", ErrorString(err));
|
2011-09-30 07:37:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2012-06-07 07:34:57 +02:00
|
|
|
ok = WriteData(filename, &webp_data);
|
|
|
|
WebPDataClear(&webp_data);
|
2011-09-30 07:37:01 +02:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
|
|
|
|
WebPMux* new_mux = WebPMuxNew();
|
|
|
|
WebPMuxAnimParams p;
|
|
|
|
WebPMuxError err;
|
|
|
|
int i;
|
|
|
|
int ok = 1;
|
|
|
|
|
|
|
|
if (new_mux == NULL) return NULL;
|
|
|
|
|
|
|
|
err = WebPMuxGetAnimationParams(mux, &p);
|
|
|
|
if (err == WEBP_MUX_OK) {
|
|
|
|
err = WebPMuxSetAnimationParams(new_mux, &p);
|
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO2("Error (%s) handling animation params.\n",
|
|
|
|
ErrorString(err), End);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* it might not be an animation. Just keep moving. */
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1; i <= 3; ++i) {
|
|
|
|
WebPData metadata;
|
|
|
|
err = WebPMuxGetChunk(mux, kFourccList[i], &metadata);
|
|
|
|
if (err == WEBP_MUX_OK && metadata.size > 0) {
|
|
|
|
err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
|
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
End:
|
|
|
|
if (!ok) {
|
|
|
|
WebPMuxDelete(new_mux);
|
|
|
|
new_mux = NULL;
|
|
|
|
}
|
|
|
|
return new_mux;
|
|
|
|
}
|
|
|
|
|
2012-08-23 11:48:51 +02:00
|
|
|
static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
|
2012-11-14 06:19:31 +01:00
|
|
|
int dispose_method, dummy;
|
2013-08-27 03:04:52 +02:00
|
|
|
char plus_minus, blend_method;
|
|
|
|
const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration,
|
|
|
|
&info->x_offset, &info->y_offset, &dispose_method,
|
|
|
|
&plus_minus, &blend_method, &dummy);
|
2012-11-14 06:19:31 +01:00
|
|
|
switch (num_args) {
|
|
|
|
case 1:
|
|
|
|
info->x_offset = info->y_offset = 0; // fall through
|
|
|
|
case 3:
|
|
|
|
dispose_method = 0; // fall through
|
|
|
|
case 4:
|
2013-08-27 03:04:52 +02:00
|
|
|
plus_minus = '+';
|
|
|
|
blend_method = 'b'; // fall through
|
|
|
|
case 6:
|
2012-11-14 06:19:31 +01:00
|
|
|
break;
|
2013-08-27 03:04:52 +02:00
|
|
|
case 2:
|
|
|
|
case 5:
|
2012-11-14 06:19:31 +01:00
|
|
|
default:
|
|
|
|
return 0;
|
2012-11-01 23:34:46 +01:00
|
|
|
}
|
2014-06-18 08:21:49 +02:00
|
|
|
|
|
|
|
WarnAboutOddOffset(info);
|
|
|
|
|
2012-11-01 23:34:46 +01:00
|
|
|
// Note: The sanity of the following conversion is checked by
|
2013-08-27 03:04:52 +02:00
|
|
|
// WebPMuxPushFrame().
|
2012-11-01 23:34:46 +01:00
|
|
|
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
|
2013-08-27 03:04:52 +02:00
|
|
|
|
|
|
|
if (blend_method != 'b') return 0;
|
|
|
|
if (plus_minus != '-' && plus_minus != '+') return 0;
|
|
|
|
info->blend_method =
|
|
|
|
(plus_minus == '+') ? WEBP_MUX_BLEND : WEBP_MUX_NO_BLEND;
|
2012-11-01 23:34:46 +01:00
|
|
|
return 1;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
2012-11-01 23:34:46 +01:00
|
|
|
static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
|
|
|
|
uint32_t a, r, g, b;
|
|
|
|
if (sscanf(args, "%u,%u,%u,%u", &a, &r, &g, &b) != 4) return 0;
|
|
|
|
if (a >= 256 || r >= 256 || g >= 256 || b >= 256) return 0;
|
|
|
|
*bgcolor = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Clean-up.
|
|
|
|
|
2017-12-01 09:21:13 +01:00
|
|
|
static void DeleteConfig(Config* const config) {
|
2011-09-30 07:37:01 +02:00
|
|
|
if (config != NULL) {
|
2017-12-01 09:21:13 +01:00
|
|
|
free(config->args_);
|
2018-02-08 08:09:14 +01:00
|
|
|
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
|
2014-09-12 09:03:28 +02:00
|
|
|
memset(config, 0, sizeof(*config));
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Parsing.
|
|
|
|
|
|
|
|
// Basic syntactic checks on the command-line arguments.
|
|
|
|
// Returns 1 on valid, 0 otherwise.
|
|
|
|
// Also fills up num_feature_args to be number of feature arguments given.
|
|
|
|
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
|
2018-02-08 08:09:14 +01:00
|
|
|
static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
2011-09-30 07:37:01 +02:00
|
|
|
int* num_feature_args) {
|
|
|
|
int num_frame_args;
|
|
|
|
int num_loop_args;
|
2012-11-01 23:34:46 +01:00
|
|
|
int num_bgcolor_args;
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
int num_durations_args;
|
2011-09-30 07:37:01 +02:00
|
|
|
int ok = 1;
|
|
|
|
|
|
|
|
assert(num_feature_args != NULL);
|
|
|
|
*num_feature_args = 0;
|
|
|
|
|
|
|
|
// Simple checks.
|
2018-02-08 08:09:14 +01:00
|
|
|
if (CountOccurrences(cmd_args, "-get") > 1) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
|
|
|
}
|
2018-02-08 08:09:14 +01:00
|
|
|
if (CountOccurrences(cmd_args, "-set") > 1) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
|
|
|
|
}
|
2018-02-08 08:09:14 +01:00
|
|
|
if (CountOccurrences(cmd_args, "-strip") > 1) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
|
|
|
|
}
|
2018-02-08 08:09:14 +01:00
|
|
|
if (CountOccurrences(cmd_args, "-info") > 1) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
|
|
|
|
}
|
2018-02-08 08:09:14 +01:00
|
|
|
if (CountOccurrences(cmd_args, "-o") > 1) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compound checks.
|
2018-02-08 08:09:14 +01:00
|
|
|
num_frame_args = CountOccurrences(cmd_args, "-frame");
|
|
|
|
num_loop_args = CountOccurrences(cmd_args, "-loop");
|
|
|
|
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
|
|
|
|
num_durations_args = CountOccurrences(cmd_args, "-duration");
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
if (num_loop_args > 1) {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
if (num_bgcolor_args > 1) {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple background colors specified.\n", ErrValidate);
|
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2012-11-01 23:34:46 +01:00
|
|
|
if ((num_frame_args == 0) && (num_loop_args + num_bgcolor_args > 0)) {
|
|
|
|
ERROR_GOTO1("ERROR: Loop count and background color are relevant only in "
|
|
|
|
"case of animation.\n", ErrValidate);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
if (num_durations_args > 0 && num_frame_args != 0) {
|
|
|
|
ERROR_GOTO1("ERROR: Can not combine -duration and -frame commands.\n",
|
|
|
|
ErrValidate);
|
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
assert(ok == 1);
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
if (num_durations_args > 0) {
|
|
|
|
*num_feature_args = num_durations_args;
|
|
|
|
} else if (num_frame_args == 0) {
|
2012-11-01 00:30:41 +01:00
|
|
|
// Single argument ('set' action for ICCP/EXIF/XMP, OR a 'get' action).
|
2011-09-30 07:37:01 +02:00
|
|
|
*num_feature_args = 1;
|
|
|
|
} else {
|
2016-09-02 14:26:37 +02:00
|
|
|
// Multiple arguments ('set' action for animation)
|
|
|
|
*num_feature_args = num_frame_args + num_loop_args + num_bgcolor_args;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ErrValidate:
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
|
|
|
|
|
2017-12-01 09:21:13 +01:00
|
|
|
#define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2018-10-03 21:39:38 +02:00
|
|
|
#define CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL) \
|
2011-09-30 07:37:01 +02:00
|
|
|
if (argc < i + (NUM)) { \
|
|
|
|
fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \
|
|
|
|
goto LABEL; \
|
|
|
|
}
|
|
|
|
|
2018-10-03 21:39:38 +02:00
|
|
|
#define CHECK_NUM_ARGS_AT_MOST(NUM, LABEL) \
|
|
|
|
if (argc > i + (NUM)) { \
|
2011-09-30 07:37:01 +02:00
|
|
|
fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \
|
|
|
|
goto LABEL; \
|
|
|
|
}
|
|
|
|
|
2018-10-03 21:39:38 +02:00
|
|
|
#define CHECK_NUM_ARGS_EXACTLY(NUM, LABEL) \
|
|
|
|
CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL); \
|
|
|
|
CHECK_NUM_ARGS_AT_MOST(NUM, LABEL);
|
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
// Parses command-line arguments to fill up config object. Also performs some
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
// semantic checks. unicode_argv contains wchar_t arguments or is null.
|
|
|
|
static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
2011-09-30 07:37:01 +02:00
|
|
|
int i = 0;
|
|
|
|
int feature_arg_index = 0;
|
|
|
|
int ok = 1;
|
2018-02-08 08:09:14 +01:00
|
|
|
int argc = config->cmd_args_.argc_;
|
|
|
|
const char* const* argv = config->cmd_args_.argv_;
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
// Unicode file paths will be used if available.
|
|
|
|
const char* const* wargv =
|
|
|
|
(unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
while (i < argc) {
|
2017-12-01 09:21:13 +01:00
|
|
|
FeatureArg* const arg = &config->args_[feature_arg_index];
|
2011-09-30 07:37:01 +02:00
|
|
|
if (argv[i][0] == '-') { // One of the action types or output.
|
|
|
|
if (!strcmp(argv[i], "-set")) {
|
|
|
|
if (ACTION_IS_NIL) {
|
|
|
|
config->action_type_ = ACTION_SET;
|
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
|
|
|
++i;
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
} else if (!strcmp(argv[i], "-duration")) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_DURATION) {
|
|
|
|
config->action_type_ = ACTION_DURATION;
|
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
2017-12-01 09:21:13 +01:00
|
|
|
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
|
|
|
|
config->type_ = FEATURE_DURATION;
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
|
|
|
}
|
|
|
|
arg->params_ = argv[i + 1];
|
|
|
|
++feature_arg_index;
|
|
|
|
i += 2;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else if (!strcmp(argv[i], "-get")) {
|
|
|
|
if (ACTION_IS_NIL) {
|
|
|
|
config->action_type_ = ACTION_GET;
|
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
} else if (!strcmp(argv[i], "-strip")) {
|
|
|
|
if (ACTION_IS_NIL) {
|
|
|
|
config->action_type_ = ACTION_STRIP;
|
2017-12-01 09:21:13 +01:00
|
|
|
config->arg_count_ = 0;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
} else if (!strcmp(argv[i], "-frame")) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(3, ErrParse);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
|
|
|
config->action_type_ = ACTION_SET;
|
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
2017-12-01 09:21:13 +01:00
|
|
|
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
|
|
|
config->type_ = FEATURE_ANMF;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
arg->subtype_ = SUBTYPE_ANMF;
|
2011-09-30 07:37:01 +02:00
|
|
|
arg->filename_ = argv[i + 1];
|
|
|
|
arg->params_ = argv[i + 2];
|
|
|
|
++feature_arg_index;
|
|
|
|
i += 3;
|
2012-11-01 23:34:46 +01:00
|
|
|
} else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
|
|
|
config->action_type_ = ACTION_SET;
|
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
}
|
2017-12-01 09:21:13 +01:00
|
|
|
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
|
|
|
config->type_ = FEATURE_ANMF;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
arg->subtype_ =
|
|
|
|
!strcmp(argv[i], "-loop") ? SUBTYPE_LOOP : SUBTYPE_BGCOLOR;
|
2011-09-30 07:37:01 +02:00
|
|
|
arg->params_ = argv[i + 1];
|
|
|
|
++feature_arg_index;
|
|
|
|
i += 2;
|
|
|
|
} else if (!strcmp(argv[i], "-o")) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
config->output_ = wargv[i + 1];
|
2011-09-30 07:37:01 +02:00
|
|
|
i += 2;
|
|
|
|
} else if (!strcmp(argv[i], "-info")) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_EXACTLY(2, ErrParse);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (config->action_type_ != NIL_ACTION) {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
|
|
|
} else {
|
|
|
|
config->action_type_ = ACTION_INFO;
|
2017-12-01 09:21:13 +01:00
|
|
|
config->arg_count_ = 0;
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
config->input_ = wargv[i + 1];
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
i += 2;
|
|
|
|
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
|
|
|
|
PrintHelp();
|
|
|
|
DeleteConfig(config);
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
2012-01-24 21:46:46 +01:00
|
|
|
exit(0);
|
2013-02-26 23:22:06 +01:00
|
|
|
} else if (!strcmp(argv[i], "-version")) {
|
|
|
|
const int version = WebPGetMuxVersion();
|
|
|
|
printf("%d.%d.%d\n",
|
|
|
|
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
|
|
|
DeleteConfig(config);
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
2013-02-26 23:22:06 +01:00
|
|
|
exit(0);
|
2013-12-18 05:50:46 +01:00
|
|
|
} else if (!strcmp(argv[i], "--")) {
|
|
|
|
if (i < argc - 1) {
|
|
|
|
++i;
|
|
|
|
if (config->input_ == NULL) {
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
config->input_ = wargv[i];
|
2013-12-18 05:50:46 +01:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
|
|
|
argv[i], ErrParse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO2("ERROR: Unknown option: '%s'.\n", argv[i], ErrParse);
|
|
|
|
}
|
|
|
|
} else { // One of the feature types or input.
|
|
|
|
if (ACTION_IS_NIL) {
|
|
|
|
ERROR_GOTO1("ERROR: Action must be specified before other arguments.\n",
|
|
|
|
ErrParse);
|
|
|
|
}
|
2012-11-01 00:30:41 +01:00
|
|
|
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
|
|
|
!strcmp(argv[i], "xmp")) {
|
2011-09-30 07:37:01 +02:00
|
|
|
if (FEATURETYPE_IS_NIL) {
|
2017-12-01 09:21:13 +01:00
|
|
|
config->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
2012-11-01 00:30:41 +01:00
|
|
|
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
|
|
|
}
|
|
|
|
if (config->action_type_ == ACTION_SET) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
arg->filename_ = wargv[i + 1];
|
2011-09-30 07:37:01 +02:00
|
|
|
++feature_arg_index;
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
++i;
|
|
|
|
}
|
2013-03-15 22:46:12 +01:00
|
|
|
} else if (!strcmp(argv[i], "frame") &&
|
2015-01-09 05:03:51 +01:00
|
|
|
(config->action_type_ == ACTION_GET)) {
|
2018-10-03 21:39:38 +02:00
|
|
|
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
2017-12-01 09:21:13 +01:00
|
|
|
config->type_ = FEATURE_ANMF;
|
2011-09-30 07:37:01 +02:00
|
|
|
arg->params_ = argv[i + 1];
|
|
|
|
++feature_arg_index;
|
|
|
|
i += 2;
|
2011-11-04 23:20:08 +01:00
|
|
|
} else { // Assume input file.
|
2011-09-30 07:37:01 +02:00
|
|
|
if (config->input_ == NULL) {
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
config->input_ = wargv[i];
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
|
|
|
argv[i], ErrParse);
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ErrParse:
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2011-11-04 23:20:08 +01:00
|
|
|
// Additional checks after config is filled.
|
2017-12-01 09:21:13 +01:00
|
|
|
static int ValidateConfig(Config* const config) {
|
2011-09-30 07:37:01 +02:00
|
|
|
int ok = 1;
|
|
|
|
|
|
|
|
// Action.
|
|
|
|
if (ACTION_IS_NIL) {
|
|
|
|
ERROR_GOTO1("ERROR: No action specified.\n", ErrValidate2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Feature type.
|
|
|
|
if (FEATURETYPE_IS_NIL && config->action_type_ != ACTION_INFO) {
|
|
|
|
ERROR_GOTO1("ERROR: No feature specified.\n", ErrValidate2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Input file.
|
|
|
|
if (config->input_ == NULL) {
|
|
|
|
if (config->action_type_ != ACTION_SET) {
|
|
|
|
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
2017-12-01 09:21:13 +01:00
|
|
|
} else if (config->type_ != FEATURE_ANMF) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Output file.
|
|
|
|
if (config->output_ == NULL && config->action_type_ != ACTION_INFO) {
|
|
|
|
ERROR_GOTO1("ERROR: No output file specified.\n", ErrValidate2);
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrValidate2:
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create config object from command-line arguments.
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
static int InitializeConfig(int argc, const char* argv[], Config* const config,
|
|
|
|
const W_CHAR** const unicode_argv) {
|
2011-09-30 07:37:01 +02:00
|
|
|
int num_feature_args = 0;
|
2018-02-08 08:09:14 +01:00
|
|
|
int ok;
|
|
|
|
|
|
|
|
memset(config, 0, sizeof(*config));
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2018-02-08 08:09:14 +01:00
|
|
|
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
|
2017-12-01 09:21:13 +01:00
|
|
|
if (!ok) return 0;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
// Validate command-line arguments.
|
2018-02-08 08:09:14 +01:00
|
|
|
if (!ValidateCommandLine(&config->cmd_args_, &num_feature_args)) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
|
|
|
}
|
|
|
|
|
2017-12-01 09:21:13 +01:00
|
|
|
config->arg_count_ = num_feature_args;
|
|
|
|
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
|
|
|
|
if (config->args_ == NULL) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse command-line.
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Err1:
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef ACTION_IS_NIL
|
|
|
|
#undef FEATURETYPE_IS_NIL
|
2018-10-03 21:39:38 +02:00
|
|
|
#undef CHECK_NUM_ARGS_AT_LEAST
|
|
|
|
#undef CHECK_NUM_ARGS_AT_MOST
|
|
|
|
#undef CHECK_NUM_ARGS_EXACTLY
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Processing.
|
|
|
|
|
2017-12-01 09:21:13 +01:00
|
|
|
static int GetFrame(const WebPMux* mux, const Config* config) {
|
2011-09-30 07:37:01 +02:00
|
|
|
WebPMuxError err = WEBP_MUX_OK;
|
|
|
|
WebPMux* mux_single = NULL;
|
2015-09-26 03:42:31 +02:00
|
|
|
int num = 0;
|
2011-09-30 07:37:01 +02:00
|
|
|
int ok = 1;
|
2014-09-11 08:35:48 +02:00
|
|
|
int parse_error = 0;
|
2016-09-02 14:26:37 +02:00
|
|
|
const WebPChunkId id = WEBP_CHUNK_ANMF;
|
2012-08-23 11:48:51 +02:00
|
|
|
WebPMuxFrameInfo info;
|
2012-10-30 22:54:46 +01:00
|
|
|
WebPDataInit(&info.bitstream);
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2017-12-01 09:21:13 +01:00
|
|
|
num = ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (num < 0) {
|
2012-11-01 01:49:15 +01:00
|
|
|
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2014-09-11 08:35:48 +02:00
|
|
|
if (parse_error) goto ErrGet;
|
2011-09-30 07:37:01 +02:00
|
|
|
|
2012-08-23 12:58:36 +02:00
|
|
|
err = WebPMuxGetFrame(mux, num, &info);
|
|
|
|
if (err == WEBP_MUX_OK && info.id != id) err = WEBP_MUX_NOT_FOUND;
|
|
|
|
if (err != WEBP_MUX_OK) {
|
2015-09-26 03:42:31 +02:00
|
|
|
ERROR_GOTO3("ERROR (%s): Could not get frame %d.\n",
|
2012-08-23 12:58:36 +02:00
|
|
|
ErrorString(err), num, ErrGet);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mux_single = WebPMuxNew();
|
|
|
|
if (mux_single == NULL) {
|
|
|
|
err = WEBP_MUX_MEMORY_ERROR;
|
2012-06-27 13:25:01 +02:00
|
|
|
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
|
|
|
ErrorString(err), ErrGet);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-10-30 22:54:46 +01:00
|
|
|
err = WebPMuxSetImage(mux_single, &info.bitstream, 1);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (err != WEBP_MUX_OK) {
|
2012-06-27 13:25:01 +02:00
|
|
|
ERROR_GOTO2("ERROR (%s): Could not create single image mux object.\n",
|
|
|
|
ErrorString(err), ErrGet);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-08-23 12:58:36 +02:00
|
|
|
|
2011-09-30 07:37:01 +02:00
|
|
|
ok = WriteWebP(mux_single, config->output_);
|
|
|
|
|
|
|
|
ErrGet:
|
2012-10-30 22:54:46 +01:00
|
|
|
WebPDataClear(&info.bitstream);
|
2011-09-30 07:37:01 +02:00
|
|
|
WebPMuxDelete(mux_single);
|
2014-09-12 08:36:12 +02:00
|
|
|
return ok && !parse_error;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read and process config.
|
2017-12-01 09:21:13 +01:00
|
|
|
static int Process(const Config* config) {
|
2011-09-30 07:37:01 +02:00
|
|
|
WebPMux* mux = NULL;
|
2012-11-01 00:30:41 +01:00
|
|
|
WebPData chunk;
|
2011-09-30 07:37:01 +02:00
|
|
|
WebPMuxError err = WEBP_MUX_OK;
|
|
|
|
int ok = 1;
|
|
|
|
|
2011-11-04 23:20:08 +01:00
|
|
|
switch (config->action_type_) {
|
2013-01-21 17:20:14 +01:00
|
|
|
case ACTION_GET: {
|
2012-05-12 01:00:57 +02:00
|
|
|
ok = CreateMux(config->input_, &mux);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (!ok) goto Err2;
|
2017-12-01 09:21:13 +01:00
|
|
|
switch (config->type_) {
|
2012-11-01 01:49:15 +01:00
|
|
|
case FEATURE_ANMF:
|
2016-09-02 14:26:37 +02:00
|
|
|
ok = GetFrame(mux, config);
|
2011-09-30 07:37:01 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FEATURE_ICCP:
|
2012-11-01 00:30:41 +01:00
|
|
|
case FEATURE_EXIF:
|
|
|
|
case FEATURE_XMP:
|
2017-12-01 09:21:13 +01:00
|
|
|
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (err != WEBP_MUX_OK) {
|
2012-11-01 00:30:41 +01:00
|
|
|
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
2017-12-01 09:21:13 +01:00
|
|
|
ErrorString(err), kDescriptions[config->type_], Err2);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-11-01 00:30:41 +01:00
|
|
|
ok = WriteData(config->output_, &chunk);
|
2011-09-30 07:37:01 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ERROR_GOTO1("ERROR: Invalid feature for action 'get'.\n", Err2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
|
|
|
case ACTION_SET: {
|
2017-12-01 09:21:13 +01:00
|
|
|
switch (config->type_) {
|
2012-11-01 23:34:46 +01:00
|
|
|
case FEATURE_ANMF: {
|
2013-01-21 17:20:14 +01:00
|
|
|
int i;
|
2012-11-01 23:34:46 +01:00
|
|
|
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
2011-09-30 07:37:01 +02:00
|
|
|
mux = WebPMuxNew();
|
|
|
|
if (mux == NULL) {
|
2012-06-27 13:25:01 +02:00
|
|
|
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
|
|
|
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2017-12-01 09:21:13 +01:00
|
|
|
for (i = 0; i < config->arg_count_; ++i) {
|
|
|
|
switch (config->args_[i].subtype_) {
|
2012-11-01 23:34:46 +01:00
|
|
|
case SUBTYPE_BGCOLOR: {
|
|
|
|
uint32_t bgcolor;
|
2017-12-01 09:21:13 +01:00
|
|
|
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
|
2012-11-01 23:34:46 +01:00
|
|
|
if (!ok) {
|
|
|
|
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
|
|
|
Err2);
|
|
|
|
}
|
|
|
|
params.bgcolor = bgcolor;
|
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
case SUBTYPE_LOOP: {
|
2014-09-11 08:35:48 +02:00
|
|
|
int parse_error = 0;
|
|
|
|
const int loop_count =
|
2017-12-01 09:21:13 +01:00
|
|
|
ExUtilGetInt(config->args_[i].params_, 10, &parse_error);
|
2014-09-12 00:26:11 +02:00
|
|
|
if (loop_count < 0 || loop_count > 65535) {
|
2012-11-01 23:34:46 +01:00
|
|
|
// Note: This is only a 'necessary' condition for loop_count
|
|
|
|
// to be valid. The 'sufficient' conditioned in checked in
|
|
|
|
// WebPMuxSetAnimationParams() method called later.
|
|
|
|
ERROR_GOTO1("ERROR: Loop count must be in the range 0 to "
|
|
|
|
"65535.\n", Err2);
|
|
|
|
}
|
2014-09-12 08:36:12 +02:00
|
|
|
ok = !parse_error;
|
|
|
|
if (!ok) goto Err2;
|
2014-09-12 08:53:05 +02:00
|
|
|
params.loop_count = loop_count;
|
2012-11-01 23:34:46 +01:00
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
case SUBTYPE_ANMF: {
|
|
|
|
WebPMuxFrameInfo frame;
|
|
|
|
frame.id = WEBP_CHUNK_ANMF;
|
2018-02-08 08:09:14 +01:00
|
|
|
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
|
|
|
|
&frame.bitstream);
|
2012-11-01 23:34:46 +01:00
|
|
|
if (!ok) goto Err2;
|
2017-12-01 09:21:13 +01:00
|
|
|
ok = ParseFrameArgs(config->args_[i].params_, &frame);
|
2012-11-01 23:34:46 +01:00
|
|
|
if (!ok) {
|
|
|
|
WebPDataClear(&frame.bitstream);
|
|
|
|
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
|
|
|
Err2);
|
|
|
|
}
|
|
|
|
err = WebPMuxPushFrame(mux, &frame, 1);
|
2012-10-30 22:54:46 +01:00
|
|
|
WebPDataClear(&frame.bitstream);
|
2012-11-01 23:34:46 +01:00
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO3("ERROR (%s): Could not add a frame at index %d."
|
2013-01-21 17:20:14 +01:00
|
|
|
"\n", ErrorString(err), i, Err2);
|
2012-11-01 23:34:46 +01:00
|
|
|
}
|
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
default: {
|
|
|
|
ERROR_GOTO1("ERROR: Invalid subtype for 'frame'", Err2);
|
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-11-01 23:34:46 +01:00
|
|
|
err = WebPMuxSetAnimationParams(mux, ¶ms);
|
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
|
|
|
|
ErrorString(err), Err2);
|
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
break;
|
2012-11-01 23:34:46 +01:00
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
|
|
|
|
case FEATURE_ICCP:
|
2012-11-01 00:30:41 +01:00
|
|
|
case FEATURE_EXIF:
|
2013-01-21 17:20:14 +01:00
|
|
|
case FEATURE_XMP: {
|
2012-05-12 01:00:57 +02:00
|
|
|
ok = CreateMux(config->input_, &mux);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (!ok) goto Err2;
|
2018-02-08 08:09:14 +01:00
|
|
|
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (!ok) goto Err2;
|
2017-12-01 09:21:13 +01:00
|
|
|
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
2012-11-01 00:30:41 +01:00
|
|
|
free((void*)chunk.bytes);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (err != WEBP_MUX_OK) {
|
2012-11-01 00:30:41 +01:00
|
|
|
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
2017-12-01 09:21:13 +01:00
|
|
|
ErrorString(err), kDescriptions[config->type_], Err2);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
|
|
|
default: {
|
2011-09-30 07:37:01 +02:00
|
|
|
ERROR_GOTO1("ERROR: Invalid feature for action 'set'.\n", Err2);
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
ok = WriteWebP(mux, config->output_);
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
case ACTION_DURATION: {
|
|
|
|
int num_frames;
|
|
|
|
ok = CreateMux(config->input_, &mux);
|
|
|
|
if (!ok) goto Err2;
|
|
|
|
err = WebPMuxNumChunks(mux, WEBP_CHUNK_ANMF, &num_frames);
|
|
|
|
ok = (err == WEBP_MUX_OK);
|
|
|
|
if (!ok) {
|
|
|
|
ERROR_GOTO1("ERROR: can not parse the number of frames.\n", Err2);
|
|
|
|
}
|
|
|
|
if (num_frames == 0) {
|
|
|
|
fprintf(stderr, "Doesn't look like the source is animated. "
|
|
|
|
"Skipping duration setting.\n");
|
|
|
|
ok = WriteWebP(mux, config->output_);
|
|
|
|
if (!ok) goto Err2;
|
|
|
|
} else {
|
|
|
|
int i;
|
|
|
|
int* durations = NULL;
|
|
|
|
WebPMux* new_mux = DuplicateMuxHeader(mux);
|
|
|
|
if (new_mux == NULL) goto Err2;
|
2019-10-15 23:16:51 +02:00
|
|
|
durations = (int*)WebPMalloc((size_t)num_frames * sizeof(*durations));
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
if (durations == NULL) goto Err2;
|
|
|
|
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
|
|
|
|
|
|
|
// Parse intervals to process.
|
2017-12-01 09:21:13 +01:00
|
|
|
for (i = 0; i < config->arg_count_; ++i) {
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
int k;
|
|
|
|
int args[3];
|
|
|
|
int duration, start, end;
|
2017-12-01 09:21:13 +01:00
|
|
|
const int nb_args = ExUtilGetInts(config->args_[i].params_,
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
10, 3, args);
|
|
|
|
ok = (nb_args >= 1);
|
|
|
|
if (!ok) goto Err3;
|
|
|
|
duration = args[0];
|
|
|
|
if (duration < 0) {
|
|
|
|
ERROR_GOTO1("ERROR: duration must be strictly positive.\n", Err3);
|
|
|
|
}
|
|
|
|
|
2016-11-10 08:26:01 +01:00
|
|
|
if (nb_args == 1) { // only duration is present -> use full interval
|
|
|
|
start = 1;
|
|
|
|
end = num_frames;
|
|
|
|
} else {
|
|
|
|
start = args[1];
|
|
|
|
if (start <= 0) {
|
|
|
|
start = 1;
|
|
|
|
} else if (start > num_frames) {
|
|
|
|
start = num_frames;
|
|
|
|
}
|
|
|
|
end = (nb_args >= 3) ? args[2] : start;
|
|
|
|
if (end == 0 || end > num_frames) end = num_frames;
|
|
|
|
}
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
|
|
|
|
for (k = start; k <= end; ++k) {
|
|
|
|
assert(k >= 1 && k <= num_frames);
|
|
|
|
durations[k - 1] = duration;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply non-negative durations to their destination frames.
|
|
|
|
for (i = 1; i <= num_frames; ++i) {
|
|
|
|
WebPMuxFrameInfo frame;
|
|
|
|
err = WebPMuxGetFrame(mux, i, &frame);
|
|
|
|
if (err != WEBP_MUX_OK || frame.id != WEBP_CHUNK_ANMF) {
|
|
|
|
ERROR_GOTO2("ERROR: can not retrieve frame #%d.\n", i, Err3);
|
|
|
|
}
|
|
|
|
if (durations[i - 1] >= 0) frame.duration = durations[i - 1];
|
|
|
|
err = WebPMuxPushFrame(new_mux, &frame, 1);
|
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO2("ERROR: error push frame data #%d\n", i, Err3);
|
|
|
|
}
|
|
|
|
WebPDataClear(&frame.bitstream);
|
|
|
|
}
|
|
|
|
WebPMuxDelete(mux);
|
|
|
|
ok = WriteWebP(new_mux, config->output_);
|
|
|
|
mux = new_mux; // transfer for the WebPMuxDelete() call
|
|
|
|
new_mux = NULL;
|
|
|
|
|
2016-11-10 08:26:01 +01:00
|
|
|
Err3:
|
2019-10-15 23:16:51 +02:00
|
|
|
WebPFree(durations);
|
add a "-duration duration,start,end" option to webpmux
this will force a constant duration for an interval of frames
in an animation.
Notes:
a) '-duration [...]' can be repeated as many times as needed.
b) intervals are taken into account in option order. If they overlap, values will be overwritten.
c) 'start' and 'end' can be omitted, but not the duration value.
d) 'end' can be equal to '0', in which case it means 'last frame'
e) single-image files are untouched (ie. not turned into an animation file).
Some example usage:
webpmux -duration 150 in.webp -o out.webp
webpmux -duration 33,10,0 in.webp -o out.webp
webpmux -duration 200,2 -duration 150,0,50 in.webp -o out.webp
Change-Id: I9b595dafa77f9221bacd080be7858b1457f54636
2016-10-21 15:14:45 +02:00
|
|
|
WebPMuxDelete(new_mux);
|
|
|
|
if (!ok) goto Err2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-01-21 17:20:14 +01:00
|
|
|
case ACTION_STRIP: {
|
2012-05-12 01:00:57 +02:00
|
|
|
ok = CreateMux(config->input_, &mux);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (!ok) goto Err2;
|
2017-12-01 09:21:13 +01:00
|
|
|
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
|
|
|
|
config->type_ == FEATURE_XMP) {
|
|
|
|
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
|
2012-11-01 00:30:41 +01:00
|
|
|
if (err != WEBP_MUX_OK) {
|
|
|
|
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
2017-12-01 09:21:13 +01:00
|
|
|
ErrorString(err), kDescriptions[config->type_], Err2);
|
2012-11-01 00:30:41 +01:00
|
|
|
}
|
|
|
|
} else {
|
2014-09-12 08:53:05 +02:00
|
|
|
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
|
|
|
break;
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
ok = WriteWebP(mux, config->output_);
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
|
|
|
case ACTION_INFO: {
|
2012-05-12 01:00:57 +02:00
|
|
|
ok = CreateMux(config->input_, &mux);
|
2011-09-30 07:37:01 +02:00
|
|
|
if (!ok) goto Err2;
|
|
|
|
ok = (DisplayInfo(mux) == WEBP_MUX_OK);
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
|
|
|
default: {
|
2011-09-30 07:37:01 +02:00
|
|
|
assert(0); // Invalid action.
|
|
|
|
break;
|
2013-01-21 17:20:14 +01:00
|
|
|
}
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Err2:
|
|
|
|
WebPMuxDelete(mux);
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Main.
|
|
|
|
|
|
|
|
int main(int argc, const char* argv[]) {
|
2017-12-01 09:21:13 +01:00
|
|
|
Config config;
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
int ok;
|
|
|
|
|
|
|
|
INIT_WARGV(argc, argv);
|
|
|
|
|
|
|
|
ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
|
2011-09-30 07:37:01 +02:00
|
|
|
if (ok) {
|
2014-09-12 09:03:28 +02:00
|
|
|
ok = Process(&config);
|
2011-09-30 07:37:01 +02:00
|
|
|
} else {
|
|
|
|
PrintHelp();
|
|
|
|
}
|
2014-09-12 09:03:28 +02:00
|
|
|
DeleteConfig(&config);
|
libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.
Impact:
- All fopen () and SHCreateStreamOnFile(),
- All fprintf() printing file paths,
- All strcmp() used with "-",
- File path parsing,
- Gif reading.
Concerned executables from examples/ and extras/:
anim_diff, anim_dump, vwebp, vwebp_sdl,
cwebp, dwebp, gif2webp, img2webp,
webpmux, webpinfo, webp_quality, get_disto
When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."
BUG=webp:398
Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-16 11:03:18 +02:00
|
|
|
FREE_WARGV_AND_RETURN(!ok);
|
2011-09-30 07:37:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|