Main MRPT website > C++ reference for MRPT 1.9.9
CImage_JPEG_streams.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/utils/CImage.h>
13 #include <mrpt/utils/CStream.h>
14 
15 // Universal include for all versions of OpenCV
16 #include <mrpt/otherlibs/do_opencv_includes.h>
17 
18 using namespace mrpt;
19 using namespace mrpt::utils;
20 
21 // ---------------------------------------------------------------------------------------
22 // START OF JPEG FUNCTIONS PART
23 // ---------------------------------------------------------------------------------------
24 /* Expanded data destination object for stdio output */
25 
26 //#undef INT32
27 #undef FAR
28 #define XMD_H
29 
30 #include <stdio.h>
31 
32 // In Windows, we HAVE TO (YES dear...) include our custom jpeglib
33 // The problem is that, without .so/.dlls, all the libs have their
34 // own jpeglib and runtime checks of expected type-sizes fail
35 // causing asserts.... (fix: JLBC 20/OCT/2008)
36 #if MRPT_HAS_JPEG_SYSTEM
37 // Normal: System libraries (typ. unix)
38 #include <jpeglib.h>
39 
40 // Convert mrpt-names to normal ones:
41 #define mrpt_jpeg_source_mgr jpeg_source_mgr
42 
43 #elif MRPT_HAS_JPEG // Built-in version
44 #include "jpeglib/mrpt_jpeglib.h"
45 #define mrpt_jpeg_source_mgr jpeg_source_mgr
46 #endif
47 
48 typedef struct
49 {
50  struct jpeg_destination_mgr pub; /* public fields */
51 
52  CStream* out; /* target stream */
53  JOCTET* buffer; /* start of buffer */
55 
57 
58 #define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
59 
60 /*
61  * Initialize destination --- called by jpeg_start_compress
62  * before any data is actually written.
63  */
64 
65 METHODDEF(void)
67 {
68  mrpt_dest_ptr dest = (mrpt_dest_ptr)cinfo->dest;
69 
70  /* Allocate the output buffer --- it will be released when done with image
71  */
72  dest->buffer = (JOCTET*)(*cinfo->mem->alloc_small)(
73  (j_common_ptr)cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(JOCTET));
74 
75  dest->pub.next_output_byte = dest->buffer;
77 }
78 
79 /*
80  * Empty the output buffer --- called whenever buffer fills up.
81  *
82  * In typical applications, this should write the entire output buffer
83  * (ignoring the current state of next_output_byte & free_in_buffer),
84  * reset the pointer & count to the start of the buffer, and return TRUE
85  * indicating that the buffer has been dumped.
86  *
87  * In applications that need to be able to suspend compression due to output
88  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
89  * In this situation, the compressor will return to its caller (possibly with
90  * an indication that it has not accepted all the supplied scanlines). The
91  * application should resume compression after it has made more room in the
92  * output buffer. Note that there are substantial restrictions on the use of
93  * suspension --- see the documentation.
94  *
95  * When suspending, the compressor will back up to a convenient restart point
96  * (typically the start of the current MCU). next_output_byte & free_in_buffer
97  * indicate where the restart point will be if the current call returns FALSE.
98  * Data beyond this point will be regenerated after resumption, so do not
99  * write it out when emptying the buffer externally.
100  */
101 
102 METHODDEF(boolean)
104 {
105  mrpt_dest_ptr dest = (mrpt_dest_ptr)cinfo->dest;
106 
107  dest->out->WriteBuffer(dest->buffer, OUTPUT_BUF_SIZE);
108 
109  dest->pub.next_output_byte = dest->buffer;
111 
112  return TRUE;
113 }
114 
115 /*
116  * Terminate destination --- called by jpeg_finish_compress
117  * after all data has been written. Usually needs to flush buffer.
118  *
119  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
120  * application must deal with any cleanup that should happen even
121  * for error exit.
122  */
123 
124 METHODDEF(void)
126 {
127  mrpt_dest_ptr dest = (mrpt_dest_ptr)cinfo->dest;
128  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
129 
130  /* Write any data remaining in the buffer */
131  if (datacount > 0) dest->out->WriteBuffer(dest->buffer, (int)datacount);
132 }
133 
134 GLOBAL(void)
136 {
137  mrpt_dest_ptr dest;
138 
139  /* The destination object is made permanent so that multiple JPEG images
140  * can be written to the same file without re-executing jpeg_stdio_dest.
141  * This makes it dangerous to use this manager and a different destination
142  * manager serially with the same JPEG object, because their private object
143  * sizes may be different. Caveat programmer.
144  */
145  if (cinfo->dest == nullptr)
146  { /* first time for this JPEG object? */
147  cinfo->dest = (jpeg_destination_mgr*)(*cinfo->mem->alloc_small)(
149  }
150 
151  dest = (mrpt_dest_ptr)cinfo->dest;
152  dest->pub.init_destination = init_destination;
153  dest->pub.empty_output_buffer = empty_output_buffer;
154  dest->pub.term_destination = term_destination;
155  dest->out = out;
156 }
157 
158 // -------------------------------------------------------------
159 
160 /* Expanded data source object for stdio input */
161 
162 typedef struct
163 {
164  mrpt_jpeg_source_mgr pub; /* public fields */
165  CStream* in; /* source stream */
166  JOCTET* buffer; /* start of buffer */
167  boolean start_of_file; /* have we gotten any data yet? */
168 } my_source_mgr;
169 
171 
172 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
173 
174 /*
175  * Initialize source --- called by jpeg_read_header
176  * before any data is actually read.
177  */
178 
179 METHODDEF(void)
181 {
182  my_src_ptr src = (my_src_ptr)cinfo->src;
183 
184  /* We reset the empty-input-file flag for each image,
185  * but we don't clear the input buffer.
186  * This is correct behavior for reading a series of images from one source.
187  */
189 }
190 
191 /*
192  * Fill the input buffer --- called whenever buffer is emptied.
193  *
194  * In typical applications, this should read fresh data into the buffer
195  * (ignoring the current state of next_input_byte & bytes_in_buffer),
196  * reset the pointer & count to the start of the buffer, and return TRUE
197  * indicating that the buffer has been reloaded. It is not necessary to
198  * fill the buffer entirely, only to obtain at least one more byte.
199  *
200  * There is no such thing as an EOF return. If the end of the file has been
201  * reached, the routine has a choice of ERREXIT() or inserting fake data into
202  * the buffer. In most cases, generating a warning message and inserting a
203  * fake EOI marker is the best course of action --- this will allow the
204  * decompressor to output however much of the image is there. However,
205  * the resulting error message is misleading if the real problem is an empty
206  * input file, so we handle that case specially.
207  *
208  * In applications that need to be able to suspend compression due to input
209  * not being available yet, a FALSE return indicates that no more data can be
210  * obtained right now, but more may be forthcoming later. In this situation,
211  * the decompressor will return to its caller (with an indication of the
212  * number of scanlines it has read, if any). The application should resume
213  * decompression after it has loaded more data into the input buffer. Note
214  * that there are substantial restrictions on the use of suspension --- see
215  * the documentation.
216  *
217  * When suspending, the decompressor will back up to a convenient restart point
218  * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
219  * indicate where the restart point will be if the current call returns FALSE.
220  * Data beyond this point must be rescanned after resumption, so move it to
221  * the front of the buffer rather than discarding it.
222  */
223 
224 METHODDEF(boolean)
226 {
227  my_src_ptr src = (my_src_ptr)cinfo->src;
228  size_t nbytes;
229 
230  nbytes = src->in->ReadBuffer(src->buffer, INPUT_BUF_SIZE);
231 
232  if (nbytes <= 0)
233  {
234  if (src->start_of_file) /* Treat empty input file as fatal error */
235  {
236  THROW_EXCEPTION("Error looking for JPEG start data!")
237  }
238 
239  /* Insert a fake EOI marker */
240  src->buffer[0] = (JOCTET)0xFF;
241  src->buffer[1] = (JOCTET)JPEG_EOI;
242  nbytes = 2;
243  }
244 
245  src->pub.next_input_byte = src->buffer;
246  src->pub.bytes_in_buffer = nbytes;
247  src->start_of_file = FALSE;
248 
249  return TRUE;
250 }
251 
252 /*
253  * Skip data --- used to skip over a potentially large amount of
254  * uninteresting data (such as an APPn marker).
255  *
256  * Writers of suspendable-input applications must note that skip_input_data
257  * is not granted the right to give a suspension return. If the skip extends
258  * beyond the data currently in the buffer, the buffer can be marked empty so
259  * that the next read will cause a fill_input_buffer call that can suspend.
260  * Arranging for additional bytes to be discarded before reloading the input
261  * buffer is the application writer's problem.
262  */
263 
264 METHODDEF(void)
265 skip_input_data(j_decompress_ptr cinfo, long num_bytes)
266 {
267  my_src_ptr src = (my_src_ptr)cinfo->src;
268 
269  /* Just a dumb implementation for now. Could use fseek() except
270  * it doesn't work on pipes. Not clear that being smart is worth
271  * any trouble anyway --- large skips are infrequent.
272  */
273  if (num_bytes > 0)
274  {
275  while (num_bytes > (long)src->pub.bytes_in_buffer)
276  {
277  num_bytes -= (long)src->pub.bytes_in_buffer;
278  (void)fill_input_buffer(cinfo);
279  /* note we assume that fill_input_buffer will never return FALSE,
280  * so suspension need not be handled.
281  */
282  }
283  src->pub.next_input_byte += (size_t)num_bytes;
284  src->pub.bytes_in_buffer -= (size_t)num_bytes;
285  }
286 }
287 
288 /*
289  * An additional method that can be provided by data source modules is the
290  * resync_to_restart method for error recovery in the presence of RST markers.
291  * For the moment, this source module just uses the default resync method
292  * provided by the JPEG library. That method assumes that no backtracking
293  * is possible.
294  */
295 
296 /*
297  * Terminate source --- called by jpeg_finish_decompress
298  * after all data has been read. Often a no-op.
299  *
300  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
301  * application must deal with any cleanup that should happen even
302  * for error exit.
303  */
304 
305 METHODDEF(void)
307 {
308  MRPT_UNUSED_PARAM(cinfo);
309  /* no work necessary here */
310 }
311 
312 /*
313  * Prepare for input from a stdio stream.
314  * The caller must have already opened the stream, and is responsible
315  * for closing it after finishing decompression.
316  */
317 
318 GLOBAL(void)
320 {
321  my_src_ptr src;
322 
323  /* The source object and input buffer are made permanent so that a series
324  * of JPEG images can be read from the same file by calling jpeg_stdio_src
325  * only before the first one. (If we discarded the buffer at the end of
326  * one image, we'd likely lose the start of the next one.)
327  * This makes it unsafe to use this manager and a different source
328  * manager serially with the same JPEG object. Caveat programmer.
329  */
330  if (cinfo->src == nullptr)
331  { /* first time for this JPEG object? */
332  cinfo->src = (mrpt_jpeg_source_mgr*)(*cinfo->mem->alloc_small)(
333  (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
334  src = (my_src_ptr)cinfo->src;
335  src->buffer = (JOCTET*)(*cinfo->mem->alloc_small)(
337  INPUT_BUF_SIZE * sizeof(JOCTET));
338  }
339 
340  src = (my_src_ptr)cinfo->src;
341  src->pub.init_source = init_source;
342  src->pub.fill_input_buffer = fill_input_buffer;
343  src->pub.skip_input_data = skip_input_data;
344  src->pub.resync_to_restart =
345  jpeg_resync_to_restart; /* use default method */
346  src->pub.term_source = term_source;
347  src->in = in;
348  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
349  src->pub.next_input_byte = nullptr; /* until buffer loaded */
350 }
351 
352 // ---------------------------------------------------------------------------------------
353 // END OF JPEG FUNCTIONS PART
354 // ---------------------------------------------------------------------------------------
355 
356 /*---------------------------------------------------------------
357  saveToStreamAsJPEG
358  ---------------------------------------------------------------*/
359 void CImage::saveToStreamAsJPEG(CStream& out, const int jpeg_quality) const
360 {
361 #if MRPT_HAS_OPENCV
362  MRPT_START
363 
364  makeSureImageIsLoaded(); // For delayed loaded images stored externally
365 
366  struct jpeg_compress_struct cinfo;
367  struct jpeg_error_mgr jerr;
368 
369  const IplImage* ipl = static_cast<const IplImage*>(img);
370 
371  const unsigned int nCols = ipl->width;
372  const unsigned int nRows = ipl->height;
373  const bool is_color = (ipl->nChannels == 3);
374 
375  // Some previous verification:
376  ASSERT_(nCols >= 1 && nRows >= 1)
377  ASSERT_(ipl)
378  ASSERT_(ipl->nChannels == 1 || ipl->nChannels == 3)
379 
380  // 1) Initialization of the JPEG compresion object:
381  // --------------------------------------------------
382  cinfo.err = jpeg_std_error(&jerr);
383  jpeg_create_compress(&cinfo);
384 
385  // 2) Set the destination of jpeg data:
386  // --------------------------------------------------
387  jpeg_stdio_dest(&cinfo, &out);
388 
389  // 3) Set parameters for compression:
390  // --------------------------------------------------
391  cinfo.image_width = nCols;
392  cinfo.image_height = nRows;
393  cinfo.input_components = is_color ? 3 : 1;
394  cinfo.in_color_space = is_color ? JCS_RGB : JCS_GRAYSCALE;
395 
396  jpeg_set_defaults(&cinfo);
397  /* Make optional parameter settings here */
398  /* Now you can set any non-default parameters you wish to.
399  * Here we just illustrate the use of quality (quantization table) scaling:
400  */
402  &cinfo, jpeg_quality /* quality per cent */,
403  TRUE /* limit to baseline-JPEG values */);
404 
405  // 4) Start:
406  // --------------------------------------------------
407  jpeg_start_compress(&cinfo, TRUE);
408 
409  // 5) Write scan lines:
410  // --------------------------------------------------
411  if (is_color)
412  {
413  JSAMPROW row_pointer[1]; /* pointer to a single row */
414  row_pointer[0] = (JSAMPROW) new char[ipl->widthStep];
415 
416  for (unsigned int row = 0; row < nRows; row++)
417  {
418  // Flip RGB bytes order!
419  char* src;
420  if (ipl->origin == 0)
421  src = &ipl->imageData[row * ipl->widthStep];
422  else
423  src = &ipl->imageData[(nRows - 1 - row) * ipl->widthStep];
424  char* target = (char*)row_pointer[0];
425  for (unsigned int col = 0; col < nCols; col++)
426  {
427  target[0] = src[2];
428  target[1] = src[1];
429  target[2] = src[0];
430 
431  target += 3;
432  src += 3;
433  }
434 
435  if (1 != jpeg_write_scanlines(&cinfo, row_pointer, 1))
436  {
437  THROW_EXCEPTION("jpeg_write_scanlines: didn't work!!");
438  }
439  }
440 
441  delete[] row_pointer[0];
442  } // end "color"
443  else
444  { // Is grayscale:
445  JSAMPROW row_pointer[1]; /* pointer to a single row */
446 
447  for (unsigned int row = 0; row < nRows; row++)
448  {
449  if (ipl->origin == 0)
450  row_pointer[0] =
451  (JSAMPROW)&ipl->imageData[row * ipl->widthStep];
452  else
453  row_pointer[0] =
454  (JSAMPROW)&ipl
455  ->imageData[(nRows - 1 - row) * ipl->widthStep];
456 
457  // Gray scale:
458  if (1 != jpeg_write_scanlines(&cinfo, row_pointer, 1))
459  {
460  THROW_EXCEPTION("jpeg_write_scanlines: didn't work!!");
461  }
462  }
463  }
464 
465  // 6) Compress and finish:
466  // --------------------------------------------------
467  jpeg_finish_compress(&cinfo);
468  jpeg_destroy_compress(&cinfo);
469 
470  // DONE!
471  MRPT_END
472 #endif
473 }
474 
475 /*---------------------------------------------------------------
476  saveToStreamAsJPEG
477  ---------------------------------------------------------------*/
479 {
480 #if MRPT_HAS_OPENCV
481  MRPT_START
482 
483  struct jpeg_decompress_struct cinfo;
484  struct jpeg_error_mgr jerr;
485 
486  /* Step 1: allocate and initialize JPEG decompression object */
487 
488  /* We set up the normal JPEG error routines, then override error_exit. */
489  cinfo.err = jpeg_std_error(&jerr);
490 
491  /* Now we can initialize the JPEG decompression object. */
492  jpeg_create_decompress(&cinfo);
493 
494  /* Step 2: specify data source (eg, a file) */
495  jpeg_stdio_src(&cinfo, &in);
496 
497  /* Step 3: read file parameters with jpeg_read_header() */
498  jpeg_read_header(&cinfo, TRUE);
499 
500  /* Step 4: set parameters for decompression */
501 
502  /* Step 5: Start decompressor */
503  jpeg_start_decompress(&cinfo);
504 
505  /* We may need to do some setup of our own at this point before reading
506  * the data. After jpeg_start_decompress() we have the correct scaled
507  * output image dimensions available, as well as the output colormap
508  * if we asked for color quantization.
509  * In this example, we need to make an output work buffer of the right size.
510  */
511  /* JSAMPLEs per row in output buffer */
512  /* physical row width in output buffer */
513  const int row_stride = cinfo.output_width * cinfo.output_components;
514  /* Make a one-row-high sample array that will go away when done with image
515  */
516  /* Output row buffer */
517  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)(
518  (j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
519 
520  // Resize the CImage now:
521  this->changeSize(
522  cinfo.output_width, cinfo.output_height, cinfo.out_color_components,
523  true);
524  IplImage* ipl = static_cast<IplImage*>(img);
525 
526  /* Step 6: while (scan lines remain to be read) */
527  /* jpeg_read_scanlines(...); */
528 
529  /* Here we use the library's state variable cinfo.output_scanline as the
530  * loop counter, so that we don't have to keep track ourselves.
531  */
532  const unsigned int nCols = cinfo.output_width;
533  const unsigned int nRows = cinfo.output_height;
534 
535  for (unsigned int row = 0; row < nRows; row++)
536  {
537  /* jpeg_read_scanlines expects an array of pointers to scanlines.
538  * Here the array is only one element long, but you could ask for
539  * more than one scanline at a time if that's more convenient.
540  */
541  jpeg_read_scanlines(&cinfo, buffer, 1);
542 
543  /* Copy into the CImage object */
544  if (isColor())
545  {
546  // Flip RGB bytes order!
547  char* target = &ipl->imageData[row * ipl->widthStep];
548  const char* src = (char*)buffer[0];
549  for (unsigned int col = 0; col < nCols; col++)
550  {
551  target[0] = src[2];
552  target[1] = src[1];
553  target[2] = src[0];
554 
555  target += 3;
556  src += 3;
557  }
558  }
559  else
560  {
561  // Gray scale:
562  memcpy(
563  &ipl->imageData[row * ipl->widthStep], buffer[0], row_stride);
564  }
565  }
566 
567  /* Step 7: Finish decompression */
568 
569  jpeg_finish_decompress(&cinfo);
570  /* We can ignore the return value since suspension is not possible
571  * with the stdio data source.
572  */
573 
574  /* Step 8: Release JPEG decompression object */
575 
576  /* This is an important step since it will release a good deal of memory. */
577  jpeg_destroy_decompress(&cinfo);
578 
579  // DONE!
580  MRPT_END
581 #endif
582 }
jpeg_set_quality(j_compress_ptr cinfo, int quality, boolean force_baseline)
Definition: jcparam.cpp:117
size_t ReadBuffer(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer.
Definition: CStream.cpp:40
init_destination(j_compress_ptr cinfo)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLuint buffer
Definition: glext.h:3917
#define JPOOL_PERMANENT
Definition: mrpt_jpeglib.h:749
mrpt_destination_mgr * mrpt_dest_ptr
jpeg_set_defaults(j_compress_ptr cinfo)
Definition: jcparam.cpp:299
#define THROW_EXCEPTION(msg)
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
jpeg_finish_decompress(j_decompress_ptr cinfo)
Definition: jdapimin.cpp:377
JDIMENSION image_height
Definition: mrpt_jpeglib.h:277
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
Definition: CStream.cpp:64
jpeg_start_decompress(j_decompress_ptr cinfo)
Definition: jdapistd.cpp:29
for(ctr=DCTSIZE;ctr > 0;ctr--)
Definition: jidctflt.cpp:56
JSAMPLE FAR * JSAMPROW
Definition: mrpt_jpeglib.h:60
my_source_mgr * my_src_ptr
GLuint src
Definition: glext.h:7278
init_source(j_decompress_ptr cinfo)
jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines)
Definition: jcapistd.cpp:69
fill_input_buffer(j_decompress_ptr cinfo)
mrpt_jpeg_source_mgr pub
J_COLOR_SPACE in_color_space
Definition: mrpt_jpeglib.h:279
#define OUTPUT_BUF_SIZE
jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired)
Definition: jdmarker.cpp:1203
jpeg_finish_compress(j_compress_ptr cinfo)
Definition: jcapimin.cpp:137
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
jpeg_destroy_decompress(j_decompress_ptr cinfo)
Definition: jdapimin.cpp:82
jpeg_stdio_src(j_decompress_ptr cinfo, CStream *in)
jpeg_read_scanlines(j_decompress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION max_lines)
Definition: jdapistd.cpp:156
#define MRPT_END
term_source(j_decompress_ptr cinfo)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define FALSE
Definition: jmorecfg.h:216
struct jpeg_destination_mgr pub
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:750
JSAMPROW * JSAMPARRAY
Definition: mrpt_jpeglib.h:61
term_destination(j_compress_ptr cinfo)
void saveToStreamAsJPEG(mrpt::utils::CStream &out, const int jpeg_quality=95) const
Save image to binary stream as a JPEG (.jpg) compressed format.
#define JPEG_EOI
void changeSize(unsigned int width, unsigned int height, TImageChannels nChannels, bool originTopLeft)
Resize the buffers in "img" to accomodate a new image size and/or format.
Definition: CImage.cpp:228
jpeg_read_header(j_decompress_ptr cinfo, boolean require_image)
Definition: jdapimin.cpp:247
jpeg_destroy_compress(j_compress_ptr cinfo)
Definition: jcapimin.cpp:79
#define jpeg_create_decompress(cinfo)
Definition: mrpt_jpeglib.h:893
#define TRUE
Definition: jmorecfg.h:219
jpeg_stdio_dest(j_compress_ptr cinfo, CStream *out)
#define MRPT_START
void makeSureImageIsLoaded() const
Checks if the image is of type "external storage", and if so and not loaded yet, load it...
Definition: CImage.cpp:1940
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define GLOBAL(type)
Definition: jmorecfg.h:177
GLenum GLenum GLvoid * row
Definition: glext.h:3576
#define METHODDEF(type)
Definition: jmorecfg.h:173
GLuint in
Definition: glext.h:7274
jpeg_std_error(struct jpeg_error_mgr *err)
Definition: jerror.cpp:222
#define INPUT_BUF_SIZE
#define ASSERT_(f)
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:911
char JOCTET
Definition: jmorecfg.h:106
void * img
The internal IplImage pointer to the actual image content.
Definition: CImage.h:1077
#define jpeg_create_compress(cinfo)
Definition: mrpt_jpeglib.h:889
empty_output_buffer(j_compress_ptr cinfo)
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:355
skip_input_data(j_decompress_ptr cinfo, long num_bytes)
void loadFromStreamAsJPEG(CStream &in)
Reads the image from a binary stream containing a binary jpeg file.
JDIMENSION image_width
Definition: mrpt_jpeglib.h:276
jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
Definition: jcapistd.cpp:30



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019