17
17
18
18
#include <stdlib.h>
19
19
#include <stdio.h>
20
+ #include <setjmp.h>
20
21
#include <jpeglib.h>
21
22
22
23
#include "pixbuf.h"
23
24
#include "dither.h"
24
25
#include "loaders.h"
25
26
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
+
26
39
struct pixbuf * pixbuf_load_jpeg (char * filename )
27
40
{
28
41
struct pixbuf * ret ;
29
42
FILE * fd ;
30
43
struct jpeg_decompress_struct cinfo ;
31
- struct jpeg_error_mgr jerr ;
44
+ struct my_error_mgr jerr ;
32
45
unsigned char * pixels ;
33
46
int i ;
34
47
unsigned char * * row_pointers ;
@@ -37,7 +50,9 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
37
50
fd = fopen (filename , "rb" );
38
51
if (fd == NULL ) goto free0 ;
39
52
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 ;
41
56
jpeg_create_decompress (& cinfo );
42
57
jpeg_stdio_src (& cinfo , fd );
43
58
jpeg_read_header (& cinfo , TRUE);
@@ -53,12 +68,13 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
53
68
for (i = 0 ;i < cinfo .image_height ;i ++ )
54
69
row_pointers [i ] = & pixels [i * 3 * cinfo .image_width ];
55
70
71
+ if (setjmp (jerr .setjmp_buffer )) goto free4 ;
56
72
jpeg_start_decompress (& cinfo );
57
73
while (cinfo .output_scanline < cinfo .output_height )
58
74
jpeg_read_scanlines (& cinfo , & row_pointers [cinfo .output_scanline ], 1 );
75
+
59
76
ret = pixbuf_new (cinfo .image_width , cinfo .image_height );
60
77
if (ret == NULL ) goto free5 ;
61
-
62
78
if (!pixbuf_dither (ret -> pixels , row_pointers , cinfo .image_width , cinfo .image_height )) {
63
79
pixbuf_dec_ref (ret );
64
80
ret = NULL ;
@@ -73,7 +89,6 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
73
89
free (pixels );
74
90
free2 :
75
91
jpeg_destroy_decompress (& cinfo );
76
- free1 :
77
92
fclose (fd );
78
93
free0 :
79
94
return ret ;
0 commit comments