1#include "mupdf/fitz.h"
2
3#include <string.h>
4#include <limits.h>
5
6static const unsigned char web_palette[] = {
7 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00,
8 0x00, 0x00, 0x33, 0x33, 0x00, 0x33, 0x66, 0x00, 0x33, 0x99, 0x00, 0x33, 0xCC, 0x00, 0x33, 0xFF, 0x00, 0x33,
9 0x00, 0x00, 0x66, 0x33, 0x00, 0x66, 0x66, 0x00, 0x66, 0x99, 0x00, 0x66, 0xCC, 0x00, 0x66, 0xFF, 0x00, 0x66,
10 0x00, 0x00, 0x99, 0x33, 0x00, 0x99, 0x66, 0x00, 0x99, 0x99, 0x00, 0x99, 0xCC, 0x00, 0x99, 0xFF, 0x00, 0x99,
11 0x00, 0x00, 0xCC, 0x33, 0x00, 0xCC, 0x66, 0x00, 0xCC, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xCC,
12 0x00, 0x00, 0xFF, 0x33, 0x00, 0xFF, 0x66, 0x00, 0xFF, 0x99, 0x00, 0xFF, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
13 0x00, 0x33, 0x00, 0x33, 0x33, 0x00, 0x66, 0x33, 0x00, 0x99, 0x33, 0x00, 0xCC, 0x33, 0x00, 0xFF, 0x33, 0x00,
14 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
15 0x00, 0x33, 0x66, 0x33, 0x33, 0x66, 0x66, 0x33, 0x66, 0x99, 0x33, 0x66, 0xCC, 0x33, 0x66, 0xFF, 0x33, 0x66,
16 0x00, 0x33, 0x99, 0x33, 0x33, 0x99, 0x66, 0x33, 0x99, 0x99, 0x33, 0x99, 0xCC, 0x33, 0x99, 0xFF, 0x33, 0x99,
17 0x00, 0x33, 0xCC, 0x33, 0x33, 0xCC, 0x66, 0x33, 0xCC, 0x99, 0x33, 0xCC, 0xCC, 0x33, 0xCC, 0xFF, 0x33, 0xCC,
18 0x00, 0x33, 0xFF, 0x33, 0x33, 0xFF, 0x66, 0x33, 0xFF, 0x99, 0x33, 0xFF, 0xCC, 0x33, 0xFF, 0xFF, 0x33, 0xFF,
19 0x00, 0x66, 0x00, 0x33, 0x66, 0x00, 0x66, 0x66, 0x00, 0x99, 0x66, 0x00, 0xCC, 0x66, 0x00, 0xFF, 0x66, 0x00,
20 0x00, 0x66, 0x33, 0x33, 0x66, 0x33, 0x66, 0x66, 0x33, 0x99, 0x66, 0x33, 0xCC, 0x66, 0x33, 0xFF, 0x66, 0x33,
21 0x00, 0x66, 0x66, 0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
22 0x00, 0x66, 0x99, 0x33, 0x66, 0x99, 0x66, 0x66, 0x99, 0x99, 0x66, 0x99, 0xCC, 0x66, 0x99, 0xFF, 0x66, 0x99,
23 0x00, 0x66, 0xCC, 0x33, 0x66, 0xCC, 0x66, 0x66, 0xCC, 0x99, 0x66, 0xCC, 0xCC, 0x66, 0xCC, 0xFF, 0x66, 0xCC,
24 0x00, 0x66, 0xFF, 0x33, 0x66, 0xFF, 0x66, 0x66, 0xFF, 0x99, 0x66, 0xFF, 0xCC, 0x66, 0xFF, 0xFF, 0x66, 0xFF,
25 0x00, 0x99, 0x00, 0x33, 0x99, 0x00, 0x66, 0x99, 0x00, 0x99, 0x99, 0x00, 0xCC, 0x99, 0x00, 0xFF, 0x99, 0x00,
26 0x00, 0x99, 0x33, 0x33, 0x99, 0x33, 0x66, 0x99, 0x33, 0x99, 0x99, 0x33, 0xCC, 0x99, 0x33, 0xFF, 0x99, 0x33,
27 0x00, 0x99, 0x66, 0x33, 0x99, 0x66, 0x66, 0x99, 0x66, 0x99, 0x99, 0x66, 0xCC, 0x99, 0x66, 0xFF, 0x99, 0x66,
28 0x00, 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0x99, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
29 0x00, 0x99, 0xCC, 0x33, 0x99, 0xCC, 0x66, 0x99, 0xCC, 0x99, 0x99, 0xCC, 0xCC, 0x99, 0xCC, 0xFF, 0x99, 0xCC,
30 0x00, 0x99, 0xFF, 0x33, 0x99, 0xFF, 0x66, 0x99, 0xFF, 0x99, 0x99, 0xFF, 0xCC, 0x99, 0xFF, 0xFF, 0x99, 0xFF,
31 0x00, 0xCC, 0x00, 0x33, 0xCC, 0x00, 0x66, 0xCC, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xCC, 0x00,
32 0x00, 0xCC, 0x33, 0x33, 0xCC, 0x33, 0x66, 0xCC, 0x33, 0x99, 0xCC, 0x33, 0xCC, 0xCC, 0x33, 0xFF, 0xCC, 0x33,
33 0x00, 0xCC, 0x66, 0x33, 0xCC, 0x66, 0x66, 0xCC, 0x66, 0x99, 0xCC, 0x66, 0xCC, 0xCC, 0x66, 0xFF, 0xCC, 0x66,
34 0x00, 0xCC, 0x99, 0x33, 0xCC, 0x99, 0x66, 0xCC, 0x99, 0x99, 0xCC, 0x99, 0xCC, 0xCC, 0x99, 0xFF, 0xCC, 0x99,
35 0x00, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
36 0x00, 0xCC, 0xFF, 0x33, 0xCC, 0xFF, 0x66, 0xCC, 0xFF, 0x99, 0xCC, 0xFF, 0xCC, 0xCC, 0xFF, 0xFF, 0xCC, 0xFF,
37 0x00, 0xFF, 0x00, 0x33, 0xFF, 0x00, 0x66, 0xFF, 0x00, 0x99, 0xFF, 0x00, 0xCC, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
38 0x00, 0xFF, 0x33, 0x33, 0xFF, 0x33, 0x66, 0xFF, 0x33, 0x99, 0xFF, 0x33, 0xCC, 0xFF, 0x33, 0xFF, 0xFF, 0x33,
39 0x00, 0xFF, 0x66, 0x33, 0xFF, 0x66, 0x66, 0xFF, 0x66, 0x99, 0xFF, 0x66, 0xCC, 0xFF, 0x66, 0xFF, 0xFF, 0x66,
40 0x00, 0xFF, 0x99, 0x33, 0xFF, 0x99, 0x66, 0xFF, 0x99, 0x99, 0xFF, 0x99, 0xCC, 0xFF, 0x99, 0xFF, 0xFF, 0x99,
41 0x00, 0xFF, 0xCC, 0x33, 0xFF, 0xCC, 0x66, 0xFF, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0xFF, 0xCC, 0xFF, 0xFF, 0xCC,
42 0x00, 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50};
51
52static const unsigned char vga_palette[] = {
53 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
54 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
55 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
56 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF,
57};
58
59static const unsigned char gray_palette[] = {
60 0x00, 0x00, 0x00, 0x54, 0x54, 0x54,
61 0xA8, 0xA8, 0xA8, 0xFF, 0xFF, 0xFF,
62};
63
64static const unsigned char bw_palette[] = {
65 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
66};
67
68enum {
69 BI_RLE24 = -1,
70 BI_RGB = 0,
71 BI_RLE8 = 1,
72 BI_RLE4 = 2,
73 BI_BITFIELDS = 3,
74 BI_JPEG = 4,
75 BI_PNG = 5,
76 BI_ALPHABITS = 6,
77 BI_UNSUPPORTED = 42,
78};
79
80struct info
81{
82 int filesize;
83 int offset;
84 int topdown;
85 int width, height;
86 int xres, yres;
87 int bitcount;
88 int compression;
89 int colors;
90 int rmask, gmask, bmask, amask;
91 unsigned char palette[256 * 3];
92
93 int extramasks;
94 int palettetype;
95 unsigned char *samples;
96
97 int rshift, gshift, bshift, ashift;
98 int rbits, gbits, bbits, abits;
99};
100
101#define read8(p) ((p)[0])
102#define read16(p) (((p)[1] << 8) | (p)[0])
103#define read32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
104
105static const unsigned char *
106bmp_read_file_header(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
107{
108 if (end - p < 14)
109 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in file header in bmp image");
110
111 if (memcmp(&p[0], "BM", 2))
112 fz_throw(ctx, FZ_ERROR_GENERIC, "invalid signature in bmp image");
113
114 info->filesize = read32(p + 2);
115 info->offset = read32(p + 10);
116
117 return p + 14;
118}
119
120static const unsigned char *
121bmp_read_bitmap_core_header(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
122{
123 int size;
124
125 size = read32(p + 0);
126 if (size != 12)
127 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported core header size in bmp image");
128
129 if (size >= 12)
130 {
131 if (end - p < 12)
132 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap core header in bmp image");
133
134 info->width = read16(p + 4);
135 info->height = read16(p + 6);
136 info->bitcount = read16(p + 10);
137 }
138
139 info->xres = 2835;
140 info->yres = 2835;
141 info->compression = BI_RGB;
142 info->palettetype = 0;
143
144 return p + size;
145}
146
147static const unsigned char *
148bmp_read_bitmap_os2_header(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
149{
150 int size;
151
152 size = read32(p + 0);
153 if (size != 16 && size != 64)
154 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported os2 header size in bmp image");
155
156 if (size >= 16)
157 {
158 if (end - p < 16)
159 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap os2 header in bmp image");
160
161 info->width = read32(p + 4);
162 info->height = read32(p + 8);
163 info->bitcount = read16(p + 14);
164
165 info->compression = BI_RGB;
166 }
167 if (size >= 64)
168 {
169 if (end - p < 64)
170 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap os2 header in bmp image");
171
172 info->compression = read32(p + 16);
173 info->xres = read32(p + 24);
174 info->yres = read32(p + 28);
175 info->colors = read32(p + 32);
176
177 /* 4 in this header is interpreted as 24 bit RLE encoding */
178 if (info->compression < 0)
179 info->compression = BI_UNSUPPORTED;
180 else if (info->compression == 4)
181 info->compression = BI_RLE24;
182 }
183
184 info->palettetype = 1;
185
186 return p + size;
187}
188
189static void maskinfo(unsigned int mask, int *shift, int *bits)
190{
191 *bits = 0;
192 *shift = 0;
193 if (mask) {
194 while ((mask & 1) == 0) {
195 *shift += 1;
196 mask >>= 1;
197 }
198 while ((mask & 1) == 1) {
199 *bits += 1;
200 mask >>= 1;
201 }
202 }
203}
204
205static const unsigned char *
206bmp_read_bitmap_info_header(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
207{
208 int size;
209
210 size = read32(p + 0);
211 if (size != 40 && size != 52 && size != 56 && size != 64 &&
212 size != 108 && size != 124)
213 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported info header size in bmp image");
214
215 if (size >= 40)
216 {
217 if (end - p < 40)
218 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap info header in bmp image");
219
220 info->width = read32(p + 4);
221 info->topdown = (p[8 + 3] & 0x80) != 0;
222 if (info->topdown)
223 info->height = -read32(p + 8);
224 else
225 info->height = read32(p + 8);
226 info->bitcount = read16(p + 14);
227 info->compression = read32(p + 16);
228 info->xres = read32(p + 24);
229 info->yres = read32(p + 28);
230 info->colors = read32(p + 32);
231
232 if (size == 40 && info->compression == BI_BITFIELDS && (info->bitcount == 16 || info->bitcount == 32))
233 info->extramasks = 1;
234 else if (size == 40 && info->compression == BI_ALPHABITS && (info->bitcount == 16 || info->bitcount == 32))
235 info->extramasks = 1;
236
237 if (info->bitcount == 16) {
238 info->rmask = 0x00007c00;
239 info->gmask = 0x000003e0;
240 info->bmask = 0x0000001f;
241 info->amask = 0x00000000;
242 } else if (info->bitcount == 32) {
243 info->rmask = 0x00ff0000;
244 info->gmask = 0x0000ff00;
245 info->bmask = 0x000000ff;
246 info->amask = 0x00000000;
247 }
248 }
249 if (size >= 52)
250 {
251 if (end - p < 52)
252 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap info header in bmp image");
253
254 if (info->compression == BI_BITFIELDS) {
255 info->rmask = read32(p + 40);
256 info->gmask = read32(p + 44);
257 info->bmask = read32(p + 48);
258 }
259 }
260 if (size >= 56)
261 {
262 if (end - p < 56)
263 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap info header in bmp image");
264
265 if (info->compression == BI_BITFIELDS) {
266 info->amask = read32(p + 52);
267 }
268 }
269
270 info->palettetype = 1;
271
272 return p + size;
273}
274
275static const unsigned char *
276bmp_read_extra_masks(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
277{
278 int size = 0;
279
280 if (info->compression == BI_BITFIELDS)
281 {
282 size = 12;
283 if (end - p < 12)
284 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in mask header in bmp image");
285
286 info->rmask = read32(p + 0);
287 info->gmask = read32(p + 4);
288 info->bmask = read32(p + 8);
289 }
290 else if (info->compression == BI_ALPHABITS)
291 {
292 size = 16;
293 if (end - p < 16)
294 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in mask header in bmp image");
295
296 /* ignore alpha mask */
297 info->rmask = read32(p + 0);
298 info->gmask = read32(p + 4);
299 info->bmask = read32(p + 8);
300 }
301
302 return p + size;
303}
304
305static int
306bmp_palette_is_gray(fz_context *ctx, struct info *info, int readcolors)
307{
308 int i;
309 for (i = 0; i < readcolors; i++)
310 {
311 int rgdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 1]);
312 int gbdiff = fz_absi(info->palette[3 * i + 1] - info->palette[3 * i + 2]);
313 int rbdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 2]);
314 if (rgdiff > 2 || gbdiff > 2 || rbdiff > 2)
315 return 0;
316 }
317 return 1;
318}
319
320static void
321bmp_load_default_palette(fz_context *ctx, struct info *info, int readcolors)
322{
323 int i;
324
325 fz_warn(ctx, "color table too short; loading default palette");
326
327 if (info->bitcount == 8)
328 {
329 if (!bmp_palette_is_gray(ctx, info, readcolors))
330 memcpy(&info->palette[readcolors * 3], &web_palette[readcolors * 3],
331 sizeof(web_palette) - readcolors * 3);
332 else
333 for (i = readcolors; i < 256; i++)
334 {
335 info->palette[3 * i + 0] = i;
336 info->palette[3 * i + 1] = i;
337 info->palette[3 * i + 2] = i;
338 }
339 }
340 else if (info->bitcount == 4)
341 {
342 if (!bmp_palette_is_gray(ctx, info, readcolors))
343 memcpy(&info->palette[readcolors * 3], &vga_palette[readcolors * 3],
344 sizeof(vga_palette) - readcolors * 3);
345 else
346 for (i = readcolors; i < 16; i++)
347 {
348 info->palette[3 * i + 0] = (i << 4) | i;
349 info->palette[3 * i + 1] = (i << 4) | i;
350 info->palette[3 * i + 2] = (i << 4) | i;
351 }
352 }
353 else if (info->bitcount == 2)
354 memcpy(info->palette, gray_palette, sizeof(gray_palette));
355 else if (info->bitcount == 1)
356 memcpy(info->palette, bw_palette, sizeof(bw_palette));
357}
358
359static const unsigned char *
360bmp_read_color_table(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
361{
362 int i, colors, readcolors;
363
364 if (info->bitcount > 8)
365 return p;
366
367 if (info->colors == 0)
368 colors = 1 << info->bitcount;
369 else
370 colors = info->colors;
371
372 colors = fz_mini(colors, 1 << info->bitcount);
373
374 if (info->palettetype == 0)
375 {
376 readcolors = fz_mini(colors, (end - p) / 3);
377 for (i = 0; i < readcolors; i++)
378 {
379 info->palette[3 * i + 0] = read8(p + i * 3 + 2);
380 info->palette[3 * i + 1] = read8(p + i * 3 + 1);
381 info->palette[3 * i + 2] = read8(p + i * 3 + 0);
382 }
383 if (readcolors < colors)
384 bmp_load_default_palette(ctx, info, readcolors);
385 return p + readcolors * 3;
386 }
387 else
388 {
389 readcolors = fz_mini(colors, (end - p) / 4);
390 for (i = 0; i < readcolors; i++)
391 {
392 /* ignore alpha channel */
393 info->palette[3 * i + 0] = read8(p + i * 4 + 2);
394 info->palette[3 * i + 1] = read8(p + i * 4 + 1);
395 info->palette[3 * i + 2] = read8(p + i * 4 + 0);
396 }
397 if (readcolors < colors)
398 bmp_load_default_palette(ctx, info, readcolors);
399 return p + readcolors * 4;
400 }
401
402 return p;
403}
404
405static unsigned char *
406bmp_decompress_rle24(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
407{
408 const unsigned char *sp;
409 unsigned char *dp, *ep, *decompressed;
410 int width = info->width;
411 int height = info->height;
412 int stride;
413 int x, i;
414
415 stride = (width*3 + 3) / 4 * 4;
416
417 sp = p;
418 dp = decompressed = fz_calloc(ctx, height, stride);
419 ep = dp + height * stride;
420 x = 0;
421
422 while (sp + 2 <= *end)
423 {
424 if (sp[0] == 0 && sp[1] == 0)
425 { /* end of line */
426 if (x*3 < stride)
427 dp += stride - x*3;
428 sp += 2;
429 x = 0;
430 }
431 else if (sp[0] == 0 && sp[1] == 1)
432 { /* end of bitmap */
433 dp = ep;
434 break;
435 }
436 else if (sp[0] == 0 && sp[1] == 2)
437 { /* delta */
438 int deltax, deltay;
439 if (sp + 4 > *end)
440 break;
441 deltax = sp[2];
442 deltay = sp[3];
443 dp += deltax*3 + deltay * stride;
444 sp += 4;
445 x += deltax;
446 }
447 else if (sp[0] == 0 && sp[1] >= 3)
448 { /* absolute */
449 int n = sp[1] * 3;
450 int nn = (n + 1) / 2 * 2;
451 if (sp + 2 + nn > *end)
452 break;
453 if (dp + n > ep) {
454 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
455 break;
456 }
457 sp += 2;
458 for (i = 0; i < n; i++)
459 dp[i] = sp[i];
460 dp += n;
461 sp += (n + 1) / 2 * 2;
462 x += n;
463 }
464 else
465 { /* encoded */
466 int n = sp[0] * 3;
467 if (sp + 1 + 3 > *end)
468 break;
469 if (dp + n > ep) {
470 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
471 break;
472 }
473 for (i = 0; i < n / 3; i++) {
474 dp[i * 3 + 0] = sp[1];
475 dp[i * 3 + 1] = sp[2];
476 dp[i * 3 + 2] = sp[3];
477 }
478 dp += n;
479 sp += 1 + 3;
480 x += n;
481 }
482 }
483
484 if (dp < ep)
485 fz_warn(ctx, "premature end of bitmap data in bmp image");
486
487 info->compression = BI_RGB;
488 info->bitcount = 24;
489 *end = ep;
490 return decompressed;
491}
492
493static unsigned char *
494bmp_decompress_rle8(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
495{
496 const unsigned char *sp;
497 unsigned char *dp, *ep, *decompressed;
498 int width = info->width;
499 int height = info->height;
500 int stride;
501 int x, i;
502
503 stride = (width + 3) / 4 * 4;
504
505 sp = p;
506 dp = decompressed = fz_calloc(ctx, height, stride);
507 ep = dp + height * stride;
508 x = 0;
509
510 while (sp + 2 <= *end)
511 {
512 if (sp[0] == 0 && sp[1] == 0)
513 { /* end of line */
514 if (x < stride)
515 dp += stride - x;
516 sp += 2;
517 x = 0;
518 }
519 else if (sp[0] == 0 && sp[1] == 1)
520 { /* end of bitmap */
521 dp = ep;
522 break;
523 }
524 else if (sp[0] == 0 && sp[1] == 2)
525 { /* delta */
526 int deltax, deltay;
527 if (sp + 4 > *end)
528 break;
529 deltax = sp[2];
530 deltay = sp[3];
531 dp += deltax + deltay * stride;
532 sp += 4;
533 x += deltax;
534 }
535 else if (sp[0] == 0 && sp[1] >= 3)
536 { /* absolute */
537 int n = sp[1];
538 int nn = (n + 1) / 2 * 2;
539 if (sp + 2 + nn > *end)
540 break;
541 if (dp + n > ep) {
542 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
543 break;
544 }
545 sp += 2;
546 for (i = 0; i < n; i++)
547 dp[i] = sp[i];
548 dp += n;
549 sp += (n + 1) / 2 * 2;
550 x += n;
551 }
552 else
553 { /* encoded */
554 int n = sp[0];
555 if (dp + n > ep) {
556 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
557 break;
558 }
559 for (i = 0; i < n; i++)
560 dp[i] = sp[1];
561 dp += n;
562 sp += 2;
563 x += n;
564 }
565 }
566
567 if (dp < ep)
568 fz_warn(ctx, "premature end of bitmap data in bmp image");
569
570 info->compression = BI_RGB;
571 info->bitcount = 8;
572 *end = ep;
573 return decompressed;
574}
575
576static unsigned char *
577bmp_decompress_rle4(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
578{
579 const unsigned char *sp;
580 unsigned char *dp, *ep, *decompressed;
581 int width = info->width;
582 int height = info->height;
583 int stride;
584 int i, x;
585
586 stride = ((width + 1) / 2 + 3) / 4 * 4;
587
588 sp = p;
589 dp = decompressed = fz_calloc(ctx, height, stride);
590 ep = dp + height * stride;
591 x = 0;
592
593 while (sp + 2 <= *end)
594 {
595 if (sp[0] == 0 && sp[1] == 0)
596 { /* end of line */
597 int xx = x / 2;
598 if (xx < stride)
599 dp += stride - xx;
600 sp += 2;
601 x = 0;
602 }
603 else if (sp[0] == 0 && sp[1] == 1)
604 { /* end of bitmap */
605 dp = ep;
606 break;
607 }
608 else if (sp[0] == 0 && sp[1] == 2)
609 { /* delta */
610 int deltax, deltay, startlow;
611 if (sp + 4 > *end)
612 break;
613 deltax = sp[2];
614 deltay = sp[3];
615 startlow = x & 1;
616 dp += (deltax + startlow) / 2 + deltay * stride;
617 sp += 4;
618 x += deltax;
619 }
620 else if (sp[0] == 0 && sp[1] >= 3)
621 { /* absolute */
622 int n = sp[1];
623 int nn = ((n + 1) / 2 + 1) / 2 * 2;
624 if (sp + 2 + nn > *end)
625 break;
626 if (dp + n / 2 > ep) {
627 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
628 break;
629 }
630 sp += 2;
631 for (i = 0; i < n; i++, x++)
632 {
633 int val = i & 1 ? (sp[i/2]) & 0xF : (sp[i/2] >> 4) & 0xF;
634 if (x & 1)
635 *dp++ |= val;
636 else
637 *dp |= val << 4;
638 }
639 sp += nn;
640 }
641 else
642 { /* encoded */
643 int n = sp[0];
644 int hi = (sp[1] >> 4) & 0xF;
645 int lo = sp[1] & 0xF;
646 if (dp + n / 2 + (x & 1) > ep) {
647 fz_warn(ctx, "buffer overflow in bitmap data in bmp image");
648 break;
649 }
650 for (i = 0; i < n; i++, x++)
651 {
652 int val = i & 1 ? lo : hi;
653 if (x & 1)
654 *dp++ |= val;
655 else
656 *dp |= val << 4;
657 }
658 sp += 2;
659 }
660 }
661
662 info->compression = BI_RGB;
663 info->bitcount = 4;
664 *end = ep;
665 return decompressed;
666}
667
668static fz_pixmap *
669bmp_read_bitmap(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end)
670{
671 const int mults[] = { 0, 8191, 2730, 1170, 546, 264, 130, 64 };
672 fz_pixmap *pix;
673 const unsigned char *ssp;
674 unsigned char *ddp;
675 unsigned char *decompressed = NULL;
676 int bitcount, width, height;
677 int sstride, dstride;
678 int rmult, gmult, bmult, amult;
679 int rtrunc, gtrunc, btrunc, atrunc;
680 int x, y;
681
682 if (info->compression == BI_RLE8)
683 ssp = decompressed = bmp_decompress_rle8(ctx, info, p, &end);
684 else if (info->compression == BI_RLE4)
685 ssp = decompressed = bmp_decompress_rle4(ctx, info, p, &end);
686 else if (info->compression == BI_RLE24)
687 ssp = decompressed = bmp_decompress_rle24(ctx, info, p, &end);
688 else
689 ssp = p;
690
691 bitcount = info->bitcount;
692 width = info->width;
693 height = info->height;
694
695 sstride = ((width * bitcount + 31) / 32) * 4;
696
697 if (ssp + sstride * height > end)
698 {
699 fz_free(ctx, decompressed);
700 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap data in bmp image");
701 }
702
703 fz_try(ctx)
704 pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), width, height, NULL, 1);
705 fz_catch(ctx)
706 {
707 fz_free(ctx, decompressed);
708 fz_rethrow(ctx);
709 }
710
711 ddp = pix->samples;
712 dstride = pix->stride;
713 if (!info->topdown)
714 {
715 ddp = pix->samples + (height - 1) * dstride;
716 dstride = -dstride;
717 }
718
719 /* These only apply for components in 16-bit and 32-bit mode
720 1-bit (1 * 8191) / 32
721 2-bit (3 * 2730) / 32
722 3-bit (7 * 1170) / 32
723 4-bit (15 * 546) / 32
724 5-bit (31 * 264) / 32
725 6-bit (63 * 130) / 32
726 7-bit (127 * 64) / 32
727 */
728 rmult = info->rbits < 8 ? mults[info->rbits] : 1;
729 gmult = info->gbits < 8 ? mults[info->gbits] : 1;
730 bmult = info->bbits < 8 ? mults[info->bbits] : 1;
731 amult = info->abits < 8 ? mults[info->abits] : 1;
732 rtrunc = info->rbits < 8 ? 5 : (info->rbits - 8);
733 gtrunc = info->gbits < 8 ? 5 : (info->gbits - 8);
734 btrunc = info->bbits < 8 ? 5 : (info->bbits - 8);
735 atrunc = info->abits < 8 ? 5 : (info->abits - 8);
736
737 for (y = 0; y < height; y++)
738 {
739 const unsigned char *sp = ssp + y * sstride;
740 unsigned char *dp = ddp + y * dstride;
741
742 switch (bitcount)
743 {
744 case 32:
745 for (x = 0; x < width; x++)
746 {
747 unsigned int sample = (sp[3] << 24) | (sp[2] << 16) | (sp[1] << 8) | sp[0];
748 unsigned int r = (sample & info->rmask) >> info->rshift;
749 unsigned int g = (sample & info->gmask) >> info->gshift;
750 unsigned int b = (sample & info->bmask) >> info->bshift;
751 unsigned int a = info->abits == 0 ? 255 : (sample & info->amask) >> info->ashift;
752 *dp++ = (r * rmult) >> rtrunc;
753 *dp++ = (g * gmult) >> gtrunc;
754 *dp++ = (b * bmult) >> btrunc;
755 *dp++ = info->abits == 0 ? a : (a * amult) >> atrunc;
756 sp += 4;
757 }
758 break;
759 case 24:
760 for (x = 0; x < width; x++)
761 {
762 *dp++ = sp[2];
763 *dp++ = sp[1];
764 *dp++ = sp[0];
765 *dp++ = 255;
766 sp += 3;
767 }
768 break;
769 case 16:
770 for (x = 0; x < width; x++)
771 {
772 unsigned int sample = (sp[1] << 8) | sp[0];
773 unsigned int r = (sample & info->rmask) >> info->rshift;
774 unsigned int g = (sample & info->gmask) >> info->gshift;
775 unsigned int b = (sample & info->bmask) >> info->bshift;
776 unsigned int a = (sample & info->amask) >> info->ashift;
777 *dp++ = (r * rmult) >> rtrunc;
778 *dp++ = (g * gmult) >> gtrunc;
779 *dp++ = (b * bmult) >> btrunc;
780 *dp++ = info->abits == 0 ? 255 : (a * amult) >> atrunc;
781 sp += 2;
782 }
783 break;
784 case 8:
785 for (x = 0; x < width; x++)
786 {
787 *dp++ = info->palette[3 * sp[0] + 0];
788 *dp++ = info->palette[3 * sp[0] + 1];
789 *dp++ = info->palette[3 * sp[0] + 2];
790 *dp++ = 255;
791 sp++;
792 }
793 break;
794 case 4:
795 for (x = 0; x < width; x++)
796 {
797 int idx;
798 switch (x & 1)
799 {
800 case 0: idx = (sp[0] >> 4) & 0x0f; break;
801 case 1: idx = (sp[0] >> 0) & 0x0f; sp++; break;
802 }
803 *dp++ = info->palette[3 * idx + 0];
804 *dp++ = info->palette[3 * idx + 1];
805 *dp++ = info->palette[3 * idx + 2];
806 *dp++ = 255;
807 }
808 break;
809 case 2:
810 for (x = 0; x < width; x++)
811 {
812 int idx;
813 switch (x & 3)
814 {
815 case 0: idx = (sp[0] >> 6) & 0x03; break;
816 case 1: idx = (sp[0] >> 4) & 0x03; break;
817 case 2: idx = (sp[0] >> 2) & 0x03; break;
818 case 3: idx = (sp[0] >> 0) & 0x03; sp++; break;
819 }
820 *dp++ = info->palette[3 * idx + 0];
821 *dp++ = info->palette[3 * idx + 1];
822 *dp++ = info->palette[3 * idx + 2];
823 *dp++ = 255;
824 }
825 break;
826 case 1:
827 for (x = 0; x < width; x++)
828 {
829 int idx;
830 switch (x & 7)
831 {
832 case 0: idx = (sp[0] >> 7) & 0x01; break;
833 case 1: idx = (sp[0] >> 6) & 0x01; break;
834 case 2: idx = (sp[0] >> 5) & 0x01; break;
835 case 3: idx = (sp[0] >> 4) & 0x01; break;
836 case 4: idx = (sp[0] >> 3) & 0x01; break;
837 case 5: idx = (sp[0] >> 2) & 0x01; break;
838 case 6: idx = (sp[0] >> 1) & 0x01; break;
839 case 7: idx = (sp[0] >> 0) & 0x01; sp++; break;
840 }
841 *dp++ = info->palette[3 * idx + 0];
842 *dp++ = info->palette[3 * idx + 1];
843 *dp++ = info->palette[3 * idx + 2];
844 *dp++ = 255;
845 }
846 break;
847 }
848 }
849
850 fz_free(ctx, decompressed);
851 fz_premultiply_pixmap(ctx, pix);
852 return pix;
853}
854
855static fz_pixmap *
856bmp_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_t total, int only_metadata)
857{
858 const unsigned char *begin = p;
859 const unsigned char *end = p + total;
860 int size;
861
862 memset(info, 0x00, sizeof (*info));
863
864 p = bmp_read_file_header(ctx, info, p, end);
865
866 info->filesize = fz_mini(info->filesize, (int)total);
867
868 if (end - p < 4)
869 fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in bitmap core header in bmp image");
870 size = read32(p + 0);
871
872 if (size == 12)
873 p = bmp_read_bitmap_core_header(ctx, info, p, end);
874 else if (size == 40 || size == 52 || size == 56 || size == 108 || size == 124)
875 {
876 p = bmp_read_bitmap_info_header(ctx, info, p, end);
877 if (info->extramasks)
878 p = bmp_read_extra_masks(ctx, info, p, end);
879 }
880 else if (size == 16 || size == 64)
881 p = bmp_read_bitmap_os2_header(ctx, info, p, end);
882 else
883 fz_throw(ctx, FZ_ERROR_GENERIC, "invalid header size (%d) in bmp image", size);
884
885 maskinfo(info->rmask, &info->rshift, &info->rbits);
886 maskinfo(info->gmask, &info->gshift, &info->gbits);
887 maskinfo(info->bmask, &info->bshift, &info->bbits);
888 maskinfo(info->amask, &info->ashift, &info->abits);
889
890 if (info->width <= 0 || info->width > SHRT_MAX || info->height <= 0 || info->height > SHRT_MAX)
891 fz_throw(ctx, FZ_ERROR_GENERIC, "dimensions (%d x %d) out of range in bmp image",
892 info->width, info->height);
893 if (info->compression != BI_RGB && info->compression != BI_RLE8 &&
894 info->compression != BI_RLE4 && info->compression != BI_BITFIELDS &&
895 info->compression != BI_JPEG && info->compression != BI_PNG &&
896 info->compression != BI_ALPHABITS && info->compression != BI_RLE24)
897 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported compression method (%d) in bmp image", info->compression);
898 if ((info->compression == BI_RGB && info->bitcount != 1 &&
899 info->bitcount != 2 && info->bitcount != 4 &&
900 info->bitcount != 8 && info->bitcount != 16 &&
901 info->bitcount != 24 && info->bitcount != 32) ||
902 (info->compression == BI_RLE8 && info->bitcount != 8) ||
903 (info->compression == BI_RLE4 && info->bitcount != 4) ||
904 (info->compression == BI_BITFIELDS && info->bitcount != 16 && info->bitcount != 32) ||
905 (info->compression == BI_JPEG && info->bitcount != 0) ||
906 (info->compression == BI_PNG && info->bitcount != 0) ||
907 (info->compression == BI_ALPHABITS && info->bitcount != 16 && info->bitcount != 32) ||
908 (info->compression == BI_RLE24 && info->bitcount != 24))
909 fz_throw(ctx, FZ_ERROR_GENERIC, "invalid bits per pixel (%d) for compression (%d) in bmp image",
910 info->bitcount, info->compression);
911 if (info->rbits < 0 || info->rbits > info->bitcount)
912 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported %d bit red mask in bmp image", info->rbits);
913 if (info->gbits < 0 || info->gbits > info->bitcount)
914 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported %d bit green mask in bmp image", info->gbits);
915 if (info->bbits < 0 || info->bbits > info->bitcount)
916 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported %d bit blue mask in bmp image", info->bbits);
917 if (info->abits < 0 || info->abits > info->bitcount)
918 fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported %d bit alpha mask in bmp image", info->abits);
919
920 if (only_metadata)
921 return NULL;
922
923 if (info->compression == BI_JPEG)
924 {
925 if (p - begin < info->offset)
926 p = begin + info->offset;
927 return fz_load_jpeg(ctx, p, end - p);
928 }
929 else if (info->compression == BI_PNG)
930 {
931 if (p - begin < info->offset)
932 p = begin + info->offset;
933 return fz_load_png(ctx, p, end - p);
934 }
935 else
936 {
937 const unsigned char *color_table_end = begin + info->offset;
938 if (end - begin < info->offset)
939 color_table_end = end;
940 p = bmp_read_color_table(ctx, info, p, color_table_end);
941
942 if (p - begin < info->offset)
943 p = begin + info->offset;
944 return bmp_read_bitmap(ctx, info, p, end);
945 }
946}
947
948fz_pixmap *
949fz_load_bmp(fz_context *ctx, const unsigned char *p, size_t total)
950{
951 struct info bmp;
952 fz_pixmap *image;
953
954 image = bmp_read_image(ctx, &bmp, p, total, 0);
955 image->xres = bmp.xres / (1000.0f / 25.4f);
956 image->yres = bmp.yres / (1000.0f / 25.4f);
957
958 return image;
959}
960
961void
962fz_load_bmp_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
963{
964 struct info bmp;
965
966 bmp_read_image(ctx, &bmp, p, total, 1);
967
968 *cspacep = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
969 *wp = bmp.width;
970 *hp = bmp.height;
971 *xresp = bmp.xres / (1000.0f / 25.4f);
972 *yresp = bmp.yres / (1000.0f / 25.4f);
973}
974