#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

Reply via email to