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

Code before:
                        m_compression_level = MIN(MAX(m_compression_level, 0), Z_BEST_COMPRESSION);
                        set_compression_level = true;
                    }
                    if( params[i] == IMWRITE_PNG_STRATEGY )
                    {
                        m_compression_strategy = params[i+1];
                        m_compression_strategy = MIN(MAX(m_compression_strategy, 0), Z_FIXED);
                    }
                    if( params[i] == IMWRITE_PNG_BILEVEL )
                    {
                        m_isBilevel = params[i+1] != 0;
                    }
                    if( params[i] == IMWRITE_PNG_FILTER )
                    {
                        m_filter = params[i+1];
                        set_filter = true;
                    }
                }

                if( m_buf || f )
                {
                    if (!set_compression_level || set_filter)
                        png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, m_filter);
                    png_set_compression_level(png_ptr, m_compression_level);
                    png_set_compression_strategy(png_ptr, m_compression_strategy);

                    png_set_IHDR( png_ptr, info_ptr, width, height, depth == CV_8U ? m_isBilevel ? 1 : 8 : 16,
                        channels == 1 ? PNG_COLOR_TYPE_GRAY :
                        channels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA,
                        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                        PNG_FILTER_TYPE_DEFAULT );

                    png_write_info( png_ptr, info_ptr );

                    if (m_isBilevel)
                        png_set_packing(png_ptr);

                    png_set_bgr( png_ptr );
                    if( !isBigEndian() )
                        png_set_swap( png_ptr );

                    buffer.allocate(height);
                    for( y = 0; y < height; y++ )
                        buffer[y] = img.data + y*img.step;

                    if (!m_metadata.empty()) {
                        std::vector<uchar>& exif = m_metadata[IMAGE_METADATA_EXIF];
                        if (!exif.empty()) {
                            writeChunk(f, "eXIf", exif.data(), (uint32_t)exif.size());
                        }
                        // [TODO] add xmp and icc. They need special handling,

Review comment (bug):
The error is user input error in code and definitely means some bug. The common rule in OpenCV is to use CV_Assert and throw exceptions for the developer mistakes, but not ignore it. I propose to return back CV_Error and merge it.

Code after:
                        m_compression_level = params[i+1];
                        m_compression_level = MIN(MAX(m_compression_level, 0), Z_BEST_COMPRESSION);
                        set_compression_level = true;
                        break;

                    case IMWRITE_PNG_STRATEGY:
                        m_compression_strategy = params[i+1];
                        m_compression_strategy = MIN(MAX(m_compression_strategy, 0), Z_FIXED);
                        break;

                    case IMWRITE_PNG_BILEVEL:
                        m_isBilevel = params[i+1] != 0;
                        break;

                    case IMWRITE_PNG_FILTER:
                        m_filter = params[i+1];
                        set_filter = true;
                        break;

                    case IMWRITE_PNG_ZLIBBUFFER_SIZE:
                        png_set_compression_buffer_size(png_ptr, params[i+1]);
                        break;

                    default:
                        CV_LOG_WARNING(NULL, "An unknown or unsupported ImwriteFlags value was specified and has been ignored.");
                        break;
                    }
                }

                if( m_buf || f )
                {
                    if (!set_compression_level || set_filter)
                        png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, m_filter);
                    png_set_compression_level(png_ptr, m_compression_level);
                    png_set_compression_strategy(png_ptr, m_compression_strategy);

                    png_set_IHDR( png_ptr, info_ptr, width, height, depth == CV_8U ? m_isBilevel ? 1 : 8 : 16,
                        channels == 1 ? PNG_COLOR_TYPE_GRAY :
                        channels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA,
                        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                        PNG_FILTER_TYPE_DEFAULT );

                    png_write_info( png_ptr, info_ptr );

                    if (m_isBilevel)
                        png_set_packing(png_ptr);

                    png_set_bgr( png_ptr );
                    if( !isBigEndian() )
                        png_set_swap( png_ptr );