-//-------------------------------------------------------------------
-
-struct r_jpeg_error_mgr
-{
- struct jpeg_error_mgr pub;
- jmp_buf envbuffer;
-};
-
-void jpeg_cb_error_exit(j_common_ptr cinfo)
-{
- struct r_jpeg_error_mgr *mptr;
- mptr = (struct r_jpeg_error_mgr *) cinfo->err;
- (*cinfo->err->output_message) (cinfo);
- longjmp(mptr->envbuffer, 1);
-}
-
-static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width)
-{
- 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 */
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
-
- if ((outfile = fopen(filename, "wb")) == NULL)
- {
- eDebug("[JPEG] can't open %s", filename);
- return -1;
- }
- jpeg_stdio_dest(&cinfo, outfile);
-
- cinfo.image_width = image_width;
- cinfo.image_height = image_height;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, quality, TRUE );
- jpeg_start_compress(&cinfo, TRUE);
- row_stride = image_width * 3;
- 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);
- fclose(outfile);
- jpeg_destroy_compress(&cinfo);
- return 0;
-}
-
-/* Expanded data source object for memory buffer input */
-typedef struct
-{
- struct jpeg_source_mgr pub; /* public fields */
- FILE *infile; /* source stream */
- JOCTET *buffer; /* start of buffer */
- boolean start_of_file; /* have we gotten any data yet? */
-} mem_source_mgr;
-
-typedef mem_source_mgr *mem_src_ptr;
-
-static void init_source (j_decompress_ptr cinfo)
-{
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
- src->start_of_file = TRUE;
-}
-
-static boolean fill_input_buffer (j_decompress_ptr cinfo)
-{
- /* no-op */ (void)cinfo;
- return TRUE;
- }
-
-static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-{
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
-
- if (num_bytes > 0)
- {
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-static void term_source (j_decompress_ptr cinfo)
-{
- /* no-op */ (void)cinfo;
-}
-
-static void jpeg_memory_src (j_decompress_ptr cinfo, unsigned char *inbfr, int len)
-{
- mem_src_ptr src;
- if (cinfo->src == NULL)
- {
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (size_t)sizeof(mem_source_mgr));
- src = (mem_src_ptr) cinfo->src;
- src->buffer = (JOCTET *) inbfr;
- }
- src = (mem_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
- src->pub.term_source = term_source;
- src->infile = 0L;
- src->pub.bytes_in_buffer = len; /* sets to entire file len */
- src->pub.next_input_byte = (JOCTET *)inbfr; /* at start of buffer */
-}
-
-static int jpeg_load_thumb(const char *filename, int *x, int *y)
-{
- struct jpeg_decompress_struct cinfo;
- struct jpeg_decompress_struct *ciptr = &cinfo;
- struct r_jpeg_error_mgr emgr;
- FILE *fh;
-
- if (!(fh = fopen(filename, "rb")))
- return 0;
-
- ciptr->err = jpeg_std_error(&emgr.pub);
- emgr.pub.error_exit = jpeg_cb_error_exit;
- if (setjmp(emgr.envbuffer) == 1)
- {
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 0;
- }
-
- jpeg_create_decompress(ciptr);
- jpeg_stdio_src(ciptr, fh);
-
- jpeg_save_markers (ciptr, JPEG_APP0 + 1, 0xffff);
-
- jpeg_read_header(ciptr, TRUE);
-
- struct jpeg_marker_struct *m = cinfo.marker_list;
-
- unsigned char *thumb_buf = NULL;
- size_t bufsize;
-
- if ( m )
- {
- unsigned char *p_data = m->data;
- while ( p_data < m->data+m->data_length )
- {
- if ( p_data[0] == 0xFF && p_data[1] == 0xD8 )
- {
- bufsize = (size_t) m->data_length - (size_t) (p_data-m->data);
- thumb_buf = new unsigned char[bufsize];
- bufsize = 0;
- do {
- thumb_buf[bufsize++] = *p_data;
- } while ( !(*p_data++ == 0xFF && *p_data == 0xD9) && p_data < m->data+m->data_length );
- thumb_buf[bufsize++] = *p_data;
- }
- p_data++;
- }
- }
-
- if ( thumb_buf != NULL )
- {
- jpeg_create_decompress(ciptr);
- jpeg_memory_src(ciptr, thumb_buf, bufsize-2);
- jpeg_read_header(ciptr, TRUE);
- }
- else
- eDebug("no exif thumbnail found! loading actual image instead");
-
- ciptr->out_color_space = JCS_RGB;
- ciptr->scale_denom = 1;
-
- jpeg_start_decompress(ciptr);
-
- *x=ciptr->output_width;
- *y=ciptr->output_height;
-
- if(ciptr->output_components == 3)
- {
- JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
- pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
- unsigned char *bp = pic_buffer;
-
- while (ciptr->output_scanline < ciptr->output_height)
- {
- jpeg_read_scanlines(ciptr, &lb, 1);
- memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
- bp += ciptr->output_width * ciptr->output_components;
- }
- }
- jpeg_finish_decompress(ciptr);
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 1;
-}
-
-static int jpeg_load(const char *filename, int *x, int *y)
-{
- struct jpeg_decompress_struct cinfo;
- struct jpeg_decompress_struct *ciptr = &cinfo;
- struct r_jpeg_error_mgr emgr;
- FILE *fh;
-
- if (!(fh = fopen(filename, "rb")))
- return 0;
-
- ciptr->err = jpeg_std_error(&emgr.pub);
- emgr.pub.error_exit = jpeg_cb_error_exit;
- if (setjmp(emgr.envbuffer) == 1)
- {
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 0;
- }
-
- jpeg_create_decompress(ciptr);
- jpeg_stdio_src(ciptr, fh);
- jpeg_read_header(ciptr, TRUE);
- ciptr->out_color_space = JCS_RGB;
- ciptr->scale_denom = 1;
-
- jpeg_start_decompress(ciptr);
-
- *x=ciptr->output_width;
- *y=ciptr->output_height;
-
- if(ciptr->output_components == 3)
- {
- JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
- pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
- unsigned char *bp = pic_buffer;
-
- while (ciptr->output_scanline < ciptr->output_height)
- {
- jpeg_read_scanlines(ciptr, &lb, 1);
- memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
- bp += ciptr->output_width * ciptr->output_components;
- }
- }
- jpeg_finish_decompress(ciptr);
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 1;
-}
-