source_manager_test.cc (4305B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include <cmath> 7 #include <cstdint> 8 #include <vector> 9 10 #include "lib/jpegli/decode.h" 11 #include "lib/jpegli/test_utils.h" 12 #include "lib/jpegli/testing.h" 13 #include "lib/jxl/base/status.h" 14 15 namespace jpegli { 16 namespace { 17 18 void ReadOutputImage(j_decompress_ptr cinfo, TestImage* output) { 19 jpegli_read_header(cinfo, /*require_image=*/TRUE); 20 jpegli_start_decompress(cinfo); 21 output->ysize = cinfo->output_height; 22 output->xsize = cinfo->output_width; 23 output->components = cinfo->num_components; 24 output->AllocatePixels(); 25 size_t stride = cinfo->output_width * cinfo->num_components; 26 while (cinfo->output_scanline < cinfo->output_height) { 27 JSAMPROW scanline = &output->pixels[cinfo->output_scanline * stride]; 28 jpegli_read_scanlines(cinfo, &scanline, 1); 29 } 30 jpegli_finish_decompress(cinfo); 31 } 32 33 struct TestConfig { 34 std::string fn; 35 std::string fn_desc; 36 DecompressParams dparams; 37 }; 38 39 class SourceManagerTestParam : public ::testing::TestWithParam<TestConfig> {}; 40 41 namespace { 42 FILE* MemOpen(const std::vector<uint8_t>& data) { 43 FILE* src = tmpfile(); 44 if (!src) return nullptr; 45 fwrite(data.data(), 1, data.size(), src); 46 rewind(src); 47 return src; 48 } 49 } // namespace 50 51 TEST_P(SourceManagerTestParam, TestStdioSourceManager) { 52 TestConfig config = GetParam(); 53 std::vector<uint8_t> compressed = ReadTestData(config.fn); 54 if (config.dparams.size_factor < 1.0) { 55 compressed.resize(compressed.size() * config.dparams.size_factor); 56 } 57 FILE* src = MemOpen(compressed); 58 ASSERT_TRUE(src); 59 TestImage output0; 60 jpeg_decompress_struct cinfo; 61 const auto try_catch_block = [&]() -> bool { 62 ERROR_HANDLER_SETUP(jpegli); 63 jpegli_create_decompress(&cinfo); 64 jpegli_stdio_src(&cinfo, src); 65 ReadOutputImage(&cinfo, &output0); 66 return true; 67 }; 68 bool ok = try_catch_block(); 69 fclose(src); 70 ASSERT_TRUE(ok); 71 jpegli_destroy_decompress(&cinfo); 72 73 TestImage output1; 74 DecodeWithLibjpeg(CompressParams(), DecompressParams(), compressed, &output1); 75 VerifyOutputImage(output1, output0, 1.0f); 76 } 77 78 TEST_P(SourceManagerTestParam, TestMemSourceManager) { 79 TestConfig config = GetParam(); 80 std::vector<uint8_t> compressed = ReadTestData(config.fn); 81 if (config.dparams.size_factor < 1.0f) { 82 compressed.resize(compressed.size() * config.dparams.size_factor); 83 } 84 TestImage output0; 85 jpeg_decompress_struct cinfo; 86 const auto try_catch_block = [&]() -> bool { 87 ERROR_HANDLER_SETUP(jpegli); 88 jpegli_create_decompress(&cinfo); 89 jpegli_mem_src(&cinfo, compressed.data(), compressed.size()); 90 ReadOutputImage(&cinfo, &output0); 91 return true; 92 }; 93 ASSERT_TRUE(try_catch_block()); 94 jpegli_destroy_decompress(&cinfo); 95 96 TestImage output1; 97 DecodeWithLibjpeg(CompressParams(), DecompressParams(), compressed, &output1); 98 VerifyOutputImage(output1, output0, 1.0f); 99 } 100 101 std::vector<TestConfig> GenerateTests() { 102 std::vector<TestConfig> all_tests; 103 { 104 std::vector<std::pair<std::string, std::string>> testfiles({ 105 {"jxl/flower/flower.png.im_q85_444.jpg", "Q85YUV444"}, 106 {"jxl/flower/flower.png.im_q85_420.jpg", "Q85YUV420"}, 107 {"jxl/flower/flower.png.im_q85_420_R13B.jpg", "Q85YUV420R13B"}, 108 }); 109 for (const auto& it : testfiles) { 110 for (float size_factor : {0.1f, 0.33f, 0.5f, 0.75f}) { 111 TestConfig config; 112 config.fn = it.first; 113 config.fn_desc = it.second; 114 config.dparams.size_factor = size_factor; 115 all_tests.push_back(config); 116 } 117 } 118 return all_tests; 119 } 120 } 121 122 std::ostream& operator<<(std::ostream& os, const TestConfig& c) { 123 os << c.fn_desc; 124 if (c.dparams.size_factor < 1.0f) { 125 os << "Partial" << static_cast<int>(c.dparams.size_factor * 100) << "p"; 126 } 127 return os; 128 } 129 130 std::string TestDescription( 131 const testing::TestParamInfo<SourceManagerTestParam::ParamType>& info) { 132 std::stringstream name; 133 name << info.param; 134 return name.str(); 135 } 136 137 JPEGLI_INSTANTIATE_TEST_SUITE_P(SourceManagerTest, SourceManagerTestParam, 138 testing::ValuesIn(GenerateTests()), 139 TestDescription); 140 141 } // namespace 142 } // namespace jpegli