Coverage Report

Created: 2024-05-20 06:23

/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.96k
#define read8(p) ((p)[0])
136
317
#define read16(p) (((p)[1] << 8) | (p)[0])
137
5.57k
#define read32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
138
139
584
#define DPM_TO_DPI(dpm) ((dpm) * 25.4f / 1000.0f)
140
141
584
#define is_bitmap_array(p) ((p)[0] == 'B' && (p)[1] == 'A')
142
876
#define is_bitmap(p) ((p)[0] == 'B' && (p)[1] == 'M')
143
144
58
#define is_os2_bmp(info) ((info)->version == 12 || (info)->version == 16 || (info)->version == 64)
145
3.19k
#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
558
#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
13
#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
279
#define is_valid_compression(info) (is_valid_win_compression(info) || is_valid_os2_compression(info))
150
151
536
#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
511
#define is_valid_rle8_bitcount(info) ((info)->compression == BI_RLE8 && (info)->bitcount == 8)
153
476
#define is_valid_rle4_bitcount(info) ((info)->compression == BI_RLE4 && (info)->bitcount == 4)
154
444
#define is_valid_bitfields_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_BITFIELDS && ((info)->bitcount == 16 || (info)->bitcount == 32))
155
277
#define is_valid_jpeg_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_JPEG && (info)->bitcount == 0)
156
277
#define is_valid_png_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_PNG && (info)->bitcount == 0)
157
277
#define is_valid_alphabits_bitcount(info) (is_win_bmp(info) && (info)->compression == BI_ALPHABITS && ((info)->bitcount == 16 || (info)->bitcount == 32))
158
273
#define is_valid_rle24_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_RLE24 && (info)->bitcount == 24)
159
5
#define is_valid_huffman1d_bitcount(info) (is_os2_bmp(info) && (info)->compression == BI_HUFFMAN1D && (info)->bitcount == 1)
160
268
#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
292
#define has_palette(info) ((info)->bitcount == 1 || (info)->bitcount == 2 || (info)->bitcount == 4 || (info)->bitcount == 8)
163
292
#define has_color_masks(info) (((info)->bitcount == 16 || (info)->bitcount == 32) && (info)->version == 40 && ((info)->compression == BI_BITFIELDS || (info)->compression == BI_ALPHABITS))
164
259
#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
292
{
171
292
  if (end - p < 14)
172
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in file header in bmp image");
173
174
292
  if (!is_bitmap(p))
175
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "invalid signature %02x%02x in bmp image", p[0], p[1]);
176
177
292
  info->type[0] = read8(p + 0);
178
292
  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
292
  info->bitmapoffset = read32(p + 10);
183
184
292
  return p + 14;
185
292
}
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
35
{
346
35
  const unsigned char *sp;
347
35
  unsigned char *dp, *ep, *decompressed;
348
35
  uint32_t width = info->width;
349
35
  uint32_t height = info->height;
350
35
  uint32_t stride;
351
35
  uint32_t x, y;
352
35
  int i;
353
354
35
  stride = (width + 3) / 4 * 4;
355
356
35
  sp = p;
357
35
  dp = decompressed = fz_calloc(ctx, height, stride);
358
35
  ep = dp + height * stride;
359
35
  x = 0;
360
35
  y = 0;
361
362
17.2k
  while (sp + 2 <= *end)
363
17.2k
  {
364
17.2k
    if (sp[0] == 0 && sp[1] == 0)
365
667
    { /* end of line */
366
667
      sp += 2;
367
667
      x = 0;
368
667
      y++;
369
667
    }
370
16.5k
    else if (sp[0] == 0 && sp[1] == 1)
371
4
    { /* end of bitmap */
372
4
      sp += 2;
373
4
      break;
374
4
    }
375
16.5k
    else if (sp[0] == 0 && sp[1] == 2)
376
26
    { /* delta */
377
26
      sp +=2;
378
26
      x += sp < *end ? *sp++ : 0;
379
26
      y += sp < *end ? *sp++ : 0;
380
26
    }
381
16.5k
    else if (sp[0] == 0 && sp[1] >= 3)
382
164
    { /* absolute */
383
164
      int dn, sn, pad;
384
164
      dn = sp[1];
385
164
      sn = dn;
386
164
      pad = sn & 1;
387
164
      sp += 2;
388
164
      if (sn > *end - sp)
389
16
      {
390
16
        fz_warn(ctx, "premature end of pixel data in absolute code in bmp image");
391
16
        sn = *end - sp;
392
16
        pad = 0;
393
16
        dn = sn;
394
16
      }
395
148
      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
17.6k
      for (i = 0; i < dn; i++)
401
17.5k
      {
402
17.5k
        uint32_t actualx = x;
403
17.5k
        uint32_t actualy = y;
404
17.5k
        if (actualx >= width || actualy >= height)
405
16.6k
        {
406
16.6k
          actualx = x % width;
407
16.6k
          actualy = y + x / width;
408
16.6k
        }
409
17.5k
        if (actualx < width && actualy < height)
410
1.70k
        {
411
1.70k
          dp = decompressed + actualy * stride + actualx;
412
1.70k
          *dp++ = sp[i];
413
1.70k
        }
414
17.5k
        x++;
415
17.5k
      }
416
164
      sp += sn + pad;
417
164
    }
418
16.3k
    else
419
16.3k
    { /* encoded */
420
16.3k
      int dn, sn;
421
16.3k
      dn = sp[0];
422
16.3k
      sn = 1;
423
16.3k
      sp++;
424
1.74M
      for (i = 0; i < dn; i++)
425
1.72M
      {
426
1.72M
        uint32_t actualx = x;
427
1.72M
        uint32_t actualy = y;
428
1.72M
        if (actualx >= width || actualy >= height)
429
1.70M
        {
430
1.70M
          actualx = x % width;
431
1.70M
          actualy = y + x / width;
432
1.70M
        }
433
1.72M
        if (actualx < width && actualy < height)
434
300k
        {
435
300k
          dp = decompressed + actualy * stride + actualx;
436
300k
          *dp++ = sp[0];
437
300k
        }
438
1.72M
        x++;
439
1.72M
      }
440
16.3k
      sp += sn;
441
16.3k
    }
442
17.2k
  }
443
444
35
  info->compression = BI_NONE;
445
35
  info->bitcount = 8;
446
35
  *end = ep;
447
35
  return decompressed;
448
35
}
449
450
static unsigned char *
451
bmp_decompress_rle4(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char **end)
452
32
{
453
32
  const unsigned char *sp;
454
32
  unsigned char *dp, *ep, *decompressed;
455
32
  uint32_t width = info->width;
456
32
  uint32_t height = info->height;
457
32
  uint32_t stride;
458
32
  uint32_t x, y;
459
32
  int i;
460
461
32
  stride = ((width + 1) / 2 + 3) / 4 * 4;
462
463
32
  sp = p;
464
32
  dp = decompressed = fz_calloc(ctx, height, stride);
465
32
  ep = dp + height * stride;
466
32
  x = 0;
467
32
  y = 0;
468
469
6.72k
  while (sp + 2 <= *end)
470
6.69k
  {
471
6.69k
    if (sp[0] == 0 && sp[1] == 0)
472
227
    { /* end of line */
473
227
      sp += 2;
474
227
      x = 0;
475
227
      y++;
476
227
    }
477
6.47k
    else if (sp[0] == 0 && sp[1] == 1)
478
3
    { /* end of bitmap */
479
3
      sp += 2;
480
3
      break;
481
3
    }
482
6.46k
    else if (sp[0] == 0 && sp[1] == 2)
483
4
    { /* delta */
484
4
      sp += 2;
485
4
      x += sp < *end ? *sp++ : 0;
486
4
      y += sp < *end ? *sp++ : 0;
487
4
    }
488
6.46k
    else if (sp[0] == 0 && sp[1] >= 3)
489
136
    { /* absolute */
490
136
      int dn, sn, pad;
491
136
      dn = sp[1];
492
136
      sn = (dn + 1) / 2;
493
136
      pad = sn & 1;
494
136
      sp += 2;
495
136
      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
119
      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
4.72k
      for (i = 0; i < dn; i++)
508
4.59k
      {
509
4.59k
        uint32_t actualx = x;
510
4.59k
        uint32_t actualy = y;
511
4.59k
        if (actualx >= width || actualy >= height)
512
3.97k
        {
513
3.97k
          actualx = x % width;
514
3.97k
          actualy = y + x / width;
515
3.97k
        }
516
4.59k
        if (actualx < width && actualy < height)
517
715
        {
518
715
          int val = i & 1 ? (sp[i >> 1]) & 0xF : (sp[i >> 1] >> 4) & 0xF;
519
715
          dp = decompressed + actualy * stride + actualx / 2;
520
715
          if (x & 1)
521
356
            *dp++ |= val;
522
359
          else
523
359
            *dp |= val << 4;
524
715
        }
525
4.59k
        x++;
526
4.59k
      }
527
136
      sp += sn + pad;
528
136
    }
529
6.32k
    else
530
6.32k
    { /* encoded */
531
6.32k
      int dn, sn;
532
6.32k
      dn = sp[0];
533
6.32k
      sn = 1;
534
6.32k
      sp++;
535
643k
      for (i = 0; i < dn; i++)
536
637k
      {
537
637k
        uint32_t actualx = x;
538
637k
        uint32_t actualy = y;
539
637k
        if (actualx >= width || actualy >= height)
540
634k
        {
541
634k
          actualx = x % width;
542
634k
          actualy = y + x / width;
543
634k
        }
544
637k
        if (actualx < width && actualy < height)
545
6.49k
        {
546
6.49k
          int val = i & 1 ? (sp[0] & 0xf) : (sp[0] >> 4) & 0xf;
547
6.49k
          dp = decompressed + actualy * stride + actualx / 2;
548
6.49k
          if (x & 1)
549
3.24k
            *dp++ |= val;
550
3.25k
          else
551
3.25k
            *dp |= val << 4;
552
6.49k
        }
553
637k
        x++;
554
637k
      }
555
6.32k
      sp += sn;
556
6.32k
    }
557
6.69k
  }
558
559
32
  info->compression = BI_NONE;
560
32
  info->bitcount = 4;
561
32
  *end = ep;
562
32
  return decompressed;
563
32
}
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
247
{
568
247
  const unsigned int mults[] = { 0, 8191, 2730, 1170, 546, 264, 130, 64 };
569
247
  fz_pixmap *pix;
570
247
  const unsigned char *ssp;
571
247
  unsigned char *ddp;
572
247
  unsigned char *decompressed = NULL;
573
247
  uint32_t bitcount;
574
247
  uint32_t width;
575
247
  int32_t height;
576
247
  uint32_t sstride;
577
247
  int32_t dstride;
578
247
  unsigned int rmult, gmult, bmult, amult;
579
247
  unsigned int rtrunc, gtrunc, btrunc, atrunc;
580
247
  uint32_t x;
581
247
  int32_t y;
582
583
247
  assert(info->width > 0 && info->width <= SHRT_MAX);
584
247
  assert(info->height > 0 && info->height <= SHRT_MAX);
585
586
247
  if (info->compression == BI_NONE)
587
20
    ssp = p;
588
227
  else if (info->compression == BI_RLE4)
589
32
    ssp = decompressed = bmp_decompress_rle4(ctx, info, p, &end);
590
195
  else if (info->compression == BI_RLE8)
591
35
    ssp = decompressed = bmp_decompress_rle8(ctx, info, p, &end);
592
160
  else if (is_win_bmp(info) && (info->compression == BI_BITFIELDS || info->compression == BI_ALPHABITS))
593
160
    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
247
  bitcount = info->bitcount;
602
247
  width = info->width;
603
247
  height = info->height;
604
605
247
  sstride = ((width * bitcount + 31) / 32) * 4;
606
247
  if (ssp + sstride * height > end)
607
172
  {
608
172
    int32_t h = (end - ssp) / sstride;
609
172
    if (h == 0 || h > SHRT_MAX)
610
7
    {
611
7
      fz_free(ctx, decompressed);
612
7
      fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions out of range in bmp image");
613
7
    }
614
172
  }
615
616
480
  fz_try(ctx)
617
480
  {
618
240
    pix = fz_new_pixmap(ctx, info->cs, width, height, NULL, 1);
619
240
    fz_set_pixmap_resolution(ctx, pix, info->xres, info->yres);
620
240
    fz_clear_pixmap(ctx, pix);
621
240
  }
622
480
  fz_catch(ctx)
623
0
  {
624
0
    fz_free(ctx, decompressed);
625
0
    fz_rethrow(ctx);
626
0
  }
627
628
240
  ddp = pix->samples;
629
240
  dstride = pix->stride;
630
240
  if (!info->topdown)
631
189
  {
632
189
    ddp = pix->samples + ((size_t) (height - 1)) * ((size_t) dstride);
633
189
    dstride = -dstride;
634
189
  }
635
636
240
  if (ssp + sstride * height > end)
637
165
  {
638
165
    fz_warn(ctx, "premature end in bitmap data in bmp image");
639
165
    height = (end - ssp) / sstride;
640
165
  }
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
240
  rmult = info->rbits < 8 ? mults[info->rbits] : 1;
652
240
  gmult = info->gbits < 8 ? mults[info->gbits] : 1;
653
240
  bmult = info->bbits < 8 ? mults[info->bbits] : 1;
654
240
  amult = info->abits < 8 ? mults[info->abits] : 1;
655
240
  rtrunc = info->rbits < 8 ? 5 : (info->rbits - 8);
656
240
  gtrunc = info->gbits < 8 ? 5 : (info->gbits - 8);
657
240
  btrunc = info->bbits < 8 ? 5 : (info->bbits - 8);
658
240
  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
128k
  for (y = 0; y < height; y++)
667
128k
  {
668
128k
    const unsigned char *sp = ssp + ((size_t) y) * ((size_t) sstride);
669
128k
    unsigned char *dp = ddp + ((size_t) y) * ((size_t) dstride);
670
671
128k
    switch (bitcount)
672
128k
    {
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.70k
    case 32:
692
13.4k
      for (x = 0; x < width; x++)
693
6.78k
      {
694
6.78k
        uint32_t sample =
695
6.78k
          (((uint32_t) sp[3]) << 24) |
696
6.78k
          (((uint32_t) sp[2]) << 16) |
697
6.78k
          (((uint32_t) sp[1]) <<  8) |
698
6.78k
          (((uint32_t) sp[0]) <<  0);
699
6.78k
        uint32_t r = (sample & info->rmask) >> info->rshift;
700
6.78k
        uint32_t g = (sample & info->gmask) >> info->gshift;
701
6.78k
        uint32_t b = (sample & info->bmask) >> info->bshift;
702
6.78k
        uint32_t a = info->abits == 0 ? 255 : (sample & info->amask) >> info->ashift;
703
6.78k
        *dp++ = (r * rmult) >> rtrunc;
704
6.78k
        *dp++ = (g * gmult) >> gtrunc;
705
6.78k
        *dp++ = (b * bmult) >> btrunc;
706
6.78k
        *dp++ = info->abits == 0 ? a : (a * amult) >> atrunc;
707
6.78k
        sp += 4;
708
6.78k
      }
709
6.70k
      break;
710
242
    case 24:
711
2.02k
      for (x = 0; x < width; x++)
712
1.77k
      {
713
1.77k
        *dp++ = sp[2];
714
1.77k
        *dp++ = sp[1];
715
1.77k
        *dp++ = sp[0];
716
1.77k
        *dp++ = 255;
717
1.77k
        sp += 3;
718
1.77k
      }
719
242
      break;
720
2.71k
    case 16:
721
8.08k
      for (x = 0; x < width; x++)
722
5.37k
      {
723
5.37k
        uint16_t sample =
724
5.37k
          (((uint16_t)sp[1]) << 8) |
725
5.37k
          (((uint16_t)sp[0]) << 0);
726
5.37k
        uint16_t r = (sample & info->rmask) >> info->rshift;
727
5.37k
        uint16_t g = (sample & info->gmask) >> info->gshift;
728
5.37k
        uint16_t b = (sample & info->bmask) >> info->bshift;
729
5.37k
        uint16_t a = (sample & info->amask) >> info->ashift;
730
5.37k
        *dp++ = (r * rmult) >> rtrunc;
731
5.37k
        *dp++ = (g * gmult) >> gtrunc;
732
5.37k
        *dp++ = (b * bmult) >> btrunc;
733
5.37k
        *dp++ = info->abits == 0 ? 255 : (a * amult) >> atrunc;
734
5.37k
        sp += 2;
735
5.37k
      }
736
2.71k
      break;
737
109k
    case 8:
738
192M
      for (x = 0; x < width; x++)
739
191M
      {
740
191M
        *dp++ = info->palette[3 * sp[0] + 0];
741
191M
        *dp++ = info->palette[3 * sp[0] + 1];
742
191M
        *dp++ = info->palette[3 * sp[0] + 2];
743
191M
        *dp++ = 255;
744
191M
        sp++;
745
191M
      }
746
109k
      break;
747
8.64k
    case 4:
748
46.5M
      for (x = 0; x < width; x++)
749
46.5M
      {
750
46.5M
        int idx;
751
46.5M
        switch (x & 1)
752
46.5M
        {
753
23.2M
        case 0: idx = (sp[0] >> 4) & 0x0f; break;
754
23.2M
        case 1: idx = (sp[0] >> 0) & 0x0f; sp++; break;
755
46.5M
        }
756
46.5M
        *dp++ = info->palette[3 * idx + 0];
757
46.5M
        *dp++ = info->palette[3 * idx + 1];
758
46.5M
        *dp++ = info->palette[3 * idx + 2];
759
46.5M
        *dp++ = 255;
760
46.5M
      }
761
8.64k
      break;
762
8.64k
    case 2:
763
80
      for (x = 0; x < width; x++)
764
64
      {
765
64
        int idx;
766
64
        switch (x & 3)
767
64
        {
768
16
        case 0: idx = (sp[0] >> 6) & 0x03; break;
769
16
        case 1: idx = (sp[0] >> 4) & 0x03; break;
770
16
        case 2: idx = (sp[0] >> 2) & 0x03; break;
771
16
        case 3: idx = (sp[0] >> 0) & 0x03; sp++; break;
772
64
        }
773
64
        *dp++ = info->palette[3 * idx + 0];
774
64
        *dp++ = info->palette[3 * idx + 1];
775
64
        *dp++ = info->palette[3 * idx + 2];
776
64
        *dp++ = 255;
777
64
      }
778
16
      break;
779
206
    case 1:
780
1.20k
      for (x = 0; x < width; x++)
781
1.00k
      {
782
1.00k
        int idx;
783
1.00k
        switch (x & 7)
784
1.00k
        {
785
305
        case 0: idx = (sp[0] >> 7) & 0x01; break;
786
100
        case 1: idx = (sp[0] >> 6) & 0x01; break;
787
100
        case 2: idx = (sp[0] >> 5) & 0x01; break;
788
100
        case 3: idx = (sp[0] >> 4) & 0x01; break;
789
99
        case 4: idx = (sp[0] >> 3) & 0x01; break;
790
99
        case 5: idx = (sp[0] >> 2) & 0x01; break;
791
99
        case 6: idx = (sp[0] >> 1) & 0x01; break;
792
99
        case 7: idx = (sp[0] >> 0) & 0x01; sp++; break;
793
1.00k
        }
794
1.00k
        *dp++ = info->palette[3 * idx + 0];
795
1.00k
        *dp++ = info->palette[3 * idx + 1];
796
1.00k
        *dp++ = info->palette[3 * idx + 2];
797
1.00k
        *dp++ = 255;
798
1.00k
      }
799
206
      break;
800
128k
    }
801
128k
  }
802
803
240
  fz_free(ctx, decompressed);
804
240
  fz_premultiply_pixmap(ctx, pix);
805
240
  return pix;
806
240
}
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
163
{
811
163
  if (info->colorspacetype == 0)
812
127
  {
813
127
    float matrix[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
814
127
    float wp[3] = { 0.95047f, 1.0f, 1.08883f }; /* D65 white point */
815
127
    float bp[3] = { 0, 0, 0 };
816
127
    float gamma[3] = { 1, 1, 1 };
817
127
    int i;
818
819
508
    for (i = 0; i < 3; i++)
820
381
      gamma[i] = (float) info->gamma[i] / (float) (1 << 16);
821
1.27k
    for (i = 0; i < 9; i++)
822
1.14k
      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
127
    return fz_new_cal_rgb_colorspace(ctx, wp, bp, gamma, matrix);
834
127
  }
835
36
  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
36
  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
36
  else if (info->colorspacetype == 0x4d424544)
846
14
  {
847
14
    fz_buffer *profile;
848
14
    fz_colorspace *cs;
849
850
14
    if ((uint32_t)(end - begin) <= info->profileoffset)
851
5
    {
852
5
      fz_warn(ctx, "ignoring color profile located outside bmp image");
853
5
      return NULL;
854
5
    }
855
9
    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
7
    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
7
    profile = fz_new_buffer_from_copied_data(ctx, begin + info->profileoffset, info->profilesize);
867
868
14
    fz_try(ctx)
869
14
      cs = fz_new_icc_colorspace(ctx, FZ_COLORSPACE_RGB, 0, "BMPRGB", profile);
870
14
    fz_always(ctx)
871
7
      fz_drop_buffer(ctx, profile);
872
7
    fz_catch(ctx)
873
5
      fz_rethrow(ctx);
874
875
2
    return cs;
876
7
  }
877
22
  else if (info->colorspacetype == 0x73524742)
878
0
  {
879
0
    return fz_keep_colorspace(ctx, fz_device_rgb(ctx));
880
0
  }
881
882
22
  fz_warn(ctx, "ignoring color profile with unknown type in bmp image");
883
22
  return NULL;
884
163
}
885
886
static void
887
compute_mask_info(unsigned int mask, unsigned int *shift, unsigned int *bits)
888
1.14k
{
889
1.14k
  *bits = 0;
890
1.14k
  *shift = 0;
891
892
3.52k
  while (mask && (mask & 1) == 0) {
893
2.38k
    *shift += 1;
894
2.38k
    mask >>= 1;
895
2.38k
  }
896
3.45k
  while (mask && (mask & 1) == 1) {
897
2.30k
    *bits += 1;
898
2.30k
    mask >>= 1;
899
2.30k
  }
900
1.14k
}
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
7
{
905
7
  int size = 0;
906
907
7
  if (info->compression == BI_BITFIELDS)
908
3
  {
909
3
    size = 12;
910
3
    if (end - p < 12)
911
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in mask header in bmp image");
912
913
3
    info->rmask = read32(p + 0);
914
3
    info->gmask = read32(p + 4);
915
3
    info->bmask = read32(p + 8);
916
3
  }
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
7
  return p + size;
930
7
}
931
932
static int
933
bmp_palette_is_gray(fz_context *ctx, struct info *info, int readcolors)
934
75
{
935
75
  int i;
936
117
  for (i = 0; i < readcolors; i++)
937
71
  {
938
71
    int rgdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 1]);
939
71
    int gbdiff = fz_absi(info->palette[3 * i + 1] - info->palette[3 * i + 2]);
940
71
    int rbdiff = fz_absi(info->palette[3 * i + 0] - info->palette[3 * i + 2]);
941
71
    if (rgdiff > 2 || gbdiff > 2 || rbdiff > 2)
942
29
      return 0;
943
71
  }
944
46
  return 1;
945
75
}
946
947
static void
948
bmp_load_default_palette(fz_context *ctx, struct info *info, int readcolors)
949
77
{
950
77
  int i;
951
952
77
  fz_warn(ctx, "color table too short; loading default palette");
953
954
77
  if (info->bitcount == 8)
955
39
  {
956
39
    if (!bmp_palette_is_gray(ctx, info, readcolors))
957
5
      memcpy(&info->palette[readcolors * 3], &web_palette[readcolors * 3],
958
5
          sizeof(web_palette) - readcolors * 3);
959
34
    else
960
8.73k
      for (i = readcolors; i < 256; i++)
961
8.70k
      {
962
8.70k
        info->palette[3 * i + 0] = i;
963
8.70k
        info->palette[3 * i + 1] = i;
964
8.70k
        info->palette[3 * i + 2] = i;
965
8.70k
      }
966
39
  }
967
38
  else if (info->bitcount == 4)
968
36
  {
969
36
    if (!bmp_palette_is_gray(ctx, info, readcolors))
970
24
      memcpy(&info->palette[readcolors * 3], &vga_palette[readcolors * 3],
971
24
          sizeof(vga_palette) - readcolors * 3);
972
12
    else
973
191
      for (i = readcolors; i < 16; i++)
974
179
      {
975
179
        info->palette[3 * i + 0] = (i << 4) | i;
976
179
        info->palette[3 * i + 1] = (i << 4) | i;
977
179
        info->palette[3 * i + 2] = (i << 4) | i;
978
179
      }
979
36
  }
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
77
}
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
13
    expected = info->colors = 1 << info->bitcount;
995
73
  else
996
73
    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
547
  for (i = 0; i < present; i++)
1004
461
  {
1005
    /* ignore alpha channel even if present */
1006
461
    info->palette[3 * i + 0] = read8(p + i * entry_size + 2);
1007
461
    info->palette[3 * i + 1] = read8(p + i * entry_size + 1);
1008
461
    info->palette[3 * i + 2] = read8(p + i * entry_size + 0);
1009
461
  }
1010
1011
86
  if (present < expected)
1012
77
    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
292
{
1020
292
  uint32_t size;
1021
1022
292
  if (end - p < 4)
1023
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "premature end in info header in bmp image");
1024
292
  size = info->version = read32(p + 0);
1025
1026
292
  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
287
  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
287
  info->compression = BI_NONE;
1033
1034
  /* OS/2 1.x or Windows v2 */
1035
287
  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
287
  if (size >= 16)
1045
272
  {
1046
    /* read32(p+0) == header size */
1047
272
    info->width = read32(p + 4);
1048
272
    info->height = read32(p + 8);
1049
    /* read16(p+12) == planes */
1050
272
    info->bitcount = read16(p + 14);
1051
272
  }
1052
1053
  /* default masks */
1054
287
  if (info->bitcount == 16)
1055
86
  {
1056
86
    info->rmask = 0x00007c00;
1057
86
    info->gmask = 0x000003e0;
1058
86
    info->bmask = 0x0000001f;
1059
86
    info->amask = 0x00000000;
1060
86
  }
1061
201
  else if (info->bitcount == 24 || info->bitcount == 32)
1062
96
  {
1063
96
    info->rmask = 0x00ff0000;
1064
96
    info->gmask = 0x0000ff00;
1065
96
    info->bmask = 0x000000ff;
1066
96
    info->amask = 0x00000000;
1067
96
  }
1068
1069
  /* Windows v3 header */
1070
287
  if (size >= 40)
1071
268
  {
1072
268
    info->compression = read32(p + 16);
1073
268
    info->bitmapsize = read32(p + 20);
1074
268
    info->xres = read32(p + 24);
1075
268
    info->yres = read32(p + 28);
1076
268
    info->colors = read32(p + 32);
1077
268
    if (info->bitcount >= 32)
1078
103
    {
1079
103
      if (info->colors != 0)
1080
97
        fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1081
103
      info->colors = 0;
1082
103
    }
1083
165
    else if (info->colors > (1U<<info->bitcount))
1084
134
    {
1085
134
      fz_warn(ctx, "Suspect BMP header; bitcount=%d, colors=%d", info->bitcount, info->colors);
1086
134
      info->colors = 1<<info->bitcount;
1087
134
    }
1088
    /* read32(p+36) == important colors */
1089
268
  }
1090
  /* Windows v3 header with RGB masks */
1091
287
  if (size == 52 || size == 56 || size == 108 || size == 124)
1092
193
  {
1093
193
    info->rmask = read32(p + 40);
1094
193
    info->gmask = read32(p + 44);
1095
193
    info->bmask = read32(p + 48);
1096
193
  }
1097
  /* Windows v3 header with RGBA masks */
1098
287
  if (size == 56 || size == 108 || size == 124)
1099
190
  {
1100
190
    info->amask = read32(p + 52);
1101
190
  }
1102
  /* OS/2 2.x long header */
1103
287
  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
287
  if (size >= 108)
1116
174
  {
1117
174
    info->colorspacetype = read32(p + 56);
1118
1119
174
    info->endpoints[0] = read32(p + 60);
1120
174
    info->endpoints[1] = read32(p + 64);
1121
174
    info->endpoints[2] = read32(p + 68);
1122
1123
174
    info->endpoints[3] = read32(p + 72);
1124
174
    info->endpoints[4] = read32(p + 76);
1125
174
    info->endpoints[5] = read32(p + 80);
1126
1127
174
    info->endpoints[6] = read32(p + 84);
1128
174
    info->endpoints[7] = read32(p + 88);
1129
174
    info->endpoints[8] = read32(p + 92);
1130
1131
174
    info->gamma[0] = read32(p + 96);
1132
174
    info->gamma[1] = read32(p + 100);
1133
174
    info->gamma[2] = read32(p + 104);
1134
174
  }
1135
  /* Windows v5 header */
1136
287
  if (size >= 124)
1137
17
  {
1138
17
    info->intent = read32(p + 108);
1139
17
    info->profileoffset = read32(p + 112);
1140
17
    info->profilesize = read32(p + 116);
1141
    /* read32(p+120) == reserved */
1142
17
  }
1143
1144
287
  return p + size;
1145
287
}
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
292
{
1151
292
  const unsigned char *profilebegin;
1152
1153
292
  memset(info, 0x00, sizeof (*info));
1154
292
  info->colorspacetype = 0xffffffff;
1155
1156
292
  p = profilebegin = bmp_read_file_header(ctx, info, begin, end, p);
1157
1158
292
  p = bmp_read_info_header(ctx, info, begin, end, p);
1159
1160
  /* clamp bitmap offset to buffer size */
1161
292
  if (info->bitmapoffset < (uint32_t)(p - begin))
1162
60
    info->bitmapoffset = (uint32_t)(p - begin);
1163
292
  if ((uint32_t)(end - begin) < info->bitmapoffset)
1164
25
    info->bitmapoffset = end - begin;
1165
1166
292
  if (has_palette(info))
1167
86
    p = bmp_read_palette(ctx, info, begin, end, p);
1168
1169
292
  if (has_color_masks(info))
1170
7
    p = bmp_read_color_masks(ctx, info, begin, end, p);
1171
1172
292
  info->xres = DPM_TO_DPI(info->xres);
1173
292
  info->yres = DPM_TO_DPI(info->yres);
1174
1175
  /* extract topdown/bottomup from height for windows bitmaps */
1176
292
  if (is_win_bmp(info))
1177
280
  {
1178
280
    int bits = info->version == 12 ? 16 : 32;
1179
1180
280
    info->topdown = (info->height >> (bits - 1)) & 1;
1181
280
    if (info->topdown)
1182
56
    {
1183
56
      info->height--;
1184
56
      info->height = ~info->height;
1185
56
      info->height &= bits == 16 ? 0xffff : 0xffffffff;
1186
56
    }
1187
280
  }
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
292
  if (info->version == 108 &&
1195
292
      info->rmask == 0x73524742 && /* colorspacetype */
1196
292
      info->gmask == 0x00000000 && /* endpoints[0] */
1197
292
      info->bmask == 0x00000000 && /* endpoints[1] */
1198
292
      info->amask == 0x00000000 && /* endpoints[2] */
1199
292
      info->colorspacetype == 0x00000000 && /* endpoints[3] */
1200
292
      info->endpoints[0] == 0x00000000 && /* endpoints[4] */
1201
292
      info->endpoints[1] == 0x00000000 && /* endpoints[5] */
1202
292
      info->endpoints[2] == 0x00000000 && /* endpoints[6] */
1203
292
      info->endpoints[3] == 0x00000000 && /* endpoints[7] */
1204
292
      info->endpoints[4] == 0x00000000 && /* endpoints[8] */
1205
292
      info->endpoints[5] == 0x00000000 && /* gamma[0] */
1206
292
      info->endpoints[6] == 0x00000000 && /* gamma[1] */
1207
292
      info->endpoints[7] == 0x00000000 && /* gamma[2] */
1208
292
      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
292
  compute_mask_info(info->rmask, &info->rshift, &info->rbits);
1233
292
  compute_mask_info(info->gmask, &info->gshift, &info->gbits);
1234
292
  compute_mask_info(info->bmask, &info->bshift, &info->bbits);
1235
292
  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
292
  if (info->width == 0 || info->width > SHRT_MAX || info->height == 0 || info->height > SHRT_MAX)
1284
13
    fz_throw(ctx, FZ_ERROR_LIMIT, "image dimensions (%u x %u) out of range in bmp image", info->width, info->height);
1285
279
  if (!is_valid_compression(info))
1286
11
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported compression method (%u) in bmp image", info->compression);
1287
268
  if (!is_valid_bitcount(info))
1288
5
    fz_throw(ctx, FZ_ERROR_FORMAT, "invalid bits per pixel (%u) for compression (%u) in bmp image", info->bitcount, info->compression);
1289
263
  if (info->rbits > info->bitcount)
1290
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit red mask in bmp image", info->rbits);
1291
263
  if (info->gbits > info->bitcount)
1292
2
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit green mask in bmp image", info->gbits);
1293
261
  if (info->bbits > info->bitcount)
1294
1
    fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported %u bit blue mask in bmp image", info->bbits);
1295
260
  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
259
  if (has_color_profile(info))
1300
163
    info->cs = bmp_read_color_profile(ctx, info, profilebegin, end);
1301
259
  if (!info->cs)
1302
120
    info->cs = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
1303
1304
259
  if (only_metadata)
1305
0
    return NULL;
1306
1307
  /* bitmap cannot begin before headers have ended */
1308
259
  if ((uint32_t)(p - begin) < info->bitmapoffset)
1309
16
    p = begin + info->bitmapoffset;
1310
1311
259
  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
259
  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
259
  else
1324
259
    return bmp_read_bitmap(ctx, info, begin, end, p);
1325
259
}
1326
1327
fz_pixmap *
1328
fz_load_bmp_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage)
1329
292
{
1330
292
  const unsigned char *begin = buf;
1331
292
  const unsigned char *end = buf + len;
1332
292
  const unsigned char *p = begin;
1333
292
  struct info info = { 0 };
1334
292
  int nextoffset = 0;
1335
292
  fz_pixmap *image = NULL;
1336
292
  int origidx = subimage;
1337
1338
292
  (void) p;
1339
1340
292
  do
1341
292
  {
1342
292
    p = begin + nextoffset;
1343
1344
292
    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
292
    if (is_bitmap_array(p))
1348
0
    {
1349
      /* read16(p+0) == type */
1350
      /* read32(p+2) == size of this header in bytes */
1351
0
      nextoffset = read32(p + 6);
1352
      /* read16(p+10) == suitable pelx dimensions */
1353
      /* read16(p+12) == suitable pely dimensions */
1354
0
      p += 14;
1355
0
      (void) p;
1356
0
    }
1357
292
    else if (is_bitmap(p))
1358
292
    {
1359
292
      nextoffset = 0;
1360
292
    }
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
292
    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
292
    else
1373
292
      subimage--;
1374
1375
292
  } while (subimage >= 0 && nextoffset > 0);
1376
1377
292
  if (subimage != -1)
1378
0
    fz_throw(ctx, FZ_ERROR_ARGUMENT, "subimage index (%d) out of range in bmp image", origidx);
1379
1380
584
  fz_try(ctx)
1381
584
    image = bmp_read_image(ctx, &info, begin, end, p, 0);
1382
584
  fz_always(ctx)
1383
292
    fz_drop_colorspace(ctx, info.cs);
1384
292
  fz_catch(ctx)
1385
52
    fz_rethrow(ctx);
1386
1387
240
  return image;
1388
292
}
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
292
{
1460
292
  const unsigned char *begin = buf;
1461
292
  const unsigned char *end = buf + len;
1462
292
  uint32_t nextoffset = 0;
1463
292
  int count = 0;
1464
1465
292
  do
1466
292
  {
1467
292
    const unsigned char *p = begin + nextoffset;
1468
1469
292
    if (end - p < 14)
1470
0
      fz_throw(ctx, FZ_ERROR_FORMAT, "not enough data for bitmap array in bmp image");
1471
1472
292
    if (is_bitmap_array(p))
1473
0
    {
1474
      /* read16(p+0) == type */
1475
      /* read32(p+2) == size of this header in bytes */
1476
0
      nextoffset = read32(p + 6);
1477
      /* read16(p+10) == suitable pelx dimensions */
1478
      /* read16(p+12) == suitable pely dimensions */
1479
0
      p += 14;
1480
0
    }
1481
292
    else if (is_bitmap(p))
1482
292
    {
1483
292
      nextoffset = 0;
1484
292
    }
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
292
    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
292
    else
1497
292
      count++;
1498
1499
292
  } while (nextoffset > 0);
1500
1501
292
  return count;
1502
292
}
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
}