+ TRACE("(%f,%f,%f,%f,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
+
+ if (!srcBitmap || !dstBitmap || srcBitmap->image.type != ImageTypeBitmap ||
+ x < 0 || y < 0 ||
+ x + width > srcBitmap->width || y + height > srcBitmap->height)
+ {
+ TRACE("<-- InvalidParameter\n");
+ return InvalidParameter;
+ }
+
+ if (format == PixelFormatDontCare)
+ format = srcBitmap->format;
+
+ area.X = roundr(x);
+ area.Y = roundr(y);
+ area.Width = roundr(width);
+ area.Height = roundr(height);
+
+ stat = GdipBitmapLockBits(srcBitmap, &area, ImageLockModeRead, format,
+ &lockeddata_src);
+ if (stat != Ok) return stat;
+
+ stat = GdipCreateBitmapFromScan0(lockeddata_src.Width, lockeddata_src.Height,
+ 0, lockeddata_src.PixelFormat, NULL, dstBitmap);
+ if (stat == Ok)
+ {
+ stat = GdipBitmapLockBits(*dstBitmap, NULL, ImageLockModeWrite,
+ lockeddata_src.PixelFormat, &lockeddata_dst);
+
+ if (stat == Ok)
+ {
+ /* copy the image data */
+ row_size = (lockeddata_src.Width * PIXELFORMATBPP(lockeddata_src.PixelFormat) +7)/8;
+ for (i=0; i<lockeddata_src.Height; i++)
+ memcpy((BYTE*)lockeddata_dst.Scan0+lockeddata_dst.Stride*i,
+ (BYTE*)lockeddata_src.Scan0+lockeddata_src.Stride*i,
+ row_size);
+
+ GdipBitmapUnlockBits(*dstBitmap, &lockeddata_dst);
+ }
+
+ if (stat != Ok)
+ GdipDisposeImage((GpImage*)*dstBitmap);
+ }
+
+ GdipBitmapUnlockBits(srcBitmap, &lockeddata_src);
+
+ if (stat != Ok)
+ {
+ *dstBitmap = NULL;
+ }
+
+ return stat;