1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html
4 #include "test_precomp.hpp"
5 
6 namespace opencv_test { namespace {
7 
8 #ifdef HAVE_JPEG
9 
10 /**
11  * Test for check whether reading exif orientation tag was processed successfully or not
12  * The test info is the set of 8 images named testExifRotate_{1 to 8}.jpg
13  * The test image is the square 10x10 points divided by four sub-squares:
14  * (R corresponds to Red, G to Green, B to Blue, W to white)
15  * ---------             ---------
16  * | R | G |             | G | R |
17  * |-------| - (tag 1)   |-------| - (tag 2)
18  * | B | W |             | W | B |
19  * ---------             ---------
20  *
21  * ---------             ---------
22  * | W | B |             | B | W |
23  * |-------| - (tag 3)   |-------| - (tag 4)
24  * | G | R |             | R | G |
25  * ---------             ---------
26  *
27  * ---------             ---------
28  * | R | B |             | G | W |
29  * |-------| - (tag 5)   |-------| - (tag 6)
30  * | G | W |             | R | B |
31  * ---------             ---------
32  *
33  * ---------             ---------
34  * | W | G |             | B | R |
35  * |-------| - (tag 7)   |-------| - (tag 8)
36  * | B | R |             | W | G |
37  * ---------             ---------
38  *
39  *
40  * Every image contains exif field with orientation tag (0x112)
41  * After reading each image the corresponding matrix must be read as
42  * ---------
43  * | R | G |
44  * |-------|
45  * | B | W |
46  * ---------
47  *
48  */
49 
50 typedef testing::TestWithParam<string> Imgcodecs_Jpeg_Exif;
51 
TEST_P(Imgcodecs_Jpeg_Exif,exif_orientation)52 TEST_P(Imgcodecs_Jpeg_Exif, exif_orientation)
53 {
54     const string root = cvtest::TS::ptr()->get_data_path();
55     const string filename = root + GetParam();
56     const int colorThresholdHigh = 250;
57     const int colorThresholdLow = 5;
58 
59     Mat m_img = imread(filename);
60     ASSERT_FALSE(m_img.empty());
61     Vec3b vec;
62 
63     //Checking the first quadrant (with supposed red)
64     vec = m_img.at<Vec3b>(2, 2); //some point inside the square
65     EXPECT_LE(vec.val[0], colorThresholdLow);
66     EXPECT_LE(vec.val[1], colorThresholdLow);
67     EXPECT_GE(vec.val[2], colorThresholdHigh);
68 
69     //Checking the second quadrant (with supposed green)
70     vec = m_img.at<Vec3b>(2, 7);  //some point inside the square
71     EXPECT_LE(vec.val[0], colorThresholdLow);
72     EXPECT_GE(vec.val[1], colorThresholdHigh);
73     EXPECT_LE(vec.val[2], colorThresholdLow);
74 
75     //Checking the third quadrant (with supposed blue)
76     vec = m_img.at<Vec3b>(7, 2);  //some point inside the square
77     EXPECT_GE(vec.val[0], colorThresholdHigh);
78     EXPECT_LE(vec.val[1], colorThresholdLow);
79     EXPECT_LE(vec.val[2], colorThresholdLow);
80 }
81 
82 const string exif_files[] =
83 {
84     "readwrite/testExifOrientation_1.jpg",
85     "readwrite/testExifOrientation_2.jpg",
86     "readwrite/testExifOrientation_3.jpg",
87     "readwrite/testExifOrientation_4.jpg",
88     "readwrite/testExifOrientation_5.jpg",
89     "readwrite/testExifOrientation_6.jpg",
90     "readwrite/testExifOrientation_7.jpg",
91     "readwrite/testExifOrientation_8.jpg"
92 };
93 
94 INSTANTIATE_TEST_CASE_P(ExifFiles, Imgcodecs_Jpeg_Exif,
95                         testing::ValuesIn(exif_files));
96 
97 //==================================================================================================
98 
TEST(Imgcodecs_Jpeg,encode_empty)99 TEST(Imgcodecs_Jpeg, encode_empty)
100 {
101     cv::Mat img;
102     std::vector<uchar> jpegImg;
103     ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception);
104 }
105 
TEST(Imgcodecs_Jpeg,encode_decode_progressive_jpeg)106 TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg)
107 {
108     cvtest::TS& ts = *cvtest::TS::ptr();
109     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
110     cv::Mat img = cv::imread(input);
111     ASSERT_FALSE(img.empty());
112 
113     std::vector<int> params;
114     params.push_back(IMWRITE_JPEG_PROGRESSIVE);
115     params.push_back(1);
116 
117     string output_progressive = cv::tempfile(".jpg");
118     EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params));
119     cv::Mat img_jpg_progressive = cv::imread(output_progressive);
120 
121     string output_normal = cv::tempfile(".jpg");
122     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
123     cv::Mat img_jpg_normal = cv::imread(output_normal);
124 
125     EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF));
126 
127     EXPECT_EQ(0, remove(output_progressive.c_str()));
128     EXPECT_EQ(0, remove(output_normal.c_str()));
129 }
130 
TEST(Imgcodecs_Jpeg,encode_decode_optimize_jpeg)131 TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
132 {
133     cvtest::TS& ts = *cvtest::TS::ptr();
134     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
135     cv::Mat img = cv::imread(input);
136     ASSERT_FALSE(img.empty());
137 
138     std::vector<int> params;
139     params.push_back(IMWRITE_JPEG_OPTIMIZE);
140     params.push_back(1);
141 
142     string output_optimized = cv::tempfile(".jpg");
143     EXPECT_NO_THROW(cv::imwrite(output_optimized, img, params));
144     cv::Mat img_jpg_optimized = cv::imread(output_optimized);
145 
146     string output_normal = cv::tempfile(".jpg");
147     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
148     cv::Mat img_jpg_normal = cv::imread(output_normal);
149 
150     EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF));
151 
152     EXPECT_EQ(0, remove(output_optimized.c_str()));
153     EXPECT_EQ(0, remove(output_normal.c_str()));
154 }
155 
TEST(Imgcodecs_Jpeg,encode_decode_rst_jpeg)156 TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
157 {
158     cvtest::TS& ts = *cvtest::TS::ptr();
159     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
160     cv::Mat img = cv::imread(input);
161     ASSERT_FALSE(img.empty());
162 
163     std::vector<int> params;
164     params.push_back(IMWRITE_JPEG_RST_INTERVAL);
165     params.push_back(1);
166 
167     string output_rst = cv::tempfile(".jpg");
168     EXPECT_NO_THROW(cv::imwrite(output_rst, img, params));
169     cv::Mat img_jpg_rst = cv::imread(output_rst);
170 
171     string output_normal = cv::tempfile(".jpg");
172     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
173     cv::Mat img_jpg_normal = cv::imread(output_normal);
174 
175     EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF));
176 
177     EXPECT_EQ(0, remove(output_rst.c_str()));
178     EXPECT_EQ(0, remove(output_normal.c_str()));
179 }
180 
181 #endif // HAVE_JPEG
182 
183 }} // namespace
184