47 #include "simage_jpeg_reader.icc"
48 #include "simage_jpeg_writer.icc"
51 #define ERR_NO_ERROR 0
55 #define ERR_OPEN_WRITE 4
56 #define ERR_JPEGLIB_WRITE 5
65 strncpy(buffer,
"JPEG loader: Error opening file", buflen);
68 strncpy(buffer,
"JPEG loader: Out of memory error", buflen);
71 strncpy(buffer,
"JPEG loader: Illegal jpeg file", buflen);
74 strncpy(buffer,
"JPEG saver: Error opening file", buflen);
76 case ERR_JPEGLIB_WRITE:
77 strncpy(buffer,
"JPEG saver: Internal libjpeg error", buflen);
84 struct jpeg_error_mgr pub;
86 jmp_buf setjmp_buffer;
90 typedef struct my_error_mgr * my_error_ptr;
93 my_error_exit (j_common_ptr cinfo)
96 my_error_ptr myerr = (my_error_ptr) cinfo->err;
105 longjmp(myerr->setjmp_buffer, 1);
110 const unsigned char *header,
113 static unsigned char jpgcmp[] = {
'J',
'F',
'I',
'F' };
114 static unsigned char jpgcmp2[] = {
'E',
'x',
'i',
'f' };
115 if (headerlen < 10)
return 0;
116 if (memcmp((
const void*)&header[6],
117 (
const void*)jpgcmp, 4) == 0)
return 1;
118 if (memcmp((
const void*)&header[6],
119 (
const void*)jpgcmp2, 4) == 0)
return 1;
124 static unsigned char*
125 copyScanline(
unsigned char *currPtr,
unsigned char *from,
int cnt)
127 memcpy((
void*)currPtr, (
void*)from, cnt);
136 int *numComponents_ret)
140 unsigned char *currPtr;
142 unsigned char *buffer;
146 struct jpeg_decompress_struct cinfo;
151 struct my_error_mgr jerr;
154 JSAMPARRAY rowbuffer;
165 if ((infile = fopen(filename,
"rb")) == NULL) {
175 cinfo.err = jpeg_std_error(&jerr.pub);
176 jerr.pub.error_exit = my_error_exit;
178 if (setjmp(jerr.setjmp_buffer)) {
182 jpegerror = ERR_JPEGLIB;
183 jpeg_destroy_decompress(&cinfo);
185 if (buffer) free(buffer);
189 jpeg_create_decompress(&cinfo);
193 simage_jpeg_src_init(&cinfo, infile);
197 (void) jpeg_read_header(&cinfo, TRUE);
210 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
212 cinfo.out_color_space = JCS_GRAYSCALE;
216 cinfo.out_color_space = JCS_RGB;
219 (void) jpeg_start_decompress(&cinfo);
231 row_stride = cinfo.output_width * cinfo.output_components;
233 rowbuffer = (*cinfo.mem->alloc_sarray)
234 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
235 width = cinfo.output_width;
236 height = cinfo.output_height;
237 buffer = currPtr = (
unsigned char*)
238 malloc((
size_t)width*height*cinfo.output_components);
249 currPtr = buffer + row_stride * (cinfo.output_height-1);
251 while (cinfo.output_scanline < cinfo.output_height) {
256 (void) jpeg_read_scanlines(&cinfo, rowbuffer, 1);
258 currPtr = copyScanline(currPtr, rowbuffer[0], row_stride);
263 (void) jpeg_finish_decompress(&cinfo);
271 jpeg_destroy_decompress(&cinfo);
287 *height_ret = height;
288 *numComponents_ret = format;
298 const unsigned char * bytes,
309 struct jpeg_compress_struct cinfo;
315 struct my_error_mgr jerr;
319 JSAMPROW row_pointer[1];
322 unsigned char * tmpbytes;
335 cinfo.err = jpeg_std_error(&jerr.pub);
337 jpeg_create_compress(&cinfo);
348 if ((outfile = fopen(filename,
"wb")) == NULL) {
352 jpeg_destroy_compress(&cinfo);
358 cinfo.err = jpeg_std_error(&jerr.pub);
359 jerr.pub.error_exit = my_error_exit;
361 if (setjmp(jerr.setjmp_buffer)) {
365 jpeg_destroy_compress(&cinfo);
367 if (tmpbytes) free(tmpbytes);
368 jpegerror = ERR_JPEGLIB_WRITE;
372 simage_jpeg_dest_init(&cinfo, outfile);
379 if (numcomponents == 4) {
381 const unsigned char * src;
382 int i, n = width * height;
383 dst = tmpbytes = (
unsigned char *) malloc(n*3);
385 for (i = 0; i < n; i++) {
393 else if (numcomponents == 2) {
395 const unsigned char * src;
396 int i, n = width * height;
397 dst = tmpbytes = (
unsigned char *) malloc(n*3);
399 for (i = 0; i < n; i++) {
412 cinfo.image_width = width;
413 cinfo.image_height = height;
414 cinfo.input_components = numcomponents;
415 cinfo.in_color_space = numcomponents == 3 ? JCS_RGB : JCS_GRAYSCALE;
420 jpeg_set_defaults(&cinfo);
424 jpeg_set_quality(&cinfo, quality, TRUE );
431 jpeg_start_compress(&cinfo, TRUE);
442 bytesperrow = width * numcomponents;
443 if (tmpbytes) bytes = tmpbytes;
445 while (cinfo.next_scanline < cinfo.image_height) {
450 row_pointer[0] = (JSAMPROW) bytes + bytesperrow * (height-cinfo.next_scanline-1);
451 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
453 if (tmpbytes) free(tmpbytes);
457 jpeg_finish_compress(&cinfo);
462 jpeg_destroy_compress(&cinfo);
int simage_jpeg_identify(const char *filename, const unsigned char *header, int headerlen)
int simage_jpeg_save(const char *filename, const unsigned char *bytes, int width, int height, int numcomponents)
int simage_jpeg_error(char *textbuffer, int buffersize)
unsigned char * simage_jpeg_load(const char *filename, int *width, int *height, int *numcomponents)