+// conversion to colour bitmap:
+bool wxBitmap::CreateFromImageAsPixmap(const wxImage& img)
+{
+ // convert alpha channel to mask, if it is present:
+ wxImage image(img);
+ image.ConvertAlphaToMask();
+
+ int width = image.GetWidth();
+ int height = image.GetHeight();
+
+ SetHeight( height );
+ SetWidth( width );
+
+ SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
+
+ GdkVisual *visual = wxTheApp->GetGdkVisual();
+
+ int bpp = visual->depth;
+
+ SetDepth( bpp );
+
+ GdkGC *gc = gdk_gc_new( GetPixmap() );
+
+ gdk_draw_rgb_image( GetPixmap(),
+ gc,
+ 0, 0,
+ width, height,
+ GDK_RGB_DITHER_NONE,
+ image.GetData(),
+ width*3 );
+
+ g_object_unref (gc);
+
+ // Create mask image
+
+ GdkImage *mask_image = (GdkImage*) NULL;
+
+ if (!image.HasMask())
+ return true;
+
+ unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height );
+
+ mask_image = gdk_image_new_bitmap( visual, mask_data, width, height );
+
+ wxMask *mask = new wxMask();
+ mask->m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 );
+
+ SetMask( mask );
+
+ int r_mask = image.GetMaskRed();
+ int g_mask = image.GetMaskGreen();
+ int b_mask = image.GetMaskBlue();
+
+ unsigned char* data = image.GetData();
+
+ int index = 0;
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ int r = data[index];
+ index++;
+ int g = data[index];
+ index++;
+ int b = data[index];
+ index++;
+
+ if ((r == r_mask) && (b == b_mask) && (g == g_mask))
+ gdk_image_put_pixel( mask_image, x, y, 1 );
+ else
+ gdk_image_put_pixel( mask_image, x, y, 0 );
+ } // for
+ } // for
+
+ // Blit mask
+
+ GdkGC *mask_gc = gdk_gc_new( GetMask()->GetBitmap() );
+
+ gdk_draw_image( GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
+
+ g_object_unref (mask_image);
+ g_object_unref (mask_gc);
+
+ return true;
+}
+
+bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image)
+{
+ int width = image.GetWidth();
+ int height = image.GetHeight();
+
+ GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+ image.HasAlpha(),
+ 8 /* bits per sample */,
+ width, height);
+ if (!pixbuf)
+ return false;
+
+ wxASSERT( image.HasAlpha() ); // for now
+ wxASSERT( gdk_pixbuf_get_n_channels(pixbuf) == 4 );
+ wxASSERT( gdk_pixbuf_get_width(pixbuf) == width );
+ wxASSERT( gdk_pixbuf_get_height(pixbuf) == height );
+
+ M_BMPDATA->m_pixbuf = pixbuf;
+ SetHeight(height);
+ SetWidth(width);
+ SetDepth(wxTheApp->GetGdkVisual()->depth);
+
+ // Copy the data:
+ unsigned char *in = image.GetData();
+ unsigned char *out = gdk_pixbuf_get_pixels(pixbuf);
+ unsigned char *alpha = image.GetAlpha();
+
+ int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width;
+
+ for (int y = 0; y < height; y++, out += rowinc)
+ {
+ for (int x = 0; x < width; x++, alpha++, out += 4, in += 3)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = *alpha;
+ }
+ }
+
+ return true;
+}
+
+wxImage wxBitmap::ConvertToImage() const
+{
+ wxImage image;
+
+ wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
+
+ image.Create(GetWidth(), GetHeight());
+ unsigned char *data = image.GetData();
+
+ if (!data)
+ {
+ wxFAIL_MSG( wxT("couldn't create image") );
+ return wxNullImage;
+ }
+
+ if (HasPixbuf())
+ {
+ GdkPixbuf *pixbuf = GetPixbuf();
+ wxASSERT( gdk_pixbuf_get_has_alpha(pixbuf) );
+
+ int w = GetWidth();
+ int h = GetHeight();
+
+ image.SetAlpha();
+
+ unsigned char *alpha = image.GetAlpha();
+ unsigned char *in = gdk_pixbuf_get_pixels(pixbuf);
+ unsigned char *out = data;
+ int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * w;
+
+ for (int y = 0; y < h; y++, in += rowinc)
+ {
+ for (int x = 0; x < w; x++, in += 4, out += 3, alpha++)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ *alpha = in[3];
+ }
+ }
+ }
+ else
+ {
+ // the colour used as transparent one in wxImage and the one it is
+ // replaced with when it really occurs in the bitmap
+ static const int MASK_RED = 1;
+ static const int MASK_GREEN = 2;
+ static const int MASK_BLUE = 3;
+ static const int MASK_BLUE_REPLACEMENT = 2;
+
+ GdkImage *gdk_image = (GdkImage*) NULL;
+
+ if (HasPixmap())
+ {
+ gdk_image = gdk_image_get( GetPixmap(),
+ 0, 0,
+ GetWidth(), GetHeight() );
+ }
+ else
+ {
+ wxFAIL_MSG( wxT("Ill-formed bitmap") );
+ }
+
+ wxCHECK_MSG( gdk_image, wxNullImage, wxT("couldn't create image") );
+
+ GdkImage *gdk_image_mask = (GdkImage*) NULL;
+ if (GetMask())
+ {
+ gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
+ 0, 0,
+ GetWidth(), GetHeight() );
+
+ image.SetMaskColour( MASK_RED, MASK_GREEN, MASK_BLUE );
+ }
+
+ int bpp = -1;
+ int red_shift_right = 0;
+ int green_shift_right = 0;
+ int blue_shift_right = 0;
+ int red_shift_left = 0;
+ int green_shift_left = 0;
+ int blue_shift_left = 0;
+ bool use_shift = false;
+
+ if (GetDepth() != 1)
+ {
+ GdkVisual *visual = gdk_drawable_get_visual( GetPixmap() );
+ if (visual == NULL)
+ visual = wxTheApp->GetGdkVisual();
+
+ bpp = visual->depth;
+ if (bpp == 16)
+ bpp = visual->red_prec + visual->green_prec + visual->blue_prec;
+ red_shift_right = visual->red_shift;
+ red_shift_left = 8-visual->red_prec;
+ green_shift_right = visual->green_shift;
+ green_shift_left = 8-visual->green_prec;
+ blue_shift_right = visual->blue_shift;
+ blue_shift_left = 8-visual->blue_prec;
+
+ use_shift = (visual->type == GDK_VISUAL_TRUE_COLOR) || (visual->type == GDK_VISUAL_DIRECT_COLOR);
+ }
+ else
+ {
+ bpp = 1;
+ }
+
+
+ GdkColormap *cmap = gtk_widget_get_default_colormap();
+
+ long pos = 0;
+ for (int j = 0; j < GetHeight(); j++)
+ {
+ for (int i = 0; i < GetWidth(); i++)
+ {
+ wxUint32 pixel = gdk_image_get_pixel( gdk_image, i, j );
+ if (bpp == 1)
+ {
+ if (pixel == 0)
+ {
+ data[pos] = 0;
+ data[pos+1] = 0;
+ data[pos+2] = 0;
+ }
+ else
+ {
+ data[pos] = 255;
+ data[pos+1] = 255;
+ data[pos+2] = 255;
+ }
+ }
+ else if (use_shift)
+ {
+ data[pos] = (pixel >> red_shift_right) << red_shift_left;
+ data[pos+1] = (pixel >> green_shift_right) << green_shift_left;
+ data[pos+2] = (pixel >> blue_shift_right) << blue_shift_left;
+ }
+ else if (cmap->colors)
+ {
+ data[pos] = cmap->colors[pixel].red >> 8;
+ data[pos+1] = cmap->colors[pixel].green >> 8;
+ data[pos+2] = cmap->colors[pixel].blue >> 8;
+ }
+ else
+ {
+ wxFAIL_MSG( wxT("Image conversion failed. Unknown visual type.") );
+ }
+
+ if (gdk_image_mask)
+ {
+ int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
+ if (mask_pixel == 0)
+ {
+ data[pos] = MASK_RED;
+ data[pos+1] = MASK_GREEN;
+ data[pos+2] = MASK_BLUE;
+ }
+ else if ( data[pos] == MASK_RED &&
+ data[pos+1] == MASK_GREEN &&
+ data[pos+2] == MASK_BLUE )
+ {
+ data[pos+2] = MASK_BLUE_REPLACEMENT;
+ }
+ }
+
+ pos += 3;
+ }
+ }
+
+ g_object_unref (gdk_image);
+ if (gdk_image_mask) g_object_unref (gdk_image_mask);
+ }
+
+ return image;
+}
+
+wxBitmap::wxBitmap( const wxString &filename, wxBitmapType type )