diff --git a/modules/highgui/include/opencv2/highgui.hpp b/modules/highgui/include/opencv2/highgui.hpp index 601b872af4..2f44c897de 100644 --- a/modules/highgui/include/opencv2/highgui.hpp +++ b/modules/highgui/include/opencv2/highgui.hpp @@ -215,12 +215,13 @@ enum { IMREAD_UNCHANGED = -1, // 8bit, color or not IMREAD_ANYCOLOR = 4 // ?, any color }; -enum { IMWRITE_JPEG_QUALITY = 1, - IMWRITE_PNG_COMPRESSION = 16, - IMWRITE_PNG_STRATEGY = 17, - IMWRITE_PNG_BILEVEL = 18, - IMWRITE_PXM_BINARY = 32, - IMWRITE_WEBP_QUALITY = 64 +enum { IMWRITE_JPEG_QUALITY = 1, + IMWRITE_JPEG_PROGRESSIVE = 2, + IMWRITE_PNG_COMPRESSION = 16, + IMWRITE_PNG_STRATEGY = 17, + IMWRITE_PNG_BILEVEL = 18, + IMWRITE_PXM_BINARY = 32, + IMWRITE_WEBP_QUALITY = 64 }; enum { IMWRITE_PNG_STRATEGY_DEFAULT = 0, diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index ec9b7853a7..699c5b6b46 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -220,6 +220,7 @@ CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD enum { CV_IMWRITE_JPEG_QUALITY =1, + CV_IMWRITE_JPEG_PROGRESSIVE =2, CV_IMWRITE_PNG_COMPRESSION =16, CV_IMWRITE_PNG_STRATEGY =17, CV_IMWRITE_PNG_BILEVEL =18, diff --git a/modules/highgui/src/grfmt_jpeg.cpp b/modules/highgui/src/grfmt_jpeg.cpp index 28c52e8598..383dbdcf55 100644 --- a/modules/highgui/src/grfmt_jpeg.cpp +++ b/modules/highgui/src/grfmt_jpeg.cpp @@ -598,6 +598,7 @@ bool JpegEncoder::write( const Mat& img, const std::vector& params ) cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE; int quality = 95; + int progressive = 0; for( size_t i = 0; i < params.size(); i += 2 ) { @@ -606,11 +607,18 @@ bool JpegEncoder::write( const Mat& img, const std::vector& params ) quality = params[i+1]; quality = MIN(MAX(quality, 0), 100); } + + if( params[i] == CV_IMWRITE_JPEG_PROGRESSIVE ) + { + progressive = params[i+1]; + } } jpeg_set_defaults( &cinfo ); jpeg_set_quality( &cinfo, quality, TRUE /* limit to baseline-JPEG values */ ); + if( progressive ) + jpeg_simple_progression( &cinfo ); jpeg_start_compress( &cinfo, TRUE ); if( channels > 1 ) diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index 11533e3cad..bfb396881e 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -386,6 +386,30 @@ TEST(Highgui_Jpeg, encode_empty) ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception); } + +TEST(Highgui_Jpeg, encode_decode_progressive_jpeg) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + std::vector params; + params.push_back(IMWRITE_JPEG_PROGRESSIVE); + params.push_back(1); + + string output_progressive = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params)); + cv::Mat img_jpg_progressive = cv::imread(output_progressive); + + string output_normal = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_normal, img)); + cv::Mat img_jpg_normal = cv::imread(output_normal); + + EXPECT_EQ(0, cv::norm(img_jpg_progressive, img_jpg_normal, NORM_INF)); + + remove(output_progressive.c_str()); +} #endif