22
22
#include " itk_jpeg.h"
23
23
#include < csetjmp>
24
24
25
+ #define JPEGIO_JPEG_MESSAGES 1
26
+
27
+ #if (defined JPEGIO_JPEG_MESSAGES && JPEGIO_JPEG_MESSAGES == 1)
28
+ # include < cstdio>
29
+ #endif
30
+
25
31
// create an error handler for jpeg that
26
32
// can longjmp out of the jpeg library
27
33
struct itk_jpeg_error_mgr
@@ -36,37 +42,31 @@ extern "C"
36
42
{
37
43
/* cinfo->err really points to a itk_jpeg_error_mgr struct, so coerce pointer
38
44
*/
39
- auto * myerr = reinterpret_cast < itk_jpeg_error_mgr *>( cinfo->err ) ;
45
+ itk_jpeg_error_mgr * myerr = ( itk_jpeg_error_mgr *) cinfo->err ;
40
46
41
47
/* Always display the message. */
42
48
/* We could postpone this until after returning, if we chose. */
43
49
(*cinfo->err ->output_message )(cinfo);
44
50
45
- jpeg_abort (cinfo); /* clean up libjpeg state */
46
51
/* Return control to the setjmp point */
47
52
longjmp (myerr->setjmp_buffer , 1 );
48
53
}
49
54
50
- METHODDEF (void ) itk_jpeg_output_message(j_common_ptr) {}
55
+ METHODDEF (void ) itk_jpeg_output_message(j_common_ptr cinfo)
56
+ {
57
+ #if (defined JPEGIO_JPEG_MESSAGES && JPEGIO_JPEG_MESSAGES == 1)
58
+ char buffer[JMSG_LENGTH_MAX + 1 ];
59
+ (*cinfo->err ->format_message )(cinfo, buffer);
60
+ printf (" %s\n " , buffer);
61
+ #else
62
+ (void )cinfo;
63
+ #endif
64
+ }
51
65
}
52
66
53
67
namespace itk
54
68
{
55
69
56
- namespace
57
- {
58
- // Wrap setjmp call to avoid warnings about variable clobbering.
59
- bool
60
- wrapSetjmp (itk_jpeg_error_mgr & jerr)
61
- {
62
- if (setjmp (jerr.setjmp_buffer ))
63
- {
64
- return true ;
65
- }
66
- return false ;
67
- }
68
- } // namespace
69
-
70
70
// simple class to call fopen on construct and
71
71
// fclose on destruct
72
72
class JPEGFileWrapper
@@ -86,7 +86,7 @@ class JPEGFileWrapper
86
86
}
87
87
}
88
88
89
- FILE * m_FilePointer;
89
+ FILE * volatile m_FilePointer;
90
90
};
91
91
92
92
bool
@@ -142,7 +142,7 @@ JPEGImageIO::CanReadFile(const char * file)
142
142
jerr.pub .output_message = itk_jpeg_output_message;
143
143
// set the jump point, if there is a jpeg error or warning
144
144
// this will evaluate to true
145
- if (wrapSetjmp (jerr))
145
+ if (setjmp (jerr. setjmp_buffer ))
146
146
{
147
147
// clean up
148
148
jpeg_destroy_decompress (&cinfo);
@@ -166,13 +166,9 @@ void
166
166
JPEGImageIO::ReadVolume (void *)
167
167
{}
168
168
169
- // -----------------------------------------------------------------------------
170
-
171
169
void
172
170
JPEGImageIO::Read (void * buffer)
173
171
{
174
- unsigned int ui;
175
-
176
172
// use this class so return will call close
177
173
JPEGFileWrapper JPEGfp (this ->GetFileName (), " rb" );
178
174
FILE * fp = JPEGfp.m_FilePointer ;
@@ -193,7 +189,7 @@ JPEGImageIO::Read(void * buffer)
193
189
jerr.pub .error_exit = itk_jpeg_error_exit;
194
190
// for any output message call itk_jpeg_output_message
195
191
jerr.pub .output_message = itk_jpeg_output_message;
196
- if (wrapSetjmp (jerr))
192
+ if (setjmp (jerr. setjmp_buffer ))
197
193
{
198
194
// clean up
199
195
jpeg_destroy_decompress (&cinfo);
@@ -212,21 +208,26 @@ JPEGImageIO::Read(void * buffer)
212
208
// prepare to read the bulk data
213
209
jpeg_start_decompress (&cinfo);
214
210
215
- SizeValueType rowbytes = cinfo.output_components * cinfo.output_width ;
216
- auto * tempImage = static_cast <JSAMPLE *>(buffer);
211
+ const auto rowbytes = cinfo.output_width * cinfo.output_components ;
212
+ auto * tempImage = static_cast <JSAMPLE *>(buffer);
217
213
218
- auto * row_pointers = new JSAMPROW[cinfo.output_height ];
219
- for (ui = 0 ; ui < cinfo.output_height ; ++ui)
214
+ auto * volatile row_pointers = new JSAMPROW[cinfo.output_height ];
215
+ for (size_t ui = 0 ; ui < cinfo.output_height ; ++ui)
220
216
{
221
217
row_pointers[ui] = tempImage + rowbytes * ui;
222
218
}
223
219
224
220
// read the bulk data
225
- unsigned int remainingRows;
226
221
while (cinfo.output_scanline < cinfo.output_height )
227
222
{
228
- remainingRows = cinfo.output_height - cinfo.output_scanline ;
229
- jpeg_read_scanlines (&cinfo, &row_pointers[cinfo.output_scanline ], remainingRows);
223
+ if (setjmp (jerr.setjmp_buffer ))
224
+ {
225
+ itkWarningMacro (" JPEG error in the file " << this ->GetFileName ());
226
+ jpeg_destroy_decompress (&cinfo);
227
+ delete[] row_pointers;
228
+ return ;
229
+ }
230
+ jpeg_read_scanlines (&cinfo, &row_pointers[cinfo.output_scanline ], cinfo.output_height - cinfo.output_scanline );
230
231
}
231
232
232
233
// finish the decompression step
@@ -398,7 +399,7 @@ JPEGImageIO::Write(const void * buffer)
398
399
}
399
400
400
401
void
401
- JPEGImageIO::WriteSlice (std::string & fileName, const void * buffer)
402
+ JPEGImageIO::WriteSlice (std::string & fileName, const void * const buffer)
402
403
{
403
404
// use this class so return will call close
404
405
JPEGFileWrapper JPEGfp (fileName.c_str (), " wb" );
@@ -410,22 +411,14 @@ JPEGImageIO::WriteSlice(std::string & fileName, const void * buffer)
410
411
<< " Reason: " << itksys::SystemTools::GetLastSystemError ());
411
412
}
412
413
413
- // Call the correct templated function for the output
414
-
415
- // overriding jpeg_error_mgr so we don't exit when an error happens
416
- // Create the jpeg compression object and error handler
417
- // struct jpeg_compress_struct cinfo;
418
- // struct itk_jpeg_error_mgr jerr;
419
-
420
414
struct itk_jpeg_error_mgr jerr;
421
415
struct jpeg_compress_struct cinfo;
422
416
cinfo.err = jpeg_std_error (&jerr.pub );
423
- // set the jump point, if there is a jpeg error or warning
424
- // this will evaluate to true
425
- if (wrapSetjmp (jerr))
417
+ // set the jump point
418
+ if (setjmp (jerr.setjmp_buffer ))
426
419
{
427
420
jpeg_destroy_compress (&cinfo);
428
- itkExceptionMacro (<< " JPEG : Out of disk space " );
421
+ itkExceptionMacro (<< " JPEG error, failed to write " << fileName );
429
422
}
430
423
431
424
jpeg_create_compress (&cinfo);
@@ -527,6 +520,7 @@ JPEGImageIO::WriteSlice(std::string & fileName, const void * buffer)
527
520
528
521
if (fflush (fp) == EOF)
529
522
{
523
+ delete[] row_pointers;
530
524
itkExceptionMacro (<< " JPEG : Out of disk space" );
531
525
}
532
526
0 commit comments