return NotImplemented;
}
+static inline void getpixel_1bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+ *index = (row[x/8]>>(7-x%8)) & 1;
+}
+
+static inline void getpixel_4bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+ if (x & 1)
+ *index = row[x/2]&0xf;
+ else
+ *index = row[x/2]>>4;
+}
+
+static inline void getpixel_8bppIndexed(BYTE *index, const BYTE *row, UINT x)
+{
+ *index = row[x];
+}
+
static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
const BYTE *row, UINT x)
{
ARGB *color)
{
BYTE r, g, b, a;
+ BYTE index;
BYTE *row;
TRACE("%p %d %d %p\n", bitmap, x, y, color);
switch (bitmap->format)
{
+ case PixelFormat1bppIndexed:
+ getpixel_1bppIndexed(&index,row,x);
+ break;
+ case PixelFormat4bppIndexed:
+ getpixel_4bppIndexed(&index,row,x);
+ break;
+ case PixelFormat8bppIndexed:
+ getpixel_8bppIndexed(&index,row,x);
+ break;
case PixelFormat16bppGrayScale:
getpixel_16bppGrayScale(&r,&g,&b,&a,row,x);
break;
break;
default:
FIXME("not implemented for format 0x%x\n", bitmap->format);
- return NotImplemented;
-}
+ return NotImplemented;
+ }
- *color = a<<24|r<<16|g<<8|b;
+ if (bitmap->format & PixelFormatIndexed)
+ *color = bitmap->image.palette_entries[index];
+ else
+ *color = a<<24|r<<16|g<<8|b;
return Ok;
}
break;
default:
FIXME("not implemented for format 0x%x\n", bitmap->format);
- return NotImplemented;
-}
+ return NotImplemented;
+ }
return Ok;
}
+GpStatus convert_pixels(UINT width, UINT height,
+ INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
+ INT src_stride, const BYTE *src_bits, PixelFormat src_format, ARGB *src_palette)
+{
+ UINT x, y;
+
+ if (src_format == dst_format ||
+ (dst_format == PixelFormat32bppRGB && PIXELFORMATBPP(src_format) == 32))
+ {
+ UINT widthbytes = PIXELFORMATBPP(src_format) * width / 8;
+ for (y=0; y<height; y++)
+ memcpy(dst_bits+dst_stride*y, src_bits+src_stride*y, widthbytes);
+ return Ok;
+ }
+
+#define convert_indexed_to_rgb(getpixel_function, setpixel_function) do { \
+ for (x=0; x<width; x++) \
+ for (y=0; y<height; y++) { \
+ BYTE index; \
+ BYTE *color; \
+ getpixel_function(&index, src_bits+src_stride*y, x); \
+ color = (BYTE*)(&src_palette[index]); \
+ setpixel_function(color[2], color[1], color[0], color[3], dst_bits+dst_stride*y, x); \
+ } \
+ return Ok; \
+} while (0);
+
+#define convert_rgb_to_rgb(getpixel_function, setpixel_function) do { \
+ for (x=0; x<width; x++) \
+ for (y=0; y<height; y++) { \
+ BYTE r, g, b, a; \
+ getpixel_function(&r, &g, &b, &a, src_bits+src_stride*y, x); \
+ setpixel_function(r, g, b, a, dst_bits+dst_stride*y, x); \
+ } \
+ return Ok; \
+} while (0);
+
+ switch (src_format)
+ {
+ case PixelFormat1bppIndexed:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat4bppIndexed:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat8bppIndexed:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat16bppGrayScale:
+ switch (dst_format)
+ {
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat16bppRGB555:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat16bppRGB565:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppRGB555);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat16bppARGB1555:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB565);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat24bppRGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppARGB1555);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat32bppRGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_24bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat32bppARGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_24bppRGB);
+ case PixelFormat32bppPARGB:
+ convert_32bppARGB_to_32bppPARGB(width, height, dst_bits, dst_stride, src_bits, src_stride);
+ return Ok;
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat32bppPARGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat48bppRGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppPARGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat64bppARGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_48bppRGB);
+ default:
+ break;
+ }
+ break;
+ case PixelFormat64bppPARGB:
+ switch (dst_format)
+ {
+ case PixelFormat16bppGrayScale:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppGrayScale);
+ case PixelFormat16bppRGB555:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB555);
+ case PixelFormat16bppRGB565:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB565);
+ case PixelFormat16bppARGB1555:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppARGB1555);
+ case PixelFormat24bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_24bppRGB);
+ case PixelFormat32bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppRGB);
+ case PixelFormat32bppARGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppARGB);
+ case PixelFormat32bppPARGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppPARGB);
+ case PixelFormat48bppRGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_48bppRGB);
+ case PixelFormat64bppARGB:
+ convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_64bppARGB);
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+#undef convert_indexed_to_rgb
+#undef convert_rgb_to_rgb
+
+ return NotImplemented;
+}
+
/* This function returns a pointer to an array of pixels that represents the
* bitmap. The *entire* bitmap is locked according to the lock mode specified by
* flags. It is correct behavior that a user who calls this function with write
GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
UINT flags, PixelFormat format, BitmapData* lockeddata)
{
- BOOL bm_is_selected;
INT stride, bitspp = PIXELFORMATBPP(format);
- HDC hdc;
- HBITMAP hbm, old = NULL;
- BITMAPINFO *pbmi;
BYTE *buff = NULL;
UINT abs_height;
GpRect act_rect; /* actual rect to be used */
+ GpStatus stat;
- TRACE("%p %p %d %d %p\n", bitmap, rect, flags, format, lockeddata);
+ TRACE("%p %p %d 0x%x %p\n", bitmap, rect, flags, format, lockeddata);
if(!lockeddata || !bitmap)
return InvalidParameter;
}
if(flags & ImageLockModeUserInputBuf)
+ {
+ static int fixme=0;
+ if (!fixme++) FIXME("ImageLockModeUserInputBuf not implemented\n");
return NotImplemented;
+ }
if(bitmap->lockmode)
+ {
+ WARN("bitmap is already locked and cannot be locked again\n");
return WrongState;
+ }
if (bitmap->bits && bitmap->format == format)
{
return Ok;
}
- hbm = bitmap->hbitmap;
- hdc = bitmap->hdc;
- bm_is_selected = (hdc != 0);
-
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- if (!pbmi)
- return OutOfMemory;
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biBitCount = 0;
-
- if(!bm_is_selected){
- hdc = CreateCompatibleDC(0);
- old = SelectObject(hdc, hbm);
+ /* Make sure we can convert to the requested format. */
+ stat = convert_pixels(0, 0, 0, NULL, format, 0, NULL, bitmap->format, NULL);
+ if (stat == NotImplemented)
+ {
+ FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
+ return NotImplemented;
}
- /* fill out bmi */
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
+ /* If we're opening for writing, make sure we'll be able to write back in
+ * the original format. */
+ if (flags & ImageLockModeWrite)
+ {
+ stat = convert_pixels(0, 0, 0, NULL, bitmap->format, 0, NULL, format, NULL);
+ if (stat == NotImplemented)
+ {
+ FIXME("cannot write bitmap from %x to %x\n", format, bitmap->format);
+ return NotImplemented;
+ }
+ }
- abs_height = abs(pbmi->bmiHeader.biHeight);
- stride = pbmi->bmiHeader.biWidth * bitspp / 8;
+ abs_height = bitmap->height;
+ stride = (bitmap->width * bitspp + 7) / 8;
stride = (stride + 3) & ~3;
buff = GdipAlloc(stride * abs_height);
- pbmi->bmiHeader.biBitCount = bitspp;
+ if (!buff) return OutOfMemory;
- if(buff)
- GetDIBits(hdc, hbm, 0, abs_height, buff, pbmi, DIB_RGB_COLORS);
-
- if(!bm_is_selected){
- SelectObject(hdc, old);
- DeleteDC(hdc);
- }
+ stat = convert_pixels(bitmap->width, bitmap->height,
+ stride, buff, format,
+ bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
- if(!buff){
- GdipFree(pbmi);
- return OutOfMemory;
+ if (stat != Ok)
+ {
+ GdipFree(buff);
+ return stat;
}
lockeddata->Width = act_rect.Width;
lockeddata->Height = act_rect.Height;
lockeddata->PixelFormat = format;
lockeddata->Reserved = flags;
-
- if(pbmi->bmiHeader.biHeight > 0){
- lockeddata->Stride = -stride;
- lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X +
- stride * (abs_height - 1 - act_rect.Y);
- }
- else{
- lockeddata->Stride = stride;
- lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
- }
+ lockeddata->Stride = stride;
+ lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
bitmap->lockmode = flags;
bitmap->numlocks++;
-
bitmap->bitmapbits = buff;
- GdipFree(pbmi);
return Ok;
}
GpStatus WINGDIPAPI GdipBitmapSetResolution(GpBitmap* bitmap, REAL xdpi, REAL ydpi)
{
- FIXME("(%p, %.2f, %.2f)\n", bitmap, xdpi, ydpi);
+ TRACE("(%p, %.2f, %.2f)\n", bitmap, xdpi, ydpi);
- return NotImplemented;
+ if (!bitmap || xdpi == 0.0 || ydpi == 0.0)
+ return InvalidParameter;
+
+ bitmap->image.xres = xdpi;
+ bitmap->image.yres = ydpi;
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
BitmapData* lockeddata)
{
- HDC hdc;
- HBITMAP hbm, old = NULL;
- BOOL bm_is_selected;
- BITMAPINFO *pbmi;
+ GpStatus stat;
+
+ TRACE("(%p,%p)\n", bitmap, lockeddata);
if(!bitmap || !lockeddata)
return InvalidParameter;
{
/* we passed a direct reference; no need to do anything */
bitmap->lockmode = 0;
+ bitmap->numlocks = 0;
return Ok;
}
- hbm = bitmap->hbitmap;
- hdc = bitmap->hdc;
- bm_is_selected = (hdc != 0);
-
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biBitCount = 0;
-
- if(!bm_is_selected){
- hdc = CreateCompatibleDC(0);
- old = SelectObject(hdc, hbm);
- }
-
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
- pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(lockeddata->PixelFormat);
- SetDIBits(hdc, hbm, 0, abs(pbmi->bmiHeader.biHeight),
- bitmap->bitmapbits, pbmi, DIB_RGB_COLORS);
+ stat = convert_pixels(bitmap->width, bitmap->height,
+ bitmap->stride, bitmap->bits, bitmap->format,
+ lockeddata->Stride, bitmap->bitmapbits, lockeddata->PixelFormat, NULL);
- if(!bm_is_selected){
- SelectObject(hdc, old);
- DeleteDC(hdc);
+ if (stat != Ok)
+ {
+ ERR("failed to convert pixels; this should never happen\n");
}
- GdipFree(pbmi);
GdipFree(bitmap->bitmapbits);
bitmap->bitmapbits = NULL;
bitmap->lockmode = 0;
+ bitmap->numlocks = 0;
- return Ok;
+ return stat;
}
GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
{
- FIXME("(%f,%f,%f,%f,%i,%p,%p): stub\n", x, y, width, height, format, srcBitmap, dstBitmap);
+ BitmapData lockeddata_src, lockeddata_dst;
+ int i;
+ UINT row_size;
+ Rect area;
+ GpStatus stat;
- return NotImplemented;
+ TRACE("(%f,%f,%f,%f,0x%x,%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;
}
GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height,
PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
{
- FIXME("(%i,%i,%i,%i,%i,%p,%p): stub\n", x, y, width, height, format, srcBitmap, dstBitmap);
+ TRACE("(%i,%i,%i,%i,0x%x,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
- return NotImplemented;
+ return GdipCloneBitmapArea(x, y, width, height, format, srcBitmap, dstBitmap);
}
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
GdipBitmapUnlockBits((GpBitmap*)*cloneImage, &lockeddata_dst);
}
- GdipBitmapUnlockBits(bitmap, &lockeddata_src);
+ if (stat != Ok)
+ GdipDisposeImage(*cloneImage);
}
+ GdipBitmapUnlockBits(bitmap, &lockeddata_src);
+
if (stat != Ok)
{
- GdipDisposeImage(*cloneImage);
*cloneImage = NULL;
}
else memcpy(&(*cloneImage)->format, &image->format, sizeof(GUID));
{
static int calls;
+ TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
+ debugstr_w(description), out_metafile);
+
if(!ref || !metafile || !out_metafile)
return InvalidParameter;
return Ok;
}
+static void generate_halftone_palette(ARGB *entries, UINT count)
+{
+ static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
+ UINT i;
+
+ for (i=0; i<8 && i<count; i++)
+ {
+ entries[i] = 0xff000000;
+ if (i&1) entries[i] |= 0x800000;
+ if (i&2) entries[i] |= 0x8000;
+ if (i&4) entries[i] |= 0x80;
+ }
+
+ if (8 < count)
+ entries[i] = 0xffc0c0c0;
+
+ for (i=9; i<16 && i<count; i++)
+ {
+ entries[i] = 0xff000000;
+ if (i&1) entries[i] |= 0xff0000;
+ if (i&2) entries[i] |= 0xff00;
+ if (i&4) entries[i] |= 0xff;
+ }
+
+ for (i=16; i<40 && i<count; i++)
+ {
+ entries[i] = 0;
+ }
+
+ for (i=40; i<256 && i<count; i++)
+ {
+ entries[i] = 0xff000000;
+ entries[i] |= halftone_values[(i-40)%6];
+ entries[i] |= halftone_values[((i-40)/6)%6] << 8;
+ entries[i] |= halftone_values[((i-40)/36)%6] << 16;
+ }
+}
+
+static GpStatus get_screen_resolution(REAL *xres, REAL *yres)
+{
+ HDC screendc = GetDC(0);
+
+ if (!screendc) return GenericError;
+
+ *xres = (REAL)GetDeviceCaps(screendc, LOGPIXELSX);
+ *yres = (REAL)GetDeviceCaps(screendc, LOGPIXELSY);
+
+ ReleaseDC(0, screendc);
+
+ return Ok;
+}
+
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
- BITMAPINFOHEADER bmih;
+ BITMAPINFO* pbmi;
HBITMAP hbitmap;
INT row_size, dib_stride;
HDC hdc;
BYTE *bits;
int i;
+ REAL xres, yres;
+ GpStatus stat;
- TRACE("%d %d %d %d %p %p\n", width, height, stride, format, scan0, bitmap);
+ TRACE("%d %d %d 0x%x %p %p\n", width, height, stride, format, scan0, bitmap);
if (!bitmap) return InvalidParameter;
if(scan0 && !stride)
return InvalidParameter;
+ stat = get_screen_resolution(&xres, &yres);
+ if (stat != Ok) return stat;
+
row_size = (width * PIXELFORMATBPP(format)+7) / 8;
dib_stride = (row_size + 3) & ~3;
if(stride == 0)
stride = dib_stride;
- bmih.biSize = sizeof(BITMAPINFOHEADER);
- bmih.biWidth = width;
- bmih.biHeight = -height;
- bmih.biPlanes = 1;
+ pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ if (!pbmi)
+ return OutOfMemory;
+
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = width;
+ pbmi->bmiHeader.biHeight = -height;
+ pbmi->bmiHeader.biPlanes = 1;
/* FIXME: use the rest of the data from format */
- bmih.biBitCount = PIXELFORMATBPP(format);
- bmih.biCompression = BI_RGB;
- bmih.biSizeImage = 0;
- bmih.biXPelsPerMeter = 0;
- bmih.biYPelsPerMeter = 0;
- bmih.biClrUsed = 0;
- bmih.biClrImportant = 0;
+ pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
hdc = CreateCompatibleDC(NULL);
- if (!hdc) return GenericError;
+ if (!hdc) {
+ GdipFree(pbmi);
+ return GenericError;
+ }
- hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&bits,
- NULL, 0);
+ hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
DeleteDC(hdc);
+ GdipFree(pbmi);
if (!hbitmap) return GenericError;
(*bitmap)->image.type = ImageTypeBitmap;
memcpy(&(*bitmap)->image.format, &ImageFormatMemoryBMP, sizeof(GUID));
(*bitmap)->image.flags = ImageFlagsNone;
+ (*bitmap)->image.palette_flags = 0;
+ (*bitmap)->image.palette_count = 0;
+ (*bitmap)->image.palette_size = 0;
+ (*bitmap)->image.palette_entries = NULL;
+ (*bitmap)->image.xres = xres;
+ (*bitmap)->image.yres = yres;
(*bitmap)->width = width;
(*bitmap)->height = height;
(*bitmap)->format = format;
(*bitmap)->bits = bits;
(*bitmap)->stride = dib_stride;
+ if (format == PixelFormat1bppIndexed ||
+ format == PixelFormat4bppIndexed ||
+ format == PixelFormat8bppIndexed)
+ {
+ (*bitmap)->image.palette_size = (*bitmap)->image.palette_count = 1 << PIXELFORMATBPP(format);
+ (*bitmap)->image.palette_entries = GdipAlloc(sizeof(ARGB) * ((*bitmap)->image.palette_size));
+
+ if (!(*bitmap)->image.palette_entries)
+ {
+ GdipDisposeImage(&(*bitmap)->image);
+ *bitmap = NULL;
+ return OutOfMemory;
+ }
+
+ if (format == PixelFormat1bppIndexed)
+ {
+ (*bitmap)->image.palette_flags = PaletteFlagsGrayScale;
+ (*bitmap)->image.palette_entries[0] = 0xff000000;
+ (*bitmap)->image.palette_entries[1] = 0xffffffff;
+ }
+ else
+ {
+ if (format == PixelFormat8bppIndexed)
+ (*bitmap)->image.palette_flags = PaletteFlagsHalftone;
+
+ generate_halftone_palette((*bitmap)->image.palette_entries,
+ (*bitmap)->image.palette_count);
+ }
+ }
+
+ TRACE("<-- %p\n", *bitmap);
+
return Ok;
}
{
GdipFree(((GpBitmap*)image)->bitmapbits);
DeleteDC(((GpBitmap*)image)->hdc);
+ DeleteObject(((GpBitmap*)image)->hbitmap);
}
+ GdipFree(image->palette_entries);
GdipFree(image);
return Ok;
GpStatus WINGDIPAPI GdipFindFirstImageItem(GpImage *image, ImageItemData* item)
{
+ static int calls;
+
+ TRACE("(%p,%p)\n", image, item);
+
if(!image || !item)
return InvalidParameter;
+ if (!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipGetImageItemData(GpImage *image, ImageItemData *item)
+{
+ static int calls;
+
+ TRACE("(%p,%p)\n", image, item);
+
+ if (!(calls++))
+ FIXME("not implemented\n");
+
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage *image, REAL *res)
{
- static int calls;
-
if(!image || !res)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ *res = image->xres;
- return NotImplemented;
+ TRACE("(%p) <-- %0.2f\n", image, *res);
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage *image, INT *size)
{
- FIXME("%p %p\n", image, size);
+ TRACE("%p %p\n", image, size);
if(!image || !size)
return InvalidParameter;
- return NotImplemented;
+ if (image->palette_count == 0)
+ *size = sizeof(ColorPalette);
+ else
+ *size = sizeof(UINT)*2 + sizeof(ARGB)*image->palette_count;
+
+ TRACE("<-- %u\n", *size);
+
+ return Ok;
}
/* FIXME: test this function for non-bitmap types */
GpStatus WINGDIPAPI GdipGetImageVerticalResolution(GpImage *image, REAL *res)
{
- static int calls;
-
if(!image || !res)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ *res = image->yres;
- return NotImplemented;
+ TRACE("(%p) <-- %0.2f\n", image, *res);
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
{
static int calls;
+ TRACE("(%p,%p,%p)\n", image, size, num);
+
if(!(calls++))
FIXME("not implemented\n");
return InvalidParameter;
}
+struct image_format_dimension
+{
+ const GUID *format;
+ const GUID *dimension;
+};
+
+struct image_format_dimension image_format_dimensions[] =
+{
+ {&ImageFormatGIF, &FrameDimensionTime},
+ {&ImageFormatIcon, &FrameDimensionResolution},
+ {NULL}
+};
+
GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image,
GDIPCONST GUID* dimensionID, UINT* count)
{
static int calls;
+ TRACE("(%p,%s,%p)\n", image, debugstr_guid(dimensionID), count);
+
if(!image || !dimensionID || !count)
return InvalidParameter;
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image,
UINT* count)
{
+ /* Native gdiplus 1.1 does not yet support multiple frame dimensions. */
+
if(!image || !count)
return InvalidParameter;
*count = 1;
- FIXME("stub\n");
-
return Ok;
}
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage* image,
GUID* dimensionIDs, UINT count)
{
- static int calls;
+ int i;
+ const GUID *result=NULL;
+
+ TRACE("(%p,%p,%u)\n", image, dimensionIDs, count);
- if(!image || !dimensionIDs)
+ if(!image || !dimensionIDs || count != 1)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ for (i=0; image_format_dimensions[i].format; i++)
+ {
+ if (IsEqualGUID(&image->format, image_format_dimensions[i].format))
+ {
+ result = image_format_dimensions[i].dimension;
+ break;
+ }
+ }
+
+ if (!result)
+ result = &FrameDimensionPage;
+
+ memcpy(dimensionIDs, result, sizeof(GUID));
return Ok;
}
bitmap = (GpBitmap*)*image;
if (status == Ok && bitmap->format == PixelFormat32bppARGB)
-{
+ {
/* WIC supports bmp files with alpha, but gdiplus does not */
bitmap->format = PixelFormat32bppRGB;
}
return status;
- }
+}
static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image)
{
return decode_image_wic(stream, &CLSID_WICJpegDecoder, image);
- }
+}
static GpStatus decode_image_png(IStream* stream, REFCLSID clsid, GpImage **image)
- {
+{
return decode_image_wic(stream, &CLSID_WICPngDecoder, image);
- }
+}
static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **image)
{
(*image)->type = ImageTypeMetafile;
(*image)->picture = pic;
(*image)->flags = ImageFlagsNone;
+ (*image)->palette_flags = 0;
+ (*image)->palette_count = 0;
+ (*image)->palette_size = 0;
+ (*image)->palette_entries = NULL;
+
+ TRACE("<-- %p\n", *image);
return Ok;
}
if (stat == Ok)
{
memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID));
-}
+ }
return stat;
}
{
static int calls;
+ TRACE("(%p,%u)\n", image, propId);
+
if(!image)
return InvalidParameter;
{
static int calls;
+ TRACE("(%p,%p)\n", image, item);
+
if(!(calls++))
FIXME("not implemented\n");
*/
GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size)
{
- static int calls = 0;
+ TRACE("(%p,%p,%i)\n", image, palette, size);
- if(!image)
+ if (!image || !palette)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ if (size < (sizeof(UINT)*2+sizeof(ARGB)*image->palette_count))
+ {
+ TRACE("<-- InsufficientBuffer\n");
+ return InsufficientBuffer;
+ }
- return NotImplemented;
+ palette->Flags = image->palette_flags;
+ palette->Count = image->palette_count;
+ memcpy(palette->Entries, image->palette_entries, sizeof(ARGB)*image->palette_count);
+
+ return Ok;
}
/*****************************************************************************
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image,
GDIPCONST ColorPalette *palette)
{
- static int calls;
+ TRACE("(%p,%p)\n", image, palette);
- if(!image || !palette)
+ if(!image || !palette || palette->Count > 256)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ if (palette->Count > image->palette_size)
+ {
+ ARGB *new_palette;
- return NotImplemented;
+ new_palette = GdipAlloc(sizeof(ARGB) * palette->Count);
+ if (!new_palette) return OutOfMemory;
+
+ GdipFree(image->palette_entries);
+ image->palette_entries = new_palette;
+ image->palette_size = palette->Count;
+ }
+
+ image->palette_flags = palette->Flags;
+ image->palette_count = palette->Count;
+ memcpy(image->palette_entries, palette->Entries, sizeof(ARGB)*palette->Count);
+
+ return Ok;
}
/*************************************************************************
BITMAP bm;
GpStatus retval;
PixelFormat format;
- BYTE* bits;
+ BitmapData lockeddata;
+ INT y;
TRACE("%p %p %p\n", hbm, hpal, bitmap);
return InvalidParameter;
}
- if (bm.bmBits)
- bits = (BYTE*)bm.bmBits + (bm.bmHeight - 1) * bm.bmWidthBytes;
- else
+ retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, 0,
+ format, NULL, bitmap);
+
+ if (retval == Ok)
{
- FIXME("can only get image data from DIB sections\n");
- bits = NULL;
- }
+ retval = GdipBitmapLockBits(*bitmap, NULL, ImageLockModeWrite,
+ format, &lockeddata);
+ if (retval == Ok)
+ {
+ if (bm.bmBits)
+ {
+ for (y=0; y<bm.bmHeight; y++)
+ {
+ memcpy((BYTE*)lockeddata.Scan0+lockeddata.Stride*y,
+ (BYTE*)bm.bmBits+bm.bmWidthBytes*(bm.bmHeight-1-y),
+ bm.bmWidthBytes);
+ }
+ }
+ else
+ {
+ HDC hdc;
+ HBITMAP oldhbm;
+ BITMAPINFO *pbmi;
+ INT src_height, dst_stride;
+ BYTE *dst_bits;
+
+ hdc = CreateCompatibleDC(NULL);
+ oldhbm = SelectObject(hdc, hbm);
+
+ pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+ if (pbmi)
+ {
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biBitCount = 0;
+
+ GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
+
+ src_height = abs(pbmi->bmiHeader.biHeight);
+
+ if (pbmi->bmiHeader.biHeight > 0)
+ {
+ dst_bits = (BYTE*)lockeddata.Scan0+lockeddata.Stride*(src_height-1);
+ dst_stride = -lockeddata.Stride;
+ }
+ else
+ {
+ dst_bits = lockeddata.Scan0;
+ dst_stride = lockeddata.Stride;
+ }
- retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, -bm.bmWidthBytes,
- format, bits, bitmap);
+ for (y=0; y<src_height; y++)
+ {
+ GetDIBits(hdc, hbm, y, 1, dst_bits+dst_stride*y,
+ pbmi, DIB_RGB_COLORS);
+ }
+
+ GdipFree(pbmi);
+ }
+ else
+ retval = OutOfMemory;
+
+ SelectObject(hdc, oldhbm);
+ DeleteDC(hdc);
+ }
+
+ GdipBitmapUnlockBits(*bitmap, &lockeddata);
+ }
+ }
return retval;
}
{
static int calls;
+ TRACE("(%p,%p,%u)\n", effect, params, size);
+
if(!(calls++))
FIXME("not implemented\n");