aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkBmpCodec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec/SkBmpCodec.cpp')
-rw-r--r--src/codec/SkBmpCodec.cpp83
1 files changed, 39 insertions, 44 deletions
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index 3e224c13a9..70397f656f 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -67,16 +67,16 @@ bool SkBmpCodec::IsBmp(const void* buffer, size_t bytesRead) {
* Creates a bmp decoder
* Reads enough of the stream to determine the image format
*/
-SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
- return SkBmpCodec::NewFromStream(stream, false);
+SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, Result* result) {
+ return SkBmpCodec::NewFromStream(stream, result, false);
}
/*
* Creates a bmp decoder for a bmp embedded in ico
* Reads enough of the stream to determine the image format
*/
-SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
- return SkBmpCodec::NewFromStream(stream, true);
+SkCodec* SkBmpCodec::NewFromIco(SkStream* stream, Result* result) {
+ return SkBmpCodec::NewFromStream(stream, result, true);
}
// Header size constants
@@ -132,14 +132,7 @@ static BmpHeaderType get_header_type(size_t infoBytes) {
}
}
-/*
- * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
- * representing success or failure. If it returned true, and codecOut was
- * not nullptr, it will be set to a new SkBmpCodec.
- * If codecOut is set to a new SkCodec, it will take ownership of the stream.
- * Otherwise, the stream will not be deleted.
- */
-bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
+SkCodec::Result SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
std::unique_ptr<SkCodec>* codecOut) {
// The total bytes in the bmp file
// We only need to use this value for RLE decoding, so we will only
@@ -157,14 +150,14 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
kBmpHeaderBytesPlusFour) {
SkCodecPrintf("Error: unable to read first bitmap header.\n");
- return false;
+ return kIncompleteInput;
}
totalBytes = get_int(hBuffer, 2);
offset = get_int(hBuffer, 10);
if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
SkCodecPrintf("Error: invalid starting location for pixel data\n");
- return false;
+ return kInvalidInput;
}
// The size of the second (info) header in bytes
@@ -173,7 +166,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
infoBytes = get_int(hBuffer, 14);
if (infoBytes < kBmpOS2V1Bytes) {
SkCodecPrintf("Error: invalid second header size.\n");
- return false;
+ return kInvalidInput;
}
} else {
// This value is only used by RLE compression. Bmp in Ico files do not
@@ -190,19 +183,19 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
uint8_t hBuffer[4];
if (stream->read(hBuffer, 4) != 4) {
SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
- return false;
+ return kIncompleteInput;
}
infoBytes = get_int(hBuffer, 0);
if (infoBytes < kBmpOS2V1Bytes) {
SkCodecPrintf("Error: invalid second header size.\n");
- return false;
+ return kInvalidInput;
}
}
// Determine image information depending on second header format
const BmpHeaderType headerType = get_header_type(infoBytes);
if (kUnknown_BmpHeaderType == headerType) {
- return false;
+ return kInvalidInput;
}
// We already read the first four bytes of the info header to get the size
@@ -212,7 +205,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
SkCodecPrintf("Error: unable to read second bitmap header.\n");
- return false;
+ return kIncompleteInput;
}
// The number of bits used per pixel in the pixel data
@@ -268,7 +261,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
case kUnknown_BmpHeaderType:
// We'll exit above in this case.
SkASSERT(false);
- return false;
+ return kInvalidInput;
}
// Check for valid dimensions from header
@@ -287,7 +280,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
constexpr int kMaxDim = 1 << 16;
if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
SkCodecPrintf("Error: invalid bitmap dimensions.\n");
- return false;
+ return kInvalidInput;
}
// Create mask struct
@@ -337,7 +330,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
uint8_t buffer[kBmpMaskBytes];
if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
SkCodecPrintf("Error: unable to read bit inputMasks.\n");
- return false;
+ return kIncompleteInput;
}
maskBytes = kBmpMaskBytes;
inputMasks.red = get_int(buffer, 0);
@@ -384,10 +377,10 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
// in chromium. I have not come across a test case
// that uses this format.
SkCodecPrintf("Error: huffman format unsupported.\n");
- return false;
+ return kUnimplemented;
default:
SkCodecPrintf("Error: invalid bmp bit masks header.\n");
- return false;
+ return kInvalidInput;
}
break;
case kJpeg_BmpCompressionMethod:
@@ -401,16 +394,16 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
// 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 false;
+ return kUnimplemented;
case kCMYK_BmpCompressionMethod:
case kCMYK8BitRLE_BmpCompressionMethod:
case kCMYK4BitRLE_BmpCompressionMethod:
// TODO: Same as above.
SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
- return false;
+ return kUnimplemented;
default:
SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
- return false;
+ return kInvalidInput;
}
iBuffer.reset();
@@ -421,7 +414,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
// Seems like we can just assume that the offset is zero and try to decode?
// Maybe we don't want to try to decode corrupt images?
SkCodecPrintf("Error: pixel data offset less than header size.\n");
- return false;
+ return kInvalidInput;
}
@@ -474,7 +467,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
break;
default:
SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
- return false;
+ return kInvalidInput;
}
if (codecOut) {
@@ -486,16 +479,17 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
codecOut->reset(new SkBmpStandardCodec(width, height, info, stream, bitsPerPixel,
numColors, bytesPerColor, offset - bytesRead,
rowOrder, isOpaque, inIco));
- return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer();
+ return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
+ ? kSuccess : kInvalidInput;
}
- return true;
+ return kSuccess;
}
case kBitMask_BmpInputFormat: {
// Bmp-in-Ico must be standard mode
if (inIco) {
SkCodecPrintf("Error: Icos may not use bit mask format.\n");
- return false;
+ return kInvalidInput;
}
switch (bitsPerPixel) {
@@ -505,7 +499,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
break;
default:
SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
- return false;
+ return kInvalidInput;
}
// Skip to the start of the pixel array.
@@ -513,7 +507,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
// in bit mask mode.
if (stream->skip(offset - bytesRead) != offset - bytesRead) {
SkCodecPrintf("Error: unable to skip to image data.\n");
- return false;
+ return kIncompleteInput;
}
if (codecOut) {
@@ -521,7 +515,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
if (nullptr == masks) {
SkCodecPrintf("Error: invalid input masks.\n");
- return false;
+ return kInvalidInput;
}
// Masked bmps are not a great fit for SkEncodedInfo, since they have
@@ -540,9 +534,10 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
const SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8);
codecOut->reset(new SkBmpMaskCodec(width, height, info, stream, bitsPerPixel,
masks.release(), rowOrder));
- return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer();
+ return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
+ ? kSuccess : kInvalidInput;
}
- return true;
+ return kSuccess;
}
case kRLE_BmpInputFormat: {
@@ -552,7 +547,7 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
// Check for a valid number of total bytes when in RLE mode
if (totalBytes <= offset) {
SkCodecPrintf("Error: RLE requires valid input size.\n");
- return false;
+ return kInvalidInput;
}
// Bmp-in-Ico must be standard mode
@@ -572,11 +567,11 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
numColors, bytesPerColor, offset - bytesRead,
rowOrder));
}
- return true;
+ return kSuccess;
}
default:
SkASSERT(false);
- return false;
+ return kInvalidInput;
}
}
@@ -584,16 +579,16 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
* Creates a bmp decoder
* Reads enough of the stream to determine the image format
*/
-SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool inIco) {
+SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, Result* result, bool inIco) {
std::unique_ptr<SkStream> streamDeleter(stream);
std::unique_ptr<SkCodec> codec;
- bool success = ReadHeader(stream, inIco, &codec);
+ *result = ReadHeader(stream, inIco, &codec);
if (codec) {
// codec has taken ownership of stream, so we do not need to
// delete it.
streamDeleter.release();
}
- return success ? codec.release() : nullptr;
+ return kSuccess == *result ? codec.release() : nullptr;
}
SkBmpCodec::SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
@@ -606,7 +601,7 @@ SkBmpCodec::SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStrea
{}
bool SkBmpCodec::onRewind() {
- return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr);
+ return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr) == kSuccess;
}
int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {