| 79 | } |
| 80 | |
| 81 | std::shared_ptr<ImageCodec> JpegCodec::MakeFromData(const std::string& filePath, |
| 82 | std::shared_ptr<Data> byteData) { |
| 83 | FILE* infile = nullptr; |
| 84 | if (byteData == nullptr && (infile = fopen(filePath.c_str(), "rb")) == nullptr) { |
| 85 | return nullptr; |
| 86 | } |
| 87 | jpeg_decompress_struct cinfo = {}; |
| 88 | my_error_mgr jerr = {}; |
| 89 | cinfo.err = jpeg_std_error(&jerr.pub); |
| 90 | Orientation orientation = Orientation::TopLeft; |
| 91 | do { |
| 92 | if (setjmp(jerr.setjmp_buffer)) break; |
| 93 | jpeg_create_decompress(&cinfo); |
| 94 | if (infile) { |
| 95 | jpeg_stdio_src(&cinfo, infile); |
| 96 | } else { |
| 97 | jpeg_mem_src(&cinfo, byteData->bytes(), byteData->size()); |
| 98 | } |
| 99 | jpeg_save_markers(&cinfo, kExifMarker, 0xFFFF); |
| 100 | if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) break; |
| 101 | orientation = get_exif_orientation(&cinfo); |
| 102 | } while (false); |
| 103 | jpeg_destroy_decompress(&cinfo); |
| 104 | if (infile) fclose(infile); |
| 105 | if (cinfo.image_width == 0 || cinfo.image_height == 0) { |
| 106 | return nullptr; |
| 107 | } |
| 108 | return std::shared_ptr<ImageCodec>(new JpegCodec(static_cast<int>(cinfo.image_width), |
| 109 | static_cast<int>(cinfo.image_height), |
| 110 | orientation, filePath, std::move(byteData))); |
| 111 | } |
| 112 | |
| 113 | bool ExtractICCProfile(jpeg_decompress_struct* cinfo, std::vector<uint8_t>& iccProfileData) { |
| 114 | jpeg_saved_marker_ptr marker = cinfo->marker_list; |
nothing calls this directly
no test coverage detected