OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBmpCodec.h" | 8 #include "SkBmpCodec.h" |
9 #include "SkBmpMaskCodec.h" | 9 #include "SkBmpMaskCodec.h" |
10 #include "SkBmpRLECodec.h" | 10 #include "SkBmpRLECodec.h" |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 // Check for a valid number of total bytes when in RLE mode | 450 // Check for a valid number of total bytes when in RLE mode |
451 if (totalBytes <= offset && kRLE_BmpInputFormat == inputFormat) { | 451 if (totalBytes <= offset && kRLE_BmpInputFormat == inputFormat) { |
452 SkCodecPrintf("Error: RLE requires valid input size.\n"); | 452 SkCodecPrintf("Error: RLE requires valid input size.\n"); |
453 return false; | 453 return false; |
454 } | 454 } |
455 const size_t RLEBytes = totalBytes - offset; | 455 const size_t RLEBytes = totalBytes - offset; |
456 | 456 |
457 // Calculate the number of bytes read so far | 457 // Calculate the number of bytes read so far |
458 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes; | 458 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes; |
459 if (!inIco && offset < bytesRead) { | 459 if (!inIco && offset < bytesRead) { |
460 // TODO (msarett): Do we really want to fail if the offset in the header is invalid? | |
461 // Seems like we can just assume that the offset is zero and try to decode? | |
462 // Maybe we don't want to try to decode corrupt images? | |
scroggo
2015/09/01 21:31:25
All good questions. I think we should support an i
| |
460 SkCodecPrintf("Error: pixel data offset less than header size.\n"); | 463 SkCodecPrintf("Error: pixel data offset less than header size.\n"); |
461 return false; | 464 return false; |
462 } | 465 } |
463 | 466 |
467 // Skip to the start of the pixel array. | |
468 // We can do this here because there is no color table to read | |
469 // in bit mask mode. | |
470 if (!inIco && kBitMask_BmpInputFormat == inputFormat) { | |
471 if (stream->skip(offset - bytesRead) != offset - bytesRead) { | |
472 SkCodecPrintf("Error: unable to skip to image data.\n"); | |
473 return false; | |
474 } | |
475 } | |
476 | |
464 if (codecOut) { | 477 if (codecOut) { |
465 // Set the image info | 478 // Set the image info |
466 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, | 479 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, |
467 colorType, alphaType); | 480 colorType, alphaType); |
468 | 481 |
469 // Return the codec | 482 // Return the codec |
470 switch (inputFormat) { | 483 switch (inputFormat) { |
471 case kStandard_BmpInputFormat: | 484 case kStandard_BmpInputFormat: |
472 *codecOut = | 485 *codecOut = new SkBmpStandardCodec(imageInfo, stream, bitsPerPix el, numColors, |
473 new SkBmpStandardCodec(imageInfo, stream, bitsPerPixel, numColors, | 486 bytesPerColor, offset - bytesRead, rowOrder, inIco); |
474 bytesPerColor, offset - bytesRead , rowOrder, inIco); | |
475 return true; | 487 return true; |
476 case kBitMask_BmpInputFormat: | 488 case kBitMask_BmpInputFormat: |
477 // Bmp-in-Ico must be standard mode | 489 // Bmp-in-Ico must be standard mode |
478 if (inIco) { | 490 if (inIco) { |
479 SkCodecPrintf("Error: Icos may not use bit mask format.\n"); | 491 SkCodecPrintf("Error: Icos may not use bit mask format.\n"); |
480 return false; | 492 return false; |
481 } | 493 } |
482 // Skip to the start of the pixel array. | |
483 // We can do this here because there is no color table to read | |
484 // in bit mask mode. | |
485 if (stream->skip(offset - bytesRead) != offset - bytesRead) { | |
486 SkCodecPrintf("Error: unable to skip to image data.\n"); | |
487 return false; | |
488 } | |
489 | 494 |
490 *codecOut = new SkBmpMaskCodec(imageInfo, stream, bitsPerPixel, masks.detach(), | 495 *codecOut = new SkBmpMaskCodec(imageInfo, stream, bitsPerPixel, masks.detach(), |
491 rowOrder); | 496 rowOrder); |
492 return true; | 497 return true; |
493 case kRLE_BmpInputFormat: | 498 case kRLE_BmpInputFormat: |
494 // Bmp-in-Ico must be standard mode | 499 // Bmp-in-Ico must be standard mode |
495 // When inIco is true, this line cannot be reached, since we | 500 // When inIco is true, this line cannot be reached, since we |
496 // require that RLE Bmps have a valid number of totalBytes, and | 501 // require that RLE Bmps have a valid number of totalBytes, and |
497 // Icos skip the header that contains totalBytes. | 502 // Icos skip the header that contains totalBytes. |
498 SkASSERT(!inIco); | 503 SkASSERT(!inIco); |
499 *codecOut = | 504 *codecOut = new SkBmpRLECodec(imageInfo, stream, bitsPerPixel, n umColors, |
500 new SkBmpRLECodec(imageInfo, stream, bitsPerPixel, numCo lors, bytesPerColor, | 505 bytesPerColor, offset - bytesRead, rowOrder, RLEBytes); |
501 offset - bytesRead, rowOrder, RLEBytes ); | |
502 return true; | 506 return true; |
503 default: | 507 default: |
504 SkASSERT(false); | 508 SkASSERT(false); |
505 return false; | 509 return false; |
506 } | 510 } |
507 } | 511 } |
508 | 512 |
509 return true; | 513 return true; |
510 } | 514 } |
511 | 515 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
631 }; | 635 }; |
632 | 636 |
633 SkScanlineDecoder* SkBmpCodec::NewSDFromStream(SkStream* stream) { | 637 SkScanlineDecoder* SkBmpCodec::NewSDFromStream(SkStream* stream) { |
634 SkAutoTDelete<SkBmpCodec> codec(static_cast<SkBmpCodec*>(SkBmpCodec::NewFrom Stream(stream))); | 638 SkAutoTDelete<SkBmpCodec> codec(static_cast<SkBmpCodec*>(SkBmpCodec::NewFrom Stream(stream))); |
635 if (!codec) { | 639 if (!codec) { |
636 return NULL; | 640 return NULL; |
637 } | 641 } |
638 | 642 |
639 return SkNEW_ARGS(SkBmpScanlineDecoder, (codec.detach())); | 643 return SkNEW_ARGS(SkBmpScanlineDecoder, (codec.detach())); |
640 } | 644 } |
OLD | NEW |