]> git.sesse.net Git - nageru/commitdiff
Fix reading of PNG images.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 9 Apr 2016 12:25:09 +0000 (14:25 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 9 Apr 2016 12:25:09 +0000 (14:25 +0200)
image_input.cpp

index 27c088d59c5b76f5ae8567fec58988bbba8882a1..5c1bd8f1f536e5b561c5eb1cee4d7ef26a071e97 100644 (file)
@@ -152,7 +152,7 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &fil
        unique_ptr<AVCodecContext, decltype(avcodec_close)*> codec_ctx_cleanup(
                codec_ctx, avcodec_close);
 
-       // Read packets until we have a frame.
+       // Read packets until we have a frame or there are none left.
        int frame_finished = 0;
        auto frame = av_frame_alloc_unique();
        do {
@@ -163,8 +163,7 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &fil
                pkt.data = nullptr;
                pkt.size = 0;
                if (av_read_frame(format_ctx.get(), &pkt) < 0) {
-                       fprintf(stderr, "%s: Cannot read frame\n", filename.c_str());
-                       return nullptr;
+                       break;
                }
                if (pkt.stream_index != stream_index) {
                        continue;
@@ -176,6 +175,21 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &fil
                }
        } while (!frame_finished);
 
+       // See if there's a cached frame for us.
+       if (!frame_finished) {
+               AVPacket pkt;
+               pkt.data = nullptr;
+               pkt.size = 0;
+               if (avcodec_decode_video2(codec_ctx, frame.get(), &frame_finished, &pkt) < 0) {
+                       fprintf(stderr, "%s: Cannot decode frame\n", filename.c_str());
+                       return nullptr;
+               }
+       }
+       if (!frame_finished) {
+               fprintf(stderr, "%s: Decoder did not output frame.\n", filename.c_str());
+               return nullptr;
+       }
+
        // TODO: Scale down if needed!
        uint8_t *pic_data[4] = {nullptr};
        unique_ptr<uint8_t *, decltype(av_freep)*> pic_data_cleanup(