Repository: opencv/opencv
File: modules/imgcodecs/src/grfmt_png.cpp (C++)

Code before:
                // Asking for blend over with no alpha is invalid.
                if (bop == 1 && mat_cur.channels() != 4)
                {
                    return false;
                }

                memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);

                if (m_is_fcTL_loaded)
                    return true;
                else
                {
                    m_is_fcTL_loaded = true;
                    return readData(img);
                }
            }
            else if (id == id_IDAT)
            {
                m_is_IDAT_loaded = true;
                png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
            }
            else if (id == id_fdAT && m_is_fcTL_loaded)
            {
                m_is_IDAT_loaded = true;
                png_save_uint_32(&chunk.p[4], static_cast<uint32_t>(chunk.p.size() - 16));
                memcpy(&chunk.p[8], "IDAT", 4);
                png_process_data(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
            }
            else if (id == id_IEND)
            {
                if (processing_finish())
                {
                    compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
                    if (!delay_den)
                        delay_den = 100;
                    m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));

                    if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
                        mat_cur.convertTo(img, CV_8U, 1. / 255);
                    else
                    {
                        if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
                            mat_cur.convertTo(mat_cur, CV_8U, 1. / 255);
                        if (mat_cur.channels() == img.channels())
                            mat_cur.copyTo(img);
                        else if (img.channels() == 1)
                            cvtColor(mat_cur, img, COLOR_BGRA2GRAY);
                        else if (img.channels() == 3)
                            cvtColor(mat_cur, img, COLOR_BGRA2BGR);
                    }
                }

Review comment (suggestion):
The line changes simple imread behavior, right? I propose to return still image in case if user reads animation as single frame. It's APNG design decision and also presumes current OpenCV behaviour.

Code after:
                delay_num = png_get_uint_16(&chunk.p[28]);
                delay_den = png_get_uint_16(&chunk.p[30]);
                dop = chunk.p[32];
                bop = chunk.p[33];

                if (int(x0 + w0) > img.cols || int(y0 + h0) > img.rows || dop > 2 || bop > 1)
                {
                    return false;
                }
                // Asking for blend over with no alpha is invalid.
                if (bop == 1 && mat_cur.channels() != 4)
                {
                    return false;
                }

                memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);

                if (m_is_fcTL_loaded)
                    return true;
                else
                {
                    m_is_fcTL_loaded = true;
                    ClearPngPtr();
                    if (!processing_start((void*)&frameRaw, mat_cur))
                        return false;
                }
            }
            else if (id == id_IDAT)
            {
                m_is_IDAT_loaded = true;
                png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
            }
            else if (id == id_fdAT && m_is_fcTL_loaded)
            {
                m_is_IDAT_loaded = true;
                png_save_uint_32(&chunk.p[4], static_cast<uint32_t>(chunk.p.size() - 16));
                memcpy(&chunk.p[8], "IDAT", 4);
                png_process_data(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
            }
            else if (id == id_IEND)
            {
                if (processing_finish())
                {
                    compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
                    if (!delay_den)
                        delay_den = 100;
                    m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));

                    if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
                        mat_cur.convertTo(img, CV_8U, 1. / 255);
                    else