gdiplus: Use public ColorPalette structure to store image palette.

This commit is contained in:
Dmitry Timoshkov 2012-07-17 14:59:43 +09:00 committed by Alexandre Julliard
parent 85d3d760d7
commit a46c1f780a
4 changed files with 53 additions and 62 deletions

View File

@ -267,10 +267,7 @@ struct GpImage{
GUID format; GUID format;
UINT flags; UINT flags;
UINT frame_count, current_frame; UINT frame_count, current_frame;
UINT palette_flags; ColorPalette *palette;
UINT palette_count;
UINT palette_size;
ARGB *palette_entries;
REAL xres, yres; REAL xres, yres;
}; };

View File

@ -2318,10 +2318,7 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete,
(*metafile)->image.type = ImageTypeMetafile; (*metafile)->image.type = ImageTypeMetafile;
memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID)); memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID));
(*metafile)->image.palette_flags = 0; (*metafile)->image.palette = NULL;
(*metafile)->image.palette_count = 0;
(*metafile)->image.palette_size = 0;
(*metafile)->image.palette_entries = NULL;
(*metafile)->image.xres = (REAL)copy->szlDevice.cx; (*metafile)->image.xres = (REAL)copy->szlDevice.cx;
(*metafile)->image.yres = (REAL)copy->szlDevice.cy; (*metafile)->image.yres = (REAL)copy->szlDevice.cy;
(*metafile)->bounds.X = (REAL)copy->rclBounds.left; (*metafile)->bounds.X = (REAL)copy->rclBounds.left;
@ -3276,7 +3273,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
convert_pixels(bitmap->width, bitmap->height, convert_pixels(bitmap->width, bitmap->height,
bitmap->width*4, temp_bits, dst_format, bitmap->width*4, temp_bits, dst_format,
bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries); bitmap->stride, bitmap->bits, bitmap->format,
bitmap->image.palette ? bitmap->image.palette->Entries : NULL);
} }
else else
{ {

View File

@ -290,7 +290,7 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
} }
if (bitmap->format & PixelFormatIndexed) if (bitmap->format & PixelFormatIndexed)
*color = bitmap->image.palette_entries[index]; *color = bitmap->image.palette->Entries[index];
else else
*color = a<<24|r<<16|g<<8|b; *color = a<<24|r<<16|g<<8|b;
@ -311,8 +311,8 @@ static inline UINT get_palette_index(BYTE r, BYTE g, BYTE b, BYTE a, GpBitmap* b
tables and thus may actually be slower if this method is called only few times per tables and thus may actually be slower if this method is called only few times per
every image. every image.
*/ */
for(i=0;i<bitmap->image.palette_size;i++) { for(i=0;i<bitmap->image.palette->Count;i++) {
ARGB color=bitmap->image.palette_entries[i]; ARGB color=bitmap->image.palette->Entries[i];
distance=abs(b-(color & 0xff)) + abs(g-(color>>8 & 0xff)) + abs(r-(color>>16 & 0xff)) + abs(a-(color>>24 & 0xff)); distance=abs(b-(color & 0xff)) + abs(g-(color>>8 & 0xff)) + abs(r-(color>>16 & 0xff)) + abs(a-(color>>24 & 0xff));
if (distance<best_distance) { if (distance<best_distance) {
best_distance=distance; best_distance=distance;
@ -1012,7 +1012,7 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
lockeddata->Stride, lockeddata->Scan0, format, lockeddata->Stride, lockeddata->Scan0, format,
bitmap->stride, bitmap->stride,
bitmap->bits + bitmap->stride * act_rect.Y + PIXELFORMATBPP(bitmap->format) * act_rect.X / 8, bitmap->bits + bitmap->stride * act_rect.Y + PIXELFORMATBPP(bitmap->format) * act_rect.X / 8,
bitmap->format, bitmap->image.palette_entries); bitmap->format, bitmap->image.palette ? bitmap->image.palette->Entries : NULL);
if (stat != Ok) if (stat != Ok)
{ {
@ -1770,10 +1770,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
(*bitmap)->image.flags = ImageFlagsNone; (*bitmap)->image.flags = ImageFlagsNone;
(*bitmap)->image.frame_count = 1; (*bitmap)->image.frame_count = 1;
(*bitmap)->image.current_frame = 0; (*bitmap)->image.current_frame = 0;
(*bitmap)->image.palette_flags = 0; (*bitmap)->image.palette = NULL;
(*bitmap)->image.palette_count = 0;
(*bitmap)->image.palette_size = 0;
(*bitmap)->image.palette_entries = NULL;
(*bitmap)->image.xres = xres; (*bitmap)->image.xres = xres;
(*bitmap)->image.yres = yres; (*bitmap)->image.yres = yres;
(*bitmap)->width = width; (*bitmap)->width = width;
@ -1796,29 +1793,30 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
format == PixelFormat4bppIndexed || format == PixelFormat4bppIndexed ||
format == PixelFormat8bppIndexed) format == PixelFormat8bppIndexed)
{ {
(*bitmap)->image.palette_size = (*bitmap)->image.palette_count = 1 << PIXELFORMATBPP(format); (*bitmap)->image.palette = GdipAlloc(sizeof(UINT) * 2 + sizeof(ARGB) * (1 << PIXELFORMATBPP(format)));
(*bitmap)->image.palette_entries = GdipAlloc(sizeof(ARGB) * ((*bitmap)->image.palette_size));
if (!(*bitmap)->image.palette_entries) if (!(*bitmap)->image.palette)
{ {
GdipDisposeImage(&(*bitmap)->image); GdipDisposeImage(&(*bitmap)->image);
*bitmap = NULL; *bitmap = NULL;
return OutOfMemory; return OutOfMemory;
} }
(*bitmap)->image.palette->Count = 1 << PIXELFORMATBPP(format);
if (format == PixelFormat1bppIndexed) if (format == PixelFormat1bppIndexed)
{ {
(*bitmap)->image.palette_flags = PaletteFlagsGrayScale; (*bitmap)->image.palette->Flags = PaletteFlagsGrayScale;
(*bitmap)->image.palette_entries[0] = 0xff000000; (*bitmap)->image.palette->Entries[0] = 0xff000000;
(*bitmap)->image.palette_entries[1] = 0xffffffff; (*bitmap)->image.palette->Entries[1] = 0xffffffff;
} }
else else
{ {
if (format == PixelFormat8bppIndexed) if (format == PixelFormat8bppIndexed)
(*bitmap)->image.palette_flags = PaletteFlagsHalftone; (*bitmap)->image.palette->Flags = PaletteFlagsHalftone;
generate_halftone_palette((*bitmap)->image.palette_entries, generate_halftone_palette((*bitmap)->image.palette->Entries,
(*bitmap)->image.palette_count); (*bitmap)->image.palette->Count);
} }
} }
@ -1979,13 +1977,11 @@ static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
if (clobber_palette) if (clobber_palette)
{ {
GdipFree(dst->image.palette_entries); GdipFree(dst->image.palette);
dst->image.palette_flags = src->image.palette_flags; dst->image.palette = src->image.palette;
dst->image.palette_count = src->image.palette_count;
dst->image.palette_entries = src->image.palette_entries;
} }
else else
GdipFree(src->image.palette_entries); GdipFree(src->image.palette);
dst->image.xres = src->image.xres; dst->image.xres = src->image.xres;
dst->image.yres = src->image.yres; dst->image.yres = src->image.yres;
@ -2048,7 +2044,7 @@ static GpStatus free_image_data(GpImage *image)
IPicture_Release(image->picture); IPicture_Release(image->picture);
if (image->stream) if (image->stream)
IStream_Release(image->stream); IStream_Release(image->stream);
GdipFree(image->palette_entries); GdipFree(image->palette);
return Ok; return Ok;
} }
@ -2237,10 +2233,10 @@ GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage *image, INT *size)
if(!image || !size) if(!image || !size)
return InvalidParameter; return InvalidParameter;
if (image->palette_count == 0) if (!image->palette || image->palette->Count == 0)
*size = sizeof(ColorPalette); *size = sizeof(ColorPalette);
else else
*size = sizeof(UINT)*2 + sizeof(ARGB)*image->palette_count; *size = sizeof(UINT)*2 + sizeof(ARGB)*image->palette->Count;
TRACE("<-- %u\n", *size); TRACE("<-- %u\n", *size);
@ -3065,7 +3061,7 @@ end:
bitmap->image.current_frame = active_frame; bitmap->image.current_frame = active_frame;
bitmap->image.stream = stream; bitmap->image.stream = stream;
if (IsEqualGUID(&wic_format, &GUID_WICPixelFormatBlackWhite)) if (IsEqualGUID(&wic_format, &GUID_WICPixelFormatBlackWhite))
bitmap->image.palette_flags = 0; bitmap->image.palette->Flags = 0;
/* Pin the source stream */ /* Pin the source stream */
IStream_AddRef(stream); IStream_AddRef(stream);
} }
@ -3140,10 +3136,7 @@ static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid
(*image)->flags = ImageFlagsNone; (*image)->flags = ImageFlagsNone;
(*image)->frame_count = 1; (*image)->frame_count = 1;
(*image)->current_frame = 0; (*image)->current_frame = 0;
(*image)->palette_flags = 0; (*image)->palette = NULL;
(*image)->palette_count = 0;
(*image)->palette_size = 0;
(*image)->palette_entries = NULL;
TRACE("<-- %p\n", *image); TRACE("<-- %p\n", *image);
@ -3598,21 +3591,32 @@ GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *par
*/ */
GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size) GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size)
{ {
INT count;
TRACE("(%p,%p,%i)\n", image, palette, size); TRACE("(%p,%p,%i)\n", image, palette, size);
if (!image || !palette) if (!image || !palette)
return InvalidParameter; return InvalidParameter;
if (size < (sizeof(UINT)*2+sizeof(ARGB)*image->palette_count)) count = image->palette ? image->palette->Count : 0;
if (size < (sizeof(UINT)*2+sizeof(ARGB)*count))
{ {
TRACE("<-- InsufficientBuffer\n"); TRACE("<-- InsufficientBuffer\n");
return InsufficientBuffer; return InsufficientBuffer;
} }
palette->Flags = image->palette_flags; if (image->palette)
palette->Count = image->palette_count; {
memcpy(palette->Entries, image->palette_entries, sizeof(ARGB)*image->palette_count); palette->Flags = image->palette->Flags;
palette->Count = image->palette->Count;
memcpy(palette->Entries, image->palette->Entries, sizeof(ARGB)*image->palette->Count);
}
else
{
palette->Flags = 0;
palette->Count = 0;
}
return Ok; return Ok;
} }
@ -3622,26 +3626,21 @@ GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, I
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image, GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image,
GDIPCONST ColorPalette *palette) GDIPCONST ColorPalette *palette)
{ {
ColorPalette *new_palette;
TRACE("(%p,%p)\n", image, palette); TRACE("(%p,%p)\n", image, palette);
if(!image || !palette || palette->Count > 256) if(!image || !palette || palette->Count > 256)
return InvalidParameter; return InvalidParameter;
if (palette->Count > image->palette_size) new_palette = GdipAlloc(2 * sizeof(UINT) + palette->Count * sizeof(ARGB));
{
ARGB *new_palette;
new_palette = GdipAlloc(sizeof(ARGB) * palette->Count);
if (!new_palette) return OutOfMemory; if (!new_palette) return OutOfMemory;
GdipFree(image->palette_entries); GdipFree(image->palette);
image->palette_entries = new_palette; image->palette = 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);
image->palette_flags = palette->Flags;
image->palette_count = palette->Count;
memcpy(image->palette_entries, palette->Entries, sizeof(ARGB)*palette->Count);
return Ok; return Ok;
} }

View File

@ -232,10 +232,7 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
(*metafile)->image.type = ImageTypeMetafile; (*metafile)->image.type = ImageTypeMetafile;
(*metafile)->image.picture = NULL; (*metafile)->image.picture = NULL;
(*metafile)->image.flags = ImageFlagsNone; (*metafile)->image.flags = ImageFlagsNone;
(*metafile)->image.palette_flags = 0; (*metafile)->image.palette = NULL;
(*metafile)->image.palette_count = 0;
(*metafile)->image.palette_size = 0;
(*metafile)->image.palette_entries = NULL;
(*metafile)->bounds = *frameRect; (*metafile)->bounds = *frameRect;
(*metafile)->unit = frameUnit; (*metafile)->unit = frameUnit;
(*metafile)->metafile_type = type; (*metafile)->metafile_type = type;