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;
 }