Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpImageIoLibjpeg.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 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
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
61void writeJPEGLibjpeg(const vpImage<unsigned char> &I, const std::string &filename, int quality)
62{
63 struct jpeg_compress_struct cinfo;
64 struct jpeg_error_mgr jerr;
65 FILE *file;
66
67 cinfo.err = jpeg_std_error(&jerr);
68 jpeg_create_compress(&cinfo);
69
70 // Test the filename
71 if (filename.empty()) {
72 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
73 }
74
75 file = fopen(filename.c_str(), "wb");
76
77 if (file == NULL) {
78 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
79 }
80
81 unsigned int width = I.getWidth();
82 unsigned int height = I.getHeight();
83
84 jpeg_stdio_dest(&cinfo, file);
85
86 cinfo.image_width = width;
87 cinfo.image_height = height;
88 cinfo.input_components = 1;
89 cinfo.in_color_space = JCS_GRAYSCALE;
90 jpeg_set_defaults(&cinfo);
91 jpeg_set_quality(&cinfo, quality, TRUE);
92
93 jpeg_start_compress(&cinfo, TRUE);
94
95 unsigned char *line;
96 line = new unsigned char[width];
97 unsigned char *input = (unsigned char *)I.bitmap;
98 while (cinfo.next_scanline < cinfo.image_height) {
99 for (unsigned int i = 0; i < width; i++) {
100 line[i] = *(input);
101 input++;
102 }
103 jpeg_write_scanlines(&cinfo, &line, 1);
104 }
105
106 jpeg_finish_compress(&cinfo);
107 jpeg_destroy_compress(&cinfo);
108 delete[] line;
109 fclose(file);
110}
111
120void writeJPEGLibjpeg(const vpImage<vpRGBa> &I, const std::string &filename, int quality)
121{
122 struct jpeg_compress_struct cinfo;
123 struct jpeg_error_mgr jerr;
124 FILE *file;
125
126 cinfo.err = jpeg_std_error(&jerr);
127 jpeg_create_compress(&cinfo);
128
129 // Test the filename
130 if (filename.empty()) {
131 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
132 }
133
134 file = fopen(filename.c_str(), "wb");
135
136 if (file == NULL) {
137 throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
138 }
139
140 unsigned int width = I.getWidth();
141 unsigned int height = I.getHeight();
142
143 jpeg_stdio_dest(&cinfo, file);
144
145 cinfo.image_width = width;
146 cinfo.image_height = height;
147 cinfo.input_components = 3;
148 cinfo.in_color_space = JCS_RGB;
149 jpeg_set_defaults(&cinfo);
150 jpeg_set_quality(&cinfo, quality, TRUE);
151
152 jpeg_start_compress(&cinfo, TRUE);
153
154 unsigned char *line;
155 line = new unsigned char[3 * width];
156 unsigned char *input = (unsigned char *)I.bitmap;
157 while (cinfo.next_scanline < cinfo.image_height) {
158 for (unsigned int i = 0; i < width; i++) {
159 line[i * 3] = *(input);
160 input++;
161 line[i * 3 + 1] = *(input);
162 input++;
163 line[i * 3 + 2] = *(input);
164 input++;
165 input++;
166 }
167 jpeg_write_scanlines(&cinfo, &line, 1);
168 }
169
170 jpeg_finish_compress(&cinfo);
171 jpeg_destroy_compress(&cinfo);
172 delete[] line;
173 fclose(file);
174}
175
191void readJPEGLibjpeg(vpImage<unsigned char> &I, const std::string &filename)
192{
193 struct jpeg_decompress_struct cinfo;
194 struct jpeg_error_mgr jerr;
195 FILE *file;
196
197 cinfo.err = jpeg_std_error(&jerr);
198 jpeg_create_decompress(&cinfo);
199
200 // Test the filename
201 if (filename.empty()) {
202 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
203 }
204
205 file = fopen(filename.c_str(), "rb");
206
207 if (file == NULL) {
208 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
209 }
210
211 jpeg_stdio_src(&cinfo, file);
212 jpeg_read_header(&cinfo, TRUE);
213
214 unsigned int width = cinfo.image_width;
215 unsigned int height = cinfo.image_height;
216
217 if ((width != I.getWidth()) || (height != I.getHeight()))
218 I.resize(height, width);
219
220 jpeg_start_decompress(&cinfo);
221
222 unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
223 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
224
225 if (cinfo.out_color_space == JCS_RGB) {
226 vpImage<vpRGBa> Ic(height, width);
227 unsigned char *output = (unsigned char *)Ic.bitmap;
228 while (cinfo.output_scanline < cinfo.output_height) {
229 jpeg_read_scanlines(&cinfo, buffer, 1);
230 for (unsigned int i = 0; i < width; i++) {
231 *(output++) = buffer[0][i * 3];
232 *(output++) = buffer[0][i * 3 + 1];
233 *(output++) = buffer[0][i * 3 + 2];
234 *(output++) = vpRGBa::alpha_default;
235 }
236 }
238 }
239
240 else if (cinfo.out_color_space == JCS_GRAYSCALE) {
241 while (cinfo.output_scanline < cinfo.output_height) {
242 unsigned int row = cinfo.output_scanline;
243 jpeg_read_scanlines(&cinfo, buffer, 1);
244 memcpy(I[row], buffer[0], rowbytes);
245 }
246 }
247
248 jpeg_finish_decompress(&cinfo);
249 jpeg_destroy_decompress(&cinfo);
250 fclose(file);
251}
252
271void readJPEGLibjpeg(vpImage<vpRGBa> &I, const std::string &filename)
272{
273 struct jpeg_decompress_struct cinfo;
274 struct jpeg_error_mgr jerr;
275 FILE *file;
276
277 cinfo.err = jpeg_std_error(&jerr);
278 jpeg_create_decompress(&cinfo);
279
280 // Test the filename
281 if (filename.empty()) {
282 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
283 }
284
285 file = fopen(filename.c_str(), "rb");
286
287 if (file == NULL) {
288 throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
289 }
290
291 jpeg_stdio_src(&cinfo, file);
292
293 jpeg_read_header(&cinfo, TRUE);
294
295 unsigned int width = cinfo.image_width;
296 unsigned int height = cinfo.image_height;
297
298 if ((width != I.getWidth()) || (height != I.getHeight()))
299 I.resize(height, width);
300
301 jpeg_start_decompress(&cinfo);
302
303 unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
304 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
305
306 if (cinfo.out_color_space == JCS_RGB) {
307 unsigned char *output = (unsigned char *)I.bitmap;
308 while (cinfo.output_scanline < cinfo.output_height) {
309 jpeg_read_scanlines(&cinfo, buffer, 1);
310 for (unsigned int i = 0; i < width; i++) {
311 *(output++) = buffer[0][i * 3];
312 *(output++) = buffer[0][i * 3 + 1];
313 *(output++) = buffer[0][i * 3 + 2];
314 *(output++) = vpRGBa::alpha_default;
315 }
316 }
317 }
318
319 else if (cinfo.out_color_space == JCS_GRAYSCALE) {
320 vpImage<unsigned char> Ig(height, width);
321
322 while (cinfo.output_scanline < cinfo.output_height) {
323 unsigned int row = cinfo.output_scanline;
324 jpeg_read_scanlines(&cinfo, buffer, 1);
325 memcpy(Ig[row], buffer[0], rowbytes);
326 }
327
329 }
330
331 jpeg_finish_decompress(&cinfo);
332 jpeg_destroy_decompress(&cinfo);
333 fclose(file);
334}
335#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:135
unsigned int getWidth() const
Definition vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition vpImage.h:795
Type * bitmap
points toward the bitmap
Definition vpImage.h:139
unsigned int getHeight() const
Definition vpImage.h:184
@ alpha_default
Definition vpRGBa.h:63