root/dwt/dnd/ImageTransfer.d

Revision 320:da968414c383, 7.7 kB (checked in by Frank Benoit <benoit@tionex.de>, 2 months ago)

Merge changes SWT 3.4.1

Line 
1 /*******************************************************************************
2  * Copyright (c) 2007, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 module dwt.dnd.ImageTransfer;
12
13 import dwt.DWT;
14 import dwt.graphics.Image;
15 import dwt.graphics.ImageData;
16 import dwt.graphics.RGB;
17 import dwt.internal.win32.OS;
18 import dwt.internal.ole.win32.COM;
19 import dwt.internal.ole.win32.OBJIDL;
20
21 import dwt.dnd.ByteArrayTransfer;
22 import dwt.dnd.TransferData;
23 import dwt.dnd.DND;
24
25 import dwt.dwthelper.utils;
26
27 /**
28  * The class <code>ImageTransfer</code> provides a platform specific mechanism
29  * for converting an Image represented as a java <code>ImageData</code> to a
30  * platform specific representation of the data and vice versa.
31  *
32  * <p>An example of a java <code>ImageData</code> is shown below:</p>
33  *
34  * <code><pre>
35  *     Image image = new Image(display, "C:\temp\img1.gif");
36  *     ImageData imgData = image.getImageData();
37  * </code></pre>
38  *
39  * @see Transfer
40  *
41  * @since 3.4
42  */
43 public class ImageTransfer : ByteArrayTransfer {
44
45     private static ImageTransfer _instance;
46     private static const String CF_DIB = "CF_DIB"; //$NON-NLS-1$
47     private static const int CF_DIBID = COM.CF_DIB;
48
49 static this(){
50      _instance = new ImageTransfer();
51 }
52
53 private this() {
54 }
55
56 /**
57  * Returns the singleton instance of the ImageTransfer class.
58  *
59  * @return the singleton instance of the ImageTransfer class
60  */
61 public static ImageTransfer getInstance () {
62     return _instance;
63 }
64
65 /**
66  * This implementation of <code>javaToNative</code> converts an ImageData object represented
67  * by java <code>ImageData</code> to a platform specific representation.
68  *
69  * @param object a java <code>ImageData</code> containing the ImageData to be converted
70  * @param transferData an empty <code>TransferData</code> object that will
71  *      be filled in on return with the platform specific format of the data
72  *
73  * @see Transfer#nativeToJava
74  */
75 public void javaToNative(Object object, TransferData transferData) {
76     if (!checkImage(object) || !isSupportedType(transferData)) {
77         DND.error(DND.ERROR_INVALID_DATA);
78     }
79     ImageData imgData = cast(ImageData)object;
80     if (imgData is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
81
82     int imageSize = imgData.data.length;
83     int imageHeight = imgData.height;
84     int bytesPerLine = imgData.bytesPerLine;
85
86     BITMAPINFOHEADER bmiHeader;
87     bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
88     bmiHeader.biSizeImage = imageSize;
89     bmiHeader.biWidth = imgData.width;
90     bmiHeader.biHeight = imageHeight;
91     bmiHeader.biPlanes = 1;
92     bmiHeader.biBitCount = cast(short)imgData.depth;
93     bmiHeader.biCompression = OS.DIB_RGB_COLORS;
94
95     int colorSize = 0;
96     if (bmiHeader.biBitCount <= 8) {
97         colorSize += (1 << bmiHeader.biBitCount) * 4;
98     }
99     byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + colorSize];
100     OS.MoveMemory(bmi.ptr, &bmiHeader, BITMAPINFOHEADER.sizeof);
101
102     RGB[] rgbs = imgData.palette.getRGBs();
103     if (rgbs !is null && colorSize > 0) {
104         int offset = BITMAPINFOHEADER.sizeof;
105         for (int j = 0; j < rgbs.length; j++) {
106             bmi[offset] = cast(byte)rgbs[j].blue;
107             bmi[offset + 1] = cast(byte)rgbs[j].green;
108             bmi[offset + 2] = cast(byte)rgbs[j].red;
109             bmi[offset + 3] = 0;
110             offset += 4;
111         }
112     }
113     auto newPtr = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, BITMAPINFOHEADER.sizeof + colorSize + imageSize);
114     OS.MoveMemory(newPtr, bmi.ptr, bmi.length);
115     auto pBitDest = newPtr + BITMAPINFOHEADER.sizeof + colorSize;
116
117     if (imageHeight <= 0) {
118         OS.MoveMemory(pBitDest, imgData.data.ptr, imageSize);
119     } else {
120         int offset = 0;
121         pBitDest += bytesPerLine * (imageHeight - 1);
122         byte[] scanline = new byte[bytesPerLine];
123         for (int i = 0; i < imageHeight; i++) {
124             System.arraycopy(imgData.data, offset, scanline, 0, bytesPerLine);
125             OS.MoveMemory(pBitDest, scanline.ptr, bytesPerLine);
126             offset += bytesPerLine;
127             pBitDest -= bytesPerLine;
128         }
129     }
130     transferData.stgmedium = new STGMEDIUM();
131     transferData.stgmedium.tymed = COM.TYMED_HGLOBAL;
132     transferData.stgmedium.unionField = newPtr;
133     transferData.stgmedium.pUnkForRelease = null;
134     transferData.result = COM.S_OK;
135 }
136
137
138 /**
139  * This implementation of <code>nativeToJava</code> converts a platform specific
140  * representation of an image to java <code>ImageData</code>.
141  *
142  * @param transferData the platform specific representation of the data to be converted
143  * @return a java <code>ImageData</code> of the image if the conversion was successful;
144  *      otherwise null
145  *
146  * @see Transfer#javaToNative
147  */
148 public Object nativeToJava(TransferData transferData) {
149     if (!isSupportedType(transferData) || transferData.pIDataObject is null) return null;
150     IDataObject dataObject = cast(IDataObject)(transferData.pIDataObject);
151     dataObject.AddRef();
152     FORMATETC* formatetc = new FORMATETC();
153     formatetc.cfFormat = COM.CF_DIB;
154     formatetc.ptd = null;
155     formatetc.dwAspect = COM.DVASPECT_CONTENT;
156     formatetc.lindex = -1;
157     formatetc.tymed = COM.TYMED_HGLOBAL;
158     STGMEDIUM* stgmedium = new STGMEDIUM();
159     stgmedium.tymed = COM.TYMED_HGLOBAL;
160     transferData.result = getData(dataObject, formatetc, stgmedium);
161
162     if (transferData.result !is COM.S_OK) return null;
163     HANDLE hMem = stgmedium.unionField;
164     dataObject.Release();
165     try {
166         auto ptr = OS.GlobalLock(hMem);
167         if (ptr is null) return null;
168         try {
169             BITMAPINFOHEADER bmiHeader;
170             OS.MoveMemory(&bmiHeader, ptr, BITMAPINFOHEADER.sizeof);
171             void* pBits;
172             auto memDib = OS.CreateDIBSection(null,  cast(BITMAPINFO*)ptr, OS.DIB_RGB_COLORS, &pBits, null, 0);
173             if (memDib is null) DWT.error(DWT.ERROR_NO_HANDLES);
174             void* bits = ptr + bmiHeader.biSize;
175             if (bmiHeader.biBitCount <= 8) {
176                 bits += (1 << bmiHeader.biBitCount) * 4;
177             } else if (bmiHeader.biCompression is OS.BI_BITFIELDS) {
178                 bits += 12;
179             }
180             if (bmiHeader.biHeight < 0) {
181                 OS.MoveMemory(pBits, bits, bmiHeader.biSizeImage);
182             } else {
183                 DIBSECTION dib;
184                 OS.GetObject(memDib, DIBSECTION.sizeof, &dib);
185                 int biHeight = dib.dsBmih.biHeight;
186                 int scanline = dib.dsBmih.biSizeImage / biHeight;
187                 auto pDestBits = pBits;
188                 auto pSourceBits = bits + scanline * (biHeight - 1);
189                 for (int i = 0; i < biHeight; i++) {
190                     OS.MoveMemory(pDestBits, pSourceBits, scanline);
191                     pDestBits += scanline;
192                     pSourceBits -= scanline;
193                 }
194             }
195             Image image = Image.win32_new(null, DWT.BITMAP, memDib);
196             ImageData data = image.getImageData();
197             OS.DeleteObject(memDib);
198             image.dispose();
199             return data;
200         } finally {
201             OS.GlobalUnlock(hMem);
202         }
203     } finally {
204         OS.GlobalFree(hMem);
205     }
206 }
207
208 protected int[] getTypeIds(){
209     return [CF_DIBID];
210 }
211
212 protected String[] getTypeNames(){
213     return [CF_DIB];
214 }
215 bool checkImage(Object object) {
216     if (object is null || !(null !is cast(ImageData)object ))  return false;
217     return true;
218 }
219
220 protected bool validate(Object object) {
221     return checkImage(object);
222 }
223 }
Note: See TracBrowser for help on using the browser.