Coverage Report

Created: 2024-05-21 06:53

/src/mupdf/source/fitz/load-bmp.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2021 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.56k
#define read8(p) ((p)[0])
136
300
#define read16(p) (((p)[1] << 8) | (p)[0])
137
5.10k
#define read32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
138
139
552
#define DPM_TO_DPI(dpm) ((dpm) * 25.4f / 1000.0f)
140
141
553
#define is_bitmap_array(p) ((p)[0] == 'B' && (p)[1] == 'A')
142
827
#define is_bitmap(p) ((p)[0] == 'B' && (p)[1] == 'M')
143
144
60
#define is_os2_bmp(info) ((info)->version == 12 || (info)->version == 16 || (info)->version == 64)
145
2.93k
#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
520
#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
17
#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
260
#define is_valid_compression(info) (is_valid_win_compression(info) || is_valid_os2_compression(info))
150
151
488
#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
464
#define is_valid_rle8_bitcount(info) ((info)->compression == BI_RLE8 && (info)->bitcount == 8)
153
431
#define is_valid_rle4_bitcount(info) ((info)->compression == BI_RLE4 && (info)->bitcount == 4)
154
398
#define is_valid_bitfields_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_BITFIELDS && ((info)->bitcount == 16 || (info)->bitcount == 32))
155
252
#define is_valid_jpeg_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_JPEG && (info)->bitcount == 0)
156
252
#define is_valid_png_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_PNG && (info)->bitcount == 0)
157
252
#define is_valid_alphabits_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_ALPHABITS && ((info)->bitcount == 16 || (info)->bitcount == 32))
158
248
#define is_valid_rle24_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_RLE24 && (info)->bitcount == 24)
159
4
#define is_valid_huffman1d_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_HUFFMAN1D && (info)->bitcount == 1)
160
244
#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
276
#define has_palette(info) ((info)->bitcount == 1 || (info)->bitcount == 2 || (info)->bitcount == 4 || (info)->bitcount == 8)
163
276
#define has_color_masks(info) (((info)->bitcount == 16 || (info)->bitcount == 32) && (info)->version == 40 && ((info)->compression == BI_BITFIELDS || (info)->compression == BI_ALPHABITS))
164
238
#define has_color_profile(info) ((info)->version == 108 || (info)->version == 124)
165
166
86
#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
276
{
171
276
  if (end - p < 14)
172
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in file header in bmp image");
173
174
276
  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
275
  info->type[0] = read8(p + 0);
178
275
  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
275
  info->bitmapoffset = read32(p + 10);
183
184
275
  return p + 14;
185
276
}
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
33
{
346
33
  const unsigned char *sp;
347
33
  unsigned char *dp, *ep, *decompressed;
348
33
  uint32_t width = info->width;
349
33
  uint32_t height = info->height;
350
33
  uint32_t stride;
351
33
  uint32_t x, y;
352
33
  int i;
353
354
33
  stride = (width + 3) / 4 * 4;
355
356
33
  sp = p;
357
33
  dp = decompressed = fz_calloc(ctx, height, stride);
358
33
  ep = dp + height * stride;
359
33
  x = 0;
360
33
  y = 0;
361
362
11.2k
  while (sp + 2 <= *end)
363
11.2k
  {
364
11.2k
    if (sp[0] == 0 && sp[1] == 0)
365
539
    { /* end of line */
366
539
      sp += 2;
367
539
      x = 0;
368
539
      y++;
369
539
    }
370
10.6k
    else if (sp[0] == 0 && sp[1] == 1)
371
2
    { /* end of bitmap */
372
2
      sp += 2;
373
2
      break;
374
2
    }
375
10.6k
    else if (sp[0] == 0 && sp[1] == 2)
376
21
    { /* delta */
377
21
      sp +=2;
378
21
      x += sp < *end ? *sp++ : 0;
379
21
      y += sp < *end ? *sp++ : 0;
380
21
    }
381
10.6k
    else if (sp[0] == 0 && sp[1] >= 3)
382
139
    { /* absolute */
383
139
      int dn, sn, pad;
384
139
      dn = sp[1];
385
139
      sn = dn;
386
139
      pad = sn & 1;
387
139
      sp += 2;
388
139
      if (sn > *end - sp)
389
20
      {
390
20
        fz_warn(ctx, "premature end of pixel data in absolute code in bmp image");
391
20
        sn = *end - sp;
392
20
        pad = 0;
393
20
        dn = sn;
394
20
      }
395
119
      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
14.8k
      for (i = 0; i < dn; i++)
401
14.7k
      {
402
14.7k
        uint32_t actualx = x;
403
14.7k
        uint32_t actualy = y;
404
14.7k
        if (actualx >= width || actualy >= height)
405
13.7k
        {
406
13.7k
          actualx = x % width;
407
13.7k
          actualy = y + x / width;
408
13.7k
        }
409
14.7k
        if (actualx < width && actualy < height)
410
1.45k
        {
411
1.45k
          dp = decompressed + actualy * stride + actualx;
412
1.45k
          *dp++ = sp[i];
413
1.45k
        }
414
14.7k
        x++;
415
14.7k
      }
416
139
      sp += sn + pad;
417
139
    }
418
10.5k
    else
419
10.5k
    { /* encoded */
420
10.5k
      int dn, sn;
421
10.5k
      dn = sp[0];
422
10.5k
      sn = 1;
423
10.5k
      sp++;
424
1.15M
      for (i = 0; i < dn; i++)
425
1.14M
      {
426
1.14M
        uint32_t actualx = x;
427
1.14M
        uint32_t actualy = y;
428
1.14M
        if (actualx >= width || actualy >= height)
429
1.13M
        {
430
1.13M
          actualx = x % width;
431
1.13M
          actualy = y + x / width;
432
1.13M
        }
433
1.14M
        if (actualx < width && actualy < height)
434
79.5k
        {
435
79.5k
          dp = decompressed + actualy * stride + actualx;
436
79.5k
          *dp++ = sp[0];
437
79.5k
        }
438
1.14M
        x++;
439
1.14M
      }
440
10.5k
      sp += sn;
441
10.5k
    }
442
11.2k
  }
443
444
33
  info->compression = BI_NONE;
445
33
  info->bitcount = 8;
446
33
  *end = ep;
447
33
  return decompressed;
448
33
}
449
450
static unsigned char *
451
bmp_decompress_rle4(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
452
33
{
453
33
  const unsigned char *sp;
454
33
  unsigned char *dp, *ep, *decompressed;
455
33
  uint32_t width = info->width;
456
33
  uint32_t height = info->height;
457
33
  uint32_t stride;
458
33
  uint32_t x, y;
459
33
  int i;
460
461
33
  stride = ((width + 1) / 2 + 3) / 4 * 4;
462
463
33
  sp = p;
464
33
  dp = decompressed = fz_calloc(ctx, height, stride);
465
33
  ep = dp + height * stride;
466
33
  x = 0;
467
33
  y = 0;
468
469
1.28k
  while (sp + 2 <= *end)
470
1.25k
  {
471
1.25k
    if (sp[0] == 0 && sp[1] == 0)
472
189
    { /* end of line */
473
189
      sp += 2;
474
189
      x = 0;
475
189
      y++;
476
189
    }
477
1.06k
    else if (sp[0] == 0 && sp[1] == 1)
478
2
    { /* end of bitmap */
479
2
      sp += 2;
480
2
      break;
481
2
    }
482
1.06k
    else if (sp[0] == 0 && sp[1] == 2)
483
3
    { /* delta */
484
3
      sp += 2;
485
3
      x += sp < *end ? *sp++ : 0;
486
3
      y += sp < *end ? *sp++ : 0;
487
3
    }
488
1.05k
    else if (sp[0] == 0 && sp[1] >= 3)
489
132
    { /* absolute */
490
132
      int dn, sn, pad;
491
132
      dn = sp[1];
492
132
      sn = (dn + 1) / 2;
493
132
      pad = sn & 1;
494
132
      sp += 2;
495
132
      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
115
      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
2.94k
      for (i = 0; i < dn; i++)
508
2.81k
      {
509
2.81k
        uint32_t actualx = x;
510
2.81k
        uint32_t actualy = y;
511
2.81k
        if (actualx >= width || actualy >= height)
512
1.62k
        {
513
1.62k
          actualx = x % width;
514
1.62k
          actualy = y + x / width;
515
1.62k
        }
516
2.81k
        if (actualx < width && actualy < height)
517
1.30k
        {
518
1.30k
          int val = i & 1 ? (sp[i >> 1]) & 0xF : (sp[i >> 1] >> 4) & 0xF;
519
1.30k
          dp = decompressed + actualy * stride + actualx / 2;
520
1.30k
          if (x & 1)
521
649
            *dp++ |= val;
522
651
          else
523
651
            *dp |= val << 4;
524
1.30k
        }
525
2.81k
        x++;
526
2.81k
      }
527
132
      sp += sn + pad;
528
132
    }
529
926
    else
530
926
    { /* encoded */
531
926
      int dn, sn;
532
926
      dn = sp[0];
533
926
      sn = 1;
534
926
      sp++;
535
85.9k
      for (i = 0; i < dn; i++)
536
85.0k
      {
537
85.0k
        uint32_t actualx = x;
538
85.0k
        uint32_t actualy = y;
539
85.0k
        if (actualx >= width || actualy >= height)
540
78.3k
        {
541
78.3k
          actualx = x % width;
542
78.3k
          actualy = y + x / width;
543
78.3k
        }
544
85.0k
        if (actualx < width && actualy < height)
545
8.71k
        {
546
8.71k
          int val = i & 1 ? (sp[0] & 0xf) : (sp[0] >> 4) & 0xf;
547
8.71k
          dp = decompressed + actualy * stride + actualx / 2;
548
8.71k
          if (x & 1)
549
4.35k
            *dp++ |= val;
550
4.36k
          else
551
4.36k
            *dp |= val << 4;
552
8.71k
        }
553
85.0k
        x++;
554
85.0k
      }
555
926
      sp += sn;
556
926
    }
557
1.25k
  }
558
559
33
  info->compression = BI_NONE;
560
33
  info->bitcount = 4;
561
33
  *end = ep;
562
33
  return decompressed;
563
33
}
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
225
{
568
225
  const unsigned int mults[] = { 0, 8191, 2730, 1170, 546, 264, 130, 64 };
569
225
  fz_pixmap *pix;
570
225
  const unsigned char *ssp;
571
225
  unsigned char *ddp;
572
225
  unsigned char *decompressed = NULL;
573
225
  uint32_t bitcount;
574
225
  uint32_t width;
575
225
  int32_t height;
576
225
  uint32_t sstride;
577
225
  int32_t dstride;
578
225
  unsigned int rmult, gmult, bmult, amult;
579
225
  unsigned int rtrunc, gtrunc, btrunc, atrunc;
580
225
  uint32_t x;
581
225
  int32_t y;
582
583
225
  assert(info->width > 0 && info->width <= SHRT_MAX);
584
225
  assert(info->height > 0 && info->height <= SHRT_MAX);
585
586
225
  if (info->compression == BI_NONE)
587
18
    ssp = p;
588
207
  else if (info->compression == BI_RLE4)
589
33
    ssp = decompressed = bmp_decompress_rle4(ctx, info, p, &end);
590
174
  else if (info->compression == BI_RLE8)
591
33
    ssp = decompressed = bmp_decompress_rle8(ctx, info, p, &end);
592
141
  else if (is_win_bmp(info) && (info->compression == BI_BITFIELDS || info->compression == BI_ALPHABITS))
593
141
    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
225
  bitcount = info->bitcount;
602
225
  width = info->width;
603
225
  height = info->height;
604
605
225
  sstride = ((width * bitcount + 31) / 32) * 4;
606
225
  if (ssp + sstride * height > end)
607
151
  {
608
151
    int32_t h = (end - ssp) / sstride;
609
151
    if (h == 0 || h > SHRT_MAX)
610
9
    {
611
9
      fz_free(ctx, decompressed);
612
9
      fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions out of range in bmp image");
613
9
    }
614
151
  }
615
616
432
  fz_try(ctx)
617
432
  {
618
216
    pix = fz_new_pixmap(ctx, info->cs, width, height, NULL, 1);
619
216
    fz_set_pixmap_resolution(ctx, pix, info->xres, info->yres);
620
216
    fz_clear_pixmap(ctx, pix);
621
216
  }
622
432
  fz_catch(ctx)
623
0
  {
624
0
    fz_free(ctx, decompressed);
625
0
    fz_rethrow(ctx);
626
0
  }
627
628
216
  ddp = pix->samples;
629
216
  dstride = pix->stride;
630
216
  if (!info->topdown)
631
160
  {
632
160
    ddp = pix->samples + ((size_t) (height - 1)) * ((size_t) dstride);
633
160
    dstride = -dstride;
634
160
  }
635
636
216
  if (ssp + sstride * height > end)
637
142
  {
638
142
    fz_warn(ctx, "premature end in bitmap data in bmp image");
639
142
    height = (end - ssp) / sstride;
640
142
  }
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
216
  rmult = info->rbits < 8 ? mults[info->rbits] : 1;
652
216
  gmult = info->gbits < 8 ? mults[info->gbits] : 1;
653
216
  bmult = info->bbits < 8 ? mults[info->bbits] : 1;
654
216
  amult = info->abits < 8 ? mults[info->abits] : 1;
655
216
  rtrunc = info->rbits < 8 ? 5 : (info->rbits - 8);
656
216
  gtrunc = info->gbits < 8 ? 5 : (info->gbits - 8);
657
216
  btrunc = info->bbits < 8 ? 5 : (info->bbits - 8);
658
216
  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
82.8k
  for (y = 0; y < height; y++)
667
82.6k
  {
668
82.6k
    const unsigned char *sp = ssp + ((size_t) y) * ((size_t) sstride);
669
82.6k
    unsigned char *dp = ddp + ((size_t) y) * ((size_t) dstride);
670
671
82.6k
    switch (bitcount)
672
82.6k
    {
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
6.51k
    case 32:
692
13.2k
      for (x = 0; x < width; x++)
693
6.72k
      {
694
6.72k
        uint32_t sample =
695
6.72k
          (((uint32_t) sp[3]) << 24) |
696
6.72k
          (((uint32_t) sp[2]) << 16) |
697
6.72k
          (((uint32_t) sp[1]) <<  8) |
698
6.72k
          (((uint32_t) sp[0]) <<  0);
699
6.72k
        uint32_t r = (sample & info->rmask) >> info->rshift;
700
6.72k
        uint32_t g = (sample & info->gmask) >> info->gshift;
701
6.72k
        uint32_t b = (sample & info->bmask) >> info->bshift;
702
6.72k
        uint32_t a = info->abits == 0 ? 255 : (sample & info->amask) >> info->ashift;
703
6.72k
        *dp++ = (r * rmult) >> rtrunc;
704
6.72k
        *dp++ = (g * gmult) >> gtrunc;
705
6.72k
        *dp++ = (b * bmult) >> btrunc;
706
6.72k
        *dp++ = info->abits == 0 ? a : (a * amult) >> atrunc;
707
6.72k
        sp += 4;
708
6.72k
      }
709
6.51k
      break;
710
575
    case 24:
711
5.61k
      for (x = 0; x < width; x++)
712
5.03k
      {
713
5.03k
        *dp++ = sp[2];
714
5.03k
        *dp++ = sp[1];
715
5.03k
        *dp++ = sp[0];
716
5.03k
        *dp++ = 255;
717
5.03k
        sp += 3;
718
5.03k
      }
719
575
      break;
720
2.76k
    case 16:
721
8.23k
      for (x = 0; x < width; x++)
722
5.46k
      {
723
5.46k
        uint16_t sample =
724
5.46k
          (((uint16_t)sp[1]) << 8) |
725
5.46k
          (((uint16_t)sp[0]) << 0);
726
5.46k
        uint16_t r = (sample & info->rmask) >> info->rshift;
727
5.46k
        uint16_t g = (sample & info->gmask) >> info->gshift;
728
5.46k
        uint16_t b = (sample & info->bmask) >> info->bshift;
729
5.46k
        uint16_t a = (sample & info->amask) >> info->ashift;
730
5.46k
        *dp++ = (r * rmult) >> rtrunc;
731
5.46k
        *dp++ = (g * gmult) >> gtrunc;
732
5.46k
        *dp++ = (b * bmult) >> btrunc;
733
5.46k
        *dp++ = info->abits == 0 ? 255 : (a * amult) >> atrunc;
734
5.46k
        sp += 2;
735
5.46k
      }
736
2.76k
      break;
737
60.9k
    case 8:
738
103M
      for (x = 0; x < width; x++)
739
103M
      {
740
103M
        *dp++ = info->palette[3 * sp[0] + 0];
741
103M
        *dp++ = info->palette[3 * sp[0] + 1];
742
103M
        *dp++ = info->palette[3 * sp[0] + 2];
743
103M
        *dp++ = 255;
744
103M
        sp++;
745
103M
      }
746
60.9k
      break;
747
11.3k
    case 4:
748
92.9M
      for (x = 0; x < width; x++)
749
92.9M
      {
750
92.9M
        int idx;
751
92.9M
        switch (x & 1)
752
92.9M
        {
753
46.4M
        case 0: idx = (sp[0] >> 4) & 0x0f; break;
754
46.4M
        case 1: idx = (sp[0] >> 0) & 0x0f; sp++; break;
755
92.9M
        }
756
92.9M
        *dp++ = info->palette[3 * idx + 0];
757
92.9M
        *dp++ = info->palette[3 * idx + 1];
758
92.9M
        *dp++ = info->palette[3 * idx + 2];
759
92.9M
        *dp++ = 255;
760
92.9M
      }
761
11.3k
      break;
762
11.3k
    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
416
    case 1:
780
4.87k
      for (x = 0; x < width; x++)
781
4.45k
      {
782
4.45k
        int idx;
783
4.45k
        switch (x & 7)
784
4.45k
        {
785
913
        case 0: idx = (sp[0] >> 7) & 0x01; break;
786
516
        case 1: idx = (sp[0] >> 6) & 0x01; break;
787
516
        case 2: idx = (sp[0] >> 5) & 0x01; break;
788
516
        case 3: idx = (sp[0] >> 4) & 0x01; break;
789
499
        case 4: idx = (sp[0] >> 3) & 0x01; break;
790
499
        case 5: idx = (sp[0] >> 2) & 0x01; break;
791
499
        case 6: idx = (sp[0] >> 1) & 0x01; break;
792
499
        case 7: idx = (sp[0] >> 0) & 0x01; sp++; break;
793
4.45k
        }
794
4.45k
        *dp++ = info->palette[3 * idx + 0];
795
4.45k
        *dp++ = info->palette[3 * idx + 1];
796
4.45k
        *dp++ = info->palette[3 * idx + 2];
797
4.45k
        *dp++ = 255;
798
4.45k
      }
799
416
      break;
800
82.6k
    }
801
82.6k
  }
802
803
216
  fz_free(ctx, decompressed);
804
216
  fz_premultiply_pixmap(ctx, pix);
805
216
  return pix;
806
216
}
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
141
{
811
141
  if (info->colorspacetype == 0)
812
101
  {
813
101
    float matrix[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
814
101
    float wp[3] = { 0.95047f, 1.0f, 1.08883f }; /* D65 white point */
815
101
    float bp[3] = { 0, 0, 0 };
816
101
    float gamma[3] = { 1, 1, 1 };
817
101
    int i;
818
819
404
    for (i = 0; i < 3; i++)
820
303
      gamma[i] = (float) info->gamma[i] / (float) (1 << 16);
821
1.01k
    for (i = 0; i < 9; i++)
822
909
      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
101
    return fz_new_cal_rgb_colorspace(ctx, wp, bp, gamma, matrix);
834
101
  }
835
40
  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
40
  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
40
  else if (info->colorspacetype == 0x4d424544)
846
15
  {
847
15
    fz_buffer *profile;
848
15
    fz_colorspace *cs;
849
850
15
    if ((uint32_t)(end - begin) <= info->profileoffset)
851
7
    {
852
7
      fz_warn(ctx, "ignoring color profile located outside bmp image");
853
7
      return NULL;
854
7
    }
855
8
    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
6
    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
6
    profile = fz_new_buffer_from_copied_data(ctx, begin + info->profileoffset, info->profilesize);
867
868
12
    fz_try(ctx)
869
12
      cs = fz_new_icc_colorspace(ctx, FZ_COLORSPACE_RGB, 0, "BMPRGB", profile);
870
12
    fz_always(ctx)
871
6
      fz_drop_buffer(ctx, profile);
872
6
    fz_catch(ctx)
873
5
      fz_rethrow(ctx);
874
875
1
    return cs;
876
6
  }
877
25
  else if (info->colorspacetype == 0x73524742)
878
0
  {
879
0
    return fz_keep_colorspace(ctx, fz_device_rgb(ctx));
880
0
  }
881
882
25
  fz_warn(ctx, "ignoring color profile with unknown type in bmp image");
883
25
  return NULL;
884
141
}
885
886
static void
887
compute_mask_info(unsigned int mask, unsigned int *shift, unsigned int *bits)
888
1.08k
{
889
1.08k
  *bits = 0;
890
1.08k
  *shift = 0;
891
892
3.11k
  while (mask && (mask & 1) == 0) {
893
2.03k
    *shift += 1;
894
2.03k
    mask >>= 1;
895
2.03k
  }
896
3.09k
  while (mask && (mask & 1) == 1) {
897
2.01k
    *bits += 1;
898
2.01k
    mask >>= 1;
899
2.01k
  }
900
1.08k
}
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
8
{
905
8
  int size = 0;
906
907
8
  if (info->compression == BI_BITFIELDS)
908
4
  {
909
4
    size = 12;
910
4
    if (end - p < 12)
911
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in mask header in bmp image");
912
913
4
    info->rmask = read32(p + 0);
914
4
    info->gmask = read32(p + 4);
915
4
    info->bmask = read32(p + 8);
916
4
  }
917
4
  else if (info->compression == BI_ALPHABITS)
918
4
  {
919
4
    size = 16;
920
4
    if (end - p < 16)
921
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in mask header in bmp image");
922
923
4
    info->rmask = read32(p + 0);
924
4
    info->gmask = read32(p + 4);
925
4
    info->bmask = read32(p + 8);
926
4
    info->amask = read32(p + 12);
927
4
  }
928
929
8
  return p + size;
930
8
}
931
932
static int
933
bmp_palette_is_gray(fz_context *ctx, struct info *info, int readcolors)
934
78
{
935
78
  int i;
936
210
  for (i = 0; i < readcolors; i++)
937
158
  {
938
158
    int rgdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 1]);
939
158
    int gbdiff = fz_absi(info->palette[3 * i + 1] - info->palette[3 * i + 2]);
940
158
    int rbdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 2]);
941
158
    if (rgdiff > 2 || gbdiff > 2 || rbdiff > 2)
942
26
      return 0;
943
158
  }
944
52
  return 1;
945
78
}
946
947
static void
948
bmp_load_default_palette(fz_context *ctx, struct info *info, int readcolors)
949
81
{
950
81
  int i;
951
952
81
  fz_warn(ctx, "color table too short; loading default palette");
953
954
81
  if (info->bitcount == 8)
955
42
  {
956
42
    if (!bmp_palette_is_gray(ctx, info, readcolors))
957
10
      memcpy(&info->palette[readcolors * 3], &web_palette[readcolors * 3],
958
10
          sizeof(web_palette) - readcolors * 3);
959
32
    else
960
8.19k
      for (i = readcolors; i < 256; i++)
961
8.16k
      {
962
8.16k
        info->palette[3 * i + 0] = i;
963
8.16k
        info->palette[3 * i + 1] = i;
964
8.16k
        info->palette[3 * i + 2] = i;
965
8.16k
      }
966
42
  }
967
39
  else if (info->bitcount == 4)
968
36
  {
969
36
    if (!bmp_palette_is_gray(ctx, info, readcolors))
970
16
      memcpy(&info->palette[readcolors * 3], &vga_palette[readcolors * 3],
971
16
          sizeof(vga_palette) - readcolors * 3);
972
20
    else
973
327
      for (i = readcolors; i < 16; i++)
974
307
      {
975
307
        info->palette[3 * i + 0] = (i << 4) | i;
976
307
        info->palette[3 * i + 1] = (i << 4) | i;
977
307
        info->palette[3 * i + 2] = (i << 4) | i;
978
307
      }
979
36
  }
980
3
  else if (info->bitcount == 2)
981
0
    memcpy(info->palette, gray_palette, sizeof(gray_palette));
982
3
  else if (info->bitcount == 1)
983
3
    memcpy(info->palette, bw_palette, sizeof(bw_palette));
984
81
}
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
86
{
989
86
  int i, expected, present, entry_size;
990
991
86
  entry_size = palette_entry_size(info);
992
993
86
  if (info->colors == 0)
994
12
    expected = info->colors = 1 << info->bitcount;
995
74
  else
996
74
    expected = fz_mini(info->colors, 1 << info->bitcount);
997
998
86
  if (info->bitmapoffset == 0)
999
0
    present = fz_mini(expected, (end - p) / entry_size);
1000
86
  else
1001
86
    present = fz_mini(expected, (begin + info->bitmapoffset - p) / entry_size);
1002
1003
423
  for (i = 0; i < present; i++)
1004
337
  {
1005
    /* ignore alpha channel even if present */
1006
337
    info->palette[3 * i + 0] = read8(p + i * entry_size + 2);
1007
337
    info->palette[3 * i + 1] = read8(p + i * entry_size + 1);
1008
337
    info->palette[3 * i + 2] = read8(p + i * entry_size + 0);
1009
337
  }
1010
1011
86
  if (present < expected)
1012
81
    bmp_load_default_palette(ctx, info, present);
1013
1014
86
  return p + present * entry_size;
1015
86
}
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
275
{
1020
275
  uint32_t size;
1021
1022
275
  if (end - p < 4)
1023
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in info header in bmp image");
1024
275
  size = info->version = read32(p + 0);
1025
1026
275
  if (!is_win_bmp(info) && !is_os2_bmp(info))
1027
5
    fz_throw(ctx, FZ_ERROR_FORMAT, "unknown header version (%u) in bmp image", info->version);
1028
270
  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
270
  info->compression = BI_NONE;
1033
1034
  /* OS/2 1.x or Windows v2 */
1035
270
  if (size == 12)
1036
15
  {
1037
    /* read32(p+0) == header size */
1038
15
    info->width = read16(p + 4);
1039
15
    info->height = read16(p + 6);
1040
    /* read16(p+8) == planes */
1041
15
    info->bitcount = read16(p + 10);
1042
15
  }
1043
  /* OS/2 2.x short header */
1044
270
  if (size >= 16)
1045
255
  {
1046
    /* read32(p+0) == header size */
1047
255
    info->width = read32(p + 4);
1048
255
    info->height = read32(p + 8);
1049
    /* read16(p+12) == planes */
1050
255
    info->bitcount = read16(p + 14);
1051
255
  }
1052
1053
  /* default masks */
1054
270
  if (info->bitcount == 16)
1055
79
  {
1056
79
    info->rmask = 0x00007c00;
1057
79
    info->gmask = 0x000003e0;
1058
79
    info->bmask = 0x0000001f;
1059
79
    info->amask = 0x00000000;
1060
79
  }
1061
191
  else if (info->bitcount == 24 || info->bitcount == 32)
1062
82
  {
1063
82
    info->rmask = 0x00ff0000;
1064
82
    info->gmask = 0x0000ff00;
1065
82
    info->bmask = 0x000000ff;
1066
82
    info->amask = 0x00000000;
1067
82
  }
1068
1069
  /* Windows v3 header */
1070
270
  if (size >= 40)
1071
253
  {
1072
253
    info->compression = read32(p + 16);
1073
253
    info->bitmapsize = read32(p + 20);
1074
253
    info->xres = read32(p + 24);
1075
253
    info->yres = read32(p + 28);
1076
253
    info->colors = read32(p + 32);
1077
253
    if (info->bitcount >= 32)
1078
95
    {
1079
95
      if (info->colors != 0)
1080
86
        fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1081
95
      info->colors = 0;
1082
95
    }
1083
158
    else if (info->colors > (1U<<info->bitcount))
1084
120
    {
1085
120
      fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1086
120
      info->colors = 1<<info->bitcount;
1087
120
    }
1088
    /* read32(p+36) == important colors */
1089
253
  }
1090
  /* Windows v3 header with RGB masks */
1091
270
  if (size == 52 || size == 56 || size == 108 || size == 124)
1092
175
  {
1093
175
    info->rmask = read32(p + 40);
1094
175
    info->gmask = read32(p + 44);
1095
175
    info->bmask = read32(p + 48);
1096
175
  }
1097
  /* Windows v3 header with RGBA masks */
1098
270
  if (size == 56 || size == 108 || size == 124)
1099
174
  {
1100
174
    info->amask = read32(p + 52);
1101
174
  }
1102
  /* OS/2 2.x long header */
1103
270
  if (size == 64)
1104
3
  {
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
3
  }
1114
  /* Windows v4 header */
1115
270
  if (size >= 108)
1116
153
  {
1117
153
    info->colorspacetype = read32(p + 56);
1118
1119
153
    info->endpoints[0] = read32(p + 60);
1120
153
    info->endpoints[1] = read32(p + 64);
1121
153
    info->endpoints[2] = read32(p + 68);
1122
1123
153
    info->endpoints[3] = read32(p + 72);
1124
153
    info->endpoints[4] = read32(p + 76);
1125
153
    info->endpoints[5] = read32(p + 80);
1126
1127
153
    info->endpoints[6] = read32(p + 84);
1128
153
    info->endpoints[7] = read32(p + 88);
1129
153
    info->endpoints[8] = read32(p + 92);
1130
1131
153
    info->gamma[0] = read32(p + 96);
1132
153
    info->gamma[1] = read32(p + 100);
1133
153
    info->gamma[2] = read32(p + 104);
1134
153
  }
1135
  /* Windows v5 header */
1136
270
  if (size >= 124)
1137
20
  {
1138
20
    info->intent = read32(p + 108);
1139
20
    info->profileoffset = read32(p + 112);
1140
20
    info->profilesize = read32(p + 116);
1141
    /* read32(p+120) == reserved */
1142
20
  }
1143
1144
270
  return p + size;
1145
270
}
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
276
{
1151
276
  const unsigned char *profilebegin;
1152
1153
276
  memset(info, 0x00, sizeof (*info));
1154
276
  info->colorspacetype = 0xffffffff;
1155
1156
276
  p = profilebegin = bmp_read_file_header(ctx, info, begin, end, p);
1157
1158
276
  p = bmp_read_info_header(ctx, info, begin, end, p);
1159
1160
  /* clamp bitmap offset to buffer size */
1161
276
  if (info->bitmapoffset < (uint32_t)(p - begin))
1162
68
    info->bitmapoffset = (uint32_t)(p - begin);
1163
276
  if ((uint32_t)(end - begin) < info->bitmapoffset)
1164
27
    info->bitmapoffset = end - begin;
1165
1166
276
  if (has_palette(info))
1167
86
    p = bmp_read_palette(ctx, info, begin, end, p);
1168
1169
276
  if (has_color_masks(info))
1170
8
    p = bmp_read_color_masks(ctx, info, begin, end, p);
1171
1172
276
  info->xres = DPM_TO_DPI(info->xres);
1173
276
  info->yres = DPM_TO_DPI(info->yres);
1174
1175
  /* extract topdown/bottomup from height for windows bitmaps */
1176
276
  if (is_win_bmp(info))
1177
265
  {
1178
265
    int bits = info->version == 12 ? 16 : 32;
1179
1180
265
    info->topdown = (info->height >> (bits - 1)) & 1;
1181
265
    if (info->topdown)
1182
67
    {
1183
67
      info->height--;
1184
67
      info->height = ~info->height;
1185
67
      info->height &= bits == 16 ? 0xffff : 0xffffffff;
1186
67
    }
1187
265
  }
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
276
  if (info->version == 108 &&
1195
276
      info->rmask == 0x73524742 && /* colorspacetype */
1196
276
      info->gmask == 0x00000000 && /* endpoints[0] */
1197
276
      info->bmask == 0x00000000 && /* endpoints[1] */
1198
276
      info->amask == 0x00000000 && /* endpoints[2] */
1199
276
      info->colorspacetype == 0x00000000 && /* endpoints[3] */
1200
276
      info->endpoints[0] == 0x00000000 && /* endpoints[4] */
1201
276
      info->endpoints[1] == 0x00000000 && /* endpoints[5] */
1202
276
      info->endpoints[2] == 0x00000000 && /* endpoints[6] */
1203
276
      info->endpoints[3] == 0x00000000 && /* endpoints[7] */
1204
276
      info->endpoints[4] == 0x00000000 && /* endpoints[8] */
1205
276
      info->endpoints[5] == 0x00000000 && /* gamma[0] */
1206
276
      info->endpoints[6] == 0x00000000 && /* gamma[1] */
1207
276
      info->endpoints[7] == 0x00000000 && /* gamma[2] */
1208
276
      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
276
  compute_mask_info(info->rmask, &info->rshift, &info->rbits);
1233
276
  compute_mask_info(info->gmask, &info->gshift, &info->gbits);
1234
276
  compute_mask_info(info->bmask, &info->bshift, &info->bbits);
1235
276
  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
276
  if (info->width == 0 || info->width > SHRT_MAX || info->height == 0 || info->height > SHRT_MAX)
1284
16
    fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions (%u x %u) out of range in bmp image", info->width, info->height);
1285
260
  if (!is_valid_compression(info))
1286
16
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported compression method (%u) in bmp image", info->compression);
1287
244
  if (!is_valid_bitcount(info))
1288
4
    fz_throw(ctx, FZ_ERROR_FORMAT, "invalid bits per pixel (%u) for compression (%u) in bmp image", info->bitcount, info->compression);
1289
240
  if (info->rbits > info->bitcount)
1290
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit red mask in bmp image", info->rbits);
1291
240
  if (info->gbits > info->bitcount)
1292
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit green mask in bmp image", info->gbits);
1293
240
  if (info->bbits > info->bitcount)
1294
1
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit blue mask in bmp image", info->bbits);
1295
239
  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
238
  if (has_color_profile(info))
1300
141
    info->cs = bmp_read_color_profile(ctx, info, profilebegin, end);
1301
238
  if (!info->cs)
1302
125
    info->cs = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
1303
1304
238
  if (only_metadata)
1305
0
    return NULL;
1306
1307
  /* bitmap cannot begin before headers have ended */
1308
238
  if ((uint32_t)(p - begin) < info->bitmapoffset)
1309
15
    p = begin + info->bitmapoffset;
1310
1311
238
  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
238
  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
238
  else
1324
238
    return bmp_read_bitmap(ctx, info, begin, end, p);
1325
238
}
1326
1327
fz_pixmap *
1328
fz_load_bmp_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage)
1329
276
{
1330
276
  const unsigned char *begin = buf;
1331
276
  const unsigned char *end = buf + len;
1332
276
  const unsigned char *p = begin;
1333
276
  struct info info = { 0 };
1334
276
  int nextoffset = 0;
1335
276
  fz_pixmap *image = NULL;
1336
276
  int origidx = subimage;
1337
1338
276
  (void) p;
1339
1340
276
  do
1341
276
  {
1342
276
    p = begin + nextoffset;
1343
1344
276
    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
276
    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
275
    else if (is_bitmap(p))
1358
275
    {
1359
275
      nextoffset = 0;
1360
275
    }
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
276
    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
276
    else
1373
276
      subimage--;
1374
1375
276
  } while (subimage >= 0 && nextoffset > 0);
1376
1377
276
  if (subimage != -1)
1378
0
    fz_throw(ctx, FZ_ERROR_ARGUMENT, "subimage index (%d) out of range in bmp image", origidx);
1379
1380
552
  fz_try(ctx)
1381
552
    image = bmp_read_image(ctx, &info, begin, end, p, 0);
1382
552
  fz_always(ctx)
1383
276
    fz_drop_colorspace(ctx, info.cs);
1384
276
  fz_catch(ctx)
1385
60
    fz_rethrow(ctx);
1386
1387
216
  return image;
1388
276
}
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
276
{
1460
276
  const unsigned char *begin = buf;
1461
276
  const unsigned char *end = buf + len;
1462
276
  uint32_t nextoffset = 0;
1463
276
  int count = 0;
1464
1465
276
  do
1466
277
  {
1467
277
    const unsigned char *p = begin + nextoffset;
1468
1469
277
    if (end - p < 14)
1470
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "not enough data for bitmap array in bmp image");
1471
1472
277
    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
276
    else if (is_bitmap(p))
1482
275
    {
1483
275
      nextoffset = 0;
1484
275
    }
1485
1
    else
1486
1
    {
1487
1
      fz_warn(ctx, "treating invalid subimage as end of file");
1488
1
      nextoffset = 0;
1489
1
    }
1490
1491
277
    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
277
    else
1497
277
      count++;
1498
1499
277
  } while (nextoffset > 0);
1500
1501
276
  return count;
1502
276
}
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
}