27 void jpeg_error_throw(j_common_ptr p_cinfo) {
28 if (p_cinfo->is_decompressor)
29 jpeg_destroy_decompress(
30 reinterpret_cast<jpeg_decompress_struct *
>(p_cinfo));
32 jpeg_destroy_compress(
33 reinterpret_cast<jpeg_compress_struct *
>(p_cinfo));
34 char buffer[JMSG_LENGTH_MAX];
35 (*p_cinfo->err->format_message)(p_cinfo, buffer);
36 throw std::runtime_error(buffer);
42 struct jpeg_decompress_struct cinfo;
43 struct jpeg_error_mgr jerr;
55 cinfo.err = jpeg_std_error(&jerr);
56 jerr.error_exit = jpeg_error_throw;
57 jpeg_create_decompress(&cinfo);
58 jpeg_stdio_src(&cinfo, file_in);
59 jpeg_read_header(&cinfo,
TRUE);
62 int num_of_channels = 3;
63 switch (cinfo.jpeg_color_space) {
66 cinfo.out_color_space = JCS_RGB;
67 cinfo.out_color_components = 3;
71 cinfo.jpeg_color_space = JCS_GRAYSCALE;
72 cinfo.out_color_components = 1;
79 "Read JPG failed: color space not supported.");
80 jpeg_destroy_decompress(&cinfo);
85 jpeg_start_decompress(&cinfo);
87 image.Reset(cinfo.output_height, cinfo.output_width, num_of_channels,
90 int row_stride = cinfo.output_width * cinfo.output_components;
91 buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
93 uint8_t *pdata =
static_cast<uint8_t *
>(
image.GetDataPtr());
95 while (cinfo.output_scanline < cinfo.output_height) {
96 jpeg_read_scanlines(&cinfo, buffer, 1);
98 buffer[0], row_stride * 1);
101 jpeg_finish_decompress(&cinfo);
102 jpeg_destroy_decompress(&cinfo);
105 }
catch (
const std::runtime_error &err) {
116 if (
image.IsEmpty()) {
121 (
image.GetChannels() != 1 &&
image.GetChannels() != 3)) {
127 if (quality < 0 || quality > 100) {
129 "Write JPG failed: image quality should be in the range "
134 struct jpeg_compress_struct cinfo;
135 struct jpeg_error_mgr jerr;
137 JSAMPROW row_pointer[1];
146 cinfo.err = jpeg_std_error(&jerr);
147 jerr.error_exit = jpeg_error_throw;
148 jpeg_create_compress(&cinfo);
149 jpeg_stdio_dest(&cinfo, file_out);
150 cinfo.image_width =
image.GetCols();
151 cinfo.image_height =
image.GetRows();
152 cinfo.input_components =
image.GetChannels();
153 cinfo.in_color_space =
154 (cinfo.input_components == 1 ? JCS_GRAYSCALE : JCS_RGB);
155 jpeg_set_defaults(&cinfo);
156 jpeg_set_quality(&cinfo, quality,
TRUE);
157 jpeg_start_compress(&cinfo,
TRUE);
158 int row_stride =
image.GetCols() *
image.GetChannels();
159 const uint8_t *pdata =
static_cast<const uint8_t *
>(
image.GetDataPtr());
160 std::vector<uint8_t> buffer(row_stride);
161 while (cinfo.next_scanline < cinfo.image_height) {
163 buffer.data(), pdata,
image.GetDevice(), row_stride * 1);
164 row_pointer[0] = buffer.data();
165 jpeg_write_scanlines(&cinfo, row_pointer, 1);
168 jpeg_finish_compress(&cinfo);
170 jpeg_destroy_compress(&cinfo);
172 }
catch (
const std::runtime_error &err) {
std::shared_ptr< core::Tensor > image
static void MemcpyFromHost(void *dst_ptr, const Device &dst_device, const void *host_ptr, size_t num_bytes)
Same as Memcpy, but with host (CPU:0) as default src_device.
static void MemcpyToHost(void *host_ptr, const void *src_ptr, const Device &src_device, size_t num_bytes)
Same as Memcpy, but with host (CPU:0) as default dst_device.
The Image class stores image with customizable rows, cols, channels, dtype and device.
constexpr int kCloudViewerImageIODefaultQuality
bool WriteImageToJPG(const std::string &filename, const geometry::Image &image, int quality)
bool ReadImageFromJPG(const std::string &filename, geometry::Image &image)
FILE * FOpen(const std::string &filename, const std::string &mode)
Generic file read and write utility for python interface.