summaryrefslogtreecommitdiffstats
path: root/widget/windows/nsDataObj.cpp
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/windows/nsDataObj.cpp
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/windows/nsDataObj.cpp')
-rw-r--r--widget/windows/nsDataObj.cpp126
1 files changed, 80 insertions, 46 deletions
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.