Merge avifCodec's open call with its getNextImage call to avoid codec init during parse, and simplify the codec API

Fixes: #636
diff --git a/include/avif/internal.h b/include/avif/internal.h
index 804f395..5e4c217 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -218,8 +218,11 @@
 struct avifCodec;
 struct avifCodecInternal;
 
-typedef avifBool (*avifCodecOpenFunc)(struct avifCodec * codec, avifDecoder * decoder); // decode only
-typedef avifBool (*avifCodecGetNextImageFunc)(struct avifCodec * codec, const avifDecodeSample * sample, avifBool alpha, avifImage * image);
+typedef avifBool (*avifCodecGetNextImageFunc)(struct avifDecoder * decoder,
+                                              struct avifCodec * codec,
+                                              const avifDecodeSample * sample,
+                                              avifBool alpha,
+                                              avifImage * image);
 // EncodeImage and EncodeFinish are not required to always emit a sample, but when all images are
 // encoded and EncodeFinish is called, the number of samples emitted must match the number of submitted frames.
 // avifCodecEncodeImageFunc may return AVIF_RESULT_UNKNOWN_ERROR to automatically emit the appropriate
@@ -242,7 +245,6 @@
                                           //
     avifDiagnostics * diag;               // Shallow copy; owned by avifEncoder or avifDecoder
 
-    avifCodecOpenFunc open;
     avifCodecGetNextImageFunc getNextImage;
     avifCodecEncodeImageFunc encodeImage;
     avifCodecEncodeFinishFunc encodeFinish;
diff --git a/src/codec_aom.c b/src/codec_aom.c
index 7d5caf0..4d45a0c 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -83,32 +83,35 @@
 }
 
 #if defined(AVIF_CODEC_AOM_DECODE)
-static avifBool aomCodecOpen(struct avifCodec * codec, avifDecoder * decoder)
+
+static avifBool aomCodecGetNextImage(struct avifDecoder * decoder,
+                                     struct avifCodec * codec,
+                                     const avifDecodeSample * sample,
+                                     avifBool alpha,
+                                     avifImage * image)
 {
-    aom_codec_dec_cfg_t cfg;
-    memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
-    cfg.threads = decoder->maxThreads;
-    cfg.allow_lowbitdepth = 1;
+    if (!codec->internal->decoderInitialized) {
+        aom_codec_dec_cfg_t cfg;
+        memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
+        cfg.threads = decoder->maxThreads;
+        cfg.allow_lowbitdepth = 1;
 
-    aom_codec_iface_t * decoder_interface = aom_codec_av1_dx();
-    if (aom_codec_dec_init(&codec->internal->decoder, decoder_interface, &cfg, 0)) {
-        return AVIF_FALSE;
-    }
-    codec->internal->decoderInitialized = AVIF_TRUE;
+        aom_codec_iface_t * decoder_interface = aom_codec_av1_dx();
+        if (aom_codec_dec_init(&codec->internal->decoder, decoder_interface, &cfg, 0)) {
+            return AVIF_FALSE;
+        }
+        codec->internal->decoderInitialized = AVIF_TRUE;
 
-    // Ensure that we only get the "highest spatial layer" as a single frame
-    // for each input sample, instead of getting each spatial layer as its own
-    // frame one at a time ("all layers").
-    if (aom_codec_control(&codec->internal->decoder, AV1D_SET_OUTPUT_ALL_LAYERS, 0)) {
-        return AVIF_FALSE;
+        // Ensure that we only get the "highest spatial layer" as a single frame
+        // for each input sample, instead of getting each spatial layer as its own
+        // frame one at a time ("all layers").
+        if (aom_codec_control(&codec->internal->decoder, AV1D_SET_OUTPUT_ALL_LAYERS, 0)) {
+            return AVIF_FALSE;
+        }
+
+        codec->internal->iter = NULL;
     }
 
-    codec->internal->iter = NULL;
-    return AVIF_TRUE;
-}
-
-static avifBool aomCodecGetNextImage(struct avifCodec * codec, const avifDecodeSample * sample, avifBool alpha, avifImage * image)
-{
     aom_image_t * nextFrame = NULL;
     for (;;) {
         nextFrame = aom_codec_get_frame(&codec->internal->decoder, &codec->internal->iter);
@@ -854,7 +857,6 @@
     memset(codec, 0, sizeof(struct avifCodec));
 
 #if defined(AVIF_CODEC_AOM_DECODE)
-    codec->open = aomCodecOpen;
     codec->getNextImage = aomCodecGetNextImage;
 #endif
 
diff --git a/src/codec_dav1d.c b/src/codec_dav1d.c
index 054f846..cc2f8e8 100644
--- a/src/codec_dav1d.c
+++ b/src/codec_dav1d.c
@@ -49,7 +49,11 @@
     avifFree(codec->internal);
 }
 
-static avifBool dav1dCodecOpen(avifCodec * codec, avifDecoder * decoder)
+static avifBool dav1dCodecGetNextImage(struct avifDecoder * decoder,
+                                       struct avifCodec * codec,
+                                       const avifDecodeSample * sample,
+                                       avifBool alpha,
+                                       avifImage * image)
 {
     if (codec->internal->dav1dContext == NULL) {
         // Give all available threads to decode a single frame as fast as possible
@@ -60,11 +64,7 @@
             return AVIF_FALSE;
         }
     }
-    return AVIF_TRUE;
-}
 
-static avifBool dav1dCodecGetNextImage(struct avifCodec * codec, const avifDecodeSample * sample, avifBool alpha, avifImage * image)
-{
     avifBool gotPicture = AVIF_FALSE;
     Dav1dPicture nextFrame;
     memset(&nextFrame, 0, sizeof(Dav1dPicture));
@@ -201,7 +201,6 @@
 {
     avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec));
     memset(codec, 0, sizeof(struct avifCodec));
-    codec->open = dav1dCodecOpen;
     codec->getNextImage = dav1dCodecGetNextImage;
     codec->destroyInternal = dav1dCodecDestroyInternal;
 
diff --git a/src/codec_libgav1.c b/src/codec_libgav1.c
index 5b21c9c..1c88772 100644
--- a/src/codec_libgav1.c
+++ b/src/codec_libgav1.c
@@ -23,7 +23,11 @@
     avifFree(codec->internal);
 }
 
-static avifBool gav1CodecOpen(avifCodec * codec, avifDecoder * decoder)
+static avifBool gav1CodecGetNextImage(struct avifDecoder * decoder,
+                                      struct avifCodec * codec,
+                                      const avifDecodeSample * sample,
+                                      avifBool alpha,
+                                      avifImage * image)
 {
     if (codec->internal->gav1Decoder == NULL) {
         codec->internal->gav1Settings.threads = decoder->maxThreads;
@@ -32,11 +36,7 @@
             return AVIF_FALSE;
         }
     }
-    return AVIF_TRUE;
-}
 
-static avifBool gav1CodecGetNextImage(struct avifCodec * codec, const avifDecodeSample * sample, avifBool alpha, avifImage * image)
-{
     if (Libgav1DecoderEnqueueFrame(codec->internal->gav1Decoder,
                                    sample->data.data,
                                    sample->data.size,
@@ -150,7 +150,6 @@
 {
     avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec));
     memset(codec, 0, sizeof(struct avifCodec));
-    codec->open = gav1CodecOpen;
     codec->getNextImage = gav1CodecGetNextImage;
     codec->destroyInternal = gav1CodecDestroyInternal;
 
diff --git a/src/read.c b/src/read.c
index bea0150..6d186e1 100644
--- a/src/read.c
+++ b/src/read.c
@@ -2745,9 +2745,6 @@
             return AVIF_RESULT_NO_CODEC_AVAILABLE;
         }
         tile->codec->diag = &decoder->diag;
-        if (!tile->codec->open(tile->codec, decoder)) {
-            return AVIF_RESULT_DECODE_COLOR_FAILED;
-        }
     }
     return AVIF_RESULT_OK;
 }
@@ -3234,7 +3231,7 @@
 
         const avifDecodeSample * sample = &tile->input->samples.sample[nextImageIndex];
 
-        if (!tile->codec->getNextImage(tile->codec, sample, tile->input->alpha, tile->image)) {
+        if (!tile->codec->getNextImage(decoder, tile->codec, sample, tile->input->alpha, tile->image)) {
             return tile->input->alpha ? AVIF_RESULT_DECODE_ALPHA_FAILED : AVIF_RESULT_DECODE_COLOR_FAILED;
         }
     }