Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageIoLibjpeg.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Libjpeg backend for JPEG image I/O operations.
32 */
33
38
39#include "vpImageIoBackend.h"
40#include <visp3/core/vpImageConvert.h>
41
42#if defined(VISP_HAVE_JPEG)
43#include <jerror.h>
44#include <jpeglib.h>
45#endif
46
47//--------------------------------------------------------------------------
48// JPEG
49//--------------------------------------------------------------------------
50
51#if defined(VISP_HAVE_JPEG)
52
62void writeJPEGLibjpeg(const vpImage<unsigned char> &I, const std::string &filename, int quality)
63{
64 struct jpeg_compress_struct cinfo;
65 struct jpeg_error_mgr jerr;
66 FILE *file;
67
68 cinfo.err = jpeg_std_error(&jerr);
69 jpeg_create_compress(&cinfo);
70
71 // Test the filename
72 if (filename.empty()) {
73 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
74 }
75
76 file = fopen(filename.c_str(), "wb");
77
78 if (file == nullptr) {
79 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
80 }
81
82 unsigned int width = I.getWidth();
83 unsigned int height = I.getHeight();
84
85 jpeg_stdio_dest(&cinfo, file);
86
87 cinfo.image_width = width;
88 cinfo.image_height = height;
89 cinfo.input_components = 1;
90 cinfo.in_color_space = JCS_GRAYSCALE;
91 jpeg_set_defaults(&cinfo);
92 jpeg_set_quality(&cinfo, quality, TRUE);
93
94 jpeg_start_compress(&cinfo, TRUE);
95
96 unsigned char *line;
97 line = new unsigned char[width];
98 unsigned char *input = (unsigned char *)I.bitmap;
99 while (cinfo.next_scanline < cinfo.image_height) {
100 for (unsigned int i = 0; i < width; ++i) {
101 line[i] = *(input);
102 input++;
103 }
104 jpeg_write_scanlines(&cinfo, &line, 1);
105 }
106
107 jpeg_finish_compress(&cinfo);
108 jpeg_destroy_compress(&cinfo);
109 delete[] line;
110 fclose(file);
111}
112
121void writeJPEGLibjpeg(const vpImage<vpRGBa> &I, const std::string &filename, int quality)
122{
123 struct jpeg_compress_struct cinfo;
124 struct jpeg_error_mgr jerr;
125 FILE *file;
126
127 cinfo.err = jpeg_std_error(&jerr);
128 jpeg_create_compress(&cinfo);
129
130 // Test the filename
131 if (filename.empty()) {
132 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
133 }
134
135 file = fopen(filename.c_str(), "wb");
136
137 if (file == nullptr) {
138 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
139 }
140
141 unsigned int width = I.getWidth();
142 unsigned int height = I.getHeight();
143
144 jpeg_stdio_dest(&cinfo, file);
145
146 cinfo.image_width = width;
147 cinfo.image_height = height;
148 cinfo.input_components = 3;
149 cinfo.in_color_space = JCS_RGB;
150 jpeg_set_defaults(&cinfo);
151 jpeg_set_quality(&cinfo, quality, TRUE);
152
153 jpeg_start_compress(&cinfo, TRUE);
154
155 unsigned char *line;
156 line = new unsigned char[3 * width];
157 unsigned char *input = (unsigned char *)I.bitmap;
158 while (cinfo.next_scanline < cinfo.image_height) {
159 for (unsigned int i = 0; i < width; ++i) {
160 line[i * 3] = *(input);
161 input++;
162 line[i * 3 + 1] = *(input);
163 input++;
164 line[i * 3 + 2] = *(input);
165 input++;
166 input++;
167 }
168 jpeg_write_scanlines(&cinfo, &line, 1);
169 }
170
171 jpeg_finish_compress(&cinfo);
172 jpeg_destroy_compress(&cinfo);
173 delete[] line;
174 fclose(file);
175}
176
192void readJPEGLibjpeg(vpImage<unsigned char> &I, const std::string &filename)
193{
194 struct jpeg_decompress_struct cinfo;
195 struct jpeg_error_mgr jerr;
196 FILE *file;
197
198 cinfo.err = jpeg_std_error(&jerr);
199 jpeg_create_decompress(&cinfo);
200
201 // Test the filename
202 if (filename.empty()) {
203 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
204 }
205
206 file = fopen(filename.c_str(), "rb");
207
208 if (file == nullptr) {
209 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
210 }
211
212 jpeg_stdio_src(&cinfo, file);
213 jpeg_read_header(&cinfo, TRUE);
214
215 unsigned int width = cinfo.image_width;
216 unsigned int height = cinfo.image_height;
217
218 if ((width != I.getWidth()) || (height != I.getHeight()))
219 I.resize(height, width);
220
221 jpeg_start_decompress(&cinfo);
222
223 unsigned int rowbytes = cinfo.output_width * static_cast<unsigned int>(cinfo.output_components);
224 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
225
226 if (cinfo.out_color_space == JCS_RGB) {
227 vpImage<vpRGBa> Ic(height, width);
228 unsigned char *output = (unsigned char *)Ic.bitmap;
229 while (cinfo.output_scanline < cinfo.output_height) {
230 jpeg_read_scanlines(&cinfo, buffer, 1);
231 for (unsigned int i = 0; i < width; ++i) {
232 *(output++) = buffer[0][i * 3];
233 *(output++) = buffer[0][i * 3 + 1];
234 *(output++) = buffer[0][i * 3 + 2];
235 *(output++) = vpRGBa::alpha_default;
236 }
237 }
239 }
240
241 else if (cinfo.out_color_space == JCS_GRAYSCALE) {
242 while (cinfo.output_scanline < cinfo.output_height) {
243 unsigned int row = cinfo.output_scanline;
244 jpeg_read_scanlines(&cinfo, buffer, 1);
245 memcpy(I[row], buffer[0], rowbytes);
246 }
247 }
248
249 jpeg_finish_decompress(&cinfo);
250 jpeg_destroy_decompress(&cinfo);
251 fclose(file);
252}
253
272void readJPEGLibjpeg(vpImage<vpRGBa> &I, const std::string &filename)
273{
274 struct jpeg_decompress_struct cinfo;
275 struct jpeg_error_mgr jerr;
276 FILE *file;
277
278 cinfo.err = jpeg_std_error(&jerr);
279 jpeg_create_decompress(&cinfo);
280
281 // Test the filename
282 if (filename.empty()) {
283 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
284 }
285
286 file = fopen(filename.c_str(), "rb");
287
288 if (file == nullptr) {
289 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
290 }
291
292 jpeg_stdio_src(&cinfo, file);
293
294 jpeg_read_header(&cinfo, TRUE);
295
296 unsigned int width = cinfo.image_width;
297 unsigned int height = cinfo.image_height;
298
299 if ((width != I.getWidth()) || (height != I.getHeight()))
300 I.resize(height, width);
301
302 jpeg_start_decompress(&cinfo);
303
304 unsigned int rowbytes = cinfo.output_width * static_cast<unsigned int>(cinfo.output_components);
305 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
306
307 if (cinfo.out_color_space == JCS_RGB) {
308 unsigned char *output = (unsigned char *)I.bitmap;
309 while (cinfo.output_scanline < cinfo.output_height) {
310 jpeg_read_scanlines(&cinfo, buffer, 1);
311 for (unsigned int i = 0; i < width; ++i) {
312 *(output++) = buffer[0][i * 3];
313 *(output++) = buffer[0][i * 3 + 1];
314 *(output++) = buffer[0][i * 3 + 2];
315 *(output++) = vpRGBa::alpha_default;
316 }
317 }
318 }
319
320 else if (cinfo.out_color_space == JCS_GRAYSCALE) {
321 vpImage<unsigned char> Ig(height, width);
322
323 while (cinfo.output_scanline < cinfo.output_height) {
324 unsigned int row = cinfo.output_scanline;
325 jpeg_read_scanlines(&cinfo, buffer, 1);
326 memcpy(Ig[row], buffer[0], rowbytes);
327 }
328
330 }
331
332 jpeg_finish_decompress(&cinfo);
333 jpeg_destroy_decompress(&cinfo);
334 fclose(file);
335}
336
337END_VISP_NAMESPACE
338
339#endif
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
@ ioError
Image io error.
Definition of the vpImage class member functions.
Definition vpImage.h:131
@ alpha_default
Definition vpRGBa.h:76