allow some more stdin/stout I/O
* allow reading from stdin for dwebp / vwebp
* allow writing to stdout for gif2webp
by introducing a new function ExUtilReadFromStdin()
Example use: cat in.webp | dwebp -o - -- - > out.png
Note that the '-- -' option must appear *last*
(as per general fashion for '--' option parsing)
Change-Id: I8df0f3a246cc325925d6b6f668ba060f7dd81d68
diff --git a/examples/example_util.c b/examples/example_util.c
index d265f69..f2d4975 100644
--- a/examples/example_util.c
+++ b/examples/example_util.c
@@ -13,18 +13,54 @@
#include "./example_util.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
// -----------------------------------------------------------------------------
// File I/O
+static const size_t kBlockSize = 16384; // default initial size
+
+int ExUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
+ size_t max_size = 0;
+ size_t size = 0;
+ uint8_t* input = NULL;
+
+ if (data == NULL || data_size == NULL) return 0;
+ *data = NULL;
+ *data_size = 0;
+
+ while (!feof(stdin)) {
+ // We double the buffer size each time and read as much as possible.
+ const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
+ void* const new_data = realloc(input, max_size + extra_size);
+ if (new_data == NULL) goto Error;
+ input = (uint8_t*)new_data;
+ max_size += extra_size;
+ size += fread(input + size, 1, extra_size, stdin);
+ if (size < max_size) break;
+ }
+ if (ferror(stdin)) goto Error;
+ *data = input;
+ *data_size = size;
+ return 1;
+
+ Error:
+ free(input);
+ fprintf(stderr, "Could not read from stdin\n");
+ return 0;
+}
+
int ExUtilReadFile(const char* const file_name,
const uint8_t** data, size_t* data_size) {
int ok;
void* file_data;
size_t file_size;
FILE* in;
+ const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
- if (file_name == NULL || data == NULL || data_size == NULL) return 0;
+ if (from_stdin) return ExUtilReadFromStdin(data, data_size);
+
+ if (data == NULL || data_size == NULL) return 0;
*data = NULL;
*data_size = 0;
@@ -56,17 +92,18 @@
const uint8_t* data, size_t data_size) {
int ok;
FILE* out;
+ const int to_stdout = (file_name == NULL) || !strcmp(file_name, "-");
- if (file_name == NULL || data == NULL) {
+ if (data == NULL) {
return 0;
}
- out = fopen(file_name, "wb");
+ out = to_stdout ? stdout : fopen(file_name, "wb");
if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
return 0;
}
ok = (fwrite(data, data_size, 1, out) == 1);
- fclose(out);
+ if (out != stdout) fclose(out);
return ok;
}