]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/image.cpp
fixed URL parsing problem
[wxWidgets.git] / src / common / image.cpp
index 5c304f0a9d458cb882b57182069609cb46d30803..bb9f59afc4ee33ef85dfec8eaec03734c08d2254 100644 (file)
@@ -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<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 );
+    }
+
+    // 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; i<height; i++ )
+    {
+        for( j=0; j<width; j++ )
+        {
+            *(ptdata++) = *(ptbits+2);
+            *(ptdata++) = *(ptbits+1);
+            *(ptdata++) = *(ptbits  );
+            ptbits += 3;
+        }
+        ptbits += padding;
+    }
+
+    // similarly, set data according to the possible mask bitmap
+    if( bitmap.GetMask() && bitmap.GetMask()->GetMaskBitmap() )
+    {
+        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<height; i++ )
+        {
+            for( j=0; j<width; j++ )
+            {
+                if( *ptbits != 0 )
+                    ptdata += 3;
+                else
+                {
+                    *(ptdata++)  = r;
+                    *(ptdata++)  = g;
+                    *(ptdata++)  = b;
+                }
+                ptbits += 3;
+            }
+            ptbits += padding;
+        }
+        SetMaskColour( r, g, b );
+        SetMask( TRUE );
+    }
+    else
+    {
+        SetMask( FALSE );
+    }
+    // free allocated resources
+    ::ReleaseDC(NULL, hdc);
+    free(lpDIBh);
+    free(lpBits);
+*/
+}
+
+#endif
+
 // A module to allow wxImage initialization/cleanup
 // without calling these functions from app.cpp or from
 // the user's application.