diff options
| author | Matthias Melcher <git@matthiasm.com> | 2020-01-10 18:46:45 +0100 |
|---|---|---|
| committer | Matthias Melcher <git@matthiasm.com> | 2020-01-10 18:46:45 +0100 |
| commit | 7e0c82637d5cb2de0d7baa5a3c2ebe8491663b06 (patch) | |
| tree | 13471c7faf41ae4ae49f9f9f0ab69c2b1b4286f5 /src/Fl_JPEG_Image.cxx | |
| parent | 82d279c2341c88da802b82e0d8732399d4f6b481 (diff) | |
Updated image readers.
Removed duplicate code from Fl_JPEG_Image, updated and unified Doxygen comments. Avoiding name conflict in new protected functions.
Diffstat (limited to 'src/Fl_JPEG_Image.cxx')
| -rw-r--r-- | src/Fl_JPEG_Image.cxx | 246 |
1 files changed, 98 insertions, 148 deletions
diff --git a/src/Fl_JPEG_Image.cxx b/src/Fl_JPEG_Image.cxx index 6dcf030b5..42e76d694 100644 --- a/src/Fl_JPEG_Image.cxx +++ b/src/Fl_JPEG_Image.cxx @@ -95,107 +95,42 @@ extern "C" { w(), h(), and d() should return values greater than zero. \param[in] filename a full path and name pointing to a valid jpeg file. + + \see Fl_JPEG_Image::Fl_JPEG_Image(const char *imagename, const unsigned char *data) */ -Fl_JPEG_Image::Fl_JPEG_Image(const char *filename) // I - File to load -: Fl_RGB_Image(0,0,0) { -#ifdef HAVE_LIBJPEG - FILE *fp; // File pointer - jpeg_decompress_struct dinfo; // Decompressor info - fl_jpeg_error_mgr jerr; // Error handler info - JSAMPROW row; // Sample row pointer - - // the following variables are pointers allocating some private space that - // is not reset by 'setjmp()' - char* max_finish_decompress_err; // count errors and give up afer a while - char* max_destroy_decompress_err; // to avoid recusion and deadlock - - // Clear data... - alloc_array = 0; - array = (uchar *)0; - - // Open the image file... - if ((fp = fl_fopen(filename, "rb")) == NULL) { - ld(ERR_FILE_ACCESS); - return; - } - - // Setup the decompressor info and read the header... - dinfo.err = jpeg_std_error((jpeg_error_mgr *)&jerr); - jerr.pub_.error_exit = fl_jpeg_error_handler; - jerr.pub_.output_message = fl_jpeg_output_handler; - - // Setup error loop variables - max_finish_decompress_err = (char*)malloc(1); // allocate space on the frame for error counters - max_destroy_decompress_err = (char*)malloc(1); // otherwise, the variables are reset on the longjmp - *max_finish_decompress_err=10; - *max_destroy_decompress_err=10; - - if (setjmp(jerr.errhand_)) - { - // JPEG error handling... - Fl::warning("JPEG file \"%s\" is too large or contains errors!\n", filename); - // if any of the cleanup routines hits another error, we would end up - // in a loop. So instead, we decrement max_err for some upper cleanup limit. - if ( ((*max_finish_decompress_err)-- > 0) && array) - jpeg_finish_decompress(&dinfo); - if ( (*max_destroy_decompress_err)-- > 0) - jpeg_destroy_decompress(&dinfo); - - fclose(fp); - - w(0); - h(0); - d(0); - - if (array) { - delete[] (uchar *)array; - array = 0; - alloc_array = 0; - } - - free(max_destroy_decompress_err); - free(max_finish_decompress_err); - - ld(ERR_FORMAT); - return; - } - - jpeg_create_decompress(&dinfo); - jpeg_stdio_src(&dinfo, fp); - jpeg_read_header(&dinfo, TRUE); - - dinfo.quantize_colors = (boolean)FALSE; - dinfo.out_color_space = JCS_RGB; - dinfo.out_color_components = 3; - dinfo.output_components = 3; - - jpeg_calc_output_dimensions(&dinfo); - - w(dinfo.output_width); - h(dinfo.output_height); - d(dinfo.output_components); - - if (((size_t)w()) * h() * d() > max_size() ) longjmp(jerr.errhand_, 1); - array = new uchar[w() * h() * d()]; - alloc_array = 1; - - jpeg_start_decompress(&dinfo); - - while (dinfo.output_scanline < dinfo.output_height) { - row = (JSAMPROW)(array + - dinfo.output_scanline * dinfo.output_width * - dinfo.output_components); - jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1); - } - - jpeg_finish_decompress(&dinfo); - jpeg_destroy_decompress(&dinfo); - - free(max_destroy_decompress_err); - free(max_finish_decompress_err); - - fclose(fp); -#endif // HAVE_LIBJPEG +Fl_JPEG_Image::Fl_JPEG_Image(const char *filename) +: Fl_RGB_Image(0,0,0) +{ + load_jpg_(filename, 0L, 0L); +} + +/** + \brief The constructor loads the JPEG image from memory. + + Construct an image from a block of memory inside the application. Fluid offers + "binary Data" chunks as a great way to add image data into the C++ source code. + name_png can be NULL. If a name is given, the image is added to the list of + shared images (see: Fl_Shared_Image) and will be available by that name. + + The inherited destructor frees all memory and server resources that are used + by the image. + + Use Fl_Image::fail() to check if Fl_JPEG_Image failed to load. fail() returns + ERR_FILE_ACCESS if the file could not be opened or read, ERR_FORMAT if the + JPEG format could not be decoded, and ERR_NO_IMAGE if the image could not + be loaded for another reason. If the image has loaded correctly, + w(), h(), and d() should return values greater than zero. + + \param name A unique name or NULL + \param data A pointer to the memory location of the JPEG image + + \see Fl_JPEG_Image::Fl_JPEG_Image(const char *filename) + \see Fl_Shared_Image + */ +Fl_JPEG_Image::Fl_JPEG_Image(const char *name, const unsigned char *data) +: Fl_RGB_Image(0,0,0) +{ + load_jpg_(0L, name, data); } @@ -270,121 +205,136 @@ static void jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *data) #endif // HAVE_LIBJPEG -/** - \brief The constructor loads the JPEG image from memory. - - Construct an image from a block of memory inside the application. Fluid offers - "binary Data" chunks as a great way to add image data into the C++ source code. - name_png can be NULL. If a name is given, the image is added to the list of - shared images (see: Fl_Shared_Image) and will be available by that name. - - The inherited destructor frees all memory and server resources that are used - by the image. - - Use Fl_Image::fail() to check if Fl_JPEG_Image failed to load. fail() returns - ERR_FILE_ACCESS if the file could not be opened or read, ERR_FORMAT if the - JPEG format could not be decoded, and ERR_NO_IMAGE if the image could not - be loaded for another reason. If the image has loaded correctly, - w(), h(), and d() should return values greater than zero. - - \param name A unique name or NULL - \param data A pointer to the memory location of the JPEG image +/* + This method reads JPEG image data and creates an RGB or grayscale image. + To avoid code duplication, we set filename if we want to read form a file or + data to read from memory instead. Sharename can be set if the image is + supposed to be added to teh Fl_Shared_Image list. */ -Fl_JPEG_Image::Fl_JPEG_Image(const char *name, const unsigned char *data) -: Fl_RGB_Image(0,0,0) { +void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const unsigned char *data) +{ #ifdef HAVE_LIBJPEG - jpeg_decompress_struct dinfo; // Decompressor info - fl_jpeg_error_mgr jerr; // Error handler info - JSAMPROW row; // Sample row pointer - + FILE *fp = 0L; // File pointer + jpeg_decompress_struct dinfo; // Decompressor info + fl_jpeg_error_mgr jerr; // Error handler info + JSAMPROW row; // Sample row pointer + // the following variables are pointers allocating some private space that // is not reset by 'setjmp()' char* max_finish_decompress_err; // count errors and give up afer a while char* max_destroy_decompress_err; // to avoid recusion and deadlock - + // Clear data... alloc_array = 0; array = (uchar *)0; - + + // Open the image file if we read from the file system + if (filename) { + if ((fp = fl_fopen(filename, "rb")) == NULL) { + ld(ERR_FILE_ACCESS); + return; + } + } else { + if (data==0L) { + ld(ERR_FILE_ACCESS); + return; + } + } + // Setup the decompressor info and read the header... dinfo.err = jpeg_std_error((jpeg_error_mgr *)&jerr); jerr.pub_.error_exit = fl_jpeg_error_handler; jerr.pub_.output_message = fl_jpeg_output_handler; - + // Setup error loop variables max_finish_decompress_err = (char*)malloc(1); // allocate space on the frame for error counters max_destroy_decompress_err = (char*)malloc(1); // otherwise, the variables are reset on the longjmp *max_finish_decompress_err=10; *max_destroy_decompress_err=10; - + if (setjmp(jerr.errhand_)) { // JPEG error handling... - Fl::warning("JPEG data is too large or contains errors!\n"); - // if any of the cleanup routines hits another error, we would end up + const char *name = "<unnamed>"; + if (filename) name = filename; + else if (sharename) name = sharename; + Fl::warning("JPEG file \"%s\" is too large or contains errors!\n", name); + // if any of the cleanup routines hits another error, we would end up // in a loop. So instead, we decrement max_err for some upper cleanup limit. if ( ((*max_finish_decompress_err)-- > 0) && array) jpeg_finish_decompress(&dinfo); if ( (*max_destroy_decompress_err)-- > 0) jpeg_destroy_decompress(&dinfo); - + + if (fp) + fclose(fp); + w(0); h(0); d(0); - + if (array) { delete[] (uchar *)array; array = 0; alloc_array = 0; } - + free(max_destroy_decompress_err); free(max_finish_decompress_err); - + + ld(ERR_FORMAT); return; } - + jpeg_create_decompress(&dinfo); - jpeg_mem_src(&dinfo, data); + if (fp) { + jpeg_stdio_src(&dinfo, fp); + } else { + jpeg_mem_src(&dinfo, data); + } jpeg_read_header(&dinfo, TRUE); - + dinfo.quantize_colors = (boolean)FALSE; dinfo.out_color_space = JCS_RGB; dinfo.out_color_components = 3; dinfo.output_components = 3; - + jpeg_calc_output_dimensions(&dinfo); - - w(dinfo.output_width); + + w(dinfo.output_width); h(dinfo.output_height); d(dinfo.output_components); - + if (((size_t)w()) * h() * d() > max_size() ) longjmp(jerr.errhand_, 1); array = new uchar[w() * h() * d()]; alloc_array = 1; - + jpeg_start_decompress(&dinfo); - + while (dinfo.output_scanline < dinfo.output_height) { row = (JSAMPROW)(array + dinfo.output_scanline * dinfo.output_width * dinfo.output_components); jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1); } - + jpeg_finish_decompress(&dinfo); jpeg_destroy_decompress(&dinfo); - + free(max_destroy_decompress_err); free(max_finish_decompress_err); - if (w() && h() && name) { - Fl_Shared_Image *si = new Fl_Shared_Image(name, this); + if (fp) + fclose(fp); + + if (sharename && w() && h()) { + Fl_Shared_Image *si = new Fl_Shared_Image(sharename, this); si->add(); } #endif // HAVE_LIBJPEG } + // // End of "$Id$". // |
