149 {
150
151
152
153 uint32_t totalBytes;
154
156
157 uint32_t infoBytes;
158
159
161
165 SkCodecPrintf(
"Error: unable to read first bitmap header.\n");
167 }
168
169 totalBytes =
get_int(hBuffer, 2);
172 SkCodecPrintf(
"Error: invalid starting location for pixel data\n");
174 }
175
176
177
178
179 infoBytes =
get_int(hBuffer, 14);
183 }
184 } else {
185
186
187
188 totalBytes = 0;
189
190
191
192
194
195
196 uint8_t hBuffer[4];
198 SkCodecPrintf(
"Error: unable to read size of second bitmap header.\n");
200 }
201 infoBytes =
get_int(hBuffer, 0);
205 }
206 }
207
208
212 }
213
214
215 const uint32_t infoBytesRemaining = infoBytes - 4;
216
217
218 std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
219 if (
stream->
read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
220 SkCodecPrintf(
"Error: unable to read second bitmap header.\n");
222 }
223
224
226
227
229
230
231 uint32_t numColors = 0;
232
233
234 uint32_t bytesPerColor;
235
236
238
239 switch (headerType) {
246
247
248
253
254
255
256 if (infoBytesRemaining >= 16) {
257 compression =
get_int(iBuffer.get(), 12);
258 if (infoBytesRemaining >= 32) {
259 numColors =
get_int(iBuffer.get(), 28);
260 }
261 }
262
263
264
265 bytesPerColor = 4;
266 break;
268
272 bytesPerColor = 3;
273 break;
275
278 }
279
280
283
284 if (
height == INT32_MIN) {
286 }
287
290 }
291
292
295 }
296
297
298 constexpr int kMaxDim = 1 << 16;
299 if (
width <= 0 || height <= 0 || width >= kMaxDim ||
height >= kMaxDim) {
302 }
303
304
307
308
309 uint32_t maskBytes = 0;
311 switch (compression) {
314
315
316
317
318
319
321 inputMasks.
red = 0x7C00;
322 inputMasks.
green = 0x03E0;
323 inputMasks.
blue = 0x001F;
325 }
326 break;
329 SkCodecPrintf(
"Warning: correcting invalid bitmap format.\n");
331 }
333 break;
336 SkCodecPrintf(
"Warning: correcting invalid bitmap format.\n");
338 }
340 break;
343
345 switch (headerType) {
347
352 }
357 break;
358 }
363
364
365
370
373 break;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
391 break;
393
394
395
396
399 default:
402 }
403 break;
407 break;
408 }
409 [[fallthrough]];
411
412
413
419
420 SkCodecPrintf(
"Error: CMYK not supported for bitmap decoding.\n");
422 default:
423 SkCodecPrintf(
"Error: invalid format for bitmap decoding.\n");
425 }
426 iBuffer.reset();
427
428
431
432
433
434 SkCodecPrintf(
"Error: pixel data offset less than header size.\n");
436 }
437
438
439
440 switch (inputFormat) {
442
443
444
445
448 bool isOpaque = true;
449
451 uint8_t bitsPerComponent;
453
454 case 1:
455 case 2:
456 case 4:
457 case 8:
458
459
462 bitsPerComponent = 8;
463 } else {
466 }
467 break;
468 case 24:
469
470
472 bitsPerComponent = 8;
473 break;
474 case 32:
475
476
478 isOpaque = false;
481 } else {
483 }
484 bitsPerComponent = 8;
485 break;
486 default:
487 SkCodecPrintf(
"Error: invalid input value for bits per pixel.\n");
489 }
490
491 if (codecOut) {
492
494
495
497 *codecOut = std::make_unique<SkBmpStandardCodec>(std::move(
info),
498 std::unique_ptr<SkStream>(
stream),
500 offset - bytesRead, rowOrder, isOpaque,
504 }
506 }
507
509
513 }
514
516 case 16:
517 case 24:
518 case 32:
519 break;
520 default:
521 SkCodecPrintf(
"Error: invalid input value for bits per pixel.\n");
523 }
524
525
526
527
531 }
532
533 if (codecOut) {
534
537 if (nullptr == masks) {
540 }
541
542
543
544
545
548 if (masks->getAlphaMask()) {
551 } else {
554 }
556 *codecOut = std::make_unique<SkBmpMaskCodec>(std::move(
info),
558 masks.release(), rowOrder);
559 return static_cast<SkBmpMaskCodec*
>(codecOut->get())->didCreateSrcBuffer()
561 }
563 }
564
566
568
569
570 if (totalBytes <=
offset) {
573 }
574
575
576
577
578
580
581 if (codecOut) {
582
583
584
585
588 *codecOut = std::make_unique<SkBmpRLECodec>(std::move(
info),
590 numColors, bytesPerColor,
offset - bytesRead,
591 rowOrder);
592 }
594 }
595 default:
598 }
599}
static constexpr uint32_t kBmpHeaderBytes
static constexpr uint32_t kBmpHeaderBytesPlusFour
static BmpHeaderType get_header_type(size_t infoBytes)
static constexpr uint32_t kBmpOS2V1Bytes
@ kCMYK8BitRLE_BmpCompressionMethod
@ kAlphaBitMasks_BmpCompressionMethod
@ k8BitRLE_BmpCompressionMethod
@ k4BitRLE_BmpCompressionMethod
@ kCMYK_BmpCompressionMethod
@ kBitMasks_BmpCompressionMethod
@ kJpeg_BmpCompressionMethod
@ kNone_BmpCompressionMethod
@ kPng_BmpCompressionMethod
@ kCMYK4BitRLE_BmpCompressionMethod
static constexpr uint32_t kBmpMaskBytes
@ kUnknown_BmpInputFormat
@ kBitMask_BmpInputFormat
@ kStandard_BmpInputFormat
static uint32_t get_int(const uint8_t *buffer, uint32_t i)
#define SkCodecPrintf(...)
static uint16_t get_short(const uint8_t *buffer, uint32_t i)
static SkMasks * CreateMasks(InputMasks masks, int bytesPerPixel)
virtual const void * getMemoryBase()
virtual size_t read(void *buffer, size_t size)=0
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)