Update ooo320-m1
[ooovba.git] / dtrans / source / os2 / clipb / OS2Bitmap.cxx
blob05691a99bf70cb553926a2c6dd23e68ca1079b02
1 /*************************************************************************
3 * $RCSfile: OS2Bitmap.cxx,v $
5 * $Revision: 1.2 $
7 * last change: $Author: obo $ $Date: 2008-07-22 17:53:52 $
9 * This code is property of Serenity Systems Intl
10 * All rights reserverd.
12 ************************************************************************/
14 #define INCL_WIN
15 #include <svpm.h>
17 #ifndef _OS2CLIPBOARD_HXX_
18 #include "Os2Clipboard.hxx"
19 #endif
21 // same typedefs from win32 sdk
22 typedef unsigned short WORD;
23 typedef unsigned long DWORD;
25 #pragma pack(push, 1)
27 typedef struct {
28 PM_BYTE rgbBlue;
29 PM_BYTE rgbGreen;
30 PM_BYTE rgbRed;
31 PM_BYTE rgbReserved;
32 } RGBQUAD, *LPRGBQUAD;
34 typedef struct
36 WORD bfType;
37 DWORD bfSize;
38 WORD bfReserved1;
39 WORD bfReserved2;
40 DWORD bfOffBits;
41 } W32_BITMAPFILEHEADER, *PW32_BITMAPFILEHEADER;
43 typedef struct
45 DWORD biSize;
46 LONG biWidth;
47 LONG biHeight;
48 WORD biPlanes;
49 WORD biBitCount;
50 DWORD biCompression;
51 DWORD biSizeImage;
52 LONG biXPelsPerMeter;
53 LONG biYPelsPerMeter;
54 DWORD biClrUsed;
55 DWORD biClrImportant;
56 } W32_BITMAPINFOHEADER, *PW32_BITMAPINFOHEADER;
58 #pragma pack(pop)
60 // store screen bitcount
61 LONG lBitCountScreen;
64 * Convert an OOo bitmap to an OS/2 bitmap handle
66 * An OOo bitmap is a BITMAPFILEHEADER structure followed by a Windows DIB
68 * OS/2 InfoHeader is a superset of Win32 InhoHeader, so we can just copy
69 * the win32 memory over the os2 memory and fix the cbFix field.
70 * colortable and bitmap data share the same format.
73 HBITMAP OOoBmpToOS2Handle( Any &aAnyB)
75 // copy bitmap to clipboard
76 Sequence<sal_Int8> ByteStream;
77 aAnyB >>= ByteStream;
79 // get w32 file header data
80 PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER)ByteStream.getArray();
81 // get w32 info header
82 PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1);
84 // create os2 infoheader2 (same fields of w32)
85 BITMAPINFOHEADER2 bih2;
86 memset( &bih2, 0, sizeof( bih2));
87 memcpy( &bih2, pbih, pbih->biSize);
88 bih2.cbFix = sizeof(bih2);
90 // Determine size of color table
91 int iNumColors, numbits=bih2.cPlanes * bih2.cBitCount;
92 if (numbits != 24)
93 iNumColors = bih2.cclrUsed ? bih2.cclrUsed : 2<<numbits;
94 else
95 iNumColors = bih2.cclrUsed;
96 int iColorTableSize = iNumColors*sizeof(RGB2);
98 // allocate bitmap info2 (header2+colortable)
99 PBITMAPINFO2 pbi2=(PBITMAPINFO2) malloc( sizeof(BITMAPINFOHEADER2)+iColorTableSize);
100 // setup header fields
101 memcpy( pbi2, &bih2, sizeof(BITMAPINFOHEADER2));
102 // copy color palette (follows pbih)
103 memcpy( &pbi2->argbColor[0], (pbih+1), iColorTableSize);
105 // get bitmap data
106 PBYTE pbPelData = (PBYTE)ByteStream.getArray() + pbfh->bfOffBits;
107 HPS hps = WinGetPS(HWND_DESKTOP);
108 HBITMAP hbm = GpiCreateBitmap( hps, &bih2, CBM_INIT, pbPelData, pbi2);
109 debug_printf( "OOoBmpToOS2Handle hbm %x\n", hbm);
110 WinReleasePS(hps);
112 // return handle
113 return hbm;
117 * Convert an OS/2 bitmap handle to OOo bitmap
119 * First we need to copy the bitmap to a PS, then we can get bitmap data.
122 int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* OOoDIBStream)
124 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
125 HDC hdc;
126 SIZEL sizl;
127 HPS hps;
128 PM_BYTE* pbBuffer;
129 ULONG cbBuffer;
131 struct {
132 BITMAPINFOHEADER2 bmp2;
133 RGB2 argb2Color[0x100];
134 } bm;
136 if (!lBitCountScreen) {
137 HPS hps = WinGetPS(HWND_DESKTOP);
138 HDC hdc = GpiQueryDevice(hps);
139 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &lBitCountScreen);
140 WinReleasePS(hps);
143 // STEP 1: get OS/2 bitmap data and header
144 // get bitmap header
145 memset(&(bm.bmp2), 0, sizeof(bm.bmp2));
146 bm.bmp2.cbFix = 16;
147 GpiQueryBitmapInfoHeader(hbm, &bm.bmp2);
149 /* Data only actually stored in clipboard quality */
150 if ( lBitCountScreen < bm.bmp2.cBitCount )
151 bm.bmp2.cBitCount = lBitCountScreen;
153 if ( bm.bmp2.cBitCount == 16 )
154 bm.bmp2.cBitCount = 24;
156 if ( bm.bmp2.cPlanes != 1 ) {
157 return 0;
160 if ( (hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL ) {
161 return 0;
164 sizl.cx = bm.bmp2.cx;
165 sizl.cy = bm.bmp2.cy;
166 if ( (hps = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL ) {
167 DevCloseDC(hdc);
168 return 0;
170 // copy bitmap to hps
171 GpiSetBitmap(hps, hbm);
173 // buffer lengths
174 cbBuffer = (((bm.bmp2.cBitCount * bm.bmp2.cx) + 31) / 32) * 4 * bm.bmp2.cy * bm.bmp2.cPlanes;
175 pbBuffer = (PM_BYTE*) malloc( cbBuffer);
176 // now get bitmap data
177 GpiQueryBitmapBits(hps, 0L, (LONG) bm.bmp2.cy, pbBuffer, (BITMAPINFO2*)&bm);
178 // free OS/2 resources
179 GpiSetBitmap(hps, (HBITMAP) NULL);
180 GpiDestroyPS(hps);
181 DevCloseDC(hdc);
183 // STEP 2: now convert to Win32 DIB
184 // Determine size of color table
185 int iNumColors, numbits=bm.bmp2.cPlanes * bm.bmp2.cBitCount;
186 if (numbits != 24)
187 iNumColors = bm.bmp2.cclrUsed ? bm.bmp2.cclrUsed : 2<<numbits;
188 else
189 iNumColors = bm.bmp2.cclrUsed;
190 int iColorTableSize = iNumColors*sizeof(RGBQUAD);
192 // reallocate data stream object size
193 OOoDIBStream->realloc( sizeof( W32_BITMAPFILEHEADER )
194 + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer);
196 // fill w32 file header data
197 PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER) OOoDIBStream->getArray();
198 memset( pbfh, 0, sizeof( W32_BITMAPFILEHEADER));
199 pbfh->bfType = 'MB';
200 pbfh->bfSize = sizeof( W32_BITMAPFILEHEADER )
201 + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer;
202 pbfh->bfOffBits = sizeof( W32_BITMAPFILEHEADER) + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize;
204 // fill w32 info header
205 PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1);
206 // copy header fields (only win32 ones) and fix size
207 memcpy( pbih, &bm.bmp2, sizeof(W32_BITMAPINFOHEADER));
208 pbih->biSize = sizeof(W32_BITMAPINFOHEADER);
210 // fill color palette (follows pbih)
211 memcpy( (pbih+1), &bm.argb2Color[0], iColorTableSize);
213 // fill bitmap data
214 memcpy( (char*) pbfh + pbfh->bfOffBits, pbBuffer, cbBuffer);
216 // done
217 free( pbBuffer);
218 return 1;
221 #ifdef TESTBMP
223 #include <io.h>
224 #include <fcntl.h>
225 #include <stdio.h>
227 int main( void)
229 HAB hAB = WinQueryAnchorBlock( HWND_DESKTOP );
231 // query clipboard data to get mimetype
232 if( WinOpenClipbrd( hAB ) )
234 ULONG handle = WinQueryClipbrdData( hAB, CF_BITMAP);
235 if (handle) {
236 Sequence< sal_Int8 > winDIBStream;
237 // convert to oustring and return it
238 if (OS2HandleToOOoBmp( handle, &winDIBStream) == 1) {
239 printf( "Conversion ok.\n");
240 int fd = open( "test.bmp", O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
241 printf( "writing to fd %d\n", fd);
242 write( fd, winDIBStream.getArray(), winDIBStream.getLength());
243 close( fd);
244 } else
245 printf( "failed conversion.\n");
248 WinCloseClipbrd( hAB);
250 return 0;
253 #endif //TESTBMP