summaryrefslogtreecommitdiffstats
path: root/image
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
commitc3b63b831cd2c64700e875b28540212c7c881ac6 (patch)
treeedd98fcbd2004d3b562904f822bf6c3322fc7f52 /image
parentd432e068a21c815d5d5e7bcbc1cc8c6e77a7d1e0 (diff)
parentcc07da9cb4d6e7a53f8d953427ffc2bca2e0c2df (diff)
downloadUXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.gz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.lz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.xz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.zip
Merge branch 'master' into 816
Diffstat (limited to 'image')
-rw-r--r--image/DecoderFactory.cpp7
-rw-r--r--image/DecoderFactory.h1
-rw-r--r--image/decoders/nsBMPDecoder.cpp40
-rw-r--r--image/decoders/nsBMPDecoder.h9
-rw-r--r--image/imgFrame.cpp2
5 files changed, 50 insertions, 9 deletions
diff --git a/image/DecoderFactory.cpp b/image/DecoderFactory.cpp
index 2085fb7c4..dffe4dc21 100644
--- a/image/DecoderFactory.cpp
+++ b/image/DecoderFactory.cpp
@@ -58,6 +58,10 @@ DecoderFactory::GetDecoderType(const char* aMimeType)
} else if (!strcmp(aMimeType, IMAGE_BMP_MS)) {
type = DecoderType::BMP;
+ // BMP_CLIPBOARD
+ } else if (!strcmp(aMimeType, IMAGE_BMP_MS_CLIPBOARD)) {
+ type = DecoderType::BMP_CLIPBOARD;
+
// ICO
} else if (!strcmp(aMimeType, IMAGE_ICO)) {
type = DecoderType::ICO;
@@ -100,6 +104,9 @@ DecoderFactory::GetDecoder(DecoderType aType,
case DecoderType::BMP:
decoder = new nsBMPDecoder(aImage);
break;
+ case DecoderType::BMP_CLIPBOARD:
+ decoder = new nsBMPDecoder(aImage, /* aForClipboard */ true);
+ break;
case DecoderType::ICO:
decoder = new nsICODecoder(aImage);
break;
diff --git a/image/DecoderFactory.h b/image/DecoderFactory.h
index f8cf64cc6..5638789ff 100644
--- a/image/DecoderFactory.h
+++ b/image/DecoderFactory.h
@@ -34,6 +34,7 @@ enum class DecoderType
GIF,
JPEG,
BMP,
+ BMP_CLIPBOARD,
ICO,
ICON,
WEBP,
diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp
index 42bb3486a..b93eb42b6 100644
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -66,6 +66,17 @@
// compression, then instead of treating the pixel data as 0RGB it is treated
// as ARGB, but only if one or more of the A values are non-zero.
//
+// Clipboard variants.
+// - It's the BMP format used for BMP images captured from the clipboard.
+// - It is missing the file header, containing the BM signature and the data
+// offset. Instead the data begins after the header.
+// - If it uses BITFIELDS compression, then there is always an additional 12
+// bytes of data after the header that must be read. In WinBMPv4+, the masks
+// are supposed to be included in the header size, which are the values we use
+// for decoding purposes, but there is additional three masks following the
+// header which must be skipped to get to the pixel data.
+//
+//
// OS/2 VERSIONS OF THE BMP FORMAT
// -------------------------------
// OS2-BMPv1.
@@ -168,10 +179,12 @@ static mozilla::LazyLogModule sBMPLog("BMPDecoder");
// The length of the mBIHSize field in the info header.
static const uint32_t BIHSIZE_FIELD_LENGTH = 4;
-nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength)
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength,
+ bool aForClipboard)
: Decoder(aImage)
, mLexer(Transition::To(aState, aLength), Transition::TerminateSuccess())
, mIsWithinICO(false)
+ , mIsForClipboard(aForClipboard)
, mMayHaveTransparency(false)
, mDoesHaveTransparency(false)
, mNumColors(0)
@@ -185,15 +198,19 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength)
{
}
-// Constructor for normal BMP files.
-nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
- : nsBMPDecoder(aImage, State::FILE_HEADER, FILE_HEADER_LENGTH)
+// Constructor for normal BMP files or from the clipboard.
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, bool aForClipboard)
+ : nsBMPDecoder(aImage,
+ aForClipboard ? State::INFO_HEADER_SIZE : State::FILE_HEADER,
+ aForClipboard ? BIHSIZE_FIELD_LENGTH : FILE_HEADER_LENGTH,
+ aForClipboard)
{
}
// Constructor used for WinBMPv3-ICO files, which lack a file header.
nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset)
- : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH)
+ : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH,
+ /* aForClipboard */ false)
{
SetIsWithinICO();
@@ -598,6 +615,13 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
// Bitfields are present in the info header, so we can read them
// immediately.
mBitFields.ReadFromHeader(aData + 36, /* aReadAlpha = */ true);
+
+ // If this came from the clipboard, then we know that even if the header
+ // explicitly includes the bitfield masks, we need to add an additional
+ // offset for the start of the RGB data.
+ if (mIsForClipboard) {
+ mH.mDataOffset += BitFields::LENGTH;
+ }
} else {
// Bitfields are present after the info header, so we will read them in
// ReadBitfields().
@@ -712,6 +736,12 @@ nsBMPDecoder::ReadColorTable(const char* aData, size_t aLength)
aData += mBytesPerColor;
}
+ // If we are decoding a BMP from the clipboard, we did not know the data
+ // offset in advance. It is defined as just after the header and color table.
+ if (mIsForClipboard) {
+ mH.mDataOffset += mPreGapLength;
+ }
+
// We know how many bytes we've read so far (mPreGapLength) and we know the
// offset of the pixel data (mH.mDataOffset), so we can determine the length
// of the gap (possibly zero) between the color table and the pixel data.
diff --git a/image/decoders/nsBMPDecoder.h b/image/decoders/nsBMPDecoder.h
index 0cf2af689..4b9568487 100644
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -164,14 +164,14 @@ private:
RLE_ABSOLUTE
};
- // This is the constructor used for normal BMP images.
- explicit nsBMPDecoder(RasterImage* aImage);
+ // This is the constructor used for normal and clipboard BMP images.
+ explicit nsBMPDecoder(RasterImage* aImage, bool aForClipboard = false);
// This is the constructor used for BMP resources in ICO images.
nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
// Helper constructor called by the other two.
- nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength);
+ nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength, bool aForClipboard);
int32_t AbsoluteHeight() const { return abs(mH.mHeight); }
@@ -198,6 +198,9 @@ private:
// If the BMP is within an ICO file our treatment of it differs slightly.
bool mIsWithinICO;
+ // If the BMP is decoded from the clipboard, we start with a data offset.
+ bool mIsForClipboard;
+
bmp::BitFields mBitFields;
// Might the image have transparency? Determined from the headers during
diff --git a/image/imgFrame.cpp b/image/imgFrame.cpp
index c9f44181d..d982c17c4 100644
--- a/image/imgFrame.cpp
+++ b/image/imgFrame.cpp
@@ -161,13 +161,13 @@ imgFrame::imgFrame()
: mMonitor("imgFrame")
, mDecoded(0, 0, 0, 0)
, mLockCount(0)
+ , mHasNoAlpha(false)
, mAborted(false)
, mFinished(false)
, mOptimizable(false)
, mTimeout(FrameTimeout::FromRawMilliseconds(100))
, mDisposalMethod(DisposalMethod::NOT_SPECIFIED)
, mBlendMethod(BlendMethod::OVER)
- , mHasNoAlpha(false)
, mPalettedImageData(nullptr)
, mPaletteDepth(0)
, mNonPremult(false)