| Index: src/codec/SkCodec_libbmp.cpp
|
| diff --git a/src/codec/SkCodec_libbmp.cpp b/src/codec/SkCodec_libbmp.cpp
|
| index 25f54597c2250a4d00c0e75e38dd7c1269b4cbc7..75c5715bda1df787b6e503c3346a1a172590bde7 100644
|
| --- a/src/codec/SkCodec_libbmp.cpp
|
| +++ b/src/codec/SkCodec_libbmp.cpp
|
| @@ -105,11 +105,12 @@ SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
|
|
|
| /*
|
| *
|
| - * Creates a bmp decoder
|
| - * Reads enough of the stream to determine the image format
|
| + * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
|
| + * representing success or failure. If it returned true, and codecOut was
|
| + * not NULL, it will be set to a new SkBmpCodec.
|
| *
|
| */
|
| -SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| +bool SkBmpCodec::ReadHeader(SkStream* stream, bool isIco, SkCodec** codecOut) {
|
| // Header size constants
|
| static const uint32_t kBmpHeaderBytes = 14;
|
| static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
|
| @@ -140,14 +141,14 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
|
| kBmpHeaderBytesPlusFour) {
|
| SkCodecPrintf("Error: unable to read first bitmap header.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| totalBytes = get_int(hBuffer.get(), 2);
|
| offset = get_int(hBuffer.get(), 10);
|
| if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
|
| SkCodecPrintf("Error: invalid starting location for pixel data\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // The size of the second (info) header in bytes
|
| @@ -156,7 +157,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| infoBytes = get_int(hBuffer.get(), 14);
|
| if (infoBytes < kBmpOS2V1Bytes) {
|
| SkCodecPrintf("Error: invalid second header size.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| } else {
|
| // This value is only used by RLE compression. Bmp in Ico files do not
|
| @@ -174,12 +175,12 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| SkNEW_ARRAY(uint8_t, 4));
|
| if (stream->read(hBuffer.get(), 4) != 4) {
|
| SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| infoBytes = get_int(hBuffer.get(), 0);
|
| if (infoBytes < kBmpOS2V1Bytes) {
|
| SkCodecPrintf("Error: invalid second header size.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| }
|
|
|
| @@ -191,7 +192,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| SkNEW_ARRAY(uint8_t, infoBytesRemaining));
|
| if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
|
| SkCodecPrintf("Error: unable to read second bitmap header.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // The number of bits used per pixel in the pixel data
|
| @@ -282,7 +283,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| } else {
|
| // There are no valid bmp headers
|
| SkCodecPrintf("Error: second bitmap header size is invalid.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // Check for valid dimensions from header
|
| @@ -300,7 +301,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| if (width < 0 || width >= kBmpMaxDim || height >= kBmpMaxDim) {
|
| // TODO: Decide if we want to support really large bmps.
|
| SkCodecPrintf("Error: invalid bitmap dimensions.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // Create mask struct
|
| @@ -340,7 +341,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
|
| kBmpMaskBytes) {
|
| SkCodecPrintf("Error: unable to read bit inputMasks.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| maskBytes = kBmpMaskBytes;
|
| inputMasks.red = get_int(mBuffer.get(), 0);
|
| @@ -366,10 +367,10 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| // in chromium. I have not come across a test case
|
| // that uses this format.
|
| SkCodecPrintf("Error: huffman format unsupported.\n");
|
| - return NULL;
|
| + return false;
|
| default:
|
| SkCodecPrintf("Error: invalid bmp bit masks header.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| break;
|
| case kJpeg_BitmapCompressionMethod:
|
| @@ -383,16 +384,16 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| // It is unsupported in the previous version and
|
| // in chromium. I think it is used mostly for printers.
|
| SkCodecPrintf("Error: compression format not supported.\n");
|
| - return NULL;
|
| + return false;
|
| case kCMYK_BitmapCompressionMethod:
|
| case kCMYK8BitRLE_BitmapCompressionMethod:
|
| case kCMYK4BitRLE_BitmapCompressionMethod:
|
| // TODO: Same as above.
|
| SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
|
| - return NULL;
|
| + return false;
|
| default:
|
| SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // Most versions of bmps should be rendered as opaque. Either they do
|
| @@ -447,7 +448,7 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| break;
|
| default:
|
| SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // Check that input bit masks are valid and create the masks object
|
| @@ -455,13 +456,13 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
|
| if (NULL == masks) {
|
| SkCodecPrintf("Error: invalid input masks.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| // Check for a valid number of total bytes when in RLE mode
|
| if (totalBytes <= offset && kRLE_BitmapInputFormat == inputFormat) {
|
| SkCodecPrintf("Error: RLE requires valid input size.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
| const size_t RLEBytes = totalBytes - offset;
|
|
|
| @@ -469,19 +470,37 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
|
| if (!isIco && offset < bytesRead) {
|
| SkCodecPrintf("Error: pixel data offset less than header size.\n");
|
| - return NULL;
|
| + return false;
|
| }
|
|
|
| - // Return the codec
|
| - // We will use ImageInfo to store width, height, and alpha type. We will
|
| - // set color type to kN32_SkColorType because that should be the default
|
| - // output.
|
| - const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
|
| - kN32_SkColorType, alphaType);
|
| - return SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
|
| - inputFormat, masks.detach(), numColors,
|
| - bytesPerColor, offset - bytesRead,
|
| - rowOrder, RLEBytes, isIco));
|
| + if (codecOut) {
|
| + // Return the codec
|
| + // We will use ImageInfo to store width, height, and alpha type. We
|
| + // will set color type to kN32_SkColorType because that should be the
|
| + // default output.
|
| + const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
|
| + kN32_SkColorType, alphaType);
|
| + *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
|
| + inputFormat, masks.detach(),
|
| + numColors, bytesPerColor,
|
| + offset - bytesRead, rowOrder,
|
| + RLEBytes, isIco));
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +/*
|
| + *
|
| + * Creates a bmp decoder
|
| + * Reads enough of the stream to determine the image format
|
| + *
|
| + */
|
| +SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
|
| + SkCodec* codec = NULL;
|
| + if (ReadHeader(stream, isIco, &codec)) {
|
| + return codec;
|
| + }
|
| + return NULL;
|
| }
|
|
|
| /*
|
| @@ -523,7 +542,9 @@ SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
|
| if (rewindState == kCouldNotRewind_RewindState) {
|
| return kCouldNotRewind;
|
| } else if (rewindState == kRewound_RewindState) {
|
| - return kCouldNotRewind; // TODO(msarett): handle rewinds
|
| + if (!ReadHeader(this->stream(), fIsIco, NULL)) {
|
| + return kCouldNotRewind;
|
| + }
|
| }
|
| if (dstInfo.dimensions() != this->getInfo().dimensions()) {
|
| SkCodecPrintf("Error: scaling not supported.\n");
|
|
|