Merge avifdump's functionality into new --info mode in avifdec
diff --git a/apps/avifdec.c b/apps/avifdec.c
index e0468ad..ad7c64b 100644
--- a/apps/avifdec.c
+++ b/apps/avifdec.c
@@ -8,6 +8,7 @@
 #include "avifutil.h"
 #include "y4m.h"
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -24,15 +25,84 @@
 static void syntax(void)
 {
     printf("Syntax: avifdec [options] input.avif output.[jpg|jpeg|png|y4m]\n");
+    printf("        avifdec --info    input.avif\n");
     printf("Options:\n");
     printf("    -h,--help         : Show syntax help\n");
     printf("    -c,--codec C      : AV1 codec to use (choose from versions list below)\n");
     printf("    -d,--depth D      : Output depth [8,16]. (PNG only; For y4m, depth is retained, and JPEG is always 8bpc)\n");
     printf("    -q,--quality Q    : Output quality [0-100]. (JPEG only, default: %d)\n", DEFAULT_JPEG_QUALITY);
+    printf("    -i,--info         : Decode all frames and display all image information instead of saving to disk\n");
     printf("\n");
     avifPrintVersions();
 }
 
+static int info(const char * inputFilename)
+{
+    FILE * inputFile = fopen(inputFilename, "rb");
+    if (!inputFile) {
+        fprintf(stderr, "Cannot open file for read: %s\n", inputFilename);
+        return 1;
+    }
+    fseek(inputFile, 0, SEEK_END);
+    size_t inputFileSize = ftell(inputFile);
+    fseek(inputFile, 0, SEEK_SET);
+
+    if (inputFileSize < 1) {
+        fprintf(stderr, "File too small: %s\n", inputFilename);
+        fclose(inputFile);
+        return 1;
+    }
+
+    avifRWData raw = AVIF_DATA_EMPTY;
+    avifRWDataRealloc(&raw, inputFileSize);
+    if (fread(raw.data, 1, inputFileSize, inputFile) != inputFileSize) {
+        fprintf(stderr, "Failed to read %zu bytes: %s\n", inputFileSize, inputFilename);
+        fclose(inputFile);
+        avifRWDataFree(&raw);
+        return 1;
+    }
+
+    fclose(inputFile);
+    inputFile = NULL;
+
+    avifDecoder * decoder = avifDecoderCreate();
+    avifResult result = avifDecoderParse(decoder, (avifROData *)&raw);
+    if (result == AVIF_RESULT_OK) {
+        printf("Image decoded: %s\n", inputFilename);
+
+        int frameIndex = 0;
+        avifBool firstImage = AVIF_TRUE;
+        while (avifDecoderNextImage(decoder) == AVIF_RESULT_OK) {
+            if (firstImage) {
+                firstImage = AVIF_FALSE;
+                avifImageDump(decoder->image);
+
+                printf(" * %" PRIu64 " timescales per second, %2.2f seconds (%" PRIu64 " timescales), %d frame%s\n",
+                       decoder->timescale,
+                       decoder->duration,
+                       decoder->durationInTimescales,
+                       decoder->imageCount,
+                       (decoder->imageCount == 1) ? "" : "s");
+                printf(" * Frames:\n");
+            }
+
+            printf("   * Decoded frame [%d] [pts %2.2f (%" PRIu64 " timescales)] [duration %2.2f (%" PRIu64 " timescales)]\n",
+                   frameIndex,
+                   decoder->imageTiming.pts,
+                   decoder->imageTiming.ptsInTimescales,
+                   decoder->imageTiming.duration,
+                   decoder->imageTiming.durationInTimescales);
+            ++frameIndex;
+        }
+    } else {
+        printf("ERROR: Failed to decode image: %s\n", avifResultToString(result));
+    }
+
+    avifRWDataFree(&raw);
+    avifDecoderDestroy(decoder);
+    return 0;
+}
+
 int main(int argc, char * argv[])
 {
     const char * inputFilename = NULL;
@@ -40,6 +110,7 @@
     int requestedDepth = 0;
     int jpegQuality = DEFAULT_JPEG_QUALITY;
     avifCodecChoice codecChoice = AVIF_CODEC_CHOICE_AUTO;
+    avifBool infoOnly = AVIF_FALSE;
 
     if (argc < 2) {
         syntax();
@@ -81,6 +152,8 @@
             } else if (jpegQuality > 100) {
                 jpegQuality = 100;
             }
+        } else if (!strcmp(arg, "-i") || !strcmp(arg, "--info")) {
+            infoOnly = AVIF_TRUE;
         } else {
             // Positional argument
             if (!inputFilename) {
@@ -97,11 +170,24 @@
         ++argIndex;
     }
 
-    if (!inputFilename || !outputFilename) {
+    if (!inputFilename) {
         syntax();
         return 1;
     }
 
+    if (infoOnly) {
+        if (!inputFilename || outputFilename) {
+            syntax();
+            return 1;
+        }
+        return info(inputFilename);
+    } else {
+        if (!inputFilename || !outputFilename) {
+            syntax();
+            return 1;
+        }
+    }
+
     FILE * inputFile = fopen(inputFilename, "rb");
     if (!inputFile) {
         fprintf(stderr, "Cannot open file for read: %s\n", inputFilename);