X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/995612e2abc1131458863ed1d3e55206df7c33de..81915974f6986634d17833ae69106091b9562a06:/src/common/image.cpp diff --git a/src/common/image.cpp b/src/common/image.cpp index 5c304f0a9d..bb9f59afc4 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -437,8 +437,32 @@ bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype ) return FALSE; } +bool wxImage::CanRead( const wxString &name ) +{ +#if wxUSE_STREAMS + wxFileInputStream stream(name); + return CanRead(stream); +#else + return FALSE; +#endif +} + #if wxUSE_STREAMS +bool wxImage::CanRead( wxInputStream &stream ) +{ + wxList &list=GetHandlers(); + + for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() ) + { + wxImageHandler *handler=(wxImageHandler*)node->GetData(); + if (handler->CanRead( stream )) + return TRUE; + } + + return FALSE; +} + bool wxImage::LoadFile( wxInputStream& stream, long type ) { UnRef(); @@ -628,7 +652,7 @@ void wxImage::CleanUpHandlers() //----------------------------------------------------------------------------- #if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxImageHandler,wxObject) +IMPLEMENT_ABSTRACT_CLASS(wxImageHandler,wxObject) #endif #if wxUSE_STREAMS @@ -1238,9 +1262,22 @@ wxImage::wxImage( const wxBitmap &bitmap ) { wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") ); - GdkImage *gdk_image = gdk_image_get( bitmap.GetPixmap(), - 0, 0, - bitmap.GetWidth(), bitmap.GetHeight() ); + GdkImage *gdk_image = (GdkImage*) NULL; + if (bitmap.GetPixmap()) + { + gdk_image = gdk_image_get( bitmap.GetPixmap(), + 0, 0, + bitmap.GetWidth(), bitmap.GetHeight() ); + } else + if (bitmap.GetBitmap()) + { + gdk_image = gdk_image_get( bitmap.GetBitmap(), + 0, 0, + bitmap.GetWidth(), bitmap.GetHeight() ); + } else + { + wxFAIL_MSG( wxT("Ill-formed bitmap") ); + } wxCHECK_RET( gdk_image, wxT("couldn't create image") ); @@ -1264,7 +1301,12 @@ wxImage::wxImage( const wxBitmap &bitmap ) SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable } - GdkVisual *visual = gdk_window_get_visual( bitmap.GetPixmap() ); + GdkVisual *visual = (GdkVisual*) NULL; + if (bitmap.GetPixmap()) + visual = gdk_window_get_visual( bitmap.GetPixmap() ); + else + visual = gdk_window_get_visual( bitmap.GetBitmap() ); + if (visual == NULL) visual = gdk_window_get_visual( (GdkWindow*) &gdk_root_parent ); int bpp = visual->depth; if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15; @@ -1277,7 +1319,7 @@ wxImage::wxImage( const wxBitmap &bitmap ) for (int i = 0; i < bitmap.GetWidth(); i++) { wxInt32 pixel = gdk_image_get_pixel( gdk_image, i, j ); - pixel = wxINT32_SWAP_ON_BE( pixel ); + // pixel = wxINT32_SWAP_ON_BE( pixel ); if (bpp <= 8) { data[pos] = cmap->colors[pixel].red >> 8; @@ -1650,6 +1692,341 @@ wxImage::wxImage( const wxBitmap &bitmap ) } #endif +#ifdef __WXPM__ +// OS/2 Presentation manager conversion routings + +wxBitmap wxImage::ConvertToBitmap() const +{ + if ( !Ok() ) + return wxNullBitmap; + wxBitmap bitmap; // remove +// TODO: +/* + int sizeLimit = 1024*768*3; + + // width and height of the device-dependent bitmap + int width = GetWidth(); + int bmpHeight = GetHeight(); + + // calc the number of bytes per scanline and padding + int bytePerLine = width*3; + int sizeDWORD = sizeof( DWORD ); + int lineBoundary = bytePerLine % sizeDWORD; + int padding = 0; + if( lineBoundary > 0 ) + { + padding = sizeDWORD - lineBoundary; + bytePerLine += padding; + } + // calc the number of DIBs and heights of DIBs + int numDIB = 1; + int hRemain = 0; + int height = sizeLimit/bytePerLine; + if( height >= bmpHeight ) + height = bmpHeight; + else + { + numDIB = bmpHeight / height; + hRemain = bmpHeight % height; + if( hRemain >0 ) numDIB++; + } + + // set bitmap parameters + wxBitmap bitmap; + wxCHECK_MSG( Ok(), bitmap, wxT("invalid image") ); + bitmap.SetWidth( width ); + bitmap.SetHeight( bmpHeight ); + bitmap.SetDepth( wxDisplayDepth() ); + + // create a DIB header + int headersize = sizeof(BITMAPINFOHEADER); + LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize ); + wxCHECK_MSG( lpDIBh, bitmap, wxT("could not allocate memory for DIB header") ); + // Fill in the DIB header + lpDIBh->bmiHeader.biSize = headersize; + lpDIBh->bmiHeader.biWidth = (DWORD)width; + lpDIBh->bmiHeader.biHeight = (DWORD)(-height); + lpDIBh->bmiHeader.biSizeImage = bytePerLine*height; + // the general formula for biSizeImage: + // ( ( ( ((DWORD)width*24) +31 ) & ~31 ) >> 3 ) * height; + lpDIBh->bmiHeader.biPlanes = 1; + lpDIBh->bmiHeader.biBitCount = 24; + lpDIBh->bmiHeader.biCompression = BI_RGB; + lpDIBh->bmiHeader.biClrUsed = 0; + // These seem not really needed for our purpose here. + lpDIBh->bmiHeader.biClrImportant = 0; + lpDIBh->bmiHeader.biXPelsPerMeter = 0; + lpDIBh->bmiHeader.biYPelsPerMeter = 0; + // memory for DIB data + unsigned char *lpBits; + lpBits = (unsigned char *)malloc( lpDIBh->bmiHeader.biSizeImage ); + if( !lpBits ) + { + wxFAIL_MSG( wxT("could not allocate memory for DIB") ); + free( lpDIBh ); + return bitmap; + } + + // 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 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; jbmiHeader), 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 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; jSetMaskBitmap( (WXHBITMAP) hbitmap ); + 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 ) +{ + // check the bitmap + if( !bitmap.Ok() ) + { + wxFAIL_MSG( wxT("invalid bitmap") ); + return; + } + + // create an wxImage object + int width = bitmap.GetWidth(); + int height = bitmap.GetHeight(); + Create( width, height ); + unsigned char *data = GetData(); + if( !data ) + { + wxFAIL_MSG( wxT("could not allocate data for image") ); + return; + } + + // calc the number of bytes per scanline and padding in the DIB + int bytePerLine = width*3; + int sizeDWORD = sizeof( DWORD ); + int lineBoundary = bytePerLine % sizeDWORD; + int padding = 0; + if( lineBoundary > 0 ) + { + padding = sizeDWORD - lineBoundary; + bytePerLine += padding; + } +// TODO: +/* + // create a DIB header + int headersize = sizeof(BITMAPINFOHEADER); + LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize ); + if( !lpDIBh ) + { + wxFAIL_MSG( wxT("could not allocate data for DIB header") ); + free( data ); + return; + } + // Fill in the DIB header + lpDIBh->bmiHeader.biSize = headersize; + lpDIBh->bmiHeader.biWidth = width; + lpDIBh->bmiHeader.biHeight = -height; + lpDIBh->bmiHeader.biSizeImage = bytePerLine * height; + lpDIBh->bmiHeader.biPlanes = 1; + lpDIBh->bmiHeader.biBitCount = 24; + lpDIBh->bmiHeader.biCompression = BI_RGB; + lpDIBh->bmiHeader.biClrUsed = 0; + // These seem not really needed for our purpose here. + lpDIBh->bmiHeader.biClrImportant = 0; + lpDIBh->bmiHeader.biXPelsPerMeter = 0; + lpDIBh->bmiHeader.biYPelsPerMeter = 0; + // memory for DIB data + unsigned char *lpBits; + lpBits = (unsigned char *) malloc( lpDIBh->bmiHeader.biSizeImage ); + if( !lpBits ) + { + wxFAIL_MSG( wxT("could not allocate data for DIB") ); + free( data ); + free( lpDIBh ); + return; + } + + // copy data from the device-dependent bitmap to the DIB + HDC hdc = ::GetDC(NULL); + HBITMAP hbitmap; + hbitmap = (HBITMAP) bitmap.GetHBITMAP(); + ::GetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS ); + + // copy DIB data into the wxImage object + int i, j; + unsigned char *ptdata = data; + unsigned char *ptbits = lpBits; + for( i=0; iGetMaskBitmap() ) + { + hbitmap = (HBITMAP) bitmap.GetMask()->GetMaskBitmap(); + // memory DC created, color set, data copied, and memory DC deleted + HDC memdc = ::CreateCompatibleDC( hdc ); + ::SetTextColor( memdc, RGB( 0, 0, 0 ) ); + ::SetBkColor( memdc, RGB( 255, 255, 255 ) ); + ::GetDIBits( memdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS ); + ::DeleteDC( memdc ); + // background color set to RGB(16,16,16) in consistent with wxGTK + unsigned char r=16, g=16, b=16; + ptdata = data; + ptbits = lpBits; + for( i=0; i