X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e9c4b1a2b5b926ced938130b2694b869403397cc..53920141b504db01a5af56b5b16fd0b4a251031b:/src/common/image.cpp?ds=sidebyside diff --git a/src/common/image.cpp b/src/common/image.cpp index 800e61fa59..08cf535a6a 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -101,11 +101,21 @@ wxImage::wxImage( const wxString& name, long type ) LoadFile( name, type ); } +wxImage::wxImage( const wxString& name, const wxString& mimetype ) +{ + LoadFile( name, mimetype ); +} + #if wxUSE_STREAMS wxImage::wxImage( wxInputStream& stream, long type ) { LoadFile( stream, type ); } + +wxImage::wxImage( wxInputStream& stream, const wxString& mimetype ) +{ + LoadFile( stream, mimetype ); +} #endif // wxUSE_STREAMS wxImage::wxImage( const wxImage& image ) @@ -146,15 +156,15 @@ wxImage wxImage::Scale( int width, int height ) { wxImage image; - wxCHECK_MSG( Ok(), image, "invlaid image" ); + wxCHECK_MSG( Ok(), image, _T("invalid image") ); - wxCHECK_MSG( (width > 0) && (height > 0), image, "invalid image size" ); + wxCHECK_MSG( (width > 0) && (height > 0), image, _T("invalid image size") ); image.Create( width, height ); char unsigned *data = image.GetData(); - wxCHECK_MSG( data, image, "unable to create image" ); + wxCHECK_MSG( data, image, _T("unable to create image") ); if (M_IMGDATA->m_hasMask) image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue ); @@ -183,12 +193,12 @@ wxImage wxImage::Scale( int width, int height ) void wxImage::SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b ) { - wxCHECK_RET( Ok(), "invalid image" ); + wxCHECK_RET( Ok(), _T("invalid image") ); int w = M_IMGDATA->m_width; int h = M_IMGDATA->m_height; - wxCHECK_RET( (x>=0) && (y>=0) && (x=0) && (y>=0) && (xm_width; int h = M_IMGDATA->m_height; - wxCHECK_MSG( (x>=0) && (y>=0) && (x=0) && (y>=0) && (xm_width; int h = M_IMGDATA->m_height; - wxCHECK_MSG( (x>=0) && (y>=0) && (x=0) && (y>=0) && (xm_width; int h = M_IMGDATA->m_height; - wxCHECK_MSG( (x>=0) && (y>=0) && (x=0) && (y>=0) && (xm_data; } void wxImage::SetData( char unsigned *data ) { - wxCHECK_RET( Ok(), "invalid image" ); + wxCHECK_RET( Ok(), _T("invalid image") ); memcpy(M_IMGDATA->m_data, data, M_IMGDATA->m_width * M_IMGDATA->m_height * 3); } void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b ) { - wxCHECK_RET( Ok(), "invalid image" ); + wxCHECK_RET( Ok(), _T("invalid image") ); M_IMGDATA->m_maskRed = r; M_IMGDATA->m_maskGreen = g; @@ -270,49 +280,49 @@ void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b ) unsigned char wxImage::GetMaskRed() const { - wxCHECK_MSG( Ok(), 0, "invalid image" ); + wxCHECK_MSG( Ok(), 0, _T("invalid image") ); return M_IMGDATA->m_maskRed; } unsigned char wxImage::GetMaskGreen() const { - wxCHECK_MSG( Ok(), 0, "invalid image" ); + wxCHECK_MSG( Ok(), 0, _T("invalid image") ); return M_IMGDATA->m_maskGreen; } unsigned char wxImage::GetMaskBlue() const { - wxCHECK_MSG( Ok(), 0, "invalid image" ); + wxCHECK_MSG( Ok(), 0, _T("invalid image") ); return M_IMGDATA->m_maskBlue; } void wxImage::SetMask( bool mask ) { - wxCHECK_RET( Ok(), "invalid image" ); + wxCHECK_RET( Ok(), _T("invalid image") ); M_IMGDATA->m_hasMask = mask; } bool wxImage::HasMask() const { - wxCHECK_MSG( Ok(), FALSE, "invalid image" ); + wxCHECK_MSG( Ok(), FALSE, _T("invalid image") ); return M_IMGDATA->m_hasMask; } int wxImage::GetWidth() const { - wxCHECK_MSG( Ok(), 0, "invalid image" ); + wxCHECK_MSG( Ok(), 0, _T("invalid image") ); return M_IMGDATA->m_width; } int wxImage::GetHeight() const { - wxCHECK_MSG( Ok(), 0, "invalid image" ); + wxCHECK_MSG( Ok(), 0, _T("invalid image") ); return M_IMGDATA->m_height; } @@ -325,9 +335,28 @@ bool wxImage::LoadFile( const wxString& filename, long type ) wxFileInputStream stream(filename); return LoadFile(stream, type); } + + else { + wxLogError( _T("Can't load image from file '%s': file does not exist."), filename.c_str() ); + + return FALSE; + } +#else // !wxUSE_STREAMS + return FALSE; +#endif // wxUSE_STREAMS +} + +bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype ) +{ +#if wxUSE_STREAMS + if (wxFileExists(filename)) + { + wxFileInputStream stream(filename); + return LoadFile(stream, mimetype); + } else { - wxLogError( "Can't load image from file '%s': file does not exist.", filename.c_str() ); + wxLogError( _T("Can't load image from file '%s': file does not exist."), filename.c_str() ); return FALSE; } @@ -340,7 +369,7 @@ bool wxImage::SaveFile( const wxString& filename, int type ) { #if wxUSE_STREAMS wxFileOutputStream stream(filename); - + if ( stream.LastError() == wxStream_NOERROR ) return SaveFile(stream, type); else @@ -348,6 +377,18 @@ bool wxImage::SaveFile( const wxString& filename, int type ) return FALSE; } +bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype ) +{ +#if wxUSE_STREAMS + wxFileOutputStream stream(filename); + + if ( stream.LastError() == wxStream_NOERROR ) + return SaveFile(stream, mimetype); + else +#endif // wxUSE_STREAMS + return FALSE; +} + #if wxUSE_STREAMS bool wxImage::LoadFile( wxInputStream& stream, long type ) { @@ -359,7 +400,7 @@ bool wxImage::LoadFile( wxInputStream& stream, long type ) if (handler == NULL) { - wxLogWarning( "No image handler for type %d defined.", type ); + wxLogWarning( _T("No image handler for type %d defined."), type ); return FALSE; } @@ -367,15 +408,49 @@ bool wxImage::LoadFile( wxInputStream& stream, long type ) return handler->LoadFile( this, stream ); } +bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype ) +{ + UnRef(); + + m_refData = new wxImageRefData; + + wxImageHandler *handler = FindHandlerMime(mimetype); + + if (handler == NULL) + { + wxLogWarning( _T("No image handler for type %s defined."), mimetype.GetData() ); + + return FALSE; + } + + return handler->LoadFile( this, stream ); +} + bool wxImage::SaveFile( wxOutputStream& stream, int type ) { - wxCHECK_MSG( Ok(), FALSE, "invalid image" ); + wxCHECK_MSG( Ok(), FALSE, _T("invalid image") ); wxImageHandler *handler = FindHandler(type); if (handler == NULL) { - wxLogWarning( "No image handler for type %d defined.", type ); + wxLogWarning( _T("No image handler for type %d defined."), type ); + + return FALSE; + } + + return handler->SaveFile( this, stream ); +} + +bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) +{ + wxCHECK_MSG( Ok(), FALSE, _T("invalid image") ); + + wxImageHandler *handler = FindHandlerMime(mimetype); + + if (handler == NULL) + { + wxLogWarning( _T("No image handler for type %s defined."), mimetype.GetData() ); return FALSE; } @@ -451,6 +526,18 @@ wxImageHandler *wxImage::FindHandler( long bitmapType ) return NULL; } +wxImageHandler *wxImage::FindHandlerMime( const wxString& mimetype ) +{ + wxNode *node = sm_handlers.First(); + while (node) + { + wxImageHandler *handler = (wxImageHandler *)node->Data(); + if (handler->GetMimeType().IsSameAs(mimetype, FALSE)) return handler; + node = node->Next(); + } + return NULL; +} + void wxImage::InitStandardHandlers() { AddHandler( new wxBMPHandler ); @@ -543,12 +630,12 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) int height = (int)dbuf[1]; if (width > 32767) { - wxLogError( "Image width > 32767 pixels for file\n" ); + wxLogError( _T("Image width > 32767 pixels for file\n") ); return FALSE; } if (height > 32767) { - wxLogError( "Image height > 32767 pixels for file\n" ); + wxLogError( _T("Image height > 32767 pixels for file\n") ); return FALSE; } stream.Read(&word, 2); @@ -557,14 +644,14 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) bpp = (int)word; if (bpp != 1 && bpp != 4 && bpp != 8 && bpp && 16 && bpp != 24 && bpp != 32) { - wxLogError( "unknown bitdepth in file\n" ); + wxLogError( _T("unknown bitdepth in file\n") ); return FALSE; } stream.Read(dbuf, 4 * 4); comp = (int)dbuf[0]; if (comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 && comp != BI_BITFIELDS) { - wxLogError( "unknown encoding in Windows BMP file\n" ); + wxLogError( _T("unknown encoding in Windows BMP file\n") ); return FALSE; } stream.Read(dbuf, 4 * 2); @@ -574,7 +661,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) /* some more sanity checks */ if (((comp == BI_RLE4) && (bpp != 4)) || ((comp == BI_RLE8) && (bpp != 8)) || ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32))) { - wxLogError( "encoding of BMP doesn't match bitdepth\n" ); + wxLogError( _T("encoding of BMP doesn't match bitdepth\n") ); return FALSE; } if (bpp < 16) @@ -583,7 +670,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) if (!cmap) { - wxLogError( "Cannot allocate RAM for color map in BMP file\n" ); + wxLogError( _T("Cannot allocate RAM for color map in BMP file\n") ); return FALSE; } } @@ -594,7 +681,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) ptr = image->GetData(); if (!ptr) { - wxLogError( "Cannot allocate RAM for RGB data in file\n" ); + wxLogError( _T("Cannot allocate RAM for RGB data in file\n") ); if (cmap) free(cmap); return FALSE; @@ -708,7 +795,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream ) { if (comp == BI_RLE4) { - wxLogError( "can't deal with 4bit encoded yet.\n"); + wxLogError( _T("can't deal with 4bit encoded yet.\n") ); image->Destroy(); free(cmap); return FALSE; @@ -886,7 +973,7 @@ wxBitmap wxImage::ConvertToBitmap() const // set bitmap parameters wxBitmap bitmap; - wxCHECK_MSG( Ok(), bitmap, "invalid image" ); + wxCHECK_MSG( Ok(), bitmap, _T("invalid image") ); bitmap.SetWidth( width ); bitmap.SetHeight( bmpHeight ); bitmap.SetDepth( wxDisplayDepth() ); @@ -894,7 +981,7 @@ wxBitmap wxImage::ConvertToBitmap() const // create a DIB header int headersize = sizeof(BITMAPINFOHEADER); LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize ); - wxCHECK_MSG( lpDIBh, bitmap, "could not allocate memory for DIB header" ); + wxCHECK_MSG( lpDIBh, bitmap, _T("could not allocate memory for DIB header") ); // Fill in the DIB header lpDIBh->bmiHeader.biSize = headersize; lpDIBh->bmiHeader.biWidth = (DWORD)width; @@ -915,7 +1002,7 @@ wxBitmap wxImage::ConvertToBitmap() const lpBits = (unsigned char *)malloc( lpDIBh->bmiHeader.biSizeImage ); if( !lpBits ) { - wxFAIL_MSG( "could not allocate memory for DIB" ); + wxFAIL_MSG( _T("could not allocate memory for DIB") ); free( lpDIBh ); return bitmap; } @@ -1058,7 +1145,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) // check the bitmap if( !bitmap.Ok() ) { - wxFAIL_MSG( "invalid bitmap" ); + wxFAIL_MSG( _T("invalid bitmap") ); return; } @@ -1069,7 +1156,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) unsigned char *data = GetData(); if( !data ) { - wxFAIL_MSG( "could not allocate data for image" ); + wxFAIL_MSG( _T("could not allocate data for image") ); return; } @@ -1089,7 +1176,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize ); if( !lpDIBh ) { - wxFAIL_MSG( "could not allocate data for DIB header" ); + wxFAIL_MSG( _T("could not allocate data for DIB header") ); free( data ); return; } @@ -1111,7 +1198,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) lpBits = (unsigned char *) malloc( lpDIBh->bmiHeader.biSizeImage ); if( !lpBits ) { - wxFAIL_MSG( "could not allocate data for DIB" ); + wxFAIL_MSG( _T("could not allocate data for DIB") ); free( data ); free( lpDIBh ); return; @@ -1190,11 +1277,15 @@ wxImage::wxImage( const wxBitmap &bitmap ) #include "gdk/gdk.h" #include "gdk/gdkx.h" +#if (GTK_MINOR_VERSION > 0) +#include "gdk/gdkrgb.h" +#endif + wxBitmap wxImage::ConvertToBitmap() const { wxBitmap bitmap; - wxCHECK_MSG( Ok(), bitmap, "invalid image" ); + wxCHECK_MSG( Ok(), bitmap, _T("invalid image") ); int width = GetWidth(); int height = GetHeight(); @@ -1202,14 +1293,54 @@ wxBitmap wxImage::ConvertToBitmap() const bitmap.SetHeight( height ); bitmap.SetWidth( width ); - // Create picture + bitmap.SetPixmap( gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, -1 ) ); + + // Retrieve depth + + GdkVisual *visual = gdk_window_get_visual( bitmap.GetPixmap() ); + if (visual == NULL) visual = gdk_window_get_visual( (GdkWindow*) &gdk_root_parent ); + int bpp = visual->depth; + + bitmap.SetDepth( bpp ); + + if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15; + if (bpp < 8) bpp = 8; + +#if (GTK_MINOR_VERSION > 0) + + if (!HasMask() && (bpp > 8)) + { + static bool s_hasInitialized = FALSE; + + if (!s_hasInitialized) + { + gdk_rgb_init(); + s_hasInitialized = TRUE; + } + + GdkGC *gc = gdk_gc_new( bitmap.GetPixmap() ); + + gdk_draw_rgb_image( bitmap.GetPixmap(), + gc, + 0, 0, + width, height, + GDK_RGB_DITHER_NONE, + GetData(), + width*3 ); + + gdk_gc_unref( gc ); + + return bitmap; + } + +#endif + + // Create picture image GdkImage *data_image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), width, height ); - bitmap.SetPixmap( gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, -1 ) ); - - // Create mask + // Create mask image GdkImage *mask_image = (GdkImage*) NULL; @@ -1225,17 +1356,6 @@ wxBitmap wxImage::ConvertToBitmap() const bitmap.SetMask( mask ); } - // Retrieve depth - - GdkVisual *visual = gdk_window_get_visual( bitmap.GetPixmap() ); - if (visual == NULL) visual = gdk_window_get_visual( (GdkWindow*) &gdk_root_parent ); - int bpp = visual->depth; - - bitmap.SetDepth( bpp ); - - if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15; - if (bpp < 8) bpp = 8; - // Render enum byte_order { RGB, RBG, BRG, BGR, GRB, GBR }; @@ -1373,13 +1493,13 @@ wxBitmap wxImage::ConvertToBitmap() const wxImage::wxImage( const wxBitmap &bitmap ) { - wxCHECK_RET( bitmap.Ok(), "invalid bitmap" ); + wxCHECK_RET( bitmap.Ok(), _T("invalid bitmap") ); GdkImage *gdk_image = gdk_image_get( bitmap.GetPixmap(), 0, 0, bitmap.GetWidth(), bitmap.GetHeight() ); - wxCHECK_RET( gdk_image, "couldn't create image" ); + wxCHECK_RET( gdk_image, _T("couldn't create image") ); Create( bitmap.GetWidth(), bitmap.GetHeight() ); char unsigned *data = GetData(); @@ -1387,7 +1507,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) if (!data) { gdk_image_destroy( gdk_image ); - wxFAIL_MSG( "couldn't create image" ); + wxFAIL_MSG( _T("couldn't create image") ); return; } @@ -1467,7 +1587,7 @@ wxBitmap wxImage::ConvertToBitmap() const { wxBitmap bitmap; - wxCHECK_MSG( Ok(), bitmap, "invalid image" ); + wxCHECK_MSG( Ok(), bitmap, _T("invalid image") ); int width = GetWidth(); int height = GetHeight(); @@ -1671,7 +1791,7 @@ wxBitmap wxImage::ConvertToBitmap() const wxImage::wxImage( const wxBitmap &bitmap ) { - wxCHECK_RET( bitmap.Ok(), "invalid bitmap" ); + wxCHECK_RET( bitmap.Ok(), _T("invalid bitmap") ); Display *dpy = (Display*) wxGetDisplay(); Visual* vis = DefaultVisual( dpy, DefaultScreen( dpy ) ); @@ -1683,7 +1803,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) bitmap.GetWidth(), bitmap.GetHeight(), AllPlanes, ZPixmap ); - wxCHECK_RET( ximage, "couldn't create image" ); + wxCHECK_RET( ximage, _T("couldn't create image") ); Create( bitmap.GetWidth(), bitmap.GetHeight() ); char unsigned *data = GetData(); @@ -1691,7 +1811,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) if (!data) { XDestroyImage( ximage ); - wxFAIL_MSG( "couldn't create image" ); + wxFAIL_MSG( _T("couldn't create image") ); return; } @@ -1804,4 +1924,3 @@ public: }; IMPLEMENT_DYNAMIC_CLASS(wxImageModule, wxModule) -