16
16
*/
17
17
18
18
#include <stdlib.h>
19
+ #include <stdio.h>
20
+ #include <jpeglib.h>
19
21
20
22
#include "pixbuf.h"
23
+ #include "dither.h"
21
24
#include "loaders.h"
22
25
23
26
struct pixbuf * pixbuf_load_jpeg (char * filename )
24
27
{
25
- /* TODO */
26
- return NULL ;
28
+ struct pixbuf * ret ;
29
+ FILE * fd ;
30
+ struct jpeg_decompress_struct cinfo ;
31
+ struct jpeg_error_mgr jerr ;
32
+ unsigned char * pixels ;
33
+ int i ;
34
+ unsigned char * * row_pointers ;
35
+
36
+ ret = NULL ;
37
+ fd = fopen (filename , "rb" );
38
+ if (fd == NULL ) goto free0 ;
39
+
40
+ cinfo .err = jpeg_std_error (& jerr ); // TODO: get rid of the exit() code
41
+ jpeg_create_decompress (& cinfo );
42
+ jpeg_stdio_src (& cinfo , fd );
43
+ jpeg_read_header (& cinfo , TRUE);
44
+
45
+ cinfo .out_color_space = JCS_RGB ;
46
+ cinfo .out_color_components = 3 ;
47
+ cinfo .dither_mode = JDITHER_NONE ;
48
+
49
+ pixels = malloc (3 * cinfo .image_width * cinfo .image_height );
50
+ if (pixels == NULL ) goto free2 ;
51
+ row_pointers = malloc (sizeof (char * )* cinfo .image_height );
52
+ if (row_pointers == NULL ) goto free3 ;
53
+ for (i = 0 ;i < cinfo .image_height ;i ++ )
54
+ row_pointers [i ] = & pixels [i * 3 * cinfo .image_width ];
55
+
56
+ jpeg_start_decompress (& cinfo );
57
+ while (cinfo .output_scanline < cinfo .output_height )
58
+ jpeg_read_scanlines (& cinfo , & row_pointers [cinfo .output_scanline ], 1 );
59
+ ret = pixbuf_new (cinfo .image_width , cinfo .image_height );
60
+ if (ret == NULL ) goto free5 ;
61
+
62
+ if (!pixbuf_dither (ret -> pixels , row_pointers , cinfo .image_width , cinfo .image_height )) {
63
+ pixbuf_dec_ref (ret );
64
+ ret = NULL ;
65
+ goto free5 ;
66
+ }
67
+
68
+ free5 :
69
+ jpeg_finish_decompress (& cinfo );
70
+ free4 :
71
+ free (row_pointers );
72
+ free3 :
73
+ free (pixels );
74
+ free2 :
75
+ jpeg_destroy_decompress (& cinfo );
76
+ free1 :
77
+ fclose (fd );
78
+ free0 :
79
+ return ret ;
27
80
}
0 commit comments