Skip to content

Commit b659351

Browse files
authored
Merge pull request opencv#25647 from Kumataro:fix25646
imgcodecs: support IMWRITE_JPEG_LUMA/CHROMA_QUALITY with internal libjpeg-turbo opencv#25647 Close opencv#25646 - increase JPEG_LIB_VERSION for internal libjpeg-turbo from 62 to 70 - add log when using IMWRITE_JPEG_LUMA/CHROMA_QUALITY with JPEG_LIB_VERSION<70 - add document IMWRITE_JPEG_LUMA/CHROMA_QUALITY requests JPEG_LIB_VERSION >= 70 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
1 parent c5976f7 commit b659351

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

3rdparty/libjpeg-turbo/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ if(WITH_ARITH_DEC)
134134
set(D_ARITH_CODING_SUPPORTED 1)
135135
endif()
136136

137-
set(JPEG_LIB_VERSION 62)
137+
set(JPEG_LIB_VERSION 70)
138138

139139
# OpenCV
140140
set(JPEG_LIB_VERSION "${VERSION}-${JPEG_LIB_VERSION}" PARENT_SCOPE)

modules/imgcodecs/include/opencv2/imgcodecs.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ enum ImwriteFlags {
8787
IMWRITE_JPEG_PROGRESSIVE = 2, //!< Enable JPEG features, 0 or 1, default is False.
8888
IMWRITE_JPEG_OPTIMIZE = 3, //!< Enable JPEG features, 0 or 1, default is False.
8989
IMWRITE_JPEG_RST_INTERVAL = 4, //!< JPEG restart interval, 0 - 65535, default is 0 - no restart.
90-
IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is -1 - don't use.
91-
IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is -1 - don't use.
90+
IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is -1 - don't use. If JPEG_LIB_VERSION < 70, Not supported.
91+
IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is -1 - don't use. If JPEG_LIB_VERSION < 70, Not supported.
9292
IMWRITE_JPEG_SAMPLING_FACTOR = 7, //!< For JPEG, set sampling factor. See cv::ImwriteJPEGSamplingFactorParams.
9393
IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting).
9494
IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE.

modules/imgcodecs/src/grfmt_jpeg.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,9 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
783783
cinfo.comp_info[1].h_samp_factor = 1;
784784
}
785785

786-
#if JPEG_LIB_VERSION >= 70
787786
if (luma_quality >= 0 && chroma_quality >= 0)
788787
{
788+
#if JPEG_LIB_VERSION >= 70
789789
cinfo.q_scale_factor[0] = jpeg_quality_scaling(luma_quality);
790790
cinfo.q_scale_factor[1] = jpeg_quality_scaling(chroma_quality);
791791
if ( luma_quality != chroma_quality )
@@ -797,8 +797,11 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
797797
cinfo.comp_info[1].h_samp_factor = 1;
798798
}
799799
jpeg_default_qtables( &cinfo, TRUE );
800-
}
800+
#else
801+
// See https://github.com/opencv/opencv/issues/25646
802+
CV_LOG_ONCE_WARNING(NULL, cv::format("IMWRITE_JPEG_LUMA/CHROMA_QUALITY are not supported bacause JPEG_LIB_VERSION < 70."));
801803
#endif // #if JPEG_LIB_VERSION >= 70
804+
}
802805

803806
jpeg_start_compress( &cinfo, TRUE );
804807

modules/imgcodecs/test/test_jpeg.cpp

+62
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ namespace opencv_test { namespace {
77

88
#ifdef HAVE_JPEG
99

10+
extern "C" {
11+
#include "jpeglib.h"
12+
}
13+
1014
/**
1115
* Test for check whether reading exif orientation tag was processed successfully or not
1216
* The test info is the set of 8 images named testExifRotate_{1 to 8}.jpg
@@ -308,6 +312,64 @@ TEST(Imgcodecs_Jpeg, encode_subsamplingfactor_usersetting_invalid)
308312
}
309313
}
310314

315+
//==================================================================================================
316+
// See https://github.com/opencv/opencv/issues/25646
317+
typedef testing::TestWithParam<std::tuple<int, int>> Imgcodecs_Jpeg_encode_withLumaChromaQuality;
318+
319+
TEST_P(Imgcodecs_Jpeg_encode_withLumaChromaQuality, basic)
320+
{
321+
const int luma = get<0>(GetParam());
322+
const int chroma = get<1>(GetParam());
323+
324+
cvtest::TS& ts = *cvtest::TS::ptr();
325+
string fname = string(ts.get_data_path()) + "../cv/shared/lena.png";
326+
327+
cv::Mat src = imread(fname, cv::IMREAD_COLOR);
328+
ASSERT_FALSE(src.empty());
329+
330+
std::vector<uint8_t> jpegNormal;
331+
ASSERT_NO_THROW(cv::imencode(".jpg", src, jpegNormal));
332+
333+
std::vector<int> param;
334+
param.push_back(IMWRITE_JPEG_LUMA_QUALITY);
335+
param.push_back(luma);
336+
param.push_back(IMWRITE_JPEG_CHROMA_QUALITY);
337+
param.push_back(chroma);
338+
339+
std::vector<uint8_t> jpegCustom;
340+
ASSERT_NO_THROW(cv::imencode(".jpg", src, jpegCustom, param));
341+
342+
#if JPEG_LIB_VERSION >= 70
343+
// For jpeg7+, we can support IMWRITE_JPEG_LUMA_QUALITY and IMWRITE_JPEG_CHROMA_QUALITY.
344+
if( (luma == 95 /* Default Luma Quality */ ) && ( chroma == 95 /* Default Chroma Quality */))
345+
{
346+
EXPECT_EQ(jpegNormal, jpegCustom);
347+
}
348+
else
349+
{
350+
EXPECT_NE(jpegNormal, jpegCustom);
351+
}
352+
#else
353+
// For jpeg6-, we cannot support IMWRITE_JPEG_LUMA/CHROMA_QUALITY because jpeg_default_qtables() is missing.
354+
// - IMWRITE_JPEG_LUMA_QUALITY updates internal parameter of IMWRITE_JPEG_QUALITY.
355+
// - IMWRITE_JPEG_CHROMA_QUALITY updates nothing.
356+
if( luma == 95 /* Default Jpeg Quality */ )
357+
{
358+
EXPECT_EQ(jpegNormal, jpegCustom);
359+
}
360+
else
361+
{
362+
EXPECT_NE(jpegNormal, jpegCustom);
363+
}
364+
#endif
365+
}
366+
367+
INSTANTIATE_TEST_CASE_P( /* nothing */,
368+
Imgcodecs_Jpeg_encode_withLumaChromaQuality,
369+
testing::Combine(
370+
testing::Values(70, 95, 100), // IMWRITE_JPEG_LUMA_QUALITY
371+
testing::Values(70, 95, 100) )); // IMWRITE_JPEG_CHROMA_QUALITY
372+
311373
#endif // HAVE_JPEG
312374

313375
}} // namespace

0 commit comments

Comments
 (0)