+ return ( sz == 128 || sz == 48 || sz == 32 || sz == 16 );
+}
+
+IconRef wxBitmapRefData::GetIconRef()
+{
+ if ( m_iconRef == NULL )
+ {
+ // Create Icon Family Handle
+
+ IconFamilyHandle iconFamily = NULL ;
+
+ if ( UMAGetSystemVersion() < 0x1040 )
+ {
+ iconFamily = (IconFamilyHandle) NewHandle( 8 ) ;
+ (**iconFamily).resourceType = kIconFamilyType ;
+ (**iconFamily).resourceSize = sizeof(OSType) + sizeof(Size);
+ }
+ else
+ {
+ iconFamily = (IconFamilyHandle) NewHandle( 0 ) ;
+ }
+
+ int w = GetWidth() ;
+ int h = GetHeight() ;
+ int sz = wxMax( w , h ) ;
+
+ OSType dataType = 0 ;
+ OSType maskType = 0 ;
+
+ switch (sz)
+ {
+ case 128:
+#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if ( UMAGetSystemVersion() >= 0x1050 )
+ {
+ dataType = kIconServices128PixelDataARGB ;
+ }
+ else
+#endif
+ {
+ dataType = kThumbnail32BitData ;
+ maskType = kThumbnail8BitMask ;
+ }
+ break;
+
+ case 48:
+#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if ( UMAGetSystemVersion() >= 0x1050 )
+ {
+ dataType = kIconServices48PixelDataARGB ;
+ }
+ else
+#endif
+ {
+ dataType = kHuge32BitData ;
+ maskType = kHuge8BitMask ;
+ }
+ break;
+
+ case 32:
+#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if ( UMAGetSystemVersion() >= 0x1050 )
+ {
+ dataType = kIconServices32PixelDataARGB ;
+ }
+ else
+#endif
+ {
+ dataType = kLarge32BitData ;
+ maskType = kLarge8BitMask ;
+ }
+ break;
+
+ case 16:
+#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if ( UMAGetSystemVersion() >= 0x1050 )
+ {
+ dataType = kIconServices16PixelDataARGB ;
+ }
+ else
+#endif
+ {
+ dataType = kSmall32BitData ;
+ maskType = kSmall8BitMask ;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if ( dataType != 0 )
+ {
+#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if ( maskType == 0 && UMAGetSystemVersion() >= 0x1050 )
+ {
+ size_t datasize = sz * sz * 4 ;
+ Handle data = NewHandle( datasize ) ;
+ HLock( data ) ;
+ unsigned char* ptr = (unsigned char*) *data ;
+ memset( ptr, 0, datasize );
+ bool hasAlpha = HasAlpha() ;
+ wxMask *mask = m_bitmapMask ;
+ unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ;
+ unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;
+
+ for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 )
+ {
+ unsigned char * source = sourcePtr;
+ unsigned char * masksource = masksourcePtr;
+ unsigned char * dest = ptr + y * sz * 4 ;
+ unsigned char a, r, g, b;
+
+ for ( int x = 0 ; x < w ; ++x )
+ {
+ a = *source ++ ;
+ r = *source ++ ;
+ g = *source ++ ;
+ b = *source ++ ;
+
+ if ( mask )
+ {
+ a = 0xFF - *masksource++ ;
+ }
+ else if ( !hasAlpha )
+ a = 0xFF ;
+ else
+ {
+#if wxMAC_USE_PREMULTIPLIED_ALPHA
+ // this must be non-premultiplied data
+ if ( a != 0xFF && a!= 0 )
+ {
+ r = r * 255 / a;
+ g = g * 255 / a;
+ b = b * 255 / a;
+ }
+#endif
+ }
+ *dest++ = a ;
+ *dest++ = r ;
+ *dest++ = g ;
+ *dest++ = b ;
+
+ }
+ }
+ HUnlock( data );
+ OSStatus err = SetIconFamilyData( iconFamily, dataType , data );
+ wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") );
+ DisposeHandle( data );
+ }
+ else
+#endif
+ {
+ // setup the header properly
+
+ Handle data = NULL ;
+ Handle maskdata = NULL ;
+ unsigned char * maskptr = NULL ;
+ unsigned char * ptr = NULL ;
+ size_t datasize, masksize ;
+
+ datasize = sz * sz * 4 ;
+ data = NewHandle( datasize ) ;
+ HLock( data ) ;
+ ptr = (unsigned char*) *data ;
+ memset( ptr , 0, datasize ) ;
+
+ masksize = sz * sz ;
+ maskdata = NewHandle( masksize ) ;
+ HLock( maskdata ) ;
+ maskptr = (unsigned char*) *maskdata ;
+ memset( maskptr , 0 , masksize ) ;
+
+ bool hasAlpha = HasAlpha() ;
+ wxMask *mask = m_bitmapMask ;
+ unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ;
+ unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;
+
+ for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 )
+ {
+ unsigned char * source = sourcePtr;
+ unsigned char * masksource = masksourcePtr;
+ unsigned char * dest = ptr + y * sz * 4 ;
+ unsigned char * maskdest = maskptr + y * sz ;
+ unsigned char a, r, g, b;
+
+ for ( int x = 0 ; x < w ; ++x )
+ {
+ a = *source ++ ;
+ r = *source ++ ;
+ g = *source ++ ;
+ b = *source ++ ;
+
+ *dest++ = 0 ;
+ *dest++ = r ;
+ *dest++ = g ;
+ *dest++ = b ;
+
+ if ( mask )
+ {
+ *maskdest++ = 0xFF - *masksource++ ;
+#if !wxMAC_USE_CORE_GRAPHICS
+ masksource++ ;
+ masksource++ ;
+ masksource++ ;
+#endif
+ }
+ else if ( hasAlpha )
+ *maskdest++ = a ;
+ else
+ *maskdest++ = 0xFF ;
+ }
+ }
+
+ OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ;
+ wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
+
+ err = SetIconFamilyData( iconFamily, maskType , maskdata ) ;
+ wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ;
+
+ HUnlock( data ) ;
+ HUnlock( maskdata ) ;
+ DisposeHandle( data ) ;
+ DisposeHandle( maskdata ) ;
+ }
+ }
+ else
+ {
+ PicHandle pic = GetPictHandle() ;
+ SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ;
+ }
+ // transform into IconRef
+
+ // cleaner version existing from 10.3 upwards
+ HLock((Handle) iconFamily);
+ OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &m_iconRef );
+ HUnlock((Handle) iconFamily);
+ wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") );
+ DisposeHandle( (Handle) iconFamily ) ;
+ }
+
+ return m_iconRef ;
+}
+
+PicHandle wxBitmapRefData::GetPictHandle()
+{
+ if ( m_pictHandle == NULL )
+ {
+#if !wxMAC_USE_CORE_GRAPHICS
+ CGrafPtr origPort = NULL ;
+ GDHandle origDev = NULL ;
+ GWorldPtr wp = NULL ;
+ GWorldPtr mask = NULL ;
+ int height = GetHeight() ;
+ int width = GetWidth() ;
+
+ Rect rect = { 0 , 0 , height , width } ;
+ RgnHandle clipRgn = NULL ;
+
+ GetGWorld( &origPort , &origDev ) ;
+ wp = GetHBITMAP( &mask ) ;
+
+ if ( mask )
+ {
+ GWorldPtr monoworld ;
+ clipRgn = NewRgn() ;
+ OSStatus err = NewGWorld( &monoworld , 1 , &rect , NULL , NULL , 0 ) ;
+ verify_noerr(err) ;
+ LockPixels( GetGWorldPixMap( monoworld ) ) ;
+ LockPixels( GetGWorldPixMap( mask ) ) ;
+ SetGWorld( monoworld , NULL ) ;
+
+ RGBColor white = { 0xffff , 0xffff , 0xffff } ;
+ RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;
+ RGBForeColor( &black ) ;
+ RGBBackColor( &white ) ;
+
+ CopyBits(GetPortBitMapForCopyBits(mask),
+ GetPortBitMapForCopyBits(monoworld),
+ &rect,
+ &rect,
+ srcCopy, NULL);
+ BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( monoworld ) ) ;
+
+ UnlockPixels( GetGWorldPixMap( monoworld ) ) ;
+ UnlockPixels( GetGWorldPixMap( mask ) ) ;
+ DisposeGWorld( monoworld ) ;
+ }
+
+ SetGWorld( wp , NULL ) ;
+ Rect portRect ;
+ GetPortBounds( wp , &portRect ) ;
+ m_pictHandle = OpenPicture(&portRect);
+
+ if (m_pictHandle)
+ {
+ RGBColor white = { 0xffff , 0xffff , 0xffff } ;
+ RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;
+
+ RGBForeColor( &black ) ;
+ RGBBackColor( &white ) ;
+
+ if ( clipRgn )
+ SetClip( clipRgn ) ;
+
+ LockPixels( GetGWorldPixMap( wp ) ) ;
+ CopyBits(GetPortBitMapForCopyBits(wp),
+ GetPortBitMapForCopyBits(wp),
+ &portRect,
+ &portRect,
+ srcCopy,clipRgn);
+ UnlockPixels( GetGWorldPixMap( wp ) ) ;
+ ClosePicture();
+ }
+
+ SetGWorld( origPort , origDev ) ;
+ if ( clipRgn )
+ DisposeRgn( clipRgn ) ;
+#else
+#ifndef __LP64__
+ GraphicsExportComponent exporter = 0;
+ OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePicture, &exporter);
+ if (noErr == err)
+ {
+ m_pictHandle = (PicHandle) NewHandle(0);
+ if ( m_pictHandle )
+ {
+ // QT does not correctly export the mask
+ // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands
+ CGImageRef imageRef = CGImageCreate();
+ err = GraphicsExportSetInputCGImage( exporter, imageRef );
+ err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle);
+ err = GraphicsExportDoExport(exporter, NULL);
+ CGImageRelease( imageRef );
+
+ size_t handleSize = GetHandleSize( (Handle) m_pictHandle );
+ // the 512 bytes header is only needed for pict files, but not in memory
+ if ( handleSize >= 512 )
+ {
+ memmove( *m_pictHandle , (char*)(*m_pictHandle)+512, handleSize - 512 );
+ SetHandleSize( (Handle) m_pictHandle, handleSize - 512 );
+ }
+ }
+ CloseComponent( exporter );
+ }
+#endif
+#endif
+ }
+
+ return m_pictHandle ;
+}
+
+#ifdef __WXMAC_OSX__
+void wxMacMemoryBufferReleaseProc(void *info, const void *data, size_t WXUNUSED(size))