1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
/* jpegmemcd.c
* (c) 1997, Toshihiro Matsui, Electrotechnical Laboratory
* JPEG compression/decompression for in-core image/jpeg_data.
*
* int JPEG_compress(RGBimage, width, height, JPEGimage,size, quality);
* int JPEG_decompress(JPEGimage, jpeg_size,
* RGBimage, result_size, *width, *height)
*/
#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
#define jpeg_memio_dest(cinfo, outbuffer, outsize) \
jpeg_mem_dest((j_compress_ptr)cinfo, (unsigned char **)outbuffer, (unsigned long *)outsize)
#define jpeg_memio_src(cinfo, inbuffer, insize) \
jpeg_mem_src((j_decompress_ptr)cinfo, (const unsigned char *)inbuffer, (unsigned long)insize)
#else
GLOBAL(void) jpeg_memio_dest (j_compress_ptr cinfo, JOCTET *jpegimgbuf, long *size);
GLOBAL(void) jpeg_memio_src (j_decompress_ptr cinfo, JOCTET *buf, long size);
#endif
int JPEG_compress(JSAMPLE *image_buffer, long width, long height,
unsigned char *jpeg_image_buffer, long size, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
long data_count=size;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_memio_dest(&cinfo, jpeg_image_buffer, &data_count);
/* fprintf(stderr,
"jpeg compress: w=%d h=%d src=%x dest=%x size=%d quality=%d\n", width, height,
image_buffer, jpeg_image_buffer, size, quality); */
cinfo.image_width = width; /* image width and height, in pixels */
cinfo.image_height = height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
return(data_count);
}
/****************************************************************/
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
static void my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
extern int JPEG_header (JOCTET *jpeg_image, long jpeg_size,
long *width, long *height , long *components)
{ struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
long total_size;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
return 0; }
jpeg_create_decompress(&cinfo);
jpeg_memio_src(&cinfo, jpeg_image, jpeg_size);
(void) jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
*width= cinfo.output_width;
*height= cinfo.output_height;
*components= cinfo.output_components;
total_size = cinfo.output_width * cinfo.output_height *
cinfo.output_components;
jpeg_destroy_decompress(&cinfo);
return(total_size);
}
extern int JPEG_decompress (JOCTET *jpeg_image, long jpeg_size,
JOCTET *result_image,
long *width, long *height)
{
JOCTET *rimage;
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
JSAMPLE *jsampbuf;
int row_stride; /* physical row width in output buffer */
long total_size;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
return 0; }
jpeg_create_decompress(&cinfo);
jpeg_memio_src(&cinfo, jpeg_image, jpeg_size);
(void) jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
*width= cinfo.output_width;
*height= cinfo.output_height;
row_stride = cinfo.output_width * cinfo.output_components;
total_size = row_stride * cinfo.output_height;
/* printf("read_JPEG: width=%d height=%d\n", *width, *height); */
/*if (total_size > result_size) {
fprintf(stderr, "jpeg_decompress: result too big. %d > %d\n",
total_size, result_size);
jpeg_destroy_decompress(&cinfo);
return(FALSE);} */
/* start decompression */
(void) jpeg_start_decompress(&cinfo);
while (cinfo.output_scanline < cinfo.output_height) {
jsampbuf= &result_image[cinfo.output_scanline * row_stride];
(void) jpeg_read_scanlines(&cinfo, &jsampbuf, 1);
}
(void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return(total_size);
}
|