Coverage Report

Created: 2025-01-11 06:55

/src/mupdf/source/fitz/load-bmp.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2024 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
25
#include "image-imp.h"
26
#include "pixmap-imp.h"
27
28
#include <string.h>
29
#include <limits.h>
30
31
#undef BMP_DEBUG
32
33
static const unsigned char web_palette[] = {
34
  0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00,
35
  0x00, 0x00, 0x33, 0x33, 0x00, 0x33, 0x66, 0x00, 0x33, 0x99, 0x00, 0x33, 0xCC, 0x00, 0x33, 0xFF, 0x00, 0x33,
36
  0x00, 0x00, 0x66, 0x33, 0x00, 0x66, 0x66, 0x00, 0x66, 0x99, 0x00, 0x66, 0xCC, 0x00, 0x66, 0xFF, 0x00, 0x66,
37
  0x00, 0x00, 0x99, 0x33, 0x00, 0x99, 0x66, 0x00, 0x99, 0x99, 0x00, 0x99, 0xCC, 0x00, 0x99, 0xFF, 0x00, 0x99,
38
  0x00, 0x00, 0xCC, 0x33, 0x00, 0xCC, 0x66, 0x00, 0xCC, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xCC,
39
  0x00, 0x00, 0xFF, 0x33, 0x00, 0xFF, 0x66, 0x00, 0xFF, 0x99, 0x00, 0xFF, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
40
  0x00, 0x33, 0x00, 0x33, 0x33, 0x00, 0x66, 0x33, 0x00, 0x99, 0x33, 0x00, 0xCC, 0x33, 0x00, 0xFF, 0x33, 0x00,
41
  0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
42
  0x00, 0x33, 0x66, 0x33, 0x33, 0x66, 0x66, 0x33, 0x66, 0x99, 0x33, 0x66, 0xCC, 0x33, 0x66, 0xFF, 0x33, 0x66,
43
  0x00, 0x33, 0x99, 0x33, 0x33, 0x99, 0x66, 0x33, 0x99, 0x99, 0x33, 0x99, 0xCC, 0x33, 0x99, 0xFF, 0x33, 0x99,
44
  0x00, 0x33, 0xCC, 0x33, 0x33, 0xCC, 0x66, 0x33, 0xCC, 0x99, 0x33, 0xCC, 0xCC, 0x33, 0xCC, 0xFF, 0x33, 0xCC,
45
  0x00, 0x33, 0xFF, 0x33, 0x33, 0xFF, 0x66, 0x33, 0xFF, 0x99, 0x33, 0xFF, 0xCC, 0x33, 0xFF, 0xFF, 0x33, 0xFF,
46
  0x00, 0x66, 0x00, 0x33, 0x66, 0x00, 0x66, 0x66, 0x00, 0x99, 0x66, 0x00, 0xCC, 0x66, 0x00, 0xFF, 0x66, 0x00,
47
  0x00, 0x66, 0x33, 0x33, 0x66, 0x33, 0x66, 0x66, 0x33, 0x99, 0x66, 0x33, 0xCC, 0x66, 0x33, 0xFF, 0x66, 0x33,
48
  0x00, 0x66, 0x66, 0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
49
  0x00, 0x66, 0x99, 0x33, 0x66, 0x99, 0x66, 0x66, 0x99, 0x99, 0x66, 0x99, 0xCC, 0x66, 0x99, 0xFF, 0x66, 0x99,
50
  0x00, 0x66, 0xCC, 0x33, 0x66, 0xCC, 0x66, 0x66, 0xCC, 0x99, 0x66, 0xCC, 0xCC, 0x66, 0xCC, 0xFF, 0x66, 0xCC,
51
  0x00, 0x66, 0xFF, 0x33, 0x66, 0xFF, 0x66, 0x66, 0xFF, 0x99, 0x66, 0xFF, 0xCC, 0x66, 0xFF, 0xFF, 0x66, 0xFF,
52
  0x00, 0x99, 0x00, 0x33, 0x99, 0x00, 0x66, 0x99, 0x00, 0x99, 0x99, 0x00, 0xCC, 0x99, 0x00, 0xFF, 0x99, 0x00,
53
  0x00, 0x99, 0x33, 0x33, 0x99, 0x33, 0x66, 0x99, 0x33, 0x99, 0x99, 0x33, 0xCC, 0x99, 0x33, 0xFF, 0x99, 0x33,
54
  0x00, 0x99, 0x66, 0x33, 0x99, 0x66, 0x66, 0x99, 0x66, 0x99, 0x99, 0x66, 0xCC, 0x99, 0x66, 0xFF, 0x99, 0x66,
55
  0x00, 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0x99, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
56
  0x00, 0x99, 0xCC, 0x33, 0x99, 0xCC, 0x66, 0x99, 0xCC, 0x99, 0x99, 0xCC, 0xCC, 0x99, 0xCC, 0xFF, 0x99, 0xCC,
57
  0x00, 0x99, 0xFF, 0x33, 0x99, 0xFF, 0x66, 0x99, 0xFF, 0x99, 0x99, 0xFF, 0xCC, 0x99, 0xFF, 0xFF, 0x99, 0xFF,
58
  0x00, 0xCC, 0x00, 0x33, 0xCC, 0x00, 0x66, 0xCC, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xCC, 0x00,
59
  0x00, 0xCC, 0x33, 0x33, 0xCC, 0x33, 0x66, 0xCC, 0x33, 0x99, 0xCC, 0x33, 0xCC, 0xCC, 0x33, 0xFF, 0xCC, 0x33,
60
  0x00, 0xCC, 0x66, 0x33, 0xCC, 0x66, 0x66, 0xCC, 0x66, 0x99, 0xCC, 0x66, 0xCC, 0xCC, 0x66, 0xFF, 0xCC, 0x66,
61
  0x00, 0xCC, 0x99, 0x33, 0xCC, 0x99, 0x66, 0xCC, 0x99, 0x99, 0xCC, 0x99, 0xCC, 0xCC, 0x99, 0xFF, 0xCC, 0x99,
62
  0x00, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
63
  0x00, 0xCC, 0xFF, 0x33, 0xCC, 0xFF, 0x66, 0xCC, 0xFF, 0x99, 0xCC, 0xFF, 0xCC, 0xCC, 0xFF, 0xFF, 0xCC, 0xFF,
64
  0x00, 0xFF, 0x00, 0x33, 0xFF, 0x00, 0x66, 0xFF, 0x00, 0x99, 0xFF, 0x00, 0xCC, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
65
  0x00, 0xFF, 0x33, 0x33, 0xFF, 0x33, 0x66, 0xFF, 0x33, 0x99, 0xFF, 0x33, 0xCC, 0xFF, 0x33, 0xFF, 0xFF, 0x33,
66
  0x00, 0xFF, 0x66, 0x33, 0xFF, 0x66, 0x66, 0xFF, 0x66, 0x99, 0xFF, 0x66, 0xCC, 0xFF, 0x66, 0xFF, 0xFF, 0x66,
67
  0x00, 0xFF, 0x99, 0x33, 0xFF, 0x99, 0x66, 0xFF, 0x99, 0x99, 0xFF, 0x99, 0xCC, 0xFF, 0x99, 0xFF, 0xFF, 0x99,
68
  0x00, 0xFF, 0xCC, 0x33, 0xFF, 0xCC, 0x66, 0xFF, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0xFF, 0xCC, 0xFF, 0xFF, 0xCC,
69
  0x00, 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
70
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77
};
78
79
static const unsigned char vga_palette[] = {
80
  0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
81
  0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
82
  0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
83
  0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF,
84
};
85
86
static const unsigned char gray_palette[] = {
87
  0x00, 0x00, 0x00, 0x54, 0x54, 0x54,
88
  0xA8, 0xA8, 0xA8, 0xFF, 0xFF, 0xFF,
89
};
90
91
static const unsigned char bw_palette[] = {
92
  0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
93
};
94
95
enum {
96
  BI_NONE = 0,
97
  BI_RLE8 = 1,
98
  BI_RLE4 = 2,
99
  BI_BITFIELDS = 3,
100
  BI_HUFFMAN1D = 3,
101
  BI_JPEG = 4,
102
  BI_RLE24 = 4,
103
  BI_PNG = 5,
104
  BI_ALPHABITS = 6,
105
};
106
107
struct info
108
{
109
  char type[2];
110
  uint32_t version;
111
  uint32_t bitmapoffset;
112
  uint32_t width, height;
113
  uint16_t bitcount;
114
  uint32_t compression;
115
  uint32_t bitmapsize;
116
  uint32_t xres, yres;
117
  uint32_t colors;
118
  uint32_t rmask, gmask, bmask, amask;
119
  uint8_t palette[256 * 3];
120
  uint32_t colorspacetype;
121
  uint32_t endpoints[3 * 3];
122
  uint32_t gamma[3];
123
  uint32_t intent;
124
  uint32_t profileoffset;
125
  uint32_t profilesize;
126
127
  int topdown;
128
  unsigned int rshift, gshift, bshift, ashift;
129
  unsigned int rbits, gbits, bbits, abits;
130
131
  unsigned char *samples;
132
  fz_colorspace *cs;
133
};
134
135
1.71k
#define read8(p) ((p)[0])
136
253
#define read16(p) (((p)[1] << 8) | (p)[0])
137
4.44k
#define read32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
138
139
500
#define DPM_TO_DPI(dpm) ((dpm) * 25.4f / 1000.0f)
140
141
500
#define is_bitmap_array(p) ((p)[0] == 'B' && (p)[1] == 'A')
142
748
#define is_bitmap(p) ((p)[0] == 'B' && (p)[1] == 'M')
143
144
19
#define is_os2_bmp(info) ((info)->version == 12 || (info)->version == 16 || (info)->version == 64)
145
2.64k
#define is_win_bmp(info) ((info)->version == 12 || (info)->version == 40 || (info)->version == 52 || (info)->version == 56 || (info)->version == 108 || (info)->version == 124)
146
147
472
#define is_valid_win_compression(info) (is_win_bmp(info) && ((info)->compression == BI_NONE || (info)->compression == BI_RLE8 || (info)->compression == BI_RLE4 || (info)->compression == BI_BITFIELDS || (info)->compression == BI_JPEG || (info)->compression == BI_PNG || (info)->compression == BI_ALPHABITS || (info)->compression == BI_RLE24))
148
4
#define is_valid_os2_compression(info) (is_os2_bmp(info) && ((info)->compression == BI_NONE || (info)->compression == BI_RLE8 || (info)->compression == BI_RLE4 || (info)->compression == BI_HUFFMAN1D || (info)->compression == BI_RLE24))
149
236
#define is_valid_compression(info) (is_valid_win_compression(info) || is_valid_os2_compression(info))
150
151
464
#define is_valid_rgb_bitcount(info) ((info)->compression == BI_NONE && ((info)->bitcount == 1 || (info)->bitcount == 2 || (info)->bitcount == 4 || (info)->bitcount == 8 || (info)->bitcount == 16 || (info)->bitcount == 24 || (info)->bitcount == 32 || (info)->bitcount == 64))
152
449
#define is_valid_rle8_bitcount(info) ((info)->compression == BI_RLE8 && (info)->bitcount == 8)
153
400
#define is_valid_rle4_bitcount(info) ((info)->compression == BI_RLE4 && (info)->bitcount == 4)
154
356
#define is_valid_bitfields_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_BITFIELDS && ((info)->bitcount == 16 || (info)->bitcount == 32))
155
237
#define is_valid_jpeg_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_JPEG && (info)->bitcount == 0)
156
237
#define is_valid_png_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_PNG && (info)->bitcount == 0)
157
237
#define is_valid_alphabits_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_ALPHABITS && ((info)->bitcount == 16 || (info)->bitcount == 32))
158
233
#define is_valid_rle24_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_RLE24 && (info)->bitcount == 24)
159
1
#define is_valid_huffman1d_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_HUFFMAN1D && (info)->bitcount == 1)
160
232
#define is_valid_bitcount(info) (is_valid_rgb_bitcount(info) || is_valid_rle8_bitcount(info) || is_valid_rle4_bitcount(info) || is_valid_bitfields_bitcount(info) || is_valid_jpeg_bitcount(info) || is_valid_png_bitcount(info) || is_valid_alphabits_bitcount(info) || is_valid_rle24_bitcount(info) || is_valid_huffman1d_bitcount(info))
161
162
250
#define has_palette(info) ((info)->bitcount == 1 || (info)->bitcount == 2 || (info)->bitcount == 4 || (info)->bitcount == 8)
163
250
#define has_color_masks(info) (((info)->bitcount == 16 || (info)->bitcount == 32) && (info)->version == 40 && ((info)->compression == BI_BITFIELDS || (info)->compression == BI_ALPHABITS))
164
228
#define has_color_profile(info) ((info)->version == 108 || (info)->version == 124)
165
166
102
#define palette_entry_size(info) ((info)->version == 12 ? 3 : 4)
167
168
static const unsigned char *
169
bmp_read_file_header(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p)
170
250
{
171
250
  if (end - p < 14)
172
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in file header in bmp image");
173
174
250
  if (!is_bitmap(p))
175
1
    fz_throw(ctx, FZ_ERROR_FORMAT, "invalid signature %02x%02x in bmp image", p[0], p[1]);
176
177
249
  info->type[0] = read8(p + 0);
178
249
  info->type[1] = read8(p + 1);
179
  /* read32(p+2) == file or header size */
180
  /* read16(p+6) == hotspot x for icons/cursors */
181
  /* read16(p+8) == hotspot y for icons/cursors */
182
249
  info->bitmapoffset = read32(p + 10);
183
184
249
  return p + 14;
185
250
}
186
187
static unsigned char *
188
bmp_decompress_huffman1d(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
189
0
{
190
0
  fz_stream *encstm, *decstm;
191
0
  fz_buffer *buf;
192
0
  unsigned char *decoded;
193
0
  size_t size;
194
195
0
  encstm = fz_open_memory(ctx, p, *end - p);
196
197
0
  fz_var(decstm);
198
0
  fz_var(buf);
199
200
0
  fz_try(ctx)
201
0
  {
202
0
    decstm = fz_open_faxd(ctx, encstm,
203
0
      0, /* 1 dimensional encoding */
204
0
      0, /* end of line not required */
205
0
      0, /* encoded byte align */
206
0
      info->width, info->height,
207
0
      0, /* end of block expected */
208
0
      1 /* black is 1 */
209
0
    );
210
0
    buf = fz_read_all(ctx, decstm, 1024);
211
0
    size = fz_buffer_extract(ctx, buf, &decoded);
212
0
    *end = decoded + size;
213
0
  }
214
0
  fz_always(ctx)
215
0
  {
216
0
    fz_drop_buffer(ctx, buf);
217
0
    fz_drop_stream(ctx, decstm);
218
0
    fz_drop_stream(ctx, encstm);
219
0
  }
220
0
  fz_catch(ctx)
221
0
    fz_rethrow(ctx);
222
223
0
  return decoded;
224
0
}
225
226
static unsigned char *
227
bmp_decompress_rle24(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
228
0
{
229
0
  const unsigned char *sp;
230
0
  unsigned char *dp, *ep, *decompressed;
231
0
  uint32_t width = info->width;
232
0
  uint32_t height = info->height;
233
0
  uint32_t stride;
234
0
  uint32_t x, y;
235
0
  int i;
236
237
0
  stride = (width*3 + 3) / 4 * 4;
238
239
0
  sp = p;
240
0
  dp = decompressed = fz_calloc(ctx, height, stride);
241
0
  ep = dp + height * stride;
242
0
  x = 0;
243
0
  y = 0;
244
245
0
  while (sp + 2 <= *end)
246
0
  {
247
0
    if (sp[0] == 0 && sp[1] == 0)
248
0
    { /* end of line */
249
0
      sp += 2;
250
0
      x = 0;
251
0
      y++;
252
0
    }
253
0
    else if (sp[0] == 0 && sp[1] == 1)
254
0
    { /* end of bitmap */
255
0
      sp += 2;
256
0
      break;
257
0
    }
258
0
    else if (sp[0] == 0 && sp[1] == 2)
259
0
    { /* delta */
260
0
      sp += 2;
261
0
      x += sp < *end ? *sp++ : 0;
262
0
      y += sp < *end ? *sp++ : 0;
263
0
    }
264
0
    else if (sp[0] == 0 && sp[1] >= 3)
265
0
    { /* absolute */
266
0
      int dn, sn, pad;
267
0
      dn = sp[1];
268
0
      sn = (dn * 3 + 1) / 2 * 2;
269
0
      pad = sn & 1;
270
0
      sp += 2;
271
0
      if (sn > *end - sp)
272
0
      {
273
0
        fz_warn(ctx, "premature end of pixel data in absolute code in bmp image");
274
0
        sn = ((*end - sp) / 3) * 3;
275
0
        pad = (*end - sp) % 3;
276
0
        dn = sn / 3;
277
0
      }
278
0
      else if (sn + pad > *end - sp)
279
0
      {
280
0
        fz_warn(ctx, "premature end of padding in absolute code in bmp image");
281
0
        pad = 0;
282
0
      }
283
0
      for (i = 0; i < dn; i++)
284
0
      {
285
0
        uint32_t actualx = x;
286
0
        uint32_t actualy = y;
287
0
        if (actualx >= width || actualy >= height)
288
0
        {
289
0
          actualx = x % width;
290
0
          actualy = y + x / width;
291
0
        }
292
0
        if (actualx < width && actualy < height)
293
0
        {
294
0
          dp = decompressed + actualy * stride + actualx * 3;
295
0
          *dp++ = sp[i * 3 + 0];
296
0
          *dp++ = sp[i * 3 + 1];
297
0
          *dp++ = sp[i * 3 + 2];
298
0
        }
299
0
        x++;
300
0
      }
301
0
      sp += sn + pad;
302
0
    }
303
0
    else
304
0
    { /* encoded */
305
0
      int dn, sn;
306
0
      dn = sp[0];
307
0
      sn = 3;
308
0
      sp++;
309
0
      if (sn > *end - sp)
310
0
      {
311
0
        fz_warn(ctx, "premature end of pixel data in encoded code in bmp image");
312
0
        sn = 0;
313
0
        dn = 0;
314
0
      }
315
0
      for (i = 0; i < dn; i++)
316
0
      {
317
0
        uint32_t actualx = x;
318
0
        uint32_t actualy = y;
319
0
        if (actualx >= width || actualy >= height)
320
0
        {
321
0
          actualx = x % width;
322
0
          actualy = y + x / width;
323
0
        }
324
0
        if (actualx < width && actualy < height)
325
0
        {
326
0
          dp = decompressed + actualy * stride + actualx * 3;
327
0
          *dp++ = sp[0];
328
0
          *dp++ = sp[1];
329
0
          *dp++ = sp[2];
330
0
        }
331
0
        x++;
332
0
      }
333
0
      sp += sn;
334
0
    }
335
0
  }
336
337
0
  info->compression = BI_NONE;
338
0
  info->bitcount = 24;
339
0
  *end = ep;
340
0
  return decompressed;
341
0
}
342
343
static unsigned char *
344
bmp_decompress_rle8(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
345
49
{
346
49
  const unsigned char *sp;
347
49
  unsigned char *dp, *ep, *decompressed;
348
49
  uint32_t width = info->width;
349
49
  uint32_t height = info->height;
350
49
  uint32_t stride;
351
49
  uint32_t x, y;
352
49
  int i;
353
354
49
  stride = (width + 3) / 4 * 4;
355
356
49
  sp = p;
357
49
  dp = decompressed = fz_calloc(ctx, height, stride);
358
49
  ep = dp + height * stride;
359
49
  x = 0;
360
49
  y = 0;
361
362
26.6k
  while (sp + 2 <= *end)
363
26.5k
  {
364
26.5k
    if (sp[0] == 0 && sp[1] == 0)
365
1.98k
    { /* end of line */
366
1.98k
      sp += 2;
367
1.98k
      x = 0;
368
1.98k
      y++;
369
1.98k
    }
370
24.5k
    else if (sp[0] == 0 && sp[1] == 1)
371
2
    { /* end of bitmap */
372
2
      sp += 2;
373
2
      break;
374
2
    }
375
24.5k
    else if (sp[0] == 0 && sp[1] == 2)
376
10
    { /* delta */
377
10
      sp +=2;
378
10
      x += sp < *end ? *sp++ : 0;
379
10
      y += sp < *end ? *sp++ : 0;
380
10
    }
381
24.5k
    else if (sp[0] == 0 && sp[1] >= 3)
382
324
    { /* absolute */
383
324
      int dn, sn, pad;
384
324
      dn = sp[1];
385
324
      sn = dn;
386
324
      pad = sn & 1;
387
324
      sp += 2;
388
324
      if (sn > *end - sp)
389
25
      {
390
25
        fz_warn(ctx, "premature end of pixel data in absolute code in bmp image");
391
25
        sn = *end - sp;
392
25
        pad = 0;
393
25
        dn = sn;
394
25
      }
395
299
      else if (sn + pad > *end - sp)
396
0
      {
397
0
        fz_warn(ctx, "premature end of padding in absolute code in bmp image");
398
0
        pad = 0;
399
0
      }
400
23.6k
      for (i = 0; i < dn; i++)
401
23.3k
      {
402
23.3k
        uint32_t actualx = x;
403
23.3k
        uint32_t actualy = y;
404
23.3k
        if (actualx >= width || actualy >= height)
405
21.6k
        {
406
21.6k
          actualx = x % width;
407
21.6k
          actualy = y + x / width;
408
21.6k
        }
409
23.3k
        if (actualx < width && actualy < height)
410
3.37k
        {
411
3.37k
          dp = decompressed + actualy * stride + actualx;
412
3.37k
          *dp++ = sp[i];
413
3.37k
        }
414
23.3k
        x++;
415
23.3k
      }
416
324
      sp += sn + pad;
417
324
    }
418
24.2k
    else
419
24.2k
    { /* encoded */
420
24.2k
      int dn, sn;
421
24.2k
      dn = sp[0];
422
24.2k
      sn = 1;
423
24.2k
      sp++;
424
2.95M
      for (i = 0; i < dn; i++)
425
2.93M
      {
426
2.93M
        uint32_t actualx = x;
427
2.93M
        uint32_t actualy = y;
428
2.93M
        if (actualx >= width || actualy >= height)
429
2.92M
        {
430
2.92M
          actualx = x % width;
431
2.92M
          actualy = y + x / width;
432
2.92M
        }
433
2.93M
        if (actualx < width && actualy < height)
434
128k
        {
435
128k
          dp = decompressed + actualy * stride + actualx;
436
128k
          *dp++ = sp[0];
437
128k
        }
438
2.93M
        x++;
439
2.93M
      }
440
24.2k
      sp += sn;
441
24.2k
    }
442
26.5k
  }
443
444
49
  info->compression = BI_NONE;
445
49
  info->bitcount = 8;
446
49
  *end = ep;
447
49
  return decompressed;
448
49
}
449
450
static unsigned char *
451
bmp_decompress_rle4(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
452
44
{
453
44
  const unsigned char *sp;
454
44
  unsigned char *dp, *ep, *decompressed;
455
44
  uint32_t width = info->width;
456
44
  uint32_t height = info->height;
457
44
  uint32_t stride;
458
44
  uint32_t x, y;
459
44
  int i;
460
461
44
  stride = ((width + 1) / 2 + 3) / 4 * 4;
462
463
44
  sp = p;
464
44
  dp = decompressed = fz_calloc(ctx, height, stride);
465
44
  ep = dp + height * stride;
466
44
  x = 0;
467
44
  y = 0;
468
469
20.2k
  while (sp + 2 <= *end)
470
20.1k
  {
471
20.1k
    if (sp[0] == 0 && sp[1] == 0)
472
415
    { /* end of line */
473
415
      sp += 2;
474
415
      x = 0;
475
415
      y++;
476
415
    }
477
19.7k
    else if (sp[0] == 0 && sp[1] == 1)
478
2
    { /* end of bitmap */
479
2
      sp += 2;
480
2
      break;
481
2
    }
482
19.7k
    else if (sp[0] == 0 && sp[1] == 2)
483
8
    { /* delta */
484
8
      sp += 2;
485
8
      x += sp < *end ? *sp++ : 0;
486
8
      y += sp < *end ? *sp++ : 0;
487
8
    }
488
19.7k
    else if (sp[0] == 0 && sp[1] >= 3)
489
232
    { /* absolute */
490
232
      int dn, sn, pad;
491
232
      dn = sp[1];
492
232
      sn = (dn + 1) / 2;
493
232
      pad = sn & 1;
494
232
      sp += 2;
495
232
      if (sn > *end - sp)
496
17
      {
497
17
        fz_warn(ctx, "premature end of pixel data in absolute code in bmp image");
498
17
        sn = *end - sp;
499
17
        pad = 0;
500
17
        dn = sn * 2;
501
17
      }
502
215
      else if (sn + pad > *end - sp)
503
0
      {
504
0
        fz_warn(ctx, "premature end of padding in absolute code in bmp image");
505
0
        pad = 0;
506
0
      }
507
22.3k
      for (i = 0; i < dn; i++)
508
22.1k
      {
509
22.1k
        uint32_t actualx = x;
510
22.1k
        uint32_t actualy = y;
511
22.1k
        if (actualx >= width || actualy >= height)
512
21.8k
        {
513
21.8k
          actualx = x % width;
514
21.8k
          actualy = y + x / width;
515
21.8k
        }
516
22.1k
        if (actualx < width && actualy < height)
517
16.3k
        {
518
16.3k
          int val = i & 1 ? (sp[i >> 1]) & 0xF : (sp[i >> 1] >> 4) & 0xF;
519
16.3k
          dp = decompressed + actualy * stride + actualx / 2;
520
16.3k
          if (x & 1)
521
8.17k
            *dp++ |= val;
522
8.19k
          else
523
8.19k
            *dp |= val << 4;
524
16.3k
        }
525
22.1k
        x++;
526
22.1k
      }
527
232
      sp += sn + pad;
528
232
    }
529
19.5k
    else
530
19.5k
    { /* encoded */
531
19.5k
      int dn, sn;
532
19.5k
      dn = sp[0];
533
19.5k
      sn = 1;
534
19.5k
      sp++;
535
2.01M
      for (i = 0; i < dn; i++)
536
1.99M
      {
537
1.99M
        uint32_t actualx = x;
538
1.99M
        uint32_t actualy = y;
539
1.99M
        if (actualx >= width || actualy >= height)
540
1.99M
        {
541
1.99M
          actualx = x % width;
542
1.99M
          actualy = y + x / width;
543
1.99M
        }
544
1.99M
        if (actualx < width && actualy < height)
545
600k
        {
546
600k
          int val = i & 1 ? (sp[0] & 0xf) : (sp[0] >> 4) & 0xf;
547
600k
          dp = decompressed + actualy * stride + actualx / 2;
548
600k
          if (x & 1)
549
300k
            *dp++ |= val;
550
300k
          else
551
300k
            *dp |= val << 4;
552
600k
        }
553
1.99M
        x++;
554
1.99M
      }
555
19.5k
      sp += sn;
556
19.5k
    }
557
20.1k
  }
558
559
44
  info->compression = BI_NONE;
560
44
  info->bitcount = 4;
561
44
  *end = ep;
562
44
  return decompressed;
563
44
}
564
565
static fz_pixmap *
566
bmp_read_bitmap(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p)
567
216
{
568
216
  const unsigned int mults[] = { 0, 8191, 2730, 1170, 546, 264, 130, 64 };
569
216
  fz_pixmap *pix;
570
216
  const unsigned char *ssp;
571
216
  unsigned char *ddp;
572
216
  unsigned char *decompressed = NULL;
573
216
  uint32_t bitcount;
574
216
  uint32_t width;
575
216
  int32_t height;
576
216
  uint32_t sstride;
577
216
  int32_t dstride;
578
216
  unsigned int rmult, gmult, bmult, amult;
579
216
  unsigned int rtrunc, gtrunc, btrunc, atrunc;
580
216
  uint32_t x;
581
216
  int32_t y;
582
583
216
  assert(info->width > 0 && info->width <= SHRT_MAX);
584
216
  assert(info->height > 0 && info->height <= SHRT_MAX);
585
586
216
  if (info->compression == BI_NONE)
587
8
    ssp = p;
588
208
  else if (info->compression == BI_RLE4)
589
44
    ssp = decompressed = bmp_decompress_rle4(ctx, info, p, &end);
590
164
  else if (info->compression == BI_RLE8)
591
49
    ssp = decompressed = bmp_decompress_rle8(ctx, info, p, &end);
592
115
  else if (is_win_bmp(info) && (info->compression == BI_BITFIELDS || info->compression == BI_ALPHABITS))
593
115
    ssp = p;
594
0
  else if (is_os2_bmp(info) && info->compression == BI_RLE24)
595
0
    ssp = decompressed = bmp_decompress_rle24(ctx, info, p, &end);
596
0
  else if (is_os2_bmp(info) && info->compression == BI_HUFFMAN1D)
597
0
    ssp = decompressed = bmp_decompress_huffman1d(ctx, info, p, &end);
598
0
  else
599
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unhandled compression (%u)  in bmp image", info->compression);
600
601
216
  bitcount = info->bitcount;
602
216
  width = info->width;
603
216
  height = info->height;
604
605
216
  sstride = ((width * bitcount + 31) / 32) * 4;
606
216
  if (ssp + sstride * height > end)
607
120
  {
608
120
    int32_t h = (end - ssp) / sstride;
609
120
    if (h == 0 || h > SHRT_MAX)
610
6
    {
611
6
      fz_free(ctx, decompressed);
612
6
      fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions out of range in bmp image");
613
6
    }
614
120
  }
615
616
420
  fz_try(ctx)
617
420
  {
618
210
    pix = fz_new_pixmap(ctx, info->cs, width, height, NULL, 1);
619
210
    fz_set_pixmap_resolution(ctx, pix, info->xres, info->yres);
620
210
    fz_clear_pixmap(ctx, pix);
621
210
  }
622
420
  fz_catch(ctx)
623
0
  {
624
0
    fz_free(ctx, decompressed);
625
0
    fz_rethrow(ctx);
626
0
  }
627
628
210
  ddp = pix->samples;
629
210
  dstride = pix->stride;
630
210
  if (!info->topdown)
631
175
  {
632
175
    ddp = pix->samples + ((size_t) (height - 1)) * ((size_t) dstride);
633
175
    dstride = -dstride;
634
175
  }
635
636
210
  if (ssp + sstride * height > end)
637
114
  {
638
114
    fz_warn(ctx, "premature end in bitmap data in bmp image");
639
114
    height = (end - ssp) / sstride;
640
114
  }
641
642
  /* These are only used for 16- and 32-bit components
643
     1-bit (1 * 8191) / 32
644
     2-bit (3 * 2730) / 32
645
     3-bit (7 * 1170) / 32
646
     4-bit (15 * 546) / 32
647
     5-bit (31 * 264) / 32
648
     6-bit (63 * 130) / 32
649
     7-bit (127 * 64) / 32
650
  */
651
210
  rmult = info->rbits < 8 ? mults[info->rbits] : 1;
652
210
  gmult = info->gbits < 8 ? mults[info->gbits] : 1;
653
210
  bmult = info->bbits < 8 ? mults[info->bbits] : 1;
654
210
  amult = info->abits < 8 ? mults[info->abits] : 1;
655
210
  rtrunc = info->rbits < 8 ? 5 : (info->rbits - 8);
656
210
  gtrunc = info->gbits < 8 ? 5 : (info->gbits - 8);
657
210
  btrunc = info->bbits < 8 ? 5 : (info->bbits - 8);
658
210
  atrunc = info->abits < 8 ? 5 : (info->abits - 8);
659
#ifdef BMP_DEBUG
660
  fz_warn(ctx, "rbits = %2d mult = %2d trunc = %2d", info->rbits, rmult, rtrunc);
661
  fz_warn(ctx, "gbits = %2d mult = %2d trunc = %2d", info->gbits, gmult, gtrunc);
662
  fz_warn(ctx, "bbits = %2d mult = %2d trunc = %2d", info->bbits, bmult, btrunc);
663
  fz_warn(ctx, "abits = %2d mult = %2d trunc = %2d", info->abits, amult, atrunc);
664
#endif
665
666
151k
  for (y = 0; y < height; y++)
667
151k
  {
668
151k
    const unsigned char *sp = ssp + ((size_t) y) * ((size_t) sstride);
669
151k
    unsigned char *dp = ddp + ((size_t) y) * ((size_t) dstride);
670
671
151k
    switch (bitcount)
672
151k
    {
673
0
    case 64:
674
0
      for (x = 0; x < width; x++)
675
0
      {
676
0
        uint32_t a = (((uint16_t)sp[7]) << 8) | (((uint16_t)sp[6]) << 0);
677
0
        uint32_t r = (((uint16_t)sp[5]) << 8) | (((uint16_t)sp[4]) << 0);
678
0
        uint32_t g = (((uint16_t)sp[3]) << 8) | (((uint16_t)sp[2]) << 0);
679
0
        uint32_t b = (((uint16_t)sp[1]) << 8) | (((uint16_t)sp[0]) << 0);
680
0
        r = (r * 255 + 4096) >> 13;
681
0
        g = (g * 255 + 4096) >> 13;
682
0
        b = (b * 255 + 4096) >> 13;
683
0
        a = (a * 255 + 4096) >> 13;
684
0
        *dp++ = r;
685
0
        *dp++ = g;
686
0
        *dp++ = b;
687
0
        *dp++ = a;
688
0
        sp += 8;
689
0
      }
690
0
      break;
691
3.53k
    case 32:
692
7.14k
      for (x = 0; x < width; x++)
693
3.60k
      {
694
3.60k
        uint32_t sample =
695
3.60k
          (((uint32_t) sp[3]) << 24) |
696
3.60k
          (((uint32_t) sp[2]) << 16) |
697
3.60k
          (((uint32_t) sp[1]) <<  8) |
698
3.60k
          (((uint32_t) sp[0]) <<  0);
699
3.60k
        uint32_t r = (sample & info->rmask) >> info->rshift;
700
3.60k
        uint32_t g = (sample & info->gmask) >> info->gshift;
701
3.60k
        uint32_t b = (sample & info->bmask) >> info->bshift;
702
3.60k
        uint32_t a = info->abits == 0 ? 255 : (sample & info->amask) >> info->ashift;
703
3.60k
        *dp++ = (r * rmult) >> rtrunc;
704
3.60k
        *dp++ = (g * gmult) >> gtrunc;
705
3.60k
        *dp++ = (b * bmult) >> btrunc;
706
3.60k
        *dp++ = info->abits == 0 ? a : (a * amult) >> atrunc;
707
3.60k
        sp += 4;
708
3.60k
      }
709
3.53k
      break;
710
28
    case 24:
711
280
      for (x = 0; x < width; x++)
712
252
      {
713
252
        *dp++ = sp[2];
714
252
        *dp++ = sp[1];
715
252
        *dp++ = sp[0];
716
252
        *dp++ = 255;
717
252
        sp += 3;
718
252
      }
719
28
      break;
720
6.84k
    case 16:
721
20.5k
      for (x = 0; x < width; x++)
722
13.6k
      {
723
13.6k
        uint16_t sample =
724
13.6k
          (((uint16_t)sp[1]) << 8) |
725
13.6k
          (((uint16_t)sp[0]) << 0);
726
13.6k
        uint16_t r = (sample & info->rmask) >> info->rshift;
727
13.6k
        uint16_t g = (sample & info->gmask) >> info->gshift;
728
13.6k
        uint16_t b = (sample & info->bmask) >> info->bshift;
729
13.6k
        uint16_t a = (sample & info->amask) >> info->ashift;
730
13.6k
        *dp++ = (r * rmult) >> rtrunc;
731
13.6k
        *dp++ = (g * gmult) >> gtrunc;
732
13.6k
        *dp++ = (b * bmult) >> btrunc;
733
13.6k
        *dp++ = info->abits == 0 ? 255 : (a * amult) >> atrunc;
734
13.6k
        sp += 2;
735
13.6k
      }
736
6.84k
      break;
737
15.9k
    case 8:
738
1.45M
      for (x = 0; x < width; x++)
739
1.44M
      {
740
1.44M
        *dp++ = info->palette[3 * sp[0] + 0];
741
1.44M
        *dp++ = info->palette[3 * sp[0] + 1];
742
1.44M
        *dp++ = info->palette[3 * sp[0] + 2];
743
1.44M
        *dp++ = 255;
744
1.44M
        sp++;
745
1.44M
      }
746
15.9k
      break;
747
124k
    case 4:
748
872k
      for (x = 0; x < width; x++)
749
748k
      {
750
748k
        int idx;
751
748k
        switch (x & 1)
752
748k
        {
753
374k
        case 0: idx = (sp[0] >> 4) & 0x0f; break;
754
374k
        case 1: idx = (sp[0] >> 0) & 0x0f; sp++; break;
755
748k
        }
756
748k
        *dp++ = info->palette[3 * idx + 0];
757
748k
        *dp++ = info->palette[3 * idx + 1];
758
748k
        *dp++ = info->palette[3 * idx + 2];
759
748k
        *dp++ = 255;
760
748k
      }
761
124k
      break;
762
124k
    case 2:
763
0
      for (x = 0; x < width; x++)
764
0
      {
765
0
        int idx;
766
0
        switch (x & 3)
767
0
        {
768
0
        case 0: idx = (sp[0] >> 6) & 0x03; break;
769
0
        case 1: idx = (sp[0] >> 4) & 0x03; break;
770
0
        case 2: idx = (sp[0] >> 2) & 0x03; break;
771
0
        case 3: idx = (sp[0] >> 0) & 0x03; sp++; break;
772
0
        }
773
0
        *dp++ = info->palette[3 * idx + 0];
774
0
        *dp++ = info->palette[3 * idx + 1];
775
0
        *dp++ = info->palette[3 * idx + 2];
776
0
        *dp++ = 255;
777
0
      }
778
0
      break;
779
310
    case 1:
780
6.12k
      for (x = 0; x < width; x++)
781
5.81k
      {
782
5.81k
        int idx;
783
5.81k
        switch (x & 7)
784
5.81k
        {
785
800
        case 0: idx = (sp[0] >> 7) & 0x01; break;
786
800
        case 1: idx = (sp[0] >> 6) & 0x01; break;
787
800
        case 2: idx = (sp[0] >> 5) & 0x01; break;
788
800
        case 3: idx = (sp[0] >> 4) & 0x01; break;
789
800
        case 4: idx = (sp[0] >> 3) & 0x01; break;
790
800
        case 5: idx = (sp[0] >> 2) & 0x01; break;
791
525
        case 6: idx = (sp[0] >> 1) & 0x01; break;
792
490
        case 7: idx = (sp[0] >> 0) & 0x01; sp++; break;
793
5.81k
        }
794
5.81k
        *dp++ = info->palette[3 * idx + 0];
795
5.81k
        *dp++ = info->palette[3 * idx + 1];
796
5.81k
        *dp++ = info->palette[3 * idx + 2];
797
5.81k
        *dp++ = 255;
798
5.81k
      }
799
310
      break;
800
151k
    }
801
151k
  }
802
803
210
  fz_free(ctx, decompressed);
804
210
  fz_premultiply_pixmap(ctx, pix);
805
210
  return pix;
806
210
}
807
808
static fz_colorspace *
809
bmp_read_color_profile(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end)
810
112
{
811
112
  if (info->colorspacetype == 0)
812
86
  {
813
86
    float matrix[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
814
86
    float wp[3] = { 0.95047f, 1.0f, 1.08883f }; /* D65 white point */
815
86
    float bp[3] = { 0, 0, 0 };
816
86
    float gamma[3] = { 1, 1, 1 };
817
86
    int i;
818
819
344
    for (i = 0; i < 3; i++)
820
258
      gamma[i] = (float) info->gamma[i] / (float) (1 << 16);
821
860
    for (i = 0; i < 9; i++)
822
774
      matrix[i] = (float) info->endpoints[i] / (float) (1 << 30);
823
824
#ifdef BMP_DEBUG
825
    fz_warn(ctx, "wp = %.6f %.6f %.6f", wp[0], wp[1], wp[2]);
826
    fz_warn(ctx, "bp = %.6f %.6f %.6f", bp[0], bp[1], bp[2]);
827
    fz_warn(ctx, "endpoints = %.6f %.6f %.6f", matrix[0], matrix[1], matrix[2]);
828
    fz_warn(ctx, "endpoints = %.6f %.6f %.6f", matrix[3], matrix[4], matrix[5]);
829
    fz_warn(ctx, "endpoints = %.6f %.6f %.6f", matrix[6], matrix[7], matrix[8]);
830
    fz_warn(ctx, "gamma = %.6f %.6f %.6f", gamma[0], gamma[1], gamma[2]);
831
#endif
832
833
86
    return fz_new_cal_rgb_colorspace(ctx, wp, bp, gamma, matrix);
834
86
  }
835
26
  else if (info->colorspacetype == 0x4c494e4b)
836
0
  {
837
0
    fz_warn(ctx, "ignoring linked color profile in bmp image");
838
0
    return NULL;
839
0
  }
840
26
  else if (info->colorspacetype == 0x57696e20)
841
0
  {
842
0
    fz_warn(ctx, "ignoring windows color profile in bmp image");
843
0
    return NULL;
844
0
  }
845
26
  else if (info->colorspacetype == 0x4d424544)
846
9
  {
847
9
    fz_buffer *profile;
848
9
    fz_colorspace *cs;
849
850
9
    if ((uint32_t)(end - begin) <= info->profileoffset)
851
4
    {
852
4
      fz_warn(ctx, "ignoring color profile located outside bmp image");
853
4
      return NULL;
854
4
    }
855
5
    if ((uint32_t)(end - begin) - info->profileoffset < info->profilesize)
856
2
    {
857
2
      fz_warn(ctx, "ignoring truncated color profile in bmp image");
858
2
      return NULL;
859
2
    }
860
3
    if (info->profilesize == 0)
861
0
    {
862
0
      fz_warn(ctx, "ignoring color profile without data in bmp image");
863
0
      return NULL;
864
0
    }
865
866
3
    profile = fz_new_buffer_from_copied_data(ctx, begin + info->profileoffset, info->profilesize);
867
868
6
    fz_try(ctx)
869
6
      cs = fz_new_icc_colorspace(ctx, FZ_COLORSPACE_RGB, 0, "BMPRGB", profile);
870
6
    fz_always(ctx)
871
3
      fz_drop_buffer(ctx, profile);
872
3
    fz_catch(ctx)
873
3
      fz_rethrow(ctx);
874
875
0
    return cs;
876
3
  }
877
17
  else if (info->colorspacetype == 0x73524742)
878
0
  {
879
0
    return fz_keep_colorspace(ctx, fz_device_rgb(ctx));
880
0
  }
881
882
17
  fz_warn(ctx, "ignoring color profile with unknown type in bmp image");
883
17
  return NULL;
884
112
}
885
886
static void
887
compute_mask_info(unsigned int mask, unsigned int *shift, unsigned int *bits)
888
972
{
889
972
  *bits = 0;
890
972
  *shift = 0;
891
892
2.50k
  while (mask && (mask & 1) == 0) {
893
1.53k
    *shift += 1;
894
1.53k
    mask >>= 1;
895
1.53k
  }
896
2.85k
  while (mask && (mask & 1) == 1) {
897
1.88k
    *bits += 1;
898
1.88k
    mask >>= 1;
899
1.88k
  }
900
972
}
901
902
static const unsigned char *
903
bmp_read_color_masks(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p)
904
11
{
905
11
  int size = 0;
906
907
11
  if (info->compression == BI_BITFIELDS)
908
6
  {
909
6
    size = 12;
910
6
    if (end - p < 12)
911
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in mask header in bmp image");
912
913
6
    info->rmask = read32(p + 0);
914
6
    info->gmask = read32(p + 4);
915
6
    info->bmask = read32(p + 8);
916
6
  }
917
5
  else if (info->compression == BI_ALPHABITS)
918
5
  {
919
5
    size = 16;
920
5
    if (end - p < 16)
921
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in mask header in bmp image");
922
923
5
    info->rmask = read32(p + 0);
924
5
    info->gmask = read32(p + 4);
925
5
    info->bmask = read32(p + 8);
926
5
    info->amask = read32(p + 12);
927
5
  }
928
929
11
  return p + size;
930
11
}
931
932
static int
933
bmp_palette_is_gray(fz_context *ctx, struct info *info, int readcolors)
934
99
{
935
99
  int i;
936
128
  for (i = 0; i < readcolors; i++)
937
84
  {
938
84
    int rgdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 1]);
939
84
    int gbdiff = fz_absi(info->palette[3 * i + 1] - info->palette[3 * i + 2]);
940
84
    int rbdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 2]);
941
84
    if (rgdiff > 2 || gbdiff > 2 || rbdiff > 2)
942
55
      return 0;
943
84
  }
944
44
  return 1;
945
99
}
946
947
static void
948
bmp_load_default_palette(fz_context *ctx, struct info *info, int readcolors)
949
101
{
950
101
  int i;
951
952
101
  fz_warn(ctx, "color table too short; loading default palette");
953
954
101
  if (info->bitcount == 8)
955
51
  {
956
51
    if (!bmp_palette_is_gray(ctx, info, readcolors))
957
11
      memcpy(&info->palette[readcolors * 3], &web_palette[readcolors * 3],
958
11
          sizeof(web_palette) - readcolors * 3);
959
40
    else
960
10.2k
      for (i = readcolors; i < 256; i++)
961
10.2k
      {
962
10.2k
        info->palette[3 * i + 0] = i;
963
10.2k
        info->palette[3 * i + 1] = i;
964
10.2k
        info->palette[3 * i + 2] = i;
965
10.2k
      }
966
51
  }
967
50
  else if (info->bitcount == 4)
968
48
  {
969
48
    if (!bmp_palette_is_gray(ctx, info, readcolors))
970
44
      memcpy(&info->palette[readcolors * 3], &vga_palette[readcolors * 3],
971
44
          sizeof(vga_palette) - readcolors * 3);
972
4
    else
973
66
      for (i = readcolors; i < 16; i++)
974
62
      {
975
62
        info->palette[3 * i + 0] = (i << 4) | i;
976
62
        info->palette[3 * i + 1] = (i << 4) | i;
977
62
        info->palette[3 * i + 2] = (i << 4) | i;
978
62
      }
979
48
  }
980
2
  else if (info->bitcount == 2)
981
0
    memcpy(info->palette, gray_palette, sizeof(gray_palette));
982
2
  else if (info->bitcount == 1)
983
2
    memcpy(info->palette, bw_palette, sizeof(bw_palette));
984
101
}
985
986
static const unsigned char *
987
bmp_read_palette(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p)
988
102
{
989
102
  int i, expected, present, entry_size;
990
991
102
  entry_size = palette_entry_size(info);
992
993
102
  if (info->colors == 0)
994
16
    expected = info->colors = 1 << info->bitcount;
995
86
  else
996
86
    expected = fz_mini(info->colors, 1 << info->bitcount);
997
998
102
  if (info->bitmapoffset == 0)
999
0
    present = fz_mini(expected, (end - p) / entry_size);
1000
102
  else
1001
102
    present = fz_mini(expected, (begin + info->bitmapoffset - p) / entry_size);
1002
1003
508
  for (i = 0; i < present; i++)
1004
406
  {
1005
    /* ignore alpha channel even if present */
1006
406
    info->palette[3 * i + 0] = read8(p + i * entry_size + 2);
1007
406
    info->palette[3 * i + 1] = read8(p + i * entry_size + 1);
1008
406
    info->palette[3 * i + 2] = read8(p + i * entry_size + 0);
1009
406
  }
1010
1011
102
  if (present < expected)
1012
101
    bmp_load_default_palette(ctx, info, present);
1013
1014
102
  return p + present * entry_size;
1015
102
}
1016
1017
static const unsigned char *
1018
bmp_read_info_header(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p)
1019
249
{
1020
249
  uint32_t size;
1021
1022
249
  if (end - p < 4)
1023
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in info header in bmp image");
1024
249
  size = info->version = read32(p + 0);
1025
1026
249
  if (!is_win_bmp(info) && !is_os2_bmp(info))
1027
6
    fz_throw(ctx, FZ_ERROR_FORMAT, "unknown header version (%u) in bmp image", info->version);
1028
243
  if ((uint32_t)(end - p) < size)
1029
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in info header in bmp image");
1030
1031
  /* default compression */
1032
243
  info->compression = BI_NONE;
1033
1034
  /* OS/2 1.x or Windows v2 */
1035
243
  if (size == 12)
1036
5
  {
1037
    /* read32(p+0) == header size */
1038
5
    info->width = read16(p + 4);
1039
5
    info->height = read16(p + 6);
1040
    /* read16(p+8) == planes */
1041
5
    info->bitcount = read16(p + 10);
1042
5
  }
1043
  /* OS/2 2.x short header */
1044
243
  if (size >= 16)
1045
238
  {
1046
    /* read32(p+0) == header size */
1047
238
    info->width = read32(p + 4);
1048
238
    info->height = read32(p + 8);
1049
    /* read16(p+12) == planes */
1050
238
    info->bitcount = read16(p + 14);
1051
238
  }
1052
1053
  /* default masks */
1054
243
  if (info->bitcount == 16)
1055
72
  {
1056
72
    info->rmask = 0x00007c00;
1057
72
    info->gmask = 0x000003e0;
1058
72
    info->bmask = 0x0000001f;
1059
72
    info->amask = 0x00000000;
1060
72
  }
1061
171
  else if (info->bitcount == 24 || info->bitcount == 32)
1062
57
  {
1063
57
    info->rmask = 0x00ff0000;
1064
57
    info->gmask = 0x0000ff00;
1065
57
    info->bmask = 0x000000ff;
1066
57
    info->amask = 0x00000000;
1067
57
  }
1068
1069
  /* Windows v3 header */
1070
243
  if (size >= 40)
1071
238
  {
1072
238
    info->compression = read32(p + 16);
1073
238
    info->bitmapsize = read32(p + 20);
1074
238
    info->xres = read32(p + 24);
1075
238
    info->yres = read32(p + 28);
1076
238
    info->colors = read32(p + 32);
1077
238
    if (info->bitcount >= 32)
1078
65
    {
1079
65
      if (info->colors != 0)
1080
64
        fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1081
65
      info->colors = 0;
1082
65
    }
1083
173
    else if (info->colors > (1U<<info->bitcount))
1084
145
    {
1085
145
      fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1086
145
      info->colors = 1<<info->bitcount;
1087
145
    }
1088
    /* read32(p+36) == important colors */
1089
238
  }
1090
  /* Windows v3 header with RGB masks */
1091
243
  if (size == 52 || size == 56 || size == 108 || size == 124)
1092
150
  {
1093
150
    info->rmask = read32(p + 40);
1094
150
    info->gmask = read32(p + 44);
1095
150
    info->bmask = read32(p + 48);
1096
150
  }
1097
  /* Windows v3 header with RGBA masks */
1098
243
  if (size == 56 || size == 108 || size == 124)
1099
149
  {
1100
149
    info->amask = read32(p + 52);
1101
149
  }
1102
  /* OS/2 2.x long header */
1103
243
  if (size == 64)
1104
1
  {
1105
    /* read16(p+40) == units */
1106
    /* read16(p+42) == reserved */
1107
    /* read16(p+44) == recording */
1108
    /* read16(p+46) == rendering */
1109
    /* read32(p+48) == size1 */
1110
    /* read32(p+52) == size2 */
1111
    /* read32(p+56) == color encoding */
1112
    /* read32(p+60) == identifier */
1113
1
  }
1114
  /* Windows v4 header */
1115
243
  if (size >= 108)
1116
124
  {
1117
124
    info->colorspacetype = read32(p + 56);
1118
1119
124
    info->endpoints[0] = read32(p + 60);
1120
124
    info->endpoints[1] = read32(p + 64);
1121
124
    info->endpoints[2] = read32(p + 68);
1122
1123
124
    info->endpoints[3] = read32(p + 72);
1124
124
    info->endpoints[4] = read32(p + 76);
1125
124
    info->endpoints[5] = read32(p + 80);
1126
1127
124
    info->endpoints[6] = read32(p + 84);
1128
124
    info->endpoints[7] = read32(p + 88);
1129
124
    info->endpoints[8] = read32(p + 92);
1130
1131
124
    info->gamma[0] = read32(p + 96);
1132
124
    info->gamma[1] = read32(p + 100);
1133
124
    info->gamma[2] = read32(p + 104);
1134
124
  }
1135
  /* Windows v5 header */
1136
243
  if (size >= 124)
1137
9
  {
1138
9
    info->intent = read32(p + 108);
1139
9
    info->profileoffset = read32(p + 112);
1140
9
    info->profilesize = read32(p + 116);
1141
    /* read32(p+120) == reserved */
1142
9
  }
1143
1144
243
  return p + size;
1145
243
}
1146
1147
1148
static fz_pixmap *
1149
bmp_read_image(fz_context *ctx, struct info *info, const unsigned char *begin, const unsigned char *end, const unsigned char *p, int only_metadata)
1150
250
{
1151
250
  const unsigned char *profilebegin;
1152
1153
250
  memset(info, 0x00, sizeof (*info));
1154
250
  info->colorspacetype = 0xffffffff;
1155
1156
250
  p = profilebegin = bmp_read_file_header(ctx, info, begin, end, p);
1157
1158
250
  p = bmp_read_info_header(ctx, info, begin, end, p);
1159
1160
  /* clamp bitmap offset to buffer size */
1161
250
  if (info->bitmapoffset < (uint32_t)(p - begin))
1162
36
    info->bitmapoffset = (uint32_t)(p - begin);
1163
250
  if ((uint32_t)(end - begin) < info->bitmapoffset)
1164
20
    info->bitmapoffset = end - begin;
1165
1166
250
  if (has_palette(info))
1167
102
    p = bmp_read_palette(ctx, info, begin, end, p);
1168
1169
250
  if (has_color_masks(info))
1170
11
    p = bmp_read_color_masks(ctx, info, begin, end, p);
1171
1172
250
  info->xres = DPM_TO_DPI(info->xres);
1173
250
  info->yres = DPM_TO_DPI(info->yres);
1174
1175
  /* extract topdown/bottomup from height for windows bitmaps */
1176
250
  if (is_win_bmp(info))
1177
242
  {
1178
242
    int bits = info->version == 12 ? 16 : 32;
1179
1180
242
    info->topdown = (info->height >> (bits - 1)) & 1;
1181
242
    if (info->topdown)
1182
38
    {
1183
38
      info->height--;
1184
38
      info->height = ~info->height;
1185
38
      info->height &= bits == 16 ? 0xffff : 0xffffffff;
1186
38
    }
1187
242
  }
1188
1189
  /* GIMP incorrectly writes BMP v5 headers that omit color masks
1190
  but include colorspace information. This means they look like
1191
  BMP v4 headers and that we interpret the colorspace information
1192
  partially as color mask data, partially as colorspace information.
1193
  Let's work around this... */
1194
250
  if (info->version == 108 &&
1195
250
      info->rmask == 0x73524742 && /* colorspacetype */
1196
250
      info->gmask == 0x00000000 && /* endpoints[0] */
1197
250
      info->bmask == 0x00000000 && /* endpoints[1] */
1198
250
      info->amask == 0x00000000 && /* endpoints[2] */
1199
250
      info->colorspacetype == 0x00000000 && /* endpoints[3] */
1200
250
      info->endpoints[0] == 0x00000000 && /* endpoints[4] */
1201
250
      info->endpoints[1] == 0x00000000 && /* endpoints[5] */
1202
250
      info->endpoints[2] == 0x00000000 && /* endpoints[6] */
1203
250
      info->endpoints[3] == 0x00000000 && /* endpoints[7] */
1204
250
      info->endpoints[4] == 0x00000000 && /* endpoints[8] */
1205
250
      info->endpoints[5] == 0x00000000 && /* gamma[0] */
1206
250
      info->endpoints[6] == 0x00000000 && /* gamma[1] */
1207
250
      info->endpoints[7] == 0x00000000 && /* gamma[2] */
1208
250
      info->endpoints[8] == 0x00000002) /* intent */
1209
0
  {
1210
0
    info->rmask = 0;
1211
    /* default masks */
1212
0
    if (info->bitcount == 16)
1213
0
    {
1214
0
      info->rmask = 0x00007c00;
1215
0
      info->gmask = 0x000003e0;
1216
0
      info->bmask = 0x0000001f;
1217
0
      info->amask = 0x00000000;
1218
0
    }
1219
0
    else if (info->bitcount >= 24)
1220
0
    {
1221
0
      info->rmask = 0x00ff0000;
1222
0
      info->gmask = 0x0000ff00;
1223
0
      info->bmask = 0x000000ff;
1224
0
      info->amask = 0x00000000;
1225
0
    }
1226
1227
0
    info->colorspacetype = 0x73524742;
1228
0
    info->intent = 0x00000002;
1229
0
  }
1230
1231
  /* get number of bits per component and component shift */
1232
250
  compute_mask_info(info->rmask, &info->rshift, &info->rbits);
1233
250
  compute_mask_info(info->gmask, &info->gshift, &info->gbits);
1234
250
  compute_mask_info(info->bmask, &info->bshift, &info->bbits);
1235
250
  compute_mask_info(info->amask, &info->ashift, &info->abits);
1236
1237
#ifdef BMP_DEBUG
1238
  {
1239
    #define chr(c) (((c) >= ' ' && (c) <= '~') ? (c) : '?')
1240
    fz_warn(ctx, "type = %02x%02x %c%c", info->type[0], info->type[1], chr(info->type[0]), chr(info->type[1]));
1241
    if (is_bitmap_array(info->type)) fz_warn(ctx, "\tbitmap array");
1242
    if (is_bitmap(info->type)) fz_warn(ctx, "\tbitmap");
1243
    fz_warn(ctx, "version = %zu", (size_t) info->version);
1244
    if (is_os2_bmp(info)) fz_warn(ctx, "OS/2 bmp");
1245
    if (is_win_bmp(info)) fz_warn(ctx, "Windows bmp");
1246
    fz_warn(ctx, "bitmapoffset = %zu", (size_t) info->bitmapoffset);
1247
    fz_warn(ctx, "width = %zu", (size_t) info->width);
1248
    fz_warn(ctx, "height = %zu", (size_t) info->height);
1249
    fz_warn(ctx, "bitcount = %zu", (size_t) info->bitcount);
1250
    fz_warn(ctx, "compression = %zu", (size_t) info->compression);
1251
    if (info->compression == BI_NONE) fz_warn(ctx, "\tNone");
1252
    if (info->compression == BI_RLE8) fz_warn(ctx, "\tRLE 8");
1253
    if (info->compression == BI_RLE4) fz_warn(ctx, "\tRLE 4");
1254
    if (is_valid_win_compression(info) && info->compression == BI_BITFIELDS) fz_warn(ctx, "\tBITFIELDS");
1255
    if (is_valid_os2_compression(info) && info->compression == BI_HUFFMAN1D) fz_warn(ctx, "\tHUFFMAN1D");
1256
    if (info->compression == BI_JPEG) fz_warn(ctx, "\tJPEG");
1257
    if (info->compression == BI_RLE24) fz_warn(ctx, "\tRLE24");
1258
    if (info->compression == BI_PNG) fz_warn(ctx, "\tPNG");
1259
    if (info->compression == BI_ALPHABITS) fz_warn(ctx, "\tALPHABITS");
1260
    fz_warn(ctx, "bitmapsize = %zu", (size_t) info->bitmapsize);
1261
    fz_warn(ctx, "xres = %zu", (size_t) info->xres);
1262
    fz_warn(ctx, "yres = %zu", (size_t) info->yres);
1263
    fz_warn(ctx, "colors = %zu", (size_t) info->colors);
1264
    fz_warn(ctx, "rmask = 0x%08zx rshift = %d rbits = %d", (size_t) info->rmask, info->rshift, info->rbits);
1265
    fz_warn(ctx, "gmask = 0x%08zx gshift = %d gbits = %d", (size_t) info->gmask, info->gshift, info->gbits);
1266
    fz_warn(ctx, "bmask = 0x%08zx bshift = %d bbits = %d", (size_t) info->bmask, info->bshift, info->bbits);
1267
    fz_warn(ctx, "amask = 0x%08zx ashift = %d abits = %d", (size_t) info->amask, info->ashift, info->abits);
1268
    fz_warn(ctx, "colorspacetype = %08zx %c%c%c%c", (size_t) info->colorspacetype,
1269
    chr((info->colorspacetype >> 24) & 0xff),
1270
    chr((info->colorspacetype >> 16) & 0xff),
1271
    chr((info->colorspacetype >>  8) & 0xff),
1272
    chr((info->colorspacetype >>  0) & 0xff));
1273
    fz_warn(ctx, "endpoints[%d] = 0x%08zx 0x%08zx 0x%08zx", 0, (size_t) info->endpoints[0], (size_t) info->endpoints[1], (size_t) info->endpoints[2]);
1274
    fz_warn(ctx, "endpoints[%d] = 0x%08zx 0x%08zx 0x%08zx", 3, (size_t) info->endpoints[3], (size_t) info->endpoints[4], (size_t) info->endpoints[5]);
1275
    fz_warn(ctx, "endpoints[%d] = 0x%08zx 0x%08zx 0x%08zx", 6, (size_t) info->endpoints[6], (size_t) info->endpoints[7], (size_t) info->endpoints[8]);
1276
    fz_warn(ctx, "gamma = 0x%08zx 0x%08zx 0x%08zx", (size_t) info->gamma[0], (size_t) info->gamma[1], (size_t) info->gamma[2]);
1277
    fz_warn(ctx, "profileoffset = %zu", (size_t) info->profileoffset);
1278
    fz_warn(ctx, "profilesize = %zu", (size_t) info->profilesize);
1279
    #undef chr
1280
  }
1281
#endif
1282
1283
250
  if (info->width == 0 || info->width > SHRT_MAX || info->height == 0 || info->height > SHRT_MAX)
1284
14
    fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions (%u x %u) out of range in bmp image", info->width, info->height);
1285
236
  if (!is_valid_compression(info))
1286
4
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported compression method (%u) in bmp image", info->compression);
1287
232
  if (!is_valid_bitcount(info))
1288
1
    fz_throw(ctx, FZ_ERROR_FORMAT, "invalid bits per pixel (%u) for compression (%u) in bmp image", info->bitcount, info->compression);
1289
231
  if (info->rbits > info->bitcount)
1290
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit red mask in bmp image", info->rbits);
1291
231
  if (info->gbits > info->bitcount)
1292
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit green mask in bmp image", info->gbits);
1293
231
  if (info->bbits > info->bitcount)
1294
2
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit blue mask in bmp image", info->bbits);
1295
229
  if (info->abits > info->bitcount)
1296
1
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit alpha mask in bmp image", info->abits);
1297
1298
  /* Read color profile or default to RGB */
1299
228
  if (has_color_profile(info))
1300
112
    info->cs = bmp_read_color_profile(ctx, info, profilebegin, end);
1301
228
  if (!info->cs)
1302
132
    info->cs = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
1303
1304
228
  if (only_metadata)
1305
0
    return NULL;
1306
1307
  /* bitmap cannot begin before headers have ended */
1308
228
  if ((uint32_t)(p - begin) < info->bitmapoffset)
1309
4
    p = begin + info->bitmapoffset;
1310
1311
228
  if (is_win_bmp(info) && info->compression == BI_JPEG)
1312
0
  {
1313
0
    if ((uint32_t)(end - p) < info->bitmapsize)
1314
0
      fz_warn(ctx, "premature end in jpeg image embedded in bmp image");
1315
0
    return fz_load_jpeg(ctx, p, end - p);
1316
0
  }
1317
228
  else if (is_win_bmp(info) && info->compression == BI_PNG)
1318
0
  {
1319
0
    if ((uint32_t)(end - p) < info->bitmapsize)
1320
0
      fz_warn(ctx, "premature end in png image embedded in bmp image");
1321
0
    return fz_load_png(ctx, p, end - p);
1322
0
  }
1323
228
  else
1324
228
    return bmp_read_bitmap(ctx, info, begin, end, p);
1325
228
}
1326
1327
fz_pixmap *
1328
fz_load_bmp_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage)
1329
250
{
1330
250
  const unsigned char *begin = buf;
1331
250
  const unsigned char *end = buf + len;
1332
250
  const unsigned char *p = begin;
1333
250
  struct info info = { 0 };
1334
250
  int nextoffset = 0;
1335
250
  fz_pixmap *image = NULL;
1336
250
  int origidx = subimage;
1337
1338
250
  (void) p;
1339
1340
250
  do
1341
250
  {
1342
250
    p = begin + nextoffset;
1343
1344
250
    if (end - p < 14)
1345
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "not enough data for bitmap array (%02x%02x) in bmp image", p[0], p[1]);
1346
1347
250
    if (is_bitmap_array(p))
1348
1
    {
1349
      /* read16(p+0) == type */
1350
      /* read32(p+2) == size of this header in bytes */
1351
1
      nextoffset = read32(p + 6);
1352
      /* read16(p+10) == suitable pelx dimensions */
1353
      /* read16(p+12) == suitable pely dimensions */
1354
1
      p += 14;
1355
1
      (void) p;
1356
1
    }
1357
249
    else if (is_bitmap(p))
1358
249
    {
1359
249
      nextoffset = 0;
1360
249
    }
1361
0
    else
1362
0
    {
1363
0
      fz_warn(ctx, "treating invalid subimage as end of file");
1364
0
      nextoffset = 0;
1365
0
    }
1366
1367
250
    if (end - begin < nextoffset)
1368
0
    {
1369
0
      fz_warn(ctx, "treating invalid next subimage offset as end of file");
1370
0
      nextoffset = 0;
1371
0
    }
1372
250
    else
1373
250
      subimage--;
1374
1375
250
  } while (subimage >= 0 && nextoffset > 0);
1376
1377
250
  if (subimage != -1)
1378
0
    fz_throw(ctx, FZ_ERROR_ARGUMENT, "subimage index (%d) out of range in bmp image", origidx);
1379
1380
500
  fz_try(ctx)
1381
500
    image = bmp_read_image(ctx, &info, begin, end, p, 0);
1382
500
  fz_always(ctx)
1383
250
    fz_drop_colorspace(ctx, info.cs);
1384
250
  fz_catch(ctx)
1385
40
    fz_rethrow(ctx);
1386
1387
210
  return image;
1388
250
}
1389
1390
void
1391
fz_load_bmp_info_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep, int subimage)
1392
0
{
1393
0
  const unsigned char *begin = buf;
1394
0
  const unsigned char *end = buf + len;
1395
0
  const unsigned char *p = begin;
1396
0
  struct info info = { 0 };
1397
0
  int nextoffset = 0;
1398
0
  int origidx = subimage;
1399
1400
0
  (void) p;
1401
1402
0
  do
1403
0
  {
1404
0
    p = begin + nextoffset;
1405
1406
0
    if (end - p < 14)
1407
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "not enough data for bitmap array (%02x%02x) in bmp image", p[0], p[1]);
1408
1409
0
    if (is_bitmap_array(p))
1410
0
    {
1411
      /* read16(p+0) == type */
1412
      /* read32(p+2) == size of this header in bytes */
1413
0
      nextoffset = read32(p + 6);
1414
      /* read16(p+10) == suitable pelx dimensions */
1415
      /* read16(p+12) == suitable pely dimensions */
1416
0
      p += 14;
1417
0
      (void) p;
1418
0
    }
1419
0
    else if (is_bitmap(p))
1420
0
    {
1421
0
      nextoffset = 0;
1422
0
    }
1423
0
    else
1424
0
    {
1425
0
      fz_warn(ctx, "treating invalid subimage as end of file");
1426
0
      nextoffset = 0;
1427
0
    }
1428
1429
0
    if (end - begin < nextoffset)
1430
0
    {
1431
0
      fz_warn(ctx, "treating invalid next subimage offset as end of file");
1432
0
      nextoffset = 0;
1433
0
    }
1434
0
    else
1435
0
      subimage--;
1436
1437
0
  } while (subimage >= 0 && nextoffset > 0);
1438
1439
0
  if (subimage != -1)
1440
0
    fz_throw(ctx, FZ_ERROR_ARGUMENT, "subimage index (%d) out of range in bmp image", origidx);
1441
1442
0
  fz_try(ctx)
1443
0
  {
1444
0
    (void) bmp_read_image(ctx, &info, begin, end, p, 1);
1445
0
    *cspacep = fz_keep_colorspace(ctx, info.cs);
1446
0
    *wp = info.width;
1447
0
    *hp = info.height;
1448
0
    *xresp = info.xres;
1449
0
    *yresp = info.yres;
1450
0
  }
1451
0
  fz_always(ctx)
1452
0
    fz_drop_colorspace(ctx, info.cs);
1453
0
  fz_catch(ctx)
1454
0
    fz_rethrow(ctx);
1455
0
}
1456
1457
int
1458
fz_load_bmp_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len)
1459
250
{
1460
250
  const unsigned char *begin = buf;
1461
250
  const unsigned char *end = buf + len;
1462
250
  uint32_t nextoffset = 0;
1463
250
  int count = 0;
1464
1465
250
  do
1466
250
  {
1467
250
    const unsigned char *p = begin + nextoffset;
1468
1469
250
    if (end - p < 14)
1470
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "not enough data for bitmap array in bmp image");
1471
1472
250
    if (is_bitmap_array(p))
1473
1
    {
1474
      /* read16(p+0) == type */
1475
      /* read32(p+2) == size of this header in bytes */
1476
1
      nextoffset = read32(p + 6);
1477
      /* read16(p+10) == suitable pelx dimensions */
1478
      /* read16(p+12) == suitable pely dimensions */
1479
1
      p += 14;
1480
1
    }
1481
249
    else if (is_bitmap(p))
1482
249
    {
1483
249
      nextoffset = 0;
1484
249
    }
1485
0
    else
1486
0
    {
1487
0
      fz_warn(ctx, "treating invalid subimage as end of file");
1488
0
      nextoffset = 0;
1489
0
    }
1490
1491
250
    if (end - begin < nextoffset)
1492
0
    {
1493
0
      fz_warn(ctx, "treating invalid next subimage offset as end of file");
1494
0
      nextoffset = 0;
1495
0
    }
1496
250
    else
1497
250
      count++;
1498
1499
250
  } while (nextoffset > 0);
1500
1501
250
  return count;
1502
250
}
1503
1504
fz_pixmap *
1505
fz_load_bmp(fz_context *ctx, const unsigned char *p, size_t total)
1506
0
{
1507
0
  return fz_load_bmp_subimage(ctx, p, total, 0);
1508
0
}
1509
1510
void
1511
fz_load_bmp_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
1512
0
{
1513
0
  fz_load_bmp_info_subimage(ctx, p, total, wp, hp, xresp, yresp, cspacep, 0);
1514
0
}