Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Unified Diff: src/codec/SkCodec_libbmp.cpp

Issue 1057483003: Handle rewinds in SkBmpCodec. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Initialize codec to defeat warning. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codec/SkCodec_libbmp.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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");
« no previous file with comments | « src/codec/SkCodec_libbmp.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698