Merge "libwebp: Unicode command tools on Windows"

This commit is contained in:
Yannis Guyon 2018-10-17 11:55:49 +00:00 committed by Gerrit Code Review
commit dc1a9518bc
23 changed files with 485 additions and 214 deletions

View File

@ -18,6 +18,11 @@ option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
OFF)
# Option needed for handling Unicode file names on Windows.
if(WIN32)
option(WEBP_UNICODE "Build Unicode executables." ON)
endif()
if(WEBP_BUILD_WEBP_JS)
set(WEBP_ENABLE_SIMD OFF)
endif()
@ -41,6 +46,11 @@ if(WEBP_ENABLE_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
endif()
if(WEBP_UNICODE)
# Windows recommends setting both UNICODE and _UNICODE.
add_definitions(-DUNICODE -D_UNICODE)
endif()
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\$\{prefix\}")
set(libdir "\$\{prefix\}/lib")

View File

@ -129,12 +129,16 @@ LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
CFGSET = TRUE
!ENDIF
!IF "$(UNICODE)" == "1"
CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
!ENDIF
#######################
# Usage
#
!IF "$(CFGSET)" == "FALSE"
!MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [<target>]
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>]
!MESSAGE
!MESSAGE where <config> is one of:
!MESSAGE - release-static - release static library
@ -483,15 +487,18 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
{src\utils}.c{$(DIROBJ)\utils}.obj::
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
LNKLIBS = ole32.lib windowscodecs.lib shlwapi.lib
!IF "$(UNICODE)" == "1"
LNKLIBS = $(LNKLIBS) Shell32.lib
!ENDIF
{$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe:
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
ole32.lib windowscodecs.lib shlwapi.lib
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
$(MT) -manifest $@.manifest -outputresource:$@;1
del $@.manifest
{$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe:
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
ole32.lib windowscodecs.lib shlwapi.lib
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
$(MT) -manifest $@.manifest -outputresource:$@;1
del $@.manifest

2
README
View File

@ -136,6 +136,8 @@ cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
or through your favorite interface (like ccmake or cmake-qt-gui).
Use option -DWEBP_UNICODE=ON for Unicode support on Windows (with chcp 65001).
Finally, once installed, you can also use WebP in your CMake project by doing:
find_package(WebP)

View File

@ -21,6 +21,7 @@
#include "./anim_util.h"
#include "./example_util.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -218,12 +219,14 @@ int main(int argc, const char* argv[]) {
const char* files[2] = { NULL, NULL };
AnimatedImage images[2];
INIT_WARGV(argc, argv);
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-dump_frames")) {
if (c < argc - 1) {
dump_frames = 1;
dump_folder = argv[++c];
dump_folder = (const char*)GET_WARGV(argv, ++c);
} else {
parse_error = 1;
}
@ -243,7 +246,7 @@ int main(int argc, const char* argv[]) {
}
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-version")) {
int dec_version, demux_version;
GetAnimatedImageVersions(&dec_version, &demux_version);
@ -252,13 +255,13 @@ int main(int argc, const char* argv[]) {
(dec_version >> 0) & 0xff,
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
(demux_version >> 0) & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else {
if (!got_input1) {
files[0] = argv[c];
files[0] = (const char*)GET_WARGV(argv, c);
got_input1 = 1;
} else if (!got_input2) {
files[1] = argv[c];
files[1] = (const char*)GET_WARGV(argv, c);
got_input2 = 1;
} else {
parse_error = 1;
@ -266,29 +269,30 @@ int main(int argc, const char* argv[]) {
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (argc < 3) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (!got_input2) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (dump_frames) {
printf("Dumping decoded frames in: %s\n", dump_folder);
WPRINTF("Dumping decoded frames in: %s\n", (const W_CHAR*)dump_folder);
}
memset(images, 0, sizeof(images));
for (i = 0; i < 2; ++i) {
printf("Decoding file: %s\n", files[i]);
WPRINTF("Decoding file: %s\n", (const W_CHAR*)files[i]);
if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) {
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", files[i]);
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n",
(const W_CHAR*)files[i]);
return_code = -2;
goto End;
} else {
@ -298,14 +302,16 @@ int main(int argc, const char* argv[]) {
if (!CompareAnimatedImagePair(&images[0], &images[1],
premultiply, min_psnr)) {
fprintf(stderr, "\nFiles %s and %s differ.\n", files[0], files[1]);
WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0],
(const W_CHAR*)files[1]);
return_code = -3;
} else {
printf("\nFiles %s and %s are identical.\n", files[0], files[1]);
WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0],
(const W_CHAR*)files[1]);
return_code = 0;
}
End:
ClearAnimatedImage(&images[0]);
ClearAnimatedImage(&images[1]);
return return_code;
FREE_WARGV_AND_RETURN(return_code);
}

View File

@ -17,6 +17,7 @@
#include "./anim_util.h"
#include "webp/decode.h"
#include "../imageio/image_enc.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -36,15 +37,17 @@ static void Help(void) {
int main(int argc, const char* argv[]) {
int error = 0;
const char* dump_folder = ".";
const char* prefix = "dump_";
const char* suffix = "png";
const W_CHAR* dump_folder = TO_W_CHAR(".");
const W_CHAR* prefix = TO_W_CHAR("dump_");
const W_CHAR* suffix = TO_W_CHAR("png");
WebPOutputFileFormat format = PNG;
int c;
INIT_WARGV(argc, argv);
if (argc < 2) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
for (c = 1; !error && c < argc; ++c) {
@ -54,23 +57,23 @@ int main(int argc, const char* argv[]) {
error = 1;
break;
}
dump_folder = argv[++c];
dump_folder = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-prefix")) {
if (c + 1 == argc) {
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
error = 1;
break;
}
prefix = argv[++c];
prefix = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-tiff")) {
format = TIFF;
suffix = "tiff";
suffix = TO_W_CHAR("tiff");
} else if (!strcmp(argv[c], "-pam")) {
format = PAM;
suffix = "pam";
suffix = TO_W_CHAR("pam");
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-version")) {
int dec_version, demux_version;
GetAnimatedImageVersions(&dec_version, &demux_version);
@ -79,21 +82,21 @@ int main(int argc, const char* argv[]) {
(dec_version >> 0) & 0xff,
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
(demux_version >> 0) & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else {
uint32_t i;
AnimatedImage image;
const char* const file = argv[c];
const W_CHAR* const file = GET_WARGV(argv, c);
memset(&image, 0, sizeof(image));
printf("Decoding file: %s as %s/%sxxxx.%s\n",
file, dump_folder, prefix, suffix);
if (!ReadAnimatedImage(file, &image, 0, NULL)) {
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", file);
WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n",
file, dump_folder, prefix, suffix);
if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) {
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file);
error = 1;
break;
}
for (i = 0; !error && i < image.num_frames; ++i) {
char out_file[1024];
W_CHAR out_file[1024];
WebPDecBuffer buffer;
WebPInitDecBuffer(&buffer);
buffer.colorspace = MODE_RGBA;
@ -103,10 +106,10 @@ int main(int argc, const char* argv[]) {
buffer.u.RGBA.rgba = image.frames[i].rgba;
buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
snprintf(out_file, sizeof(out_file), "%s/%s%.4d.%s",
dump_folder, prefix, i, suffix);
if (!WebPSaveImage(&buffer, format, out_file)) {
fprintf(stderr, "Error while saving image '%s'\n", out_file);
WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s",
dump_folder, prefix, i, suffix);
if (!WebPSaveImage(&buffer, format, (const char*)out_file)) {
WFPRINTF(stderr, "Error while saving image '%s'\n", out_file);
error = 1;
}
WebPFreeDecBuffer(&buffer);
@ -114,5 +117,5 @@ int main(int argc, const char* argv[]) {
ClearAnimatedImage(&image);
}
}
return error ? 1 : 0;
FREE_WARGV_AND_RETURN(error ? 1 : 0);
}

View File

@ -24,6 +24,8 @@
#include "webp/demux.h"
#include "../imageio/imageio_util.h"
#include "./gifdec.h"
#include "./unicode.h"
#include "./unicode_gif.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -152,42 +154,42 @@ static int DumpFrame(const char filename[], const char dump_folder[],
int ok = 0;
size_t max_len;
int y;
const char* base_name = NULL;
char* file_name = NULL;
const W_CHAR* base_name = NULL;
W_CHAR* file_name = NULL;
FILE* f = NULL;
const char* row;
if (dump_folder == NULL) dump_folder = ".";
if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR(".");
base_name = strrchr(filename, '/');
base_name = (base_name == NULL) ? filename : base_name + 1;
max_len = strlen(dump_folder) + 1 + strlen(base_name)
base_name = WSTRRCHR(filename, '/');
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
+ strlen("_frame_") + strlen(".pam") + 8;
file_name = (char*)malloc(max_len * sizeof(*file_name));
file_name = (W_CHAR*)malloc(max_len * sizeof(*file_name));
if (file_name == NULL) goto End;
if (snprintf(file_name, max_len, "%s/%s_frame_%d.pam",
dump_folder, base_name, frame_num) < 0) {
if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
(const W_CHAR*)dump_folder, base_name, frame_num) < 0) {
fprintf(stderr, "Error while generating file name\n");
goto End;
}
f = fopen(file_name, "wb");
f = WFOPEN(file_name, "wb");
if (f == NULL) {
fprintf(stderr, "Error opening file for writing: %s\n", file_name);
WFPRINTF(stderr, "Error opening file for writing: %s\n", file_name);
ok = 0;
goto End;
}
if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
"DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
canvas_width, canvas_height) < 0) {
fprintf(stderr, "Write error for file %s\n", file_name);
WFPRINTF(stderr, "Write error for file %s\n", file_name);
goto End;
}
row = (const char*)rgba;
for (y = 0; y < canvas_height; ++y) {
if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) {
fprintf(stderr, "Error writing to file: %s\n", file_name);
WFPRINTF(stderr, "Error writing to file: %s\n", file_name);
goto End;
}
row += canvas_width * kNumChannels;
@ -223,7 +225,7 @@ static int ReadAnimatedWebP(const char filename[],
dec = WebPAnimDecoderNew(webp_data, NULL);
if (dec == NULL) {
fprintf(stderr, "Error parsing image: %s\n", filename);
WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename);
goto End;
}
@ -511,15 +513,15 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
int gif_error;
GifFileType* gif;
gif = DGifOpenFileName(filename, NULL);
gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL);
if (gif == NULL) {
fprintf(stderr, "Could not read file: %s.\n", filename);
WFPRINTF(stderr, "Could not read file: %s.\n", (const W_CHAR*)filename);
return 0;
}
gif_error = DGifSlurp(gif);
if (gif_error != GIF_OK) {
fprintf(stderr, "Could not parse image: %s.\n", filename);
WFPRINTF(stderr, "Could not parse image: %s.\n", (const W_CHAR*)filename);
GIFDisplayError(gif, gif_error);
DGifCloseFile(gif, NULL);
return 0;
@ -705,7 +707,7 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
memset(image, 0, sizeof(*image));
if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) {
fprintf(stderr, "Error reading file: %s\n", filename);
WFPRINTF(stderr, "Error reading file: %s\n", (const W_CHAR*)filename);
return 0;
}
@ -715,9 +717,9 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
} else if (IsGIF(&webp_data)) {
ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
} else {
fprintf(stderr,
"Unknown file type: %s. Supported file types are WebP and GIF\n",
filename);
WFPRINTF(stderr,
"Unknown file type: %s. Supported file types are WebP and GIF\n",
(const W_CHAR*)filename);
ok = 0;
}
if (!ok) ClearAnimatedImage(image);

View File

@ -24,6 +24,7 @@
#include "../imageio/image_dec.h"
#include "../imageio/imageio_util.h"
#include "./stopwatch.h"
#include "./unicode.h"
#include "webp/encode.h"
#ifndef WEBP_DLL
@ -88,7 +89,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
}
}
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
return ok;
@ -114,7 +116,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
}
End:
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
return ok;
@ -185,7 +188,7 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
if (short_output) {
fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
} else {
fprintf(stderr, "File: %s\n", file_name);
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
8.f * stats->coded_size / pic->width / pic->height);
@ -204,7 +207,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
const int num_i16 = stats->block_count[1];
const int num_skip = stats->block_count[2];
const int total = num_i4 + num_i16;
fprintf(stderr, "File: %s\n", file_name);
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
fprintf(stderr, "Dimension: %d x %d%s\n",
pic->width, pic->height,
stats->alpha_data_size ? " (with alpha)" : "");
@ -309,7 +312,7 @@ static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) {
const int alpha_height =
WebPPictureHasTransparency(picture) ? picture->height : 0;
const int height = picture->height + uv_height + alpha_height;
FILE* const f = fopen(PGM_name, "wb");
FILE* const f = WFOPEN(PGM_name, "wb");
if (f == NULL) return 0;
fprintf(f, "P5\n%d %d\n255\n", stride, height);
for (y = 0; y < picture->height; ++y) {
@ -663,32 +666,34 @@ int main(int argc, const char *argv[]) {
Metadata metadata;
Stopwatch stop_watch;
INIT_WARGV(argc, argv);
MetadataInit(&metadata);
WebPMemoryWriterInit(&memory_writer);
if (!WebPPictureInit(&picture) ||
!WebPPictureInit(&original_picture) ||
!WebPConfigInit(&config)) {
fprintf(stderr, "Error! Version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (argc == 1) {
HelpShort();
return 0;
FREE_WARGV_AND_RETURN(0);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
HelpShort();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
HelpLong();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
out_file = (const char*)GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-d") && c < argc - 1) {
dump_file = argv[++c];
dump_file = (const char*)GET_WARGV(argv, ++c);
config.show_compressed = 1;
} else if (!strcmp(argv[c], "-print_psnr")) {
config.show_compressed = 1;
@ -816,7 +821,7 @@ int main(int argc, const char *argv[]) {
const int version = WebPGetEncoderVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-progress")) {
show_progress = 1;
} else if (!strcmp(argv[c], "-quiet")) {
@ -878,8 +883,7 @@ int main(int argc, const char *argv[]) {
if (i == kNumTokens) {
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
(int)(token - start), start);
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
start = token + 1;
}
@ -893,19 +897,19 @@ int main(int argc, const char *argv[]) {
} else if (!strcmp(argv[c], "-v")) {
verbose = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (in_file == NULL) {
@ -955,7 +959,8 @@ int main(int argc, const char *argv[]) {
}
if (!ReadPicture(in_file, &picture, keep_alpha,
(keep_metadata == 0) ? NULL : &metadata)) {
fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file);
WFPRINTF(stderr, "Error! Cannot read input picture file '%s'\n",
(const W_CHAR*)in_file);
goto Error;
}
picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
@ -971,14 +976,15 @@ int main(int argc, const char *argv[]) {
// Open the output
if (out_file != NULL) {
const int use_stdout = !strcmp(out_file, "-");
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
const int use_stdout = !WSTRCMP(out_file, "-");
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(out_file, "wb");
if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file);
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
(const W_CHAR*)out_file);
goto Error;
} else {
if (!short_output && !quiet) {
fprintf(stderr, "Saving file '%s'\n", out_file);
WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)out_file);
}
}
if (keep_metadata == 0) {
@ -1093,7 +1099,8 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Warning: can't dump file (-d option) "
"in lossless mode.\n");
} else if (!DumpPicture(&picture, dump_file)) {
fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file);
WFPRINTF(stderr, "Warning, couldn't dump picture %s\n",
(const W_CHAR*)dump_file);
}
}
@ -1169,7 +1176,7 @@ int main(int argc, const char *argv[]) {
fclose(out);
}
return return_value;
FREE_WARGV_AND_RETURN(return_value);
}
//------------------------------------------------------------------------------

View File

@ -24,6 +24,7 @@
#include "../imageio/image_enc.h"
#include "../imageio/webpdec.h"
#include "./stopwatch.h"
#include "./unicode.h"
static int verbose = 0;
static int quiet = 0;
@ -42,7 +43,7 @@ extern void* VP8GetCPUInfo; // opaque forward declaration.
static int SaveOutput(const WebPDecBuffer* const buffer,
WebPOutputFileFormat format, const char* const out_file) {
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
const int use_stdout = (out_file != NULL) && !WSTRCMP(out_file, "-");
int ok = 1;
Stopwatch stop_watch;
@ -56,7 +57,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
if (use_stdout) {
fprintf(stderr, "Saved to stdout\n");
} else {
fprintf(stderr, "Saved file %s\n", out_file);
WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file);
}
}
if (verbose) {
@ -67,7 +68,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
if (use_stdout) {
fprintf(stderr, "Error writing to stdout !!\n");
} else {
fprintf(stderr, "Error writing file %s !!\n", out_file);
WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file);
}
}
return ok;
@ -191,18 +192,20 @@ int main(int argc, const char *argv[]) {
int incremental = 0;
int c;
INIT_WARGV(argc, argv);
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
out_file = (const char*)GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-alpha")) {
format = ALPHA_PLANE_ONLY;
} else if (!strcmp(argv[c], "-nofancy")) {
@ -223,7 +226,7 @@ int main(int argc, const char *argv[]) {
const int version = WebPGetDecoderVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-pgm")) {
format = PGM;
} else if (!strcmp(argv[c], "-yuv")) {
@ -284,26 +287,26 @@ int main(int argc, const char *argv[]) {
} else if (!strcmp(argv[c], "-incremental")) {
incremental = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (in_file == NULL) {
fprintf(stderr, "missing input file!!\n");
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (quiet) verbose = 0;
@ -312,7 +315,7 @@ int main(int argc, const char *argv[]) {
VP8StatusCode status = VP8_STATUS_OK;
size_t data_size = 0;
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
return -1;
FREE_WARGV_AND_RETURN(-1);
}
switch (format) {
@ -389,18 +392,18 @@ int main(int argc, const char *argv[]) {
if (out_file != NULL) {
if (!quiet) {
fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. "
"Now saving...\n",
in_file, output_buffer->width, output_buffer->height,
WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file);
fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n",
output_buffer->width, output_buffer->height,
bitstream->has_alpha ? " (with alpha)" : "",
kFormatType[bitstream->format]);
}
ok = SaveOutput(output_buffer, format, out_file);
} else {
if (!quiet) {
fprintf(stderr, "File %s can be decoded "
"(dimensions: %d x %d %s. Format: %s).\n",
in_file, output_buffer->width, output_buffer->height,
WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file);
fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n",
output_buffer->width, output_buffer->height,
bitstream->has_alpha ? " (with alpha)" : "",
kFormatType[bitstream->format]);
fprintf(stderr, "Nothing written; "
@ -411,7 +414,7 @@ int main(int argc, const char *argv[]) {
WebPFreeDecBuffer(output_buffer);
free((void*)external_buffer);
free((void*)data);
return ok ? 0 : -1;
FREE_WARGV_AND_RETURN(ok ? 0 : -1);
}
//------------------------------------------------------------------------------

View File

@ -90,6 +90,14 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[],
if (argc == 1 && argv[0][0] != '-') {
char* cur;
const char sep[] = " \t\r\n\f\v";
#if defined(_WIN32) && defined(_UNICODE)
fprintf(stderr,
"Error: Reading arguments from a file is a feature unavailable "
"with Unicode binaries.\n");
return 0;
#endif
if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
return 0;
}

View File

@ -33,6 +33,8 @@
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./gifdec.h"
#include "./unicode.h"
#include "./unicode_gif.h"
#if !defined(STDIN_FILENO)
#define STDIN_FILENO 0
@ -99,7 +101,7 @@ int main(int argc, const char *argv[]) {
int gif_error = GIF_ERROR;
WebPMuxError err = WEBP_MUX_OK;
int ok = 0;
const char *in_file = NULL, *out_file = NULL;
const W_CHAR *in_file = NULL, *out_file = NULL;
GifFileType* gif = NULL;
int frame_duration = 0;
int frame_timestamp = 0;
@ -132,11 +134,13 @@ int main(int argc, const char *argv[]) {
int default_kmin = 1; // Whether to use default kmin value.
int default_kmax = 1;
INIT_WARGV(argc, argv);
if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
!WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
!WebPPictureInit(&prev_canvas)) {
fprintf(stderr, "Error! Version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
config.lossless = 1; // Use lossless compression by default.
@ -146,16 +150,16 @@ int main(int argc, const char *argv[]) {
if (argc == 1) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
out_file = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-lossy")) {
config.lossless = 0;
} else if (!strcmp(argv[c], "-mixed")) {
@ -212,7 +216,7 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
(int)(token - start), start);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
start = token + 1;
}
@ -225,7 +229,7 @@ int main(int argc, const char *argv[]) {
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
enc_version & 0xff, (mux_version >> 16) & 0xff,
(mux_version >> 8) & 0xff, mux_version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
enc_options.verbose = 0;
@ -233,19 +237,19 @@ int main(int argc, const char *argv[]) {
verbose = 1;
enc_options.verbose = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c < argc - 1) in_file = GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
@ -269,13 +273,7 @@ int main(int argc, const char *argv[]) {
}
// Start the decoder object
#if LOCAL_GIF_PREREQ(5,0)
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO, &gif_error)
: DGifOpenFileName(in_file, &gif_error);
#else
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO)
: DGifOpenFileName(in_file);
#endif
gif = DGifOpenFileUnicode(in_file, &gif_error);
if (gif == NULL) goto End;
// Loop over GIF images
@ -544,17 +542,18 @@ int main(int argc, const char *argv[]) {
}
if (out_file != NULL) {
if (!ImgIoUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) {
fprintf(stderr, "Error writing output file: %s\n", out_file);
if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes,
webp_data.size)) {
WFPRINTF(stderr, "Error writing output file: %s\n", out_file);
goto End;
}
if (!quiet) {
if (!strcmp(out_file, "-")) {
if (!WSTRCMP(out_file, "-")) {
fprintf(stderr, "Saved %d bytes to STDIO\n",
(int)webp_data.size);
} else {
fprintf(stderr, "Saved output file (%d bytes): %s\n",
(int)webp_data.size, out_file);
WFPRINTF(stderr, "Saved output file (%d bytes): %s\n",
(int)webp_data.size, out_file);
}
}
} else {
@ -589,7 +588,7 @@ int main(int argc, const char *argv[]) {
#endif
}
return !ok;
FREE_WARGV_AND_RETURN(!ok);
}
#else // !WEBP_HAVE_GIF

View File

@ -27,6 +27,7 @@
#include "../imageio/image_dec.h"
#include "../imageio/imageio_util.h"
#include "./stopwatch.h"
#include "./unicode.h"
#include "webp/encode.h"
#include "webp/mux.h"
@ -134,8 +135,13 @@ int main(int argc, const char* argv[]) {
int c;
int have_input = 0;
CommandLineArguments cmd_args;
int ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
if (!ok) return 1;
int ok;
INIT_WARGV(argc, argv);
ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
if (!ok) FREE_WARGV_AND_RETURN(1);
argc = cmd_args.argc_;
argv = cmd_args.argv_;
@ -154,7 +160,7 @@ int main(int argc, const char* argv[]) {
int parse_error = 0;
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
argv[c] = NULL;
output = argv[++c];
output = (const char*)GET_WARGV_SHIFTED(argv, ++c);
} else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
argv[c] = NULL;
anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
@ -241,7 +247,7 @@ int main(int argc, const char* argv[]) {
// read next input image
pic.use_argb = 1;
ok = ReadImage(argv[c], &pic);
ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic);
if (!ok) goto End;
if (enc == NULL) {
@ -273,8 +279,8 @@ int main(int argc, const char* argv[]) {
if (!ok) goto End;
if (verbose) {
fprintf(stderr, "Added frame #%3d at time %4d (file: %s)\n",
pic_num, timestamp_ms, argv[c]);
WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n",
pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c));
}
timestamp_ms += duration;
++pic_num;
@ -298,7 +304,7 @@ int main(int argc, const char* argv[]) {
if (ok) {
if (output != NULL) {
ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size);
if (ok) fprintf(stderr, "output file: %s ", output);
if (ok) WFPRINTF(stderr, "output file: %s ", (const W_CHAR*)output);
} else {
fprintf(stderr, "[no output file specified] ");
}
@ -310,5 +316,5 @@ int main(int argc, const char* argv[]) {
}
WebPDataClear(&webp_data);
ExUtilDeleteCommandLineArguments(&cmd_args);
return ok ? 0 : 1;
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}

101
examples/unicode.h Normal file
View File

@ -0,0 +1,101 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// -----------------------------------------------------------------------------
//
// Unicode support for Windows. The main idea is to maintain an array of Unicode
// arguments (wargv) and use it only for file paths. The regular argv is used
// for everything else.
//
// Author: Yannis Guyon (yguyon@google.com)
#ifndef WEBP_EXAMPLES_UNICODE_H_
#define WEBP_EXAMPLES_UNICODE_H_
#if defined(_WIN32) && defined(_UNICODE)
// wchar_t is used instead of TCHAR because we only perform additional work when
// Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t.
#include <wchar.h>
#include <windows.h>
#include <shellapi.h>
// Create a wchar_t array containing Unicode parameters.
#define INIT_WARGV(ARGC, ARGV) \
int wargc; \
const W_CHAR** const wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); \
do { \
if (wargv == NULL || wargc != (ARGC)) { \
fprintf(stderr, "Error: Unable to get Unicode arguments.\n"); \
FREE_WARGV_AND_RETURN(-1); \
} \
} while (0)
// Use this to get a Unicode argument (e.g. file path).
#define GET_WARGV(UNUSED, C) wargv[C]
// For cases where argv is shifted by one compared to wargv.
#define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1]
#define GET_WARGV_OR_NULL() wargv
// Release resources. LocalFree() is needed after CommandLineToArgvW().
#define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv)
#define LOCAL_FREE(WARGV) \
do { \
if ((WARGV) != NULL) LocalFree(WARGV); \
} while (0)
#define W_CHAR wchar_t // WCHAR without underscore might already be defined.
#define TO_W_CHAR(STR) (L##STR)
#define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT))
#define WPRINTF(STR, ...) wprintf(TO_W_CHAR(STR), __VA_ARGS__)
#define WFPRINTF(STDERR, STR, ...) fwprintf(STDERR, TO_W_CHAR(STR), __VA_ARGS__)
#define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME)
#define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
#define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
#define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__)
#else
// Unicode file paths work as is on Unix platforms, and no extra work is done on
// Windows either if Unicode is disabled.
#define INIT_WARGV(ARGC, ARGV)
#define GET_WARGV(ARGV, C) (ARGV)[C]
#define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C]
#define GET_WARGV_OR_NULL() NULL
#define FREE_WARGV()
#define LOCAL_FREE(WARGV)
#define W_CHAR char
#define TO_W_CHAR(STR) (STR)
#define WFOPEN(ARG, OPT) fopen(ARG, OPT)
#define WPRINTF(STR, ...) printf(STR, __VA_ARGS__)
#define WFPRINTF(STDERR, STR, ...) fprintf(STDERR, STR, __VA_ARGS__)
#define WSTRLEN(FILENAME) strlen(FILENAME)
#define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR)
#define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR)
#define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__)
#endif // defined(_WIN32) && defined(_UNICODE)
// Don't forget to free wargv before returning (e.g. from main).
#define FREE_WARGV_AND_RETURN(VALUE) \
do { \
FREE_WARGV(); \
return (VALUE); \
} while (0)
#endif // WEBP_EXAMPLES_UNICODE_H_

75
examples/unicode_gif.h Normal file
View File

@ -0,0 +1,75 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// -----------------------------------------------------------------------------
//
// giflib doesn't have a Unicode DGifOpenFileName(). Let's make one.
//
// Author: Yannis Guyon (yguyon@google.com)
#ifndef WEBP_EXAMPLES_UNICODE_GIF_H_
#define WEBP_EXAMPLES_UNICODE_GIF_H_
#include "./unicode.h"
#ifdef HAVE_CONFIG_H
#include "webp/config.h" // For WEBP_HAVE_GIF
#endif
#if defined(WEBP_HAVE_GIF)
#ifdef _WIN32
#include <fcntl.h> // Not standard, needed for _topen and flags.
#include <io.h>
#endif
#include <gif_lib.h>
#include <string.h>
#include "./gifdec.h"
#if !defined(STDIN_FILENO)
#define STDIN_FILENO 0
#endif
static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) {
if (!WSTRCMP(file_name, "-")) {
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileHandle(STDIN_FILENO, error);
#else
(void)error;
return DGifOpenFileHandle(STDIN_FILENO);
#endif
}
#if defined(_WIN32) && defined(_UNICODE)
int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
if (file_handle == -1) {
if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
return NULL;
}
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileHandle(file_handle, error);
#else
return DGifOpenFileHandle(file_handle);
#endif
#else
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileName(file_name, error);
#else
return DGifOpenFileName(file_name);
#endif
#endif // defined(_WIN32) && defined(_UNICODE)
// DGifCloseFile() is called later.
}
#endif // defined(WEBP_HAVE_GIF)
#endif // WEBP_EXAMPLES_UNICODE_GIF_H_

View File

@ -42,6 +42,7 @@
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -470,9 +471,11 @@ int main(int argc, char *argv[]) {
WebPDecoderConfig* const config = &kParams.config;
WebPIterator* const curr = &kParams.curr_frame;
INIT_WARGV(argc, argv);
if (!WebPInitDecoderConfig(config)) {
fprintf(stderr, "Library version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
config->options.dithering_strength = 50;
config->options.alpha_dithering_strength = 100;
@ -484,7 +487,7 @@ int main(int argc, char *argv[]) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-noicc")) {
kParams.use_color_profile = 0;
} else if (!strcmp(argv[c], "-nofancy")) {
@ -507,30 +510,30 @@ int main(int argc, char *argv[]) {
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
dec_version & 0xff, (dmux_version >> 16) & 0xff,
(dmux_version >> 8) & 0xff, dmux_version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-mt")) {
config->options.use_threads = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) kParams.file_name = argv[++c];
if (c < argc - 1) kParams.file_name = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
printf("Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
kParams.file_name = argv[c];
kParams.file_name = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (kParams.file_name == NULL) {
printf("missing input file!!\n");
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
}
if (!ImgIoUtilReadFile(kParams.file_name,
@ -605,11 +608,11 @@ int main(int argc, char *argv[]) {
// Should only be reached when using FREEGLUT:
ClearParams();
return 0;
FREE_WARGV_AND_RETURN(0);
Error:
ClearParams();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
#else // !WEBP_HAVE_GL

View File

@ -20,6 +20,7 @@
#endif
#include "../imageio/imageio_util.h"
#include "./unicode.h"
#include "webp/decode.h"
#include "webp/format_constants.h"
#include "webp/mux_types.h"
@ -1119,19 +1120,21 @@ int main(int argc, const char* argv[]) {
WebPInfoStatus webp_info_status = WEBP_INFO_OK;
WebPInfo webp_info;
INIT_WARGV(argc, argv);
if (argc == 1) {
HelpShort();
return WEBP_INFO_OK;
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
}
// Parse command-line input.
for (c = 1; c < argc; ++c) {
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
HelpShort();
return WEBP_INFO_OK;
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
HelpLong();
return WEBP_INFO_OK;
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
} else if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
} else if (!strcmp(argv[c], "-diag")) {
@ -1144,7 +1147,7 @@ int main(int argc, const char* argv[]) {
const int version = WebPGetDecoderVersion();
printf("WebP Decoder version: %d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else { // Assume the remaining are all input files.
break;
}
@ -1152,27 +1155,28 @@ int main(int argc, const char* argv[]) {
if (c == argc) {
HelpShort();
return WEBP_INFO_INVALID_COMMAND;
FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
}
// Process input files one by one.
for (; c < argc; ++c) {
WebPData webp_data;
const char* in_file = NULL;
const W_CHAR* in_file = NULL;
WebPInfoInit(&webp_info);
webp_info.quiet_ = quiet;
webp_info.show_diagnosis_ = show_diag;
webp_info.show_summary_ = show_summary;
webp_info.parse_bitstream_ = parse_bitstream;
in_file = argv[c];
if (in_file == NULL || !ReadFileToWebPData(in_file, &webp_data)) {
in_file = GET_WARGV(argv, c);
if (in_file == NULL ||
!ReadFileToWebPData((const char*)in_file, &webp_data)) {
webp_info_status = WEBP_INFO_INVALID_COMMAND;
fprintf(stderr, "Failed to open input file %s.\n", in_file);
WFPRINTF(stderr, "Failed to open input file %s.\n", in_file);
continue;
}
if (!webp_info.quiet_) printf("File: %s\n", in_file);
if (!webp_info.quiet_) WPRINTF("File: %s\n", in_file);
webp_info_status = AnalyzeWebP(&webp_info, &webp_data);
WebPDataClear(&webp_data);
}
return webp_info_status;
FREE_WARGV_AND_RETURN(webp_info_status);
}

View File

@ -62,6 +62,7 @@
#include "webp/mux.h"
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./unicode.h"
//------------------------------------------------------------------------------
// Config object to parse command-line arguments.
@ -390,23 +391,25 @@ static int CreateMux(const char* const filename, WebPMux** mux) {
*mux = WebPMuxCreate(&bitstream, 1);
WebPDataClear(&bitstream);
if (*mux != NULL) return 1;
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
(const W_CHAR*)filename);
return 0;
}
static int WriteData(const char* filename, const WebPData* const webpdata) {
int ok = 0;
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb")
: ImgIoUtilSetBinaryMode(stdout);
FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
: ImgIoUtilSetBinaryMode(stdout);
if (fout == NULL) {
fprintf(stderr, "Error opening output WebP file %s!\n", filename);
WFPRINTF(stderr, "Error opening output WebP file %s!\n",
(const W_CHAR*)filename);
return 0;
}
if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
fprintf(stderr, "Error writing file %s!\n", filename);
WFPRINTF(stderr, "Error writing file %s!\n", (const W_CHAR*)filename);
} else {
fprintf(stderr, "Saved file %s (%d bytes)\n",
filename, (int)webpdata->size);
WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
(const W_CHAR*)filename, (int)webpdata->size);
ok = 1;
}
if (fout != stdout) fclose(fout);
@ -612,13 +615,16 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
CHECK_NUM_ARGS_AT_MOST(NUM, LABEL);
// Parses command-line arguments to fill up config object. Also performs some
// semantic checks.
static int ParseCommandLine(Config* config) {
// semantic checks. unicode_argv contains wchar_t arguments or is null.
static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
int i = 0;
int feature_arg_index = 0;
int ok = 1;
int argc = config->cmd_args_.argc_;
const char* const* argv = config->cmd_args_.argv_;
// Unicode file paths will be used if available.
const char* const* wargv =
(unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
while (i < argc) {
FeatureArg* const arg = &config->args_[feature_arg_index];
@ -696,7 +702,7 @@ static int ParseCommandLine(Config* config) {
i += 2;
} else if (!strcmp(argv[i], "-o")) {
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
config->output_ = argv[i + 1];
config->output_ = wargv[i + 1];
i += 2;
} else if (!strcmp(argv[i], "-info")) {
CHECK_NUM_ARGS_EXACTLY(2, ErrParse);
@ -705,24 +711,26 @@ static int ParseCommandLine(Config* config) {
} else {
config->action_type_ = ACTION_INFO;
config->arg_count_ = 0;
config->input_ = argv[i + 1];
config->input_ = wargv[i + 1];
}
i += 2;
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
PrintHelp();
DeleteConfig(config);
LOCAL_FREE((W_CHAR** const)unicode_argv);
exit(0);
} 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);
LOCAL_FREE((W_CHAR** const)unicode_argv);
exit(0);
} else if (!strcmp(argv[i], "--")) {
if (i < argc - 1) {
++i;
if (config->input_ == NULL) {
config->input_ = argv[i];
config->input_ = wargv[i];
} else {
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
argv[i], ErrParse);
@ -747,7 +755,7 @@ static int ParseCommandLine(Config* config) {
}
if (config->action_type_ == ACTION_SET) {
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
arg->filename_ = argv[i + 1];
arg->filename_ = wargv[i + 1];
++feature_arg_index;
i += 2;
} else {
@ -762,7 +770,7 @@ static int ParseCommandLine(Config* config) {
i += 2;
} else { // Assume input file.
if (config->input_ == NULL) {
config->input_ = argv[i];
config->input_ = wargv[i];
} else {
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
argv[i], ErrParse);
@ -808,8 +816,8 @@ static int ValidateConfig(Config* const config) {
}
// Create config object from command-line arguments.
static int InitializeConfig(int argc, const char* argv[],
Config* const config) {
static int InitializeConfig(int argc, const char* argv[], Config* const config,
const W_CHAR** const unicode_argv) {
int num_feature_args = 0;
int ok;
@ -830,7 +838,7 @@ static int InitializeConfig(int argc, const char* argv[],
}
// Parse command-line.
if (!ParseCommandLine(config) || !ValidateConfig(config)) {
if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
}
@ -1140,14 +1148,18 @@ static int Process(const Config* config) {
int main(int argc, const char* argv[]) {
Config config;
int ok = InitializeConfig(argc - 1, argv + 1, &config);
int ok;
INIT_WARGV(argc, argv);
ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
if (ok) {
ok = Process(&config);
} else {
PrintHelp();
}
DeleteConfig(&config);
return !ok;
FREE_WARGV_AND_RETURN(!ok);
}
//------------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@
#include "webp/encode.h"
#include "imageio/image_dec.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
int keep_alpha) {
@ -48,7 +49,8 @@ static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
End:
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
return ok ? data_size : 0;
@ -239,9 +241,11 @@ int main(int argc, const char *argv[]) {
const char* name2 = NULL;
const char* output = NULL;
INIT_WARGV(argc, argv);
if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
fprintf(stderr, "Can't init pictures\n");
return 1;
FREE_WARGV_AND_RETURN(1);
}
for (c = 1; c < argc; ++c) {
@ -263,11 +267,11 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
goto End;
}
output = argv[c];
output = (const char*)GET_WARGV(argv, c);
} else if (name1 == NULL) {
name1 = argv[c];
name1 = (const char*)GET_WARGV(argv, c);
} else {
name2 = argv[c];
name2 = (const char*)GET_WARGV(argv, c);
}
}
if (help || name1 == NULL || name2 == NULL) {
@ -347,5 +351,5 @@ int main(int argc, const char *argv[]) {
End:
WebPPictureFree(&pic1);
WebPPictureFree(&pic2);
return ret;
FREE_WARGV_AND_RETURN(ret);
}

View File

@ -25,6 +25,7 @@
#include "webp_to_sdl.h"
#include "webp/decode.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
#if defined(WEBP_HAVE_JUST_SDL_H)
#include <SDL.h>
@ -51,19 +52,22 @@ static void ProcessEvents(void) {
int main(int argc, char* argv[]) {
int c;
int ok = 0;
INIT_WARGV(argc, argv);
for (c = 1; c < argc; ++c) {
const char* file = NULL;
const uint8_t* webp = NULL;
size_t webp_size = 0;
if (!strcmp(argv[c], "-h")) {
printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]);
return 0;
FREE_WARGV_AND_RETURN(0);
} else {
file = argv[c];
file = (const char*)GET_WARGV(argv, c);
}
if (file == NULL) continue;
if (!ImgIoUtilReadFile(file, &webp, &webp_size)) {
fprintf(stderr, "Error opening file: %s\n", file);
WFPRINTF(stderr, "Error opening file: %s\n", (const W_CHAR*)file);
goto Error;
}
if (webp_size != (size_t)(int)webp_size) {
@ -73,7 +77,7 @@ int main(int argc, char* argv[]) {
ok = WebpToSDL((const char*)webp, (int)webp_size);
free((void*)webp);
if (!ok) {
fprintf(stderr, "Error decoding file %s\n", file);
WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);
goto Error;
}
ProcessEvents();
@ -82,7 +86,7 @@ int main(int argc, char* argv[]) {
Error:
SDL_Quit();
return ok ? 0 : 1;
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}
#else // !WEBP_HAVE_SDL

View File

@ -13,26 +13,30 @@
#include "extras/extras.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
int main(int argc, const char *argv[]) {
int c;
int quiet = 0;
int ok = 1;
INIT_WARGV(argc, argv);
for (c = 1; ok && c < argc; ++c) {
if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
} else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
printf("webp_quality [-h][-quiet] webp_files...\n");
return 0;
FREE_WARGV_AND_RETURN(0);
} else {
const char* const filename = argv[c];
const char* const filename = (const char*)GET_WARGV(argv, c);
const uint8_t* data = NULL;
size_t data_size = 0;
int q;
ok = ImgIoUtilReadFile(filename, &data, &data_size);
if (!ok) break;
q = VP8EstimateQuality(data, data_size);
if (!quiet) printf("[%s] ", filename);
if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename);
if (q < 0) {
fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
ok = 0;
@ -46,5 +50,5 @@ int main(int argc, const char *argv[]) {
free((void*)data);
}
}
return ok ? 0 : 1;
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}

View File

@ -29,11 +29,13 @@
// code with COBJMACROS.
#include <ole2.h> // CreateStreamOnHGlobal()
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>
#include <wincodec.h>
#endif
#include "./imageio_util.h"
#include "../examples/unicode.h"
//------------------------------------------------------------------------------
// PNG
@ -61,11 +63,12 @@ static HRESULT CreateOutputStream(const char* out_file_name,
// Output to a memory buffer. This is freed when 'stream' is released.
IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
} else {
IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name,
STGM_WRITE | STGM_CREATE, stream));
}
if (FAILED(hr)) {
fprintf(stderr, "Error opening output file %s (%08lx)\n",
out_file_name, hr);
_ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"),
(const LPTSTR)out_file_name, hr);
}
return hr;
}
@ -549,7 +552,8 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
const char* const out_file_name) {
FILE* fout = NULL;
int needs_open_file = 1;
const int use_stdout = (out_file_name != NULL) && !strcmp(out_file_name, "-");
const int use_stdout =
(out_file_name != NULL) && !WSTRCMP(out_file_name, "-");
int ok = 1;
if (buffer == NULL || out_file_name == NULL) return 0;
@ -560,9 +564,10 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
if (needs_open_file) {
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
: fopen(out_file_name, "wb");
: WFOPEN(out_file_name, "wb");
if (fout == NULL) {
fprintf(stderr, "Error opening output file %s\n", out_file_name);
WFPRINTF(stderr, "Error opening output file %s\n",
(const W_CHAR*)out_file_name);
return 0;
}
}

View File

@ -18,6 +18,7 @@
#endif
#include <stdlib.h>
#include <string.h>
#include "../examples/unicode.h"
// -----------------------------------------------------------------------------
// File I/O
@ -73,7 +74,7 @@ int ImgIoUtilReadFile(const char* const file_name,
uint8_t* file_data;
size_t file_size;
FILE* in;
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-");
if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
@ -81,9 +82,9 @@ int ImgIoUtilReadFile(const char* const file_name,
*data = NULL;
*data_size = 0;
in = fopen(file_name, "rb");
in = WFOPEN(file_name, "rb");
if (in == NULL) {
fprintf(stderr, "cannot open input file '%s'\n", file_name);
WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name);
return 0;
}
fseek(in, 0, SEEK_END);
@ -93,16 +94,16 @@ int ImgIoUtilReadFile(const char* const file_name,
file_data = (uint8_t*)malloc(file_size + 1);
if (file_data == NULL) {
fclose(in);
fprintf(stderr, "memory allocation failure when reading file %s\n",
file_name);
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
(const W_CHAR*)file_name);
return 0;
}
ok = (fread(file_data, file_size, 1, in) == 1);
fclose(in);
if (!ok) {
fprintf(stderr, "Could not read %d bytes of data from file %s\n",
(int)file_size, file_name);
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
(int)file_size, (const W_CHAR*)file_name);
free(file_data);
return 0;
}
@ -118,14 +119,15 @@ int ImgIoUtilWriteFile(const char* const file_name,
const uint8_t* data, size_t data_size) {
int ok;
FILE* out;
const int to_stdout = (file_name == NULL) || !strcmp(file_name, "-");
const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-");
if (data == NULL) {
return 0;
}
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(file_name, "wb");
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb");
if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
(const W_CHAR*)file_name);
return 0;
}
ok = (fwrite(data, data_size, 1, out) == 1);

View File

@ -22,6 +22,7 @@
#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/encode.h"
#include "../examples/unicode.h"
#include "./imageio_util.h"
#include "./metadata.h"
@ -43,7 +44,7 @@ static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
}
void PrintWebPError(const char* const in_file, int status) {
fprintf(stderr, "Decoding of %s failed.\n", in_file);
WFPRINTF(stderr, "Decoding of %s failed.\n", (const W_CHAR*)in_file);
fprintf(stderr, "Status: %d", status);
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
fprintf(stderr, "(%s)", kStatusMessages[status]);

View File

@ -29,12 +29,14 @@
// code with COBJMACROS.
#include <ole2.h> // CreateStreamOnHGlobal()
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>
#include <wincodec.h>
#include "webp/encode.h"
#include "../examples/unicode.h"
#include "./imageio_util.h"
#include "./metadata.h"
#include "webp/encode.h"
#define IFS(fn) \
do { \
@ -85,7 +87,7 @@ WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_,
static HRESULT OpenInputStream(const char* filename, IStream** stream) {
HRESULT hr = S_OK;
if (!strcmp(filename, "-")) {
if (!WSTRCMP(filename, "-")) {
const uint8_t* data = NULL;
size_t data_size = 0;
const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
@ -108,11 +110,12 @@ static HRESULT OpenInputStream(const char* filename, IStream** stream) {
hr = E_FAIL;
}
} else {
IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream));
}
if (FAILED(hr)) {
fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
_ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"),
(const LPTSTR)filename, hr);
}
return hr;
}