Beispiel #1
0
void wxHtmlImageCell::SetImage(const wxImage& img)
{
#if !defined(__WXMSW__) || wxUSE_WXDIB
    if ( img.IsOk() )
    {
        delete m_bitmap;

        int ww, hh;
        ww = img.GetWidth();
        hh = img.GetHeight();

        if ( m_bmpW == wxDefaultCoord)
            m_bmpW = ww;
        if ( m_bmpH == wxDefaultCoord)
            m_bmpH = hh;

        // Only scale the bitmap at the rendering stage,
        // so we don't lose quality twice
/*
        if ((m_bmpW != ww) || (m_bmpH != hh))
        {
            wxImage img2 = img.Scale(m_bmpW, m_bmpH);
            m_bitmap = new wxBitmap(img2);
        }
        else
*/
            m_bitmap = new wxBitmap(img);
    }
#endif
}
Beispiel #2
0
void FrameRenderer::setBodyRightImage(const wxImage &image)
{
	OS_ASSERT(image.IsOk());

	m_imageBodyRight = image;
	if(m_imageBodyRight.HasAlpha())
		m_imageBodyRight.ConvertAlphaToMask();
}
Beispiel #3
0
void FrameRenderer::setTopImage(const wxImage &image)
{
	OS_ASSERT(image.IsOk());

	m_imageTop = image;
	if(m_imageTop.HasAlpha())
		m_imageTop.ConvertAlphaToMask();
}
bool wxCreateGreyedImage(const wxImage& in, wxImage& out)
{
#if wxUSE_IMAGE
    out = in.ConvertToGreyscale();
    if ( out.IsOk() )
        return true;
#endif // wxUSE_IMAGE
    return false;
}
Beispiel #5
0
void AffineTransformTestCase::setUp()
{
#if wxUSE_DC_TRANSFORM_MATRIX
    m_imgOrig.LoadFile("horse.jpg");

    CPPUNIT_ASSERT( m_imgOrig.IsOk() );

    m_bmpOrig = wxBitmap(m_imgOrig);
#endif // wxUSE_DC_TRANSFORM_MATRIX
}
Beispiel #6
0
static void addMipMap(GLuint* texture, const wxImage &l_Image, int &level) {
    if (l_Image.IsOk() == true)
    {
        glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, (GLsizei)l_Image.GetWidth(), (GLsizei)l_Image.GetHeight(),
                     0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)l_Image.GetData());
        int err = glGetError();
        if (err == GL_NO_ERROR) {
            level++;
        }
    }
}
Beispiel #7
0
void wxLEDPanel::SetImage(const wxImage img)
{
    if(!img.IsOk()) return;
    m_text.Empty();

    m_content_mo.Init(img);
    m_aniFrameNr=-1;

    // Find the place for the bitmap
	ResetPos();

	// Set in field
	m_field.Clear();
	m_field.SetDatesAt(m_pos,m_content_mo);
}
Beispiel #8
0
void InfoPanel::LoadBannerImage()
{
  const wxImage banner_image = WxUtils::ToWxImage(m_game_list_item.GetBannerImage());
  const wxSize banner_min_size = m_banner->GetMinSize();

  if (banner_image.IsOk())
  {
    m_banner->SetBitmap(WxUtils::ScaleImageToBitmap(banner_image, this, banner_min_size));
    m_banner->Bind(wxEVT_RIGHT_DOWN, &InfoPanel::OnRightClickBanner, this);
  }
  else
  {
    m_banner->SetBitmap(WxUtils::LoadScaledResourceBitmap("nobanner", this, banner_min_size));
  }
}
Beispiel #9
0
wxImage BorderInvariantResizeImage(const wxImage& image, int width, int height)
{
	if (!image.IsOk() || (width == image.GetWidth() && height == image.GetHeight()))
		return image;

	wxImage ret(width, height);
	Resizer data_resize(ret, image, false);
	data_resize();

	if (image.HasAlpha()) {
		ret.InitAlpha();
		Resizer alpha_resize(ret, image, true);
		alpha_resize();
	}

	return ret;
}
Beispiel #10
0
wxBitmap::wxBitmap(const wxImage& imageOrig, int depth)
{
    wxCHECK_RET( imageOrig.IsOk(), wxT("invalid image") );

    wxImage image(imageOrig);

    // convert mask to alpha channel, because wxMask isn't implemented yet
    // FIXME: don't do this, implement proper wxMask support
    if ( image.HasMask() )
        image.InitAlpha();

    DFBSurfacePixelFormat format = DepthToFormat(depth);
    if ( format == DSPF_UNKNOWN && image.HasAlpha() )
        format = DSPF_ARGB;

    // create surface in screen's format (unless we need alpha channel,
    // in which case use ARGB):
    if ( !CreateWithFormat(image.GetWidth(), image.GetHeight(), format) )
        return;

    // then copy the image to it:
    wxIDirectFBSurfacePtr dst = M_BITMAP->m_surface;

    switch ( dst->GetPixelFormat() )
    {
        case DSPF_RGB24:
        case DSPF_RGB32:
        case DSPF_ARGB:
            CopyImageToSurface(image, dst);
            break;

        default:
        {
            // wxBitmap uses different pixel format, so we have to use a
            // temporary surface and blit to the bitmap via it:
            wxIDirectFBSurfacePtr src(CreateSurfaceForImage(image));
            CopyImageToSurface(image, src);

            if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
                return;
            if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) )
                return;
        }
    }
}
Beispiel #11
0
// Add any additional bitmaps/icons to the internal image list
void wxAdvancedListCtrl::AddImageSmall(wxImage Image)
{
    if (GetImageList(wxIMAGE_LIST_SMALL) == NULL)
    {
        // Art provider images are 16x15, WTF?! Kept for compatibility :'(
        wxImageList *ImageList = new wxImageList(16, 15, true, FIRST_IMAGE);
        AssignImageList(ImageList, wxIMAGE_LIST_SMALL);
        
        // Add our sort icons by default.
        GetImageList(wxIMAGE_LIST_SMALL)->Add(wxImage(SortArrowAscending));
        GetImageList(wxIMAGE_LIST_SMALL)->Add(wxImage(SortArrowDescending));
    }
    
    if (Image.IsOk())
    {
        GetImageList(wxIMAGE_LIST_SMALL)->Add(Image);
    }
}
// Add any additional bitmaps/icons to the internal image list
int wxAdvancedListCtrl::AddImageSmall(wxImage Image)
{
    if (GetImageList(wxIMAGE_LIST_SMALL) == NULL)
    {
        wxImageList *ImageList = new wxImageList(16, 16, true);
        AssignImageList(ImageList, wxIMAGE_LIST_SMALL);

        // Add our sort icons by default.
        ImageList_SortArrowUp = GetImageList(wxIMAGE_LIST_SMALL)->Add(wxImage(SortArrowAscending));
        ImageList_SortArrowDown = GetImageList(wxIMAGE_LIST_SMALL)->Add(wxImage(SortArrowDescending));
    }

    if (Image.IsOk())
    {
        return GetImageList(wxIMAGE_LIST_SMALL)->Add(Image);
    }

    return -1;
}
Beispiel #13
0
/**< set the iamge to dispaly */
bool ImagePanel::SetImg(wxImage& img)
{
	// whether the new image can be used
	if (!img.IsOk())
		return false;
	// reference the image used to display.
	if (m_img.IsOk())
		m_img.Destroy();
	m_img = img;

	// calculate display params
	m_szClient = GetClientSize();
	wxSize szImg = m_img.GetSize();
	// if wnd's size greate then img's size, image disp as its actual size
	if (m_szClient.GetWidth() > szImg.GetWidth() && m_szClient.GetHeight() > szImg.GetHeight() )
		ImgZoomActual();
	else
		ImgZoomFit();

	return true;
}
Beispiel #14
0
// Add any additional bitmaps/icons to the internal image list
int wxAdvancedListCtrl::AddImageSmall(wxImage Image)
{
    if (GetImageList(wxIMAGE_LIST_SMALL) == NULL)
    {
        wxImageList *ImageList = new wxImageList(16, 16, true);
        AssignImageList(ImageList, wxIMAGE_LIST_SMALL);
        
        wxBitmap sort_up(16, 16), sort_down(16, 16);
        wxColour Mask = wxColour(255,255,255);
        
        // Draw sort arrows using the native renderer
        {
            wxMemoryDC renderer_dc;

             // sort arrow up
            renderer_dc.SelectObject(sort_up);
            renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(Mask, wxSOLID));
            renderer_dc.Clear();
            wxRendererNative::Get().DrawHeaderButtonContents(this, renderer_dc, wxRect(0, 0, 16, 16), 0, wxHDR_SORT_ICON_UP);

             // sort arrow down
            renderer_dc.SelectObject(sort_down);
            renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(Mask, wxSOLID));
            renderer_dc.Clear();
            wxRendererNative::Get().DrawHeaderButtonContents(this, renderer_dc, wxRect(0, 0, 16, 16), 0, wxHDR_SORT_ICON_DOWN);
        }

        // Add our sort icons to the image list
        ImageList_SortArrowDown = GetImageList(wxIMAGE_LIST_SMALL)->Add(sort_down, Mask);
        ImageList_SortArrowUp = GetImageList(wxIMAGE_LIST_SMALL)->Add(sort_up, Mask);
    }
    
    if (Image.IsOk())
    {
        return GetImageList(wxIMAGE_LIST_SMALL)->Add(Image);
    }
    
    return -1;
}
Beispiel #15
0
/*static*/ void
wxMemoryFSHandler::AddFile(const wxString& filename,
                           const wxImage& image,
                           wxBitmapType type)
{
    if ( !CheckDoesntExist(filename) )
        return;

    wxMemoryOutputStream mems;
    if ( image.IsOk() && image.SaveFile(mems, type) )
    {
        m_Hash[filename] = new wxMemoryFSFile
                               (
                                    mems,
                                    wxImage::FindHandler(type)->GetMimeType()
                               );
    }
    else
    {
        wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
    }
}
Beispiel #16
0
wxBitmap gcThemeManager::getSprite(wxImage& img, const char* spriteId, const char* spriteName)
{
	SpriteRectI* rect = getSpriteRect(spriteId, spriteName);

	if (!rect || !img.IsOk())
		return wxBitmap();

	int w = rect->getW();
	int h = rect->getH();
	int x = rect->getX();
	int y = rect->getY();

	if (w < 0)
		w = img.GetWidth();

	if (h < 0)
		h =	img.GetHeight();

	if (w > img.GetWidth())
		w = img.GetWidth();

	if (h > img.GetHeight())
		h =	img.GetHeight();

	if (x < 0)
		x = 0;

	if (x > img.GetWidth() - w)
		x = 0;

	if (y < 0)
		y = 0;

	if (y > img.GetHeight() - h)
		y = 0;

	return wxBitmap( img.GetSubImage( wxRect(x,y,w,h) ) );
}
Beispiel #17
0
void Map::AssignImgData(ImgData *imgdata, wxImage &img)
{
    if(imgdata == NULL) return;

    if(img.IsOk())
    {
        unsigned char *pixdata, *alphadata;
        int width, height;
        long datasize;

        if(!img.HasAlpha()) img.SetAlpha();
        width = img.GetWidth();
        height = img.GetHeight();
        pixdata = img.GetData();
        alphadata = img.GetAlpha();
        datasize = (long) 4  * width * height;

        (*imgdata).width = (long)width;
        (*imgdata).height = (long)height;
        (*imgdata).data = (unsigned char*)malloc(datasize);
        if((*imgdata).data == NULL) return;

        int pi = 0, ai = 0;
        for(int di = 0; di < datasize;)
        {
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = pixdata[pi++];
            (*imgdata).data[di++] = alphadata[ai++];
        }
    }
    else
    {
        (*imgdata).width = 0;
        (*imgdata).height = 0;
        (*imgdata).data = NULL;
    }
}
Beispiel #18
0
//all shapes are loaded from same image file to reduce file I/O and caching
//thiss also allows animated images to be self-contained
void PianoRenderCache::Piano_load_shapes(RenderBuffer &buffer, const wxString& filename)
{
    debug_function(10); //Debug debug("load_shapes('%s')", (const char*)filename.c_str());
    debug(1, "load shapes file '%s'", (const char*)filename.c_str());
    //reload shapes even if file name hasn't changed; color map might be different now
    //    if (!CachedShapeFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change
    if (!wxFileExists(filename)) return;
    Piano_flush_shapes(); //invalidate cached data
    if (!Shapes.LoadFile(filename, wxBITMAP_TYPE_ANY, 0) || !Shapes.IsOk())
    {
        //wxMessageBox("Error loading image file: "+NewPictureName);
        Shapes.Clear();
        return;
    }
    
    if (buffer.GetColorCount() < 2) return; //use colors from shapes file if no user-selected colors
    //    int imgwidth=image.GetWidth();
    //    int imght   =image.GetHeight();
    //    std::hash_map<WXCOLORREF, int> palcounts;
    //TODO: use wxImage.GetData for better performance?
    //TODO: use multiple images within same file?
    for (int y = Shapes.GetHeight() - 1; y >= 0; --y) //bottom->top
        for (int x = 0; x < Shapes.GetWidth(); ++x) //left->right
            if (!Shapes.IsTransparent(x, y))
            {
                xlColor color, mapped;
                color.Set(Shapes.GetRed(x, y), Shapes.GetGreen(x, y), Shapes.GetBlue(x, y));
                if (ColorMap.find(color.GetRGB()) != ColorMap.end()) continue; //already saw this color
                buffer.palette.GetColor(ColorMap.size() % buffer.GetColorCount(), mapped); //assign user-selected colors to shape palette sequentially, loop if run out of colors
                debug(10, "shape color[%d] 0x%x => user-selected color [%d] 0x%x", ColorMap.size(), color.GetRGB(), ColorMap.size() % GetColorCount(), mapped.GetRGB());
                ColorMap[color.GetRGB()] = mapped; //.GetRGB();
                //                ShapePalette.push_back(c.GetRGB()); //keep a list of unique colors in order of occurrence from origin L-R, B-T
            }
    debug(2, "w %d, h %d, #colors %d", Shapes.GetWidth(), Shapes.GetHeight(), ColorMap.size());
    CachedShapeFilename = filename; //don't load same file again
}
Beispiel #19
0
void OpenCVHelper::convertCVMatToWxImage(const cv::Mat &cvimg, wxImage &img)
{
	if(!img.IsOk()
		|| img.GetWidth() != cvimg.cols
		|| img.GetHeight() != cvimg.rows)
	{
		img.Create(cvimg.cols, cvimg.rows, false);
	}
	const cv::Vec3b *cvPtr = cvimg.ptr<cv::Vec3b>(0);
	unsigned char *wxPtr = img.GetData();
	for(int y = 0; y < img.GetHeight(); y++)
	{
		for(int x = 0; x < img.GetWidth(); x++)
		{
/*			localPreviewImage.SetRGB(x, y, img_outcv.at<cv::Vec3b>(y, x)[2],
				img_outcv.at<cv::Vec3b>(y, x)[1],
				img_outcv.at<cv::Vec3b>(y, x)[0]);*/
			*(wxPtr++) = (*cvPtr)[2];
			*(wxPtr++) = (*cvPtr)[1];
			*(wxPtr++) = (*cvPtr)[0];
			cvPtr++;
		}
	}
}
Beispiel #20
0
wxImage ScaleImage(wxImage image, double source_scale_factor, double content_scale_factor,
                   wxSize output_size, wxRect usable_rect, LSIFlags flags,
                   const wxColour& fill_color)
{
  if (!image.IsOk())
  {
    wxFAIL_MSG("WxUtils::ScaleImage expects a valid image.");
    return image;
  }

  if (content_scale_factor != 1.0)
  {
    output_size *= content_scale_factor;
    usable_rect.SetPosition(usable_rect.GetPosition() * content_scale_factor);
    usable_rect.SetSize(usable_rect.GetSize() * content_scale_factor);
  }

  // Fix the output size if it's unset.
  wxSize img_size = image.GetSize();
  if (output_size.GetWidth() < 1)
    output_size.SetWidth(
        static_cast<int>(img_size.GetWidth() * (content_scale_factor / source_scale_factor)));
  if (output_size.GetHeight() < 1)
    output_size.SetHeight(
        static_cast<int>(img_size.GetHeight() * (content_scale_factor / source_scale_factor)));

  // Fix the usable rect. If it's empty then the whole canvas is usable.
  if (usable_rect.IsEmpty())
  {
    // Constructs a temp wxRect 0,0->output_size then move assigns it.
    usable_rect = output_size;
  }
  else if (!usable_rect.Intersects(output_size))
  {
    wxFAIL_MSG("Usable Zone Rectangle is not inside the canvas. Check the output size is correct.");
    image.Create(1, 1, false);
    image.SetRGB(0, 0, fill_color.Red(), fill_color.Green(), fill_color.Blue());
    if (fill_color.Alpha() == wxALPHA_TRANSPARENT)
      image.SetMaskColour(fill_color.Red(), fill_color.Green(), fill_color.Blue());
    usable_rect = output_size;
  }

  // Step 1: Scale the image
  if ((flags & LSI_SCALE) != LSI_SCALE_NONE)
  {
    if (flags & LSI_SCALE_NO_ASPECT)
    {
      // Stretch scale without preserving the aspect ratio.
      bool scale_width = (img_size.GetWidth() > usable_rect.GetWidth() && flags & LSI_SCALE_DOWN) ||
                         (img_size.GetWidth() < usable_rect.GetWidth() && flags & LSI_SCALE_UP);
      bool scale_height =
          (img_size.GetHeight() > usable_rect.GetHeight() && flags & LSI_SCALE_DOWN) ||
          (img_size.GetHeight() < usable_rect.GetHeight() && flags & LSI_SCALE_UP);
      if (scale_width || scale_height)
      {
        // NOTE: Using BICUBIC instead of HIGH because it's the same internally
        //   except that downscaling uses a box filter with awful obvious aliasing
        //   for non-integral scale factors.
        image.Rescale(scale_width ? usable_rect.GetWidth() : img_size.GetWidth(),
                      scale_height ? usable_rect.GetHeight() : img_size.GetHeight(),
                      wxIMAGE_QUALITY_BICUBIC);
      }
    }
    else
    {
      // Scale while preserving the aspect ratio.
      double scale = std::min(static_cast<double>(usable_rect.GetWidth()) / img_size.GetWidth(),
                              static_cast<double>(usable_rect.GetHeight()) / img_size.GetHeight());
      int target_width = static_cast<int>(img_size.GetWidth() * scale);
      int target_height = static_cast<int>(img_size.GetHeight() * scale);
      // Bilinear produces sharper images when upscaling, bicubic tends to smear/blur sharp edges.
      if (scale > 1.0 && flags & LSI_SCALE_UP)
        image.Rescale(target_width, target_height, wxIMAGE_QUALITY_BILINEAR);
      else if (scale < 1.0 && flags & LSI_SCALE_DOWN)
        image.Rescale(target_width, target_height, wxIMAGE_QUALITY_BICUBIC);
    }
    img_size = image.GetSize();
  }

  // Step 2: Resize the canvas to match the output size.
  // NOTE: If NOT using LSI_SCALE_DOWN then this will implicitly crop the image
  if (img_size != output_size || usable_rect.GetPosition() != wxPoint())
  {
    wxPoint base = usable_rect.GetPosition();
    if (flags & LSI_ALIGN_HCENTER)
      base.x += (usable_rect.GetWidth() - img_size.GetWidth()) / 2;
    else if (flags & LSI_ALIGN_RIGHT)
      base.x += usable_rect.GetWidth() - img_size.GetWidth();
    if (flags & LSI_ALIGN_VCENTER)
      base.y += (usable_rect.GetHeight() - img_size.GetHeight()) / 2;
    else if (flags & LSI_ALIGN_BOTTOM)
      base.y += usable_rect.GetHeight() - img_size.GetHeight();

    int r = -1, g = -1, b = -1;
    if (fill_color.Alpha() != wxALPHA_TRANSPARENT)
    {
      r = fill_color.Red();
      g = fill_color.Green();
      b = fill_color.Blue();
    }
    image.Resize(output_size, base, r, g, b);
  }

  return image;
}
Beispiel #21
0
bool MyVideoCaptureWindow::OnProcessFrame(wxImage& wximg)
{
    // This function is only called with a valid wxImage, but for this sample we'll verify that.
    wxCHECK_MSG(wximg.IsOk(), false, wxT("Invalid image to process"));

    bool refresh = true; // return value
    int i, j, jj;
    const int width        = wximg.GetWidth();
    const int height       = wximg.GetHeight();
    const int width_x3     = width*3;
    const int imgdata_size = width*height*3;
    unsigned char *imgdata = wximg.GetData();

    static wxImage lastimage(width, height); // for motion detector

    // Invert the image - negative
    if (m_frame->m_processMenu->IsChecked(ID_IMGPROCESS_NEGATIVE))
    {
        for (i = 0; i < imgdata_size; ++i) imgdata[i] = 255 - imgdata[i];
    }

    // Very basic edge detector
    if (m_frame->m_processMenu->IsChecked(ID_IMGPROCESS_EDGE))
    {
        unsigned char *imgrow = new unsigned char[width_x3];

        if (imgrow)
        {
            unsigned char *rowptr = wximg.GetData();

            for (j = 0; j < height; ++j)
            {
                int jj = j*width_x3;
                memcpy(imgrow, rowptr, width_x3);

                for (i = 3; i < width_x3; i += 3)
                {
                    imgdata[i   + jj] = abs((int)imgrow[i  ] - imgrow[i-3])*4;
                    imgdata[i+1 + jj] = abs((int)imgrow[i+1] - imgrow[i-2])*4;
                    imgdata[i+2 + jj] = abs((int)imgrow[i+2] - imgrow[i-1])*4;
                }

                rowptr += width_x3;
            }

            delete []imgrow;
        }
    }

    // Very basic motion detector,
    //    tweak pixel_threshold, pixels_changed_threshold
    if (m_frame->m_processMenu->IsChecked(ID_IMGPROCESS_MOTION))
    {
        // is the last image still good?
        if (!lastimage.Ok() ||
            (lastimage.GetWidth()  != width) ||
            (lastimage.GetHeight() != height))
        {
            lastimage.Create(width,height);
        }

        unsigned char *lastdata = lastimage.GetData();

        int pixel_threshold          = 64; // each pixel checked has to differ by this
        int pixels_changed_threshold = 10; // this many pixels must change

        int pixels_changed = 0; // # of pixels changed by threshold

        int skip_rows = 3;      // horiz rows to skip
        int skip_cols = 13;     // vert cols to skip

        for (j = 0; j < height; j += skip_rows)
        {
            jj = j*width_x3;

            for (i = 0; i < width_x3; i += skip_cols)
            {
                if(abs((int)imgdata[i+jj] - lastdata[i+jj]) > pixel_threshold)
                    pixels_changed++;
            }
        }

        if (pixels_changed < pixels_changed_threshold) refresh = false;

        memcpy(lastdata, imgdata, sizeof(unsigned char)*imgdata_size);
    }

    return refresh;
}
Beispiel #22
0
bool wxDIB::Create(const wxImage& image, PixelFormat pf)
{
    wxCHECK_MSG( image.IsOk(), false, wxT("invalid wxImage in wxDIB ctor") );

    const int h = image.GetHeight();
    const int w = image.GetWidth();

    // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise
    // a 24bpp RGB is sufficient
    const bool hasAlpha = image.HasAlpha();
    const int bpp = hasAlpha ? 32 : 24;

    if ( !Create(w, h, bpp) )
        return false;

    // DIBs are stored in bottom to top order (see also the comment above in
    // Create()) so we need to copy bits line by line and starting from the end
    const int srcBytesPerLine = w * 3;
    const int dstBytesPerLine = GetLineSize(w, bpp);
    const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine);
    const unsigned char *alpha = hasAlpha ? image.GetAlpha() + (h - 1)*w
                                          : NULL;
    unsigned char *dstLineStart = (unsigned char *)m_data;
    for ( int y = 0; y < h; y++ )
    {
        // Copy one DIB line. Note that RGB components order is reversed in
        // Windows bitmaps compared to wxImage and is actually BGR.
        unsigned char *dst = dstLineStart;
        if ( alpha )
        {
            int x;

            switch ( pf )
            {
                case PixelFormat_PreMultiplied:
                    // Pre-multiply pixel values so that the DIB could be used
                    // with ::AlphaBlend().
                    for ( x = 0; x < w; x++ )
                    {
                        const unsigned char a = *alpha++;
                        *dst++ = (unsigned char)((src[2] * a + 127) / 255);
                        *dst++ = (unsigned char)((src[1] * a + 127) / 255);
                        *dst++ = (unsigned char)((src[0] * a + 127) / 255);
                        *dst++ = a;
                        src += 3;
                    }
                    break;

                case PixelFormat_NotPreMultiplied:
                    // Just copy pixel data without changing it.
                    for ( x = 0; x < w; x++ )
                    {
                        *dst++ = src[2];
                        *dst++ = src[1];
                        *dst++ = src[0];

                        *dst++ = *alpha++;
                        src += 3;
                    }
                    break;
            }

        }
        else // no alpha channel
        {
            for ( int x = 0; x < w; x++ )
            {
                *dst++ = src[2];
                *dst++ = src[1];
                *dst++ = src[0];
                src += 3;
            }
        }

        // pass to the previous line in the image
        src -= 2*srcBytesPerLine;
        if ( alpha )
            alpha -= 2*w;

        // and to the next one in the DIB
        dstLineStart += dstBytesPerLine;
    }

    return true;
}