Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | #include "muxps.h" |
||
3 | |||
4 | #include |
||
5 | #include |
||
6 | |||
7 | struct jpeg_error_mgr_jmp |
||
8 | { |
||
9 | struct jpeg_error_mgr super; |
||
10 | jmp_buf env; |
||
11 | char msg[JMSG_LENGTH_MAX]; |
||
12 | }; |
||
13 | |||
14 | static void error_exit(j_common_ptr cinfo) |
||
15 | { |
||
16 | struct jpeg_error_mgr_jmp *err = (struct jpeg_error_mgr_jmp *)cinfo->err; |
||
17 | cinfo->err->format_message(cinfo, err->msg); |
||
18 | longjmp(err->env, 1); |
||
19 | } |
||
20 | |||
21 | static void init_source(j_decompress_ptr cinfo) |
||
22 | { |
||
23 | /* nothing to do */ |
||
24 | } |
||
25 | |||
26 | static void term_source(j_decompress_ptr cinfo) |
||
27 | { |
||
28 | /* nothing to do */ |
||
29 | } |
||
30 | |||
31 | static boolean fill_input_buffer(j_decompress_ptr cinfo) |
||
32 | { |
||
33 | static unsigned char eoi[2] = { 0xFF, JPEG_EOI }; |
||
34 | struct jpeg_source_mgr *src = cinfo->src; |
||
35 | src->next_input_byte = eoi; |
||
36 | src->bytes_in_buffer = 2; |
||
37 | return 1; |
||
38 | } |
||
39 | |||
40 | static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) |
||
41 | { |
||
42 | struct jpeg_source_mgr *src = cinfo->src; |
||
43 | if (num_bytes > 0) |
||
44 | { |
||
45 | src->next_input_byte += num_bytes; |
||
46 | src->bytes_in_buffer -= num_bytes; |
||
47 | } |
||
48 | } |
||
49 | |||
50 | int |
||
51 | xps_decode_jpeg(fz_pixmap **imagep, byte *rbuf, int rlen) |
||
52 | { |
||
53 | struct jpeg_decompress_struct cinfo; |
||
54 | struct jpeg_error_mgr_jmp err; |
||
55 | struct jpeg_source_mgr src; |
||
56 | unsigned char *row[1], *sp, *dp; |
||
57 | fz_colorspace *colorspace; |
||
58 | unsigned int x; |
||
59 | int k; |
||
60 | |||
61 | fz_pixmap *image = NULL; |
||
62 | |||
63 | if (setjmp(err.env)) |
||
64 | { |
||
65 | if (image) |
||
66 | fz_drop_pixmap(image); |
||
67 | return fz_throw("jpeg error: %s", err.msg); |
||
68 | } |
||
69 | |||
70 | cinfo.err = jpeg_std_error(&err.super); |
||
71 | err.super.error_exit = error_exit; |
||
72 | |||
73 | jpeg_create_decompress(&cinfo); |
||
74 | |||
75 | cinfo.src = &src; |
||
76 | src.init_source = init_source; |
||
77 | src.fill_input_buffer = fill_input_buffer; |
||
78 | src.skip_input_data = skip_input_data; |
||
79 | src.resync_to_restart = jpeg_resync_to_restart; |
||
80 | src.term_source = term_source; |
||
81 | src.next_input_byte = rbuf; |
||
82 | src.bytes_in_buffer = rlen; |
||
83 | |||
84 | jpeg_read_header(&cinfo, 1); |
||
85 | |||
86 | jpeg_start_decompress(&cinfo); |
||
87 | |||
88 | if (cinfo.output_components == 1) |
||
89 | colorspace = fz_device_gray; |
||
90 | else if (cinfo.output_components == 3) |
||
91 | colorspace = fz_device_rgb; |
||
92 | else if (cinfo.output_components == 4) |
||
93 | colorspace = fz_device_cmyk; |
||
94 | else |
||
95 | return fz_throw("bad number of components in jpeg: %d", cinfo.output_components); |
||
96 | |||
97 | image = fz_new_pixmap_with_limit(colorspace, cinfo.output_width, cinfo.output_height); |
||
98 | if (!image) |
||
99 | { |
||
100 | jpeg_finish_decompress(&cinfo); |
||
101 | jpeg_destroy_decompress(&cinfo); |
||
102 | return fz_throw("out of memory"); |
||
103 | } |
||
104 | |||
105 | if (cinfo.density_unit == 1) |
||
106 | { |
||
107 | image->xres = cinfo.X_density; |
||
108 | image->yres = cinfo.Y_density; |
||
109 | } |
||
110 | else if (cinfo.density_unit == 2) |
||
111 | { |
||
112 | image->xres = cinfo.X_density * 254 / 100; |
||
113 | image->yres = cinfo.Y_density * 254 / 100; |
||
114 | } |
||
115 | |||
116 | fz_clear_pixmap(image); |
||
117 | |||
118 | row[0] = fz_malloc(cinfo.output_components * cinfo.output_width); |
||
119 | dp = image->samples; |
||
120 | while (cinfo.output_scanline < cinfo.output_height) |
||
121 | { |
||
122 | jpeg_read_scanlines(&cinfo, row, 1); |
||
123 | sp = row[0]; |
||
124 | for (x = 0; x < cinfo.output_width; x++) |
||
125 | { |
||
126 | for (k = 0; k < cinfo.output_components; k++) |
||
127 | *dp++ = *sp++; |
||
128 | *dp++ = 255; |
||
129 | } |
||
130 | } |
||
131 | fz_free(row[0]); |
||
132 | |||
133 | jpeg_finish_decompress(&cinfo); |
||
134 | jpeg_destroy_decompress(&cinfo); |
||
135 | |||
136 | *imagep = image; |
||
137 | return fz_okay; |
||
138 | }>>> |