+ // create and set the device-dependent bitmap
+ HDC hdc = ::GetDC(NULL);
+ HDC memdc = ::CreateCompatibleDC( hdc );
+ HBITMAP hbitmap;
+ hbitmap = ::CreateCompatibleBitmap( hdc, width, bmpHeight );
+ ::SelectObject( memdc, hbitmap);
+
+ // copy image data into DIB data and then into DDB (in a loop)
+ unsigned char *data = GetData();
+ int i, j, n;
+ int origin = 0;
+ unsigned char *ptdata = data;
+ unsigned char *ptbits;
+
+ for( n=0; n<numDIB; n++ )
+ {
+ if( numDIB > 1 && n == numDIB-1 && hRemain > 0 )
+ {
+ // redefine height and size of the (possibly) last smaller DIB
+ // memory is not reallocated
+ height = hRemain;
+ lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
+ lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
+ }
+ ptbits = lpBits;
+
+ for( j=0; j<height; j++ )
+ {
+ for( i=0; i<width; i++ )
+ {
+ *(ptbits++) = *(ptdata+2);
+ *(ptbits++) = *(ptdata+1);
+ *(ptbits++) = *(ptdata );
+ ptdata += 3;
+ }
+ for( i=0; i< padding; i++ ) *(ptbits++) = 0;
+ }
+ ::StretchDIBits( memdc, 0, origin, width, height,\
+ 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
+ origin += height;
+ // if numDIB = 1, lines below can also be used
+ // hbitmap = CreateDIBitmap( hdc, &(lpDIBh->bmiHeader), CBM_INIT, lpBits, lpDIBh, DIB_RGB_COLORS );
+ // The above line is equivalent to the following two lines.
+ // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
+ // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
+ // or the following lines
+ // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
+ // HDC memdc = ::CreateCompatibleDC( hdc );
+ // ::SelectObject( memdc, hbitmap);
+ // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
+ // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
+ // ::SelectObject( memdc, 0 );
+ // ::DeleteDC( memdc );
+ }
+ bitmap.SetHBITMAP( (WXHBITMAP) hbitmap );
+
+ // similarly, created an mono-bitmap for the possible mask
+ if( HasMask() )
+ {
+ hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
+ ::SelectObject( memdc, hbitmap);
+ if( numDIB == 1 ) height = bmpHeight;
+ else height = sizeLimit/bytePerLine;
+ lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
+ lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
+ origin = 0;
+ unsigned char r = GetMaskRed();
+ unsigned char g = GetMaskGreen();
+ unsigned char b = GetMaskBlue();
+ unsigned char zero = 0, one = 255;
+ ptdata = data;
+ for( n=0; n<numDIB; n++ )
+ {
+ if( numDIB > 1 && n == numDIB - 1 && hRemain > 0 )
+ {
+ // redefine height and size of the (possibly) last smaller DIB
+ // memory is not reallocated
+ height = hRemain;
+ lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
+ lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
+ }
+ ptbits = lpBits;
+ for( int j=0; j<height; j++ )
+ {
+ for(i=0; i<width; i++ )
+ {
+ if( (*(ptdata++)!=r) | (*(ptdata++)!=g) | (*(ptdata++)!=b) )
+ {
+ *(ptbits++) = one;
+ *(ptbits++) = one;
+ *(ptbits++) = one;
+ }
+ else
+ {
+ *(ptbits++) = zero;
+ *(ptbits++) = zero;
+ *(ptbits++) = zero;
+ }
+ }
+ for( i=0; i< padding; i++ ) *(ptbits++) = zero;
+ }
+ ::StretchDIBits( memdc, 0, origin, width, height,\
+ 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
+ origin += height;
+ }
+ // create a wxMask object
+ wxMask *mask = new wxMask();
+ mask->SetMaskBitmap( (WXHBITMAP) hbitmap );
+ bitmap.SetMask( mask );
+ // It will be deleted when the wxBitmap object is deleted (as of 01/1999)
+ /* The following can also be used but is slow to run
+ wxColour colour( GetMaskRed(), GetMaskGreen(), GetMaskBlue());
+ wxMask *mask = new wxMask( bitmap, colour );
+ bitmap.SetMask( mask );
+ */
+ }
+
+ // free allocated resources
+ ::SelectObject( memdc, 0 );
+ ::DeleteDC( memdc );
+ ::ReleaseDC(NULL, hdc);
+ free(lpDIBh);
+ free(lpBits);
+
+ // check the wxBitmap object
+ if( bitmap.GetHBITMAP() )
+ bitmap.SetOk( TRUE );
+ else
+ bitmap.SetOk( FALSE );
+
+ return bitmap;
+}
+
+wxImage::wxImage( const wxBitmap &bitmap )