summaryrefslogtreecommitdiffstats
path: root/widget
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-02-07 22:06:24 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-02-07 22:06:24 +0100
commit6992106dc7894fab3f620263e99b4083b36bf9e8 (patch)
tree2a3554cf7bfabfeee0cc56ca58b04773a902cb76 /widget
parent0b6d9a47051be9ef4d064c6f7c60717da91d0bc2 (diff)
downloadUXP-6992106dc7894fab3f620263e99b4083b36bf9e8.tar
UXP-6992106dc7894fab3f620263e99b4083b36bf9e8.tar.gz
UXP-6992106dc7894fab3f620263e99b4083b36bf9e8.tar.lz
UXP-6992106dc7894fab3f620263e99b4083b36bf9e8.tar.xz
UXP-6992106dc7894fab3f620263e99b4083b36bf9e8.zip
Use existing image decoders to handle clipboard BMP data.
This gets rid of the old nsImageClipboard widget code in favor of using the nsBMPDecoder in imglib.
Diffstat (limited to 'widget')
-rw-r--r--widget/windows/moz.build1
-rw-r--r--widget/windows/nsClipboard.cpp47
-rw-r--r--widget/windows/nsDataObj.cpp126
-rw-r--r--widget/windows/nsImageClipboard.cpp497
-rw-r--r--widget/windows/nsImageClipboard.h93
-rw-r--r--widget/windows/nsNativeThemeWin.cpp2
6 files changed, 120 insertions, 646 deletions
diff --git a/widget/windows/moz.build b/widget/windows/moz.build
index 1e7fc4b02..4a449de95 100644
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -41,7 +41,6 @@ UNIFIED_SOURCES += [
'nsDataObjCollection.cpp',
'nsDragService.cpp',
'nsIdleServiceWin.cpp',
- 'nsImageClipboard.cpp',
'nsLookAndFeel.cpp',
'nsNativeDragSource.cpp',
'nsNativeDragTarget.cpp',
diff --git a/widget/windows/nsClipboard.cpp b/widget/windows/nsClipboard.cpp
index 432badeb5..c93f351c8 100644
--- a/widget/windows/nsClipboard.cpp
+++ b/widget/windows/nsClipboard.cpp
@@ -26,7 +26,6 @@
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "nsPrimitiveHelpers.h"
-#include "nsImageClipboard.h"
#include "nsIWidget.h"
#include "nsIComponentManager.h"
#include "nsWidgetsCID.h"
@@ -36,6 +35,8 @@
#include "nsIOutputStream.h"
#include "nsEscape.h"
#include "nsIObserverService.h"
+#include "nsMimeTypes.h"
+#include "imgITools.h"
using mozilla::LogLevel;
@@ -474,17 +475,45 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
if (aMIMEImageFormat)
{
uint32_t allocLen = 0;
- unsigned char * clipboardData;
+ const char * clipboardData;
if (NS_SUCCEEDED(GetGlobalData(stm.hGlobal, (void **)&clipboardData, &allocLen)))
{
- nsImageFromClipboard converter;
- nsIInputStream * inputStream;
- converter.GetEncodedImageStream(clipboardData, aMIMEImageFormat, &inputStream); // addrefs for us, don't release
- if ( inputStream ) {
- *aData = inputStream;
- *aLen = sizeof(nsIInputStream*);
- result = NS_OK;
+ nsCOMPtr<imgIContainer> container;
+ nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+ nsCOMPtr<nsIInputStream> inputStream;
+ nsresult rv = NS_NewByteInputStream(getter_AddRefs(inputStream),
+ clipboardData,
+ allocLen,
+ NS_ASSIGNMENT_DEPEND);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ result = imgTools->DecodeImage(inputStream,
+ NS_LITERAL_CSTRING(IMAGE_BMP_MS_CLIPBOARD),
+ getter_AddRefs(container));
+ if (NS_FAILED(result)) {
+ break;
}
+
+ nsAutoCString mimeType;
+ if (strcmp(aMIMEImageFormat, kJPGImageMime) == 0) {
+ mimeType.Assign(IMAGE_JPEG);
+ } else {
+ mimeType.Assign(aMIMEImageFormat);
+ }
+
+ result = imgTools->EncodeImage(container, mimeType, EmptyString(),
+ getter_AddRefs(inputStream));
+ if (NS_FAILED(result)) {
+ break;
+ }
+
+ if (!inputStream) {
+ result = NS_ERROR_FAILURE;
+ break;
+ }
+
+ *aData = inputStream.forget().take();
+ *aLen = sizeof(nsIInputStream*);
}
} break;
diff --git a/widget/windows/nsDataObj.cpp b/widget/windows/nsDataObj.cpp
index 977a87c08..ee2db7b65 100644
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -17,7 +17,6 @@
#include "IEnumFE.h"
#include "nsPrimitiveHelpers.h"
#include "nsXPIDLString.h"
-#include "nsImageClipboard.h"
#include "nsCRT.h"
#include "nsPrintfCString.h"
#include "nsIStringBundle.h"
@@ -35,6 +34,8 @@
#include "nsIContentPolicy.h"
#include "nsContentUtils.h"
#include "nsIPrincipal.h"
+#include "nsMimeTypes.h"
+#include "imgITools.h"
#include "WinUtils.h"
#include "mozilla/LazyIdleThread.h"
@@ -45,6 +46,7 @@
using namespace mozilla;
using namespace mozilla::widget;
+#define BFH_LENGTH 14
#define DEFAULT_THREAD_TIMEOUT_MS 30000
NS_IMPL_ISUPPORTS(nsDataObj::CStream, nsIStreamListener)
@@ -917,20 +919,60 @@ nsDataObj::GetDib(const nsACString& inFlavor,
}
if ( image ) {
- // use the |nsImageToClipboard| helper class to build up a bitmap. We now own
- // the bits, and pass them back to the OS in |aSTG|.
- nsImageToClipboard converter(image, aFormat.cfFormat == CF_DIBV5);
- HANDLE bits = nullptr;
- nsresult rv = converter.GetPicture ( &bits );
- if ( NS_SUCCEEDED(rv) && bits ) {
- aSTG.hGlobal = bits;
- aSTG.tymed = TYMED_HGLOBAL;
- result = S_OK;
+ nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+
+ nsAutoString options;
+ if (aFormat.cfFormat == CF_DIBV5) {
+ options.AppendLiteral("version=5");
+ } else {
+ options.AppendLiteral("version=3");
+ }
+
+ nsCOMPtr<nsIInputStream> inputStream;
+ nsresult rv = imgTools->EncodeImage(image, NS_LITERAL_CSTRING(IMAGE_BMP),
+ options, getter_AddRefs(inputStream));
+ if (NS_FAILED(rv) || !inputStream) {
+ return E_FAIL;
}
- } // if we have an image
- else
+
+ nsCOMPtr<imgIEncoder> encoder = do_QueryInterface(inputStream);
+ if (!encoder) {
+ return E_FAIL;
+ }
+
+ uint32_t size = 0;
+ rv = encoder->GetImageBufferUsed(&size);
+ if (NS_FAILED(rv) || size <= BFH_LENGTH) {
+ return E_FAIL;
+ }
+
+ char *src = nullptr;
+ rv = encoder->GetImageBuffer(&src);
+ if (NS_FAILED(rv) || !src) {
+ return E_FAIL;
+ }
+
+ // We don't want the file header.
+ src += BFH_LENGTH;
+ size -= BFH_LENGTH;
+
+ HGLOBAL glob = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
+ if (!glob) {
+ DWORD err = ::GetLastError();
+ return E_FAIL;
+ }
+
+ char *dst = (char*) ::GlobalLock(glob);
+ ::CopyMemory(dst, src, size);
+ ::GlobalUnlock(glob);
+
+ aSTG.hGlobal = glob;
+ aSTG.tymed = TYMED_HGLOBAL;
+ result = S_OK;
+ } else {
NS_WARNING ( "Definitely not an image on clipboard" );
- return result;
+ }
+ return result;
}
@@ -1535,18 +1577,29 @@ HRESULT nsDataObj::DropImage(FORMATETC& aFE, STGMEDIUM& aSTG)
if (!image)
return E_FAIL;
- // Use the clipboard helper class to build up a memory bitmap.
- nsImageToClipboard converter(image);
- HANDLE bits = nullptr;
- rv = converter.GetPicture(&bits); // Clipboard routines return a global handle we own.
+ nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+ nsCOMPtr<nsIInputStream> inputStream;
+ rv = imgTools->EncodeImage(image, NS_LITERAL_CSTRING(IMAGE_BMP),
+ NS_LITERAL_STRING("version=3"),
+ getter_AddRefs(inputStream));
+ if (NS_FAILED(rv) || !inputStream) {
+ return E_FAIL;
+ }
+
+ nsCOMPtr<imgIEncoder> encoder = do_QueryInterface(inputStream);
+ if (!encoder) {
+ return E_FAIL;
+ }
- if (NS_FAILED(rv) || !bits)
+ uint32_t size = 0;
+ rv = encoder->GetImageBufferUsed(&size);
+ if (NS_FAILED(rv)) {
return E_FAIL;
+ }
- // We now own these bits!
- uint32_t bitmapSize = GlobalSize(bits);
- if (!bitmapSize) {
- GlobalFree(bits);
+ char *src = nullptr;
+ rv = encoder->GetImageBuffer(&src);
+ if (NS_FAILED(rv) || !src) {
return E_FAIL;
}
@@ -1554,7 +1607,6 @@ HRESULT nsDataObj::DropImage(FORMATETC& aFE, STGMEDIUM& aSTG)
nsCOMPtr<nsIFile> dropFile;
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(dropFile));
if (!dropFile) {
- GlobalFree(bits);
return E_FAIL;
}
@@ -1568,7 +1620,6 @@ HRESULT nsDataObj::DropImage(FORMATETC& aFE, STGMEDIUM& aSTG)
dropFile->AppendNative(filename);
rv = dropFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0660);
if (NS_FAILED(rv)) {
- GlobalFree(bits);
return E_FAIL;
}
@@ -1581,33 +1632,16 @@ HRESULT nsDataObj::DropImage(FORMATETC& aFE, STGMEDIUM& aSTG)
nsCOMPtr<nsIOutputStream> outStream;
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), dropFile);
if (NS_FAILED(rv)) {
- GlobalFree(bits);
return E_FAIL;
}
- char * bm = (char *)GlobalLock(bits);
-
- BITMAPFILEHEADER fileHdr;
- BITMAPINFOHEADER *bmpHdr = (BITMAPINFOHEADER*)bm;
-
- fileHdr.bfType = ((WORD) ('M' << 8) | 'B');
- fileHdr.bfSize = GlobalSize (bits) + sizeof(fileHdr);
- fileHdr.bfReserved1 = 0;
- fileHdr.bfReserved2 = 0;
- fileHdr.bfOffBits = (DWORD) (sizeof(fileHdr) + bmpHdr->biSize);
-
- uint32_t writeCount = 0;
- if (NS_FAILED(outStream->Write((const char *)&fileHdr, sizeof(fileHdr), &writeCount)) ||
- NS_FAILED(outStream->Write((const char *)bm, bitmapSize, &writeCount)))
- rv = NS_ERROR_FAILURE;
+ uint32_t written = 0;
+ rv = outStream->Write(src, size, &written);
+ if (NS_FAILED(rv) || written != size) {
+ return E_FAIL;
+ }
outStream->Close();
-
- GlobalUnlock(bits);
- GlobalFree(bits);
-
- if (NS_FAILED(rv))
- return E_FAIL;
}
// Pass the file name back to the drop target so that it can access the file.
diff --git a/widget/windows/nsImageClipboard.cpp b/widget/windows/nsImageClipboard.cpp
deleted file mode 100644
index fab62eab5..000000000
--- a/widget/windows/nsImageClipboard.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsImageClipboard.h"
-
-#include "gfxUtils.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/gfx/DataSurfaceHelpers.h"
-#include "mozilla/RefPtr.h"
-#include "nsITransferable.h"
-#include "nsGfxCIID.h"
-#include "nsMemory.h"
-#include "prmem.h"
-#include "imgIEncoder.h"
-#include "nsLiteralString.h"
-#include "nsComponentManagerUtils.h"
-
-#define BFH_LENGTH 14
-
-using namespace mozilla;
-using namespace mozilla::gfx;
-
-/* Things To Do 11/8/00
-
-Check image metrics, can we support them? Do we need to?
-Any other render format? HTML?
-
-*/
-
-
-//
-// nsImageToClipboard ctor
-//
-// Given an imgIContainer, convert it to a DIB that is ready to go on the win32 clipboard
-//
-nsImageToClipboard::nsImageToClipboard(imgIContainer* aInImage, bool aWantDIBV5)
- : mImage(aInImage)
- , mWantDIBV5(aWantDIBV5)
-{
- // nothing to do here
-}
-
-
-//
-// nsImageToClipboard dtor
-//
-// Clean up after ourselves. We know that we have created the bitmap
-// successfully if we still have a pointer to the header.
-//
-nsImageToClipboard::~nsImageToClipboard()
-{
-}
-
-
-//
-// GetPicture
-//
-// Call to get the actual bits that go on the clipboard. If an error
-// ocurred during conversion, |outBits| will be null.
-//
-// NOTE: The caller owns the handle and must delete it with ::GlobalRelease()
-//
-nsresult
-nsImageToClipboard :: GetPicture ( HANDLE* outBits )
-{
- NS_ASSERTION ( outBits, "Bad parameter" );
-
- return CreateFromImage ( mImage, outBits );
-
-} // GetPicture
-
-
-//
-// CalcSize
-//
-// Computes # of bytes needed by a bitmap with the specified attributes.
-//
-int32_t
-nsImageToClipboard :: CalcSize ( int32_t aHeight, int32_t aColors, WORD aBitsPerPixel, int32_t aSpanBytes )
-{
- int32_t HeaderMem = sizeof(BITMAPINFOHEADER);
-
- // add size of pallette to header size
- if (aBitsPerPixel < 16)
- HeaderMem += aColors * sizeof(RGBQUAD);
-
- if (aHeight < 0)
- aHeight = -aHeight;
-
- return (HeaderMem + (aHeight * aSpanBytes));
-}
-
-
-//
-// CalcSpanLength
-//
-// Computes the span bytes for determining the overall size of the image
-//
-int32_t
-nsImageToClipboard::CalcSpanLength(uint32_t aWidth, uint32_t aBitCount)
-{
- int32_t spanBytes = (aWidth * aBitCount) >> 5;
-
- if ((aWidth * aBitCount) & 0x1F)
- spanBytes++;
- spanBytes <<= 2;
-
- return spanBytes;
-}
-
-
-//
-// CreateFromImage
-//
-// Do the work to setup the bitmap header and copy the bits out of the
-// image.
-//
-nsresult
-nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap )
-{
- nsresult rv;
- *outBitmap = nullptr;
-
- RefPtr<SourceSurface> surface =
- inImage->GetFrame(imgIContainer::FRAME_CURRENT,
- imgIContainer::FLAG_SYNC_DECODE);
- NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
-
- MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
- surface->GetFormat() == SurfaceFormat::B8G8R8X8);
-
- RefPtr<DataSourceSurface> dataSurface;
- if (surface->GetFormat() == SurfaceFormat::B8G8R8A8) {
- dataSurface = surface->GetDataSurface();
- } else {
- // XXXjwatt Bug 995923 - get rid of this copy and handle B8G8R8X8
- // directly below once bug 995807 is fixed.
- dataSurface = gfxUtils::
- CopySurfaceToDataSourceSurfaceWithFormat(surface,
- SurfaceFormat::B8G8R8A8);
- }
- NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
-
- nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- uint32_t format;
- nsAutoString options;
- if (mWantDIBV5) {
- options.AppendLiteral("version=5;bpp=");
- } else {
- options.AppendLiteral("version=3;bpp=");
- }
- switch (dataSurface->GetFormat()) {
- case SurfaceFormat::B8G8R8A8:
- format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
- options.AppendInt(32);
- break;
-#if 0
- // XXXjwatt Bug 995923 - fix |format| and reenable once bug 995807 is fixed.
- case SurfaceFormat::B8G8R8X8:
- format = imgIEncoder::INPUT_FORMAT_RGB;
- options.AppendInt(24);
- break;
-#endif
- default:
- NS_NOTREACHED("Unexpected surface format");
- return NS_ERROR_INVALID_ARG;
- }
-
- DataSourceSurface::MappedSurface map;
- bool mappedOK = dataSurface->Map(DataSourceSurface::MapType::READ, &map);
- NS_ENSURE_TRUE(mappedOK, NS_ERROR_FAILURE);
-
- rv = encoder->InitFromData(map.mData, 0,
- dataSurface->GetSize().width,
- dataSurface->GetSize().height,
- map.mStride,
- format, options);
- dataSurface->Unmap();
- NS_ENSURE_SUCCESS(rv, rv);
-
- uint32_t size;
- encoder->GetImageBufferUsed(&size);
- NS_ENSURE_TRUE(size > BFH_LENGTH, NS_ERROR_FAILURE);
- HGLOBAL glob = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT,
- size - BFH_LENGTH);
- if (!glob)
- return NS_ERROR_OUT_OF_MEMORY;
-
- char *dst = (char*) ::GlobalLock(glob);
- char *src;
- rv = encoder->GetImageBuffer(&src);
- NS_ENSURE_SUCCESS(rv, rv);
-
- ::CopyMemory(dst, src + BFH_LENGTH, size - BFH_LENGTH);
- ::GlobalUnlock(glob);
-
- *outBitmap = (HANDLE)glob;
- return NS_OK;
-}
-
-nsImageFromClipboard :: nsImageFromClipboard ()
-{
- // nothing to do here
-}
-
-nsImageFromClipboard :: ~nsImageFromClipboard ( )
-{
-}
-
-//
-// GetEncodedImageStream
-//
-// Take the raw clipboard image data and convert it to aMIMEFormat in the form of a nsIInputStream
-//
-nsresult
-nsImageFromClipboard ::GetEncodedImageStream (unsigned char * aClipboardData, const char * aMIMEFormat, nsIInputStream** aInputStream )
-{
- NS_ENSURE_ARG_POINTER (aInputStream);
- NS_ENSURE_ARG_POINTER (aMIMEFormat);
- nsresult rv;
- *aInputStream = nullptr;
-
- // pull the size information out of the BITMAPINFO header and
- // initialize the image
- BITMAPINFO* header = (BITMAPINFO *) aClipboardData;
- int32_t width = header->bmiHeader.biWidth;
- int32_t height = header->bmiHeader.biHeight;
- // neg. heights mean the Y axis is inverted and we don't handle that case
- NS_ENSURE_TRUE(height > 0, NS_ERROR_FAILURE);
-
- unsigned char * rgbData = new unsigned char[width * height * 3 /* RGB */];
-
- if (rgbData) {
- BYTE * pGlobal = (BYTE *) aClipboardData;
- // Convert the clipboard image into RGB packed pixel data
- rv = ConvertColorBitMap((unsigned char *) (pGlobal + header->bmiHeader.biSize), header, rgbData);
- // if that succeeded, encode the bitmap as aMIMEFormat data. Don't return early or we risk leaking rgbData
- if (NS_SUCCEEDED(rv)) {
- nsAutoCString encoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type="));
-
- // Map image/jpg to image/jpeg (which is how the encoder is registered).
- if (strcmp(aMIMEFormat, kJPGImageMime) == 0)
- encoderCID.AppendLiteral("image/jpeg");
- else
- encoderCID.Append(aMIMEFormat);
- nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get(), &rv);
- if (NS_SUCCEEDED(rv)){
- rv = encoder->InitFromData(rgbData, 0, width, height, 3 * width /* RGB * # pixels in a row */,
- imgIEncoder::INPUT_FORMAT_RGB, EmptyString());
- if (NS_SUCCEEDED(rv)) {
- encoder.forget(aInputStream);
- }
- }
- }
- delete [] rgbData;
- }
- else
- rv = NS_ERROR_OUT_OF_MEMORY;
-
- return rv;
-} // GetImage
-
-//
-// InvertRows
-//
-// Take the image data from the clipboard and invert the rows. Modifying aInitialBuffer in place.
-//
-void
-nsImageFromClipboard::InvertRows(unsigned char * aInitialBuffer, uint32_t aSizeOfBuffer, uint32_t aNumBytesPerRow)
-{
- if (!aNumBytesPerRow)
- return;
-
- uint32_t numRows = aSizeOfBuffer / aNumBytesPerRow;
- unsigned char * row = new unsigned char[aNumBytesPerRow];
-
- uint32_t currentRow = 0;
- uint32_t lastRow = (numRows - 1) * aNumBytesPerRow;
- while (currentRow < lastRow)
- {
- // store the current row into a temporary buffer
- memcpy(row, &aInitialBuffer[currentRow], aNumBytesPerRow);
- memcpy(&aInitialBuffer[currentRow], &aInitialBuffer[lastRow], aNumBytesPerRow);
- memcpy(&aInitialBuffer[lastRow], row, aNumBytesPerRow);
- lastRow -= aNumBytesPerRow;
- currentRow += aNumBytesPerRow;
- }
-
- delete[] row;
-}
-
-//
-// ConvertColorBitMap
-//
-// Takes the clipboard bitmap and converts it into a RGB packed pixel values.
-//
-nsresult
-nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer)
-{
- uint8_t bitCount = pBitMapInfo->bmiHeader.biBitCount;
- uint32_t imageSize = pBitMapInfo->bmiHeader.biSizeImage; // may be zero for BI_RGB bitmaps which means we need to calculate by hand
- uint32_t bytesPerPixel = bitCount / 8;
-
- if (bitCount <= 4)
- bytesPerPixel = 1;
-
- // rows are DWORD aligned. Calculate how many real bytes are in each row in the bitmap. This number won't
- // correspond to biWidth.
- uint32_t rowSize = (bitCount * pBitMapInfo->bmiHeader.biWidth + 7) / 8; // +7 to round up
- if (rowSize % 4)
- rowSize += (4 - (rowSize % 4)); // Pad to DWORD Boundary
-
- // if our buffer includes a color map, skip over it
- if (bitCount <= 8)
- {
- int32_t bytesToSkip = (pBitMapInfo->bmiHeader.biClrUsed ? pBitMapInfo->bmiHeader.biClrUsed : (1 << bitCount) ) * sizeof(RGBQUAD);
- aInputBuffer += bytesToSkip;
- }
-
- bitFields colorMasks; // only used if biCompression == BI_BITFIELDS
-
- if (pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS)
- {
- // color table consists of 3 DWORDS containing the color masks...
- colorMasks.red = (*((uint32_t*)&(pBitMapInfo->bmiColors[0])));
- colorMasks.green = (*((uint32_t*)&(pBitMapInfo->bmiColors[1])));
- colorMasks.blue = (*((uint32_t*)&(pBitMapInfo->bmiColors[2])));
- CalcBitShift(&colorMasks);
- aInputBuffer += 3 * sizeof(DWORD);
- }
- else if (pBitMapInfo->bmiHeader.biCompression == BI_RGB && !imageSize) // BI_RGB can have a size of zero which means we figure it out
- {
- // XXX: note use rowSize here and not biWidth. rowSize accounts for the DWORD padding for each row
- imageSize = rowSize * pBitMapInfo->bmiHeader.biHeight;
- }
-
- // The windows clipboard image format inverts the rows
- InvertRows(aInputBuffer, imageSize, rowSize);
-
- if (!pBitMapInfo->bmiHeader.biCompression || pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS)
- {
- uint32_t index = 0;
- uint32_t writeIndex = 0;
-
- unsigned char redValue, greenValue, blueValue;
- uint8_t colorTableEntry = 0;
- int8_t bit; // used for grayscale bitmaps where each bit is a pixel
- uint32_t numPixelsLeftInRow = pBitMapInfo->bmiHeader.biWidth; // how many more pixels do we still need to read for the current row
- uint32_t pos = 0;
-
- while (index < imageSize)
- {
- switch (bitCount)
- {
- case 1:
- for (bit = 7; bit >= 0 && numPixelsLeftInRow; bit--)
- {
- colorTableEntry = (aInputBuffer[index] >> bit) & 1;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
- numPixelsLeftInRow--;
- }
- pos += 1;
- break;
- case 4:
- {
- // each aInputBuffer[index] entry contains data for two pixels.
- // read the first pixel
- colorTableEntry = aInputBuffer[index] >> 4;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
- numPixelsLeftInRow--;
-
- if (numPixelsLeftInRow) // now read the second pixel
- {
- colorTableEntry = aInputBuffer[index] & 0xF;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
- numPixelsLeftInRow--;
- }
- pos += 1;
- }
- break;
- case 8:
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbRed;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbGreen;
- aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbBlue;
- numPixelsLeftInRow--;
- pos += 1;
- break;
- case 16:
- {
- uint16_t num = 0;
- num = (uint8_t) aInputBuffer[index+1];
- num <<= 8;
- num |= (uint8_t) aInputBuffer[index];
-
- redValue = ((uint32_t) (((float)(num & 0xf800) / 0xf800) * 0xFF0000) & 0xFF0000)>> 16;
- greenValue = ((uint32_t)(((float)(num & 0x07E0) / 0x07E0) * 0x00FF00) & 0x00FF00)>> 8;
- blueValue = ((uint32_t)(((float)(num & 0x001F) / 0x001F) * 0x0000FF) & 0x0000FF);
-
- // now we have the right RGB values...
- aOutBuffer[writeIndex++] = redValue;
- aOutBuffer[writeIndex++] = greenValue;
- aOutBuffer[writeIndex++] = blueValue;
- numPixelsLeftInRow--;
- pos += 2;
- }
- break;
- case 32:
- case 24:
- if (pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS)
- {
- uint32_t val = *((uint32_t*) (aInputBuffer + index) );
- aOutBuffer[writeIndex++] = (val & colorMasks.red) >> colorMasks.redRightShift << colorMasks.redLeftShift;
- aOutBuffer[writeIndex++] = (val & colorMasks.green) >> colorMasks.greenRightShift << colorMasks.greenLeftShift;
- aOutBuffer[writeIndex++] = (val & colorMasks.blue) >> colorMasks.blueRightShift << colorMasks.blueLeftShift;
- numPixelsLeftInRow--;
- pos += 4; // we read in 4 bytes of data in order to process this pixel
- }
- else
- {
- aOutBuffer[writeIndex++] = aInputBuffer[index+2];
- aOutBuffer[writeIndex++] = aInputBuffer[index+1];
- aOutBuffer[writeIndex++] = aInputBuffer[index];
- numPixelsLeftInRow--;
- pos += bytesPerPixel; // 3 bytes for 24 bit data, 4 bytes for 32 bit data (we skip over the 4th byte)...
- }
- break;
- default:
- // This is probably the wrong place to check this...
- return NS_ERROR_FAILURE;
- }
-
- index += bytesPerPixel; // increment our loop counter
-
- if (!numPixelsLeftInRow)
- {
- if (rowSize != pos)
- {
- // advance index to skip over remaining padding bytes
- index += (rowSize - pos);
- }
- numPixelsLeftInRow = pBitMapInfo->bmiHeader.biWidth;
- pos = 0;
- }
-
- } // while we still have bytes to process
- }
-
- return NS_OK;
-}
-
-void nsImageFromClipboard::CalcBitmask(uint32_t aMask, uint8_t& aBegin, uint8_t& aLength)
-{
- // find the rightmost 1
- uint8_t pos;
- bool started = false;
- aBegin = aLength = 0;
- for (pos = 0; pos <= 31; pos++)
- {
- if (!started && (aMask & (1 << pos)))
- {
- aBegin = pos;
- started = true;
- }
- else if (started && !(aMask & (1 << pos)))
- {
- aLength = pos - aBegin;
- break;
- }
- }
-}
-
-void nsImageFromClipboard::CalcBitShift(bitFields * aColorMask)
-{
- uint8_t begin, length;
- // red
- CalcBitmask(aColorMask->red, begin, length);
- aColorMask->redRightShift = begin;
- aColorMask->redLeftShift = 8 - length;
- // green
- CalcBitmask(aColorMask->green, begin, length);
- aColorMask->greenRightShift = begin;
- aColorMask->greenLeftShift = 8 - length;
- // blue
- CalcBitmask(aColorMask->blue, begin, length);
- aColorMask->blueRightShift = begin;
- aColorMask->blueLeftShift = 8 - length;
-}
diff --git a/widget/windows/nsImageClipboard.h b/widget/windows/nsImageClipboard.h
deleted file mode 100644
index 25b33cc56..000000000
--- a/widget/windows/nsImageClipboard.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsImageClipboard_h
-#define nsImageClipboard_h
-
-/* Things To Do 11/8/00
-
-Check image metrics, can we support them? Do we need to?
-Any other render format? HTML?
-
-*/
-
-#include "nsError.h"
-#include <windows.h>
-
-#include "nsCOMPtr.h"
-#include "imgIContainer.h"
-#include "nsIInputStream.h"
-
-
-//
-// nsImageToClipboard
-//
-// A utility class that takes an imgIContainer and does all the bitmap magic
-// to allow us to put it on the clipboard
-//
-class nsImageToClipboard
-{
-public:
- nsImageToClipboard(imgIContainer* aInImage, bool aWantDIBV5 = true);
- ~nsImageToClipboard();
-
- // Call to get the actual bits that go on the clipboard. If |nullptr|, the
- // setup operations have failed.
- //
- // NOTE: The caller owns the handle and must delete it with ::GlobalRelease()
- nsresult GetPicture ( HANDLE* outBits ) ;
-
-private:
-
- // Computes # of bytes needed by a bitmap with the specified attributes.
- int32_t CalcSize(int32_t aHeight, int32_t aColors, WORD aBitsPerPixel, int32_t aSpanBytes);
- int32_t CalcSpanLength(uint32_t aWidth, uint32_t aBitCount);
-
- // Do the work
- nsresult CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap );
-
- nsCOMPtr<imgIContainer> mImage; // the image we're working with
- bool mWantDIBV5;
-
-}; // class nsImageToClipboard
-
-
-struct bitFields {
- uint32_t red;
- uint32_t green;
- uint32_t blue;
- uint8_t redLeftShift;
- uint8_t redRightShift;
- uint8_t greenLeftShift;
- uint8_t greenRightShift;
- uint8_t blueLeftShift;
- uint8_t blueRightShift;
-};
-
-//
-// nsImageFromClipboard
-//
-// A utility class that takes a DIB from the win32 clipboard and does
-// all the bitmap magic to convert it to a PNG or a JPEG in the form of a nsIInputStream
-//
-class nsImageFromClipboard
-{
-public:
- nsImageFromClipboard () ;
- ~nsImageFromClipboard ( ) ;
-
- // Retrieve the newly created image
- nsresult GetEncodedImageStream (unsigned char * aClipboardData, const char * aMIMEFormat, nsIInputStream** outImage);
-
-private:
-
- void InvertRows(unsigned char * aInitialBuffer, uint32_t aSizeOfBuffer, uint32_t aNumBytesPerRow);
- nsresult ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer);
- void CalcBitmask(uint32_t aMask, uint8_t& aBegin, uint8_t& aLength);
- void CalcBitShift(bitFields * aColorMask);
-
-}; // nsImageFromClipboard
-
-#endif
diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp
index 475ebce94..e84a2b80c 100644
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -8,6 +8,7 @@
#include "mozilla/EventStates.h"
#include "mozilla/Logging.h"
#include "mozilla/WindowsVersion.h"
+#include "mozilla/gfx/Types.h" // for Color::FromABGR
#include "nsDeviceContext.h"
#include "nsRenderingContext.h"
#include "nsRect.h"
@@ -40,6 +41,7 @@
#include <algorithm>
using namespace mozilla;
+using namespace mozilla::gfx;
using namespace mozilla::widget;
extern mozilla::LazyLogModule gWindowsLog;