#ifndef HAVE_WRITE_JPEG_H #define HAVE_WRITE_JPEG_H #ifndef WRITE_DATA_ERROR # define WRITE_DATA_ERROR -1 #endif
#ifndef WRITE_DATA_OK # define WRITE_DATA_OK 0 #endif #ifndef MAX_JPG_COM_LENGTH # define MAX_JPG_COM_LENGTH 65000L /* must be <= 65533 in any case */ #endif /* Allow C++ Portability */ // #ifdef __cplusplus extern "C" { // #endif /* write a JPEG file */ extern int write_jpg (const char *file_name, /* Name of file to be written */ unsigned char *datap, /* pointer to image data array */ int width, /* Image width */ int height, /* Image height */ int depth, /* Image depth, valid values 1(mono), 3(RGB) */ char *keyword, /* Keyword to use in COM chunk (may be NULL) */ char *description); /* String to use in COM chunk (may be NULL) */ // return zero for success, -1 for error /* NOTE: As a special case, setting quality to 0 just uses the default settings */ extern void set_jpg_quality (int quality); /* Set image quality param (0 - 100) */ extern int get_jpg_quality (void); /* Read current quality setting */ /* Allow C++ Portability */ // #ifdef __cplusplus } // #endif #endif /* HAVE_WRITE_JPEG_H */ #include <cstring> using std::strlen; #include <cstdlib> using std::malloc; using std::free; #include <cstdio> using std::fopen; extern "C" { #ifdef WIN32 #include <jpeg/jpeglib.h> #else #include <jpeglib.h> #endif } #include "write_jpg.h" /* Holds Global quality setting - accessed only by the accessor methods provided */ static int quality = 0; /* Image quality param (0 - 100) (0 uses lib defaults) */ /***********************************************************************/ void set_jpg_quality (int iv) { if (iv < 0) iv = 0; else if (iv > 100) iv = 100; quality = iv; } /********************************************************************************/ int get_jpg_quality (void) { return quality; } /********************************************************************************/ int write_jpg (const char *file_name, // Name of file to be written unsigned char *datap, // pointer to image data array int width, // Image width int height, // Image height int depth, // Image depth,valid values 1(mono), 3(RGB) char *keyword, // Keyword to use in COM chunk (may be NULL) char *description) // String to use in COM chunk (may be NULL) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *outfile; /* target file */ JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ char *com_block_txt; /* Used to hold any COM block we write out */ /* Only handle RGB or Greyscale images for now */ if ((depth != 3) && (depth != 1)) { return WRITE_DATA_ERROR; } com_block_txt = NULL; /* Setup jpeg error handling */ cinfo.err = jpeg_std_error (&jerr); /* Now we can initialise the JPEG compression object. */ jpeg_create_compress (&cinfo); /* Open the output file */ if ((outfile = fopen (file_name, "wb")) == NULL) { //fprintf (stderr, "can't open %s\n", file_name); return WRITE_DATA_ERROR; } jpeg_stdio_dest (&cinfo, outfile); /* Setup compression parameters */ cinfo.image_width = width; /* image width and height, in pixels */ cinfo.image_height = height; cinfo.input_components = depth; /* number of bytes per pixel */ if (depth == 3) { cinfo.in_color_space = JCS_RGB; /* RGB input image */ } else { cinfo.in_color_space = JCS_GRAYSCALE; /* Greyscale input image */ } /* Now use the library routine to set default compression parameters. */ jpeg_set_defaults (&cinfo); j_compress_ptr pI= &cinfo; /* Do we want to override the default compression quality? */ if (quality > 10) jpeg_set_quality(pI, quality, TRUE); /* Start compressor */ jpeg_start_compress (pI, 1); /* Now we have started the compressor, do we have a COM chunk to write out? */ if ((keyword != NULL) && (description != NULL)) { unsigned int ulen = strlen(keyword) + strlen(description); if ((ulen > 0) && (ulen < MAX_JPG_COM_LENGTH)) { com_block_txt = (char*) malloc(ulen + 8); sprintf(com_block_txt, "%s: %s", keyword, description); jpeg_write_marker(&cinfo, JPEG_COM, (JOCTET*)com_block_txt, strlen(com_block_txt)); } } /* Cycle through the input data, writing out the image */ row_stride = width * depth; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { /* For each data line... */ row_pointer[0] = &datap[cinfo.next_scanline * row_stride]; jpeg_write_scanlines (&cinfo, row_pointer, 1); } /* Finish compression */ jpeg_finish_compress (&cinfo); /* Now close the output file. */ fclose (outfile); /* Free the JPEG compression object and other allocated memory */ jpeg_destroy_compress (&cinfo); if (com_block_txt) free(com_block_txt); /* And we're done! */ return WRITE_DATA_OK; } _______________________________________________ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk