Skip to content

Commit fc9b0c8

Browse files
author
Sebastien Bourdeauducq
committedNov 21, 2011
JPEG loader: error handling
1 parent 65038bd commit fc9b0c8

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed
 

Diff for: ‎src/pixbuf/loaderjpeg.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,31 @@
1717

1818
#include <stdlib.h>
1919
#include <stdio.h>
20+
#include <setjmp.h>
2021
#include <jpeglib.h>
2122

2223
#include "pixbuf.h"
2324
#include "dither.h"
2425
#include "loaders.h"
2526

27+
struct my_error_mgr {
28+
struct jpeg_error_mgr pub;
29+
jmp_buf setjmp_buffer;
30+
};
31+
32+
static void my_error_exit(j_common_ptr cinfo)
33+
{
34+
struct my_error_mgr * myerr = (struct my_error_mgr *)cinfo->err;
35+
(*cinfo->err->output_message) (cinfo);
36+
longjmp(myerr->setjmp_buffer, 1);
37+
}
38+
2639
struct pixbuf *pixbuf_load_jpeg(char *filename)
2740
{
2841
struct pixbuf *ret;
2942
FILE *fd;
3043
struct jpeg_decompress_struct cinfo;
31-
struct jpeg_error_mgr jerr;
44+
struct my_error_mgr jerr;
3245
unsigned char *pixels;
3346
int i;
3447
unsigned char **row_pointers;
@@ -37,7 +50,9 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
3750
fd = fopen(filename, "rb");
3851
if(fd == NULL) goto free0;
3952

40-
cinfo.err = jpeg_std_error(&jerr); // TODO: get rid of the exit() code
53+
cinfo.err = jpeg_std_error((struct jpeg_error_mgr *)&jerr);
54+
jerr.pub.error_exit = my_error_exit;
55+
if(setjmp(jerr.setjmp_buffer)) goto free2;
4156
jpeg_create_decompress(&cinfo);
4257
jpeg_stdio_src(&cinfo, fd);
4358
jpeg_read_header(&cinfo, TRUE);
@@ -53,12 +68,13 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
5368
for(i=0;i<cinfo.image_height;i++)
5469
row_pointers[i] = &pixels[i*3*cinfo.image_width];
5570

71+
if(setjmp(jerr.setjmp_buffer)) goto free4;
5672
jpeg_start_decompress(&cinfo);
5773
while(cinfo.output_scanline < cinfo.output_height)
5874
jpeg_read_scanlines(&cinfo, &row_pointers[cinfo.output_scanline], 1);
75+
5976
ret = pixbuf_new(cinfo.image_width, cinfo.image_height);
6077
if(ret == NULL) goto free5;
61-
6278
if(!pixbuf_dither(ret->pixels, row_pointers, cinfo.image_width, cinfo.image_height)) {
6379
pixbuf_dec_ref(ret);
6480
ret = NULL;
@@ -73,7 +89,6 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
7389
free(pixels);
7490
free2:
7591
jpeg_destroy_decompress(&cinfo);
76-
free1:
7792
fclose(fd);
7893
free0:
7994
return ret;

0 commit comments

Comments
 (0)
Please sign in to comment.