Subversion Repositories Kolibri OS

Rev

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
}