/*********************************************************************** * GetBitmapBits [GDI32.@] * * Copies bitmap bits of bitmap to buffer. * * RETURNS * Success: Number of bytes copied * Failure: 0 */ LONG WINAPI GetBitmapBits( HBITMAP hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes to copy */ LPVOID bits) /* [out] Pointer to buffer to receive bits */ { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct gdi_image_bits src_bits; struct bitblt_coords src; int dst_stride, max, ret; BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); if (!bmp) return 0; dst_stride = get_bitmap_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel ); ret = max = dst_stride * bmp->dib.dsBm.bmHeight; if (!bits) goto done; if (count > max) count = max; ret = count; src.visrect.left = 0; src.visrect.right = bmp->dib.dsBm.bmWidth; src.visrect.top = 0; src.visrect.bottom = (count + dst_stride - 1) / dst_stride; src.x = src.y = 0; src.width = src.visrect.right - src.visrect.left; src.height = src.visrect.bottom - src.visrect.top; if (!get_image_from_bitmap( bmp, info, &src_bits, &src )) { const char *src_ptr = src_bits.ptr; int src_stride = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); /* GetBitmapBits returns 16-bit aligned data */ if (info->bmiHeader.biHeight > 0) { src_ptr += (info->bmiHeader.biHeight - 1) * src_stride; src_stride = -src_stride; } src_ptr += src.visrect.top * src_stride; if (src_stride == dst_stride) memcpy( bits, src_ptr, count ); else while (count > 0) { memcpy( bits, src_ptr, min( count, dst_stride ) ); src_ptr += src_stride; bits = (char *)bits + dst_stride; count -= dst_stride; } if (src_bits.free) src_bits.free( &src_bits ); } else ret = 0; done: GDI_ReleaseObj( hbitmap ); return ret; }
static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct gdi_image_bits bits; struct bitblt_coords src; BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); if (!bmp) return FALSE; src.visrect.left = src.x = 0; src.visrect.top = src.y = 0; src.visrect.right = src.width = bmp->dib.dsBm.bmWidth; src.visrect.bottom = src.height = bmp->dib.dsBm.bmHeight; if (get_image_from_bitmap( bmp, info, &bits, &src )) goto done; brush->bits = bits; if (!bits.free) { if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done; memcpy( brush->bits.ptr, bits.ptr, info->bmiHeader.biSizeImage ); brush->bits.free = free_heap_bits; } if (!(brush->info = HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( info, DIB_RGB_COLORS )))) { if (brush->bits.free) brush->bits.free( &brush->bits ); goto done; } memcpy( brush->info, info, get_dib_info_size( info, DIB_RGB_COLORS )); brush->bits.is_copy = FALSE; /* the bits can't be modified */ brush->usage = DIB_RGB_COLORS; done: GDI_ReleaseObj( bitmap ); return brush->info != NULL; }