Author: akhaldi
Date: Sun Jul 19 13:31:15 2015
New Revision: 68437
URL:
http://svn.reactos.org/svn/reactos?rev=68437&view=rev
Log:
[GDIPLUS] Sync with Wine Staging 1.7.47. CORE-9924
Added:
trunk/reactos/dll/win32/gdiplus/gdiplus11.manifest (with props)
Modified:
trunk/reactos/dll/win32/gdiplus/font.c
trunk/reactos/dll/win32/gdiplus/gdiplus.rc
trunk/reactos/dll/win32/gdiplus/gdiplus.spec
trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
trunk/reactos/dll/win32/gdiplus/graphics.c
trunk/reactos/dll/win32/gdiplus/image.c
trunk/reactos/dll/win32/gdiplus/metafile.c
trunk/reactos/dll/win32/gdiplus/region.c
trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/gdiplus/font.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/font.c?r…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -450,7 +450,7 @@
matrix = graphics->worldtrans;
- if (font->unit == UnitPixel)
+ if (font->unit == UnitPixel || font->unit == UnitWorld)
{
height = units_to_pixels(font->emSize, graphics->unit, graphics->yres);
if (graphics->unit != UnitDisplay)
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.rc [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.rc [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -20,3 +20,6 @@
/* @makedep: gdiplus.manifest */
WINE_MANIFEST 24 gdiplus.manifest
+
+/* @makedep: gdiplus11.manifest */
+WINE_MANIFEST11 24 gdiplus11.manifest
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -610,7 +610,7 @@
610 stdcall GdipFindFirstImageItem(ptr ptr)
611 stub GdipFindNextImageItem
612 stdcall GdipGetImageItemData(ptr ptr)
-613 stub GdipCreateEffect
+613 stdcall -stub GdipCreateEffect(ptr ptr)
614 stdcall GdipDeleteEffect(ptr)
615 stub GdipGetEffectParameterSize
616 stub GdipGetEffectParameters
@@ -621,7 +621,7 @@
621 stub GdipBitmapGetHistogram
622 stub GdipBitmapGetHistogramSize
623 stub GdipBitmapConvertFormat
-624 stub GdipImageSetAbort
+624 stdcall GdipImageSetAbort(ptr ptr)
625 stub GdipGraphicsSetAbort
626 stub GdipDrawImageFX
627 stdcall GdipConvertToEmfPlus(ptr ptr ptr long ptr ptr)
Added: trunk/reactos/dll/win32/gdiplus/gdiplus11.manifest
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus1…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus11.manifest (added)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus11.manifest [iso-8859-1] Sun Jul 19 13:31:15
2015
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
+ <assemblyIdentity type="win32" name="Microsoft.Windows.GdiPlus"
version="1.1.7601.23038" processorArchitecture=""
publicKeyToken="6595b64144ccf1df"/>
+ <file name="gdiplus.dll"/>
+</assembly>
Propchange: trunk/reactos/dll/win32/gdiplus/gdiplus11.manifest
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus_…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] Sun Jul 19 13:31:15
2015
@@ -47,8 +47,14 @@
#define MAX_DASHLEN (16) /* this is a limitation of gdi */
#define INCH_HIMETRIC (2540)
-#define VERSION_MAGIC 0xdbc01001
+#define VERSION_MAGIC 0xdbc01001
+#define VERSION_MAGIC2 0xdbc01002
#define TENSION_CONST (0.3)
+
+#define GIF_DISPOSE_UNSPECIFIED 0
+#define GIF_DISPOSE_DO_NOT_DISPOSE 1
+#define GIF_DISPOSE_RESTORE_TO_BKGND 2
+#define GIF_DISPOSE_RESTORE_TO_PREV 3
COLORREF ARGB2COLORREF(ARGB color) DECLSPEC_HIDDEN;
HBITMAP ARGB2BMP(ARGB color) DECLSPEC_HIDDEN;
@@ -120,6 +126,26 @@
b = ((bg&0xff)*bg_alpha + (fg&0xff)*fg_alpha)/a;
g = (((bg>>8)&0xff)*bg_alpha + ((fg>>8)&0xff)*fg_alpha)/a;
r = (((bg>>16)&0xff)*bg_alpha + ((fg>>16)&0xff)*fg_alpha)/a;
+
+ return (a<<24)|(r<<16)|(g<<8)|b;
+}
+
+/* fg is premult, bg and return value are not */
+static inline ARGB color_over_fgpremult(ARGB bg, ARGB fg)
+{
+ BYTE b, g, r, a;
+ BYTE bg_alpha, fg_alpha;
+
+ fg_alpha = (fg>>24)&0xff;
+
+ if (fg_alpha == 0) return bg;
+
+ bg_alpha = (((bg>>24)&0xff) * (0xff-fg_alpha)) / 0xff;
+
+ a = bg_alpha + fg_alpha;
+ b = ((bg&0xff)*bg_alpha + (fg&0xff)*0xff)/a;
+ g = (((bg>>8)&0xff)*bg_alpha + ((fg>>8)&0xff)*0xff)/a;
+ r = (((bg>>16)&0xff)*bg_alpha + ((fg>>16)&0xff)*0xff)/a;
return (a<<24)|(r<<16)|(g<<8)|b;
}
@@ -278,7 +304,7 @@
struct GpImage{
IPicture *picture;
- IStream *stream; /* source stream */
+ IWICBitmapDecoder *decoder;
ImageType type;
GUID format;
UINT flags;
Modified: trunk/reactos/dll/win32/gdiplus/graphics.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphics…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -247,6 +247,7 @@
(pt[1].Y - pt[0].Y) * (pt[1].Y - pt[0].Y)) / sqrt(2.0);
width *= units_to_pixels(pen->width, pen->unit == UnitWorld ?
graphics->unit : pen->unit, graphics->xres);
+ width *= graphics->scale;
}
if(pen->dash == DashStyleCustom){
@@ -349,21 +350,28 @@
return GdipGetRegionHRgn(graphics->clip, NULL, hrgn);
}
-/* Draw non-premultiplied ARGB data to the given graphics object */
+/* Draw ARGB data to the given graphics object */
static GpStatus alpha_blend_bmp_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
- const BYTE *src, INT src_width, INT src_height, INT src_stride)
+ const BYTE *src, INT src_width, INT src_height, INT src_stride, const PixelFormat
fmt)
{
GpBitmap *dst_bitmap = (GpBitmap*)graphics->image;
INT x, y;
- for (x=0; x<src_width; x++)
- {
- for (y=0; y<src_height; y++)
+ for (y=0; y<src_height; y++)
+ {
+ for (x=0; x<src_width; x++)
{
ARGB dst_color, src_color;
+ src_color = ((ARGB*)(src + src_stride * y))[x];
+
+ if (!(src_color & 0xff000000))
+ continue;
+
GdipBitmapGetPixel(dst_bitmap, x+dst_x, y+dst_y, &dst_color);
- src_color = ((ARGB*)(src + src_stride * y))[x];
- GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color,
src_color));
+ if (fmt & PixelFormatPAlpha)
+ GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y,
color_over_fgpremult(dst_color, src_color));
+ else
+ GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color,
src_color));
}
}
@@ -371,7 +379,7 @@
}
static GpStatus alpha_blend_hdc_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
- const BYTE *src, INT src_width, INT src_height, INT src_stride)
+ const BYTE *src, INT src_width, INT src_height, INT src_stride, PixelFormat fmt)
{
HDC hdc;
HBITMAP hbitmap;
@@ -395,7 +403,8 @@
hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
(void**)&temp_bits, NULL, 0);
- if (GetDeviceCaps(graphics->hdc, SHADEBLENDCAPS) == SB_NONE)
+ if (GetDeviceCaps(graphics->hdc, SHADEBLENDCAPS) == SB_NONE ||
+ fmt & PixelFormatPAlpha)
memcpy(temp_bits, src, src_width * src_height * 4);
else
convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits,
@@ -411,7 +420,7 @@
}
static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst_y,
- const BYTE *src, INT src_width, INT src_height, INT src_stride, HRGN hregion)
+ const BYTE *src, INT src_width, INT src_height, INT src_stride, HRGN hregion,
PixelFormat fmt)
{
GpStatus stat=Ok;
@@ -461,7 +470,7 @@
stat = alpha_blend_bmp_pixels(graphics, rects[i].left, rects[i].top,
&src[(rects[i].left - dst_x) * 4 + (rects[i].top - dst_y) *
src_stride],
rects[i].right - rects[i].left, rects[i].bottom - rects[i].top,
- src_stride);
+ src_stride, fmt);
}
GdipFree(rgndata);
@@ -494,7 +503,7 @@
ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND);
stat = alpha_blend_hdc_pixels(graphics, dst_x, dst_y, src, src_width,
- src_height, src_stride);
+ src_height, src_stride, fmt);
RestoreDC(graphics->hdc, save);
@@ -505,27 +514,29 @@
}
static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
- const BYTE *src, INT src_width, INT src_height, INT src_stride)
-{
- return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height,
src_stride, NULL);
+ const BYTE *src, INT src_width, INT src_height, INT src_stride, PixelFormat fmt)
+{
+ return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height,
src_stride, NULL, fmt);
}
static ARGB blend_colors(ARGB start, ARGB end, REAL position)
{
- ARGB result=0;
- ARGB i;
- INT a1, a2, a3;
-
- a1 = (start >> 24) & 0xff;
- a2 = (end >> 24) & 0xff;
-
- a3 = (int)(a1*(1.0f - position)+a2*(position));
-
- result |= a3 << 24;
-
- for (i=0xff; i<=0xff0000; i = i << 8)
- result |= (int)((start&i)*(1.0f - position)+(end&i)*(position))&i;
- return result;
+ INT start_a, end_a, final_a;
+ INT pos;
+
+ pos = gdip_round(position * 0xff);
+
+ start_a = ((start >> 24) & 0xff) * (pos ^ 0xff);
+ end_a = ((end >> 24) & 0xff) * pos;
+
+ final_a = start_a + end_a;
+
+ if (final_a < 0xff) return 0;
+
+ return (final_a / 0xff) << 24 |
+ ((((start >> 16) & 0xff) * start_a + (((end >> 16) & 0xff) *
end_a)) / final_a) << 16 |
+ ((((start >> 8) & 0xff) * start_a + (((end >> 8) & 0xff) *
end_a)) / final_a) << 8 |
+ (((start & 0xff) * start_a + ((end & 0xff) * end_a)) / final_a);
}
static ARGB blend_line_gradient(GpLineGradient* brush, REAL position)
@@ -645,8 +656,9 @@
return (r == g) && (g == b);
}
-static void apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
- UINT width, UINT height, INT stride, ColorAdjustType type)
+/* returns preferred pixel format for the applied attributes */
+static PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE
data,
+ UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt)
{
UINT x, y;
INT i;
@@ -657,6 +669,9 @@
const struct color_key *key;
BYTE min_blue, min_green, min_red;
BYTE max_blue, max_green, max_red;
+
+ if (!data || fmt != PixelFormat32bppARGB)
+ return PixelFormat32bppARGB;
if (attributes->colorkeys[type].enabled)
key = &attributes->colorkeys[type];
@@ -690,6 +705,9 @@
attributes->colorremaptables[ColorAdjustTypeDefault].enabled)
{
const struct color_remap_table *table;
+
+ if (!data || fmt != PixelFormat32bppARGB)
+ return PixelFormat32bppARGB;
if (attributes->colorremaptables[type].enabled)
table = &attributes->colorremaptables[type];
@@ -720,6 +738,9 @@
int gray_matrix[5][5];
BOOL identity;
+ if (!data || fmt != PixelFormat32bppARGB)
+ return PixelFormat32bppARGB;
+
if (attributes->colormatrices[type].enabled)
colormatrices = &attributes->colormatrices[type];
else
@@ -758,6 +779,9 @@
{
REAL gamma;
+ if (!data || fmt != PixelFormat32bppARGB)
+ return PixelFormat32bppARGB;
+
if (attributes->gamma_enabled[type])
gamma = attributes->gamma[type];
else
@@ -782,6 +806,8 @@
*src_color = (*src_color & 0xff000000) | (red << 16) | (green
<< 8) | blue;
}
}
+
+ return fmt;
}
/* Given a bitmap and its source rectangle, find the smallest rectangle in the
@@ -1226,7 +1252,7 @@
if (stat == Ok)
apply_image_attributes(fill->imageattributes, fill->bitmap_bits,
bitmap->width, bitmap->height,
- src_stride, ColorAdjustTypeBitmap);
+ src_stride, ColorAdjustTypeBitmap, lockeddata.PixelFormat);
if (stat != Ok)
{
@@ -2115,7 +2141,7 @@
HFONT unscaled_font;
TEXTMETRICW textmet;
- if (font->unit == UnitPixel)
+ if (font->unit == UnitPixel || font->unit == UnitWorld)
font_height = font->emSize;
else
{
@@ -2138,8 +2164,8 @@
GpMatrix xform = *matrix;
GdipTransformMatrixPoints(&xform, pt, 3);
}
- if (graphics)
- GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt,
3);
+
+ GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
@@ -2979,15 +3005,18 @@
return OutOfMemory;
src_stride = sizeof(ARGB) * src_area.Width;
- /* Read the bits we need from the source bitmap into an ARGB buffer. */
+ /* Read the bits we need from the source bitmap into a compatible buffer. */
lockeddata.Width = src_area.Width;
lockeddata.Height = src_area.Height;
lockeddata.Stride = src_stride;
- lockeddata.PixelFormat = PixelFormat32bppARGB;
lockeddata.Scan0 = src_data;
+ if (!do_resampling && bitmap->format == PixelFormat32bppPARGB)
+ lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0,
0, 0, ColorAdjustTypeBitmap, bitmap->format);
+ else
+ lockeddata.PixelFormat = PixelFormat32bppARGB;
stat = GdipBitmapLockBits(bitmap, &src_area,
ImageLockModeRead|ImageLockModeUserInputBuf,
- PixelFormat32bppARGB, &lockeddata);
+ lockeddata.PixelFormat, &lockeddata);
if (stat == Ok)
stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
@@ -3000,7 +3029,7 @@
apply_image_attributes(imageAttributes, src_data,
src_area.Width, src_area.Height,
- src_stride, ColorAdjustTypeBitmap);
+ src_stride, ColorAdjustTypeBitmap, lockeddata.PixelFormat);
if (do_resampling)
{
@@ -3048,7 +3077,8 @@
}
stat = alpha_blend_pixels(graphics, dst_area.left, dst_area.top,
- dst_data, dst_area.right - dst_area.left, dst_area.bottom - dst_area.top,
dst_stride);
+ dst_data, dst_area.right - dst_area.left, dst_area.bottom - dst_area.top,
dst_stride,
+ lockeddata.PixelFormat);
GdipFree(src_data);
@@ -3998,7 +4028,8 @@
if (stat == Ok)
stat = alpha_blend_pixels_hrgn(graphics, gp_bound_rect.X,
gp_bound_rect.Y, (BYTE*)pixel_data, gp_bound_rect.Width,
- gp_bound_rect.Height, gp_bound_rect.Width * 4, hregion);
+ gp_bound_rect.Height, gp_bound_rect.Width * 4, hregion,
+ PixelFormat32bppARGB);
GdipFree(pixel_data);
}
@@ -4730,6 +4761,9 @@
scaled_rect.Width = layoutRect->Width * args.rel_width;
scaled_rect.Height = layoutRect->Height * args.rel_height;
+ if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23;
+ if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23;
+
get_font_hfont(graphics, font, stringFormat, &gdifont, NULL);
oldfont = SelectObject(hdc, gdifont);
@@ -5705,7 +5739,7 @@
{
stat = METAFILE_GetDC((GpMetafile*)graphics->image, hdc);
}
- else if (!graphics->hdc || graphics->alpha_hdc ||
+ else if (!graphics->hdc ||
(graphics->image && graphics->image->type == ImageTypeBitmap
&& ((GpBitmap*)graphics->image)->format & PixelFormatAlpha))
{
/* Create a fake HDC and fill it with a constant color. */
@@ -5797,7 +5831,7 @@
/* Write the changed pixels to the real target. */
alpha_blend_pixels(graphics, 0, 0, graphics->temp_bits,
graphics->temp_hbitmap_width, graphics->temp_hbitmap_height,
- graphics->temp_hbitmap_width * 4);
+ graphics->temp_hbitmap_width * 4, PixelFormat32bppARGB);
/* Clean up. */
DeleteDC(graphics->temp_hdc);
@@ -6352,7 +6386,7 @@
/* draw the result */
stat = alpha_blend_pixels(graphics, min_x, min_y, pixel_data, pixel_area.Width,
- pixel_area.Height, pixel_data_stride);
+ pixel_area.Height, pixel_data_stride, PixelFormat32bppARGB);
GdipFree(pixel_data);
Modified: trunk/reactos/dll/win32/gdiplus/image.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/image.c?…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -23,6 +23,8 @@
#include <ole2.h>
#include <olectl.h>
+HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
+
#define PIXELFORMATBPP(x) ((x) ? ((x) >> 8) & 255 : 24)
static const struct
@@ -52,8 +54,7 @@
IWICPalette *wic_palette;
ColorPalette *palette = NULL;
- hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
- &IID_IWICImagingFactory, (void **)&factory);
+ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
if (hr != S_OK) return NULL;
hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
@@ -69,22 +70,36 @@
}
if (hr == S_OK)
{
+ WICBitmapPaletteType type;
+ BOOL alpha;
UINT count;
- BOOL mono, gray;
-
- IWICPalette_IsBlackWhite(wic_palette, &mono);
- IWICPalette_IsGrayscale(wic_palette, &gray);
IWICPalette_GetColorCount(wic_palette, &count);
palette = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(UINT) + count *
sizeof(ARGB));
IWICPalette_GetColors(wic_palette, count, palette->Entries,
&palette->Count);
- if (mono)
- palette->Flags = 0;
- else if (gray)
- palette->Flags = PaletteFlagsGrayScale;
- else
- palette->Flags = PaletteFlagsHalftone;
+ IWICPalette_GetType(wic_palette, &type);
+ switch(type) {
+ case WICBitmapPaletteTypeFixedGray4:
+ case WICBitmapPaletteTypeFixedGray16:
+ case WICBitmapPaletteTypeFixedGray256:
+ palette->Flags = PaletteFlagsGrayScale;
+ break;
+ case WICBitmapPaletteTypeFixedHalftone8:
+ case WICBitmapPaletteTypeFixedHalftone27:
+ case WICBitmapPaletteTypeFixedHalftone64:
+ case WICBitmapPaletteTypeFixedHalftone125:
+ case WICBitmapPaletteTypeFixedHalftone216:
+ case WICBitmapPaletteTypeFixedHalftone252:
+ case WICBitmapPaletteTypeFixedHalftone256:
+ palette->Flags = PaletteFlagsHalftone;
+ break;
+ default:
+ palette->Flags = 0;
+ }
+ IWICPalette_HasAlpha(wic_palette, &alpha);
+ if(alpha)
+ palette->Flags |= PaletteFlagsHasAlpha;
}
IWICPalette_Release(wic_palette);
}
@@ -119,6 +134,15 @@
return x;
}
+
+#ifndef __REACTOS__
+GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect)
+{
+ FIXME("(%s, %p): stub\n", debugstr_guid(&guid), effect);
+ *effect = NULL;
+ return NotImplemented;
+}
+#endif
GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap* bitmap, CGpEffect* effect,
RECT* roi, BOOL useAuxData, VOID** auxData, INT* auxDataSize)
@@ -1853,7 +1877,7 @@
(*bitmap)->height = height;
(*bitmap)->format = format;
(*bitmap)->image.picture = NULL;
- (*bitmap)->image.stream = NULL;
+ (*bitmap)->image.decoder = NULL;
(*bitmap)->hbitmap = hbitmap;
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
@@ -2070,9 +2094,9 @@
GdipFree(dst->prop_item);
dst->prop_item = src->prop_item;
dst->prop_count = src->prop_count;
- if (dst->image.stream)
- IStream_Release(dst->image.stream);
- dst->image.stream = src->image.stream;
+ if (dst->image.decoder)
+ IWICBitmapDecoder_Release(dst->image.decoder);
+ dst->image.decoder = src->image.decoder;
dst->image.frame_count = src->image.frame_count;
dst->image.current_frame = src->image.current_frame;
dst->image.format = src->image.format;
@@ -2118,8 +2142,8 @@
}
if (image->picture)
IPicture_Release(image->picture);
- if (image->stream)
- IStream_Release(image->stream);
+ if (image->decoder)
+ IWICBitmapDecoder_Release(image->decoder);
GdipFree(image->palette);
return Ok;
@@ -3026,8 +3050,8 @@
PROPVARIANT id, value;
BOOL ret = FALSE;
- IWICMetadataReader_GetMetadataFormat(reader, &format);
- if (!IsEqualGUID(&format, guid)) return FALSE;
+ hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
+ if (FAILED(hr) || !IsEqualGUID(&format, guid)) return FALSE;
PropVariantInit(&id);
PropVariantInit(&value);
@@ -3053,8 +3077,8 @@
PROPVARIANT id, value;
PropertyItem *item = NULL;
- IWICMetadataReader_GetMetadataFormat(reader, &format);
- if (!IsEqualGUID(&format, guid)) return NULL;
+ hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
+ if (FAILED(hr) || !IsEqualGUID(&format, guid)) return NULL;
PropVariantInit(&id);
PropVariantInit(&value);
@@ -3162,8 +3186,7 @@
if (!get_bool_property(reader, &GUID_MetadataFormatLSD, global_flagW))
return NULL;
- hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
- &IID_IWICImagingFactory, (void **)&factory);
+ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
if (hr != S_OK) return NULL;
hr = IWICImagingFactory_CreatePalette(factory, &palette);
@@ -3221,14 +3244,13 @@
return index;
}
-static LONG get_gif_frame_delay(IWICBitmapFrameDecode *frame)
-{
- static const WCHAR delayW[] = {
'D','e','l','a','y',0 };
+static LONG get_gif_frame_property(IWICBitmapFrameDecode *frame, const GUID *format,
const WCHAR *property)
+{
HRESULT hr;
IWICMetadataBlockReader *block_reader;
IWICMetadataReader *reader;
UINT block_count, i;
- PropertyItem *delay;
+ PropertyItem *prop;
LONG value = 0;
hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader,
(void **)&block_reader);
@@ -3242,13 +3264,15 @@
hr = IWICMetadataBlockReader_GetReaderByIndex(block_reader, i,
&reader);
if (hr == S_OK)
{
- delay = get_property(reader, &GUID_MetadataFormatGCE, delayW);
- if (delay)
+ prop = get_property(reader, format, property);
+ if (prop)
{
- if (delay->type == PropertyTagTypeShort &&
delay->length == 2)
- value = *(SHORT *)delay->value;
-
- GdipFree(delay);
+ if (prop->type == PropertyTagTypeByte &&
prop->length == 1)
+ value = *(BYTE *)prop->value;
+ else if (prop->type == PropertyTagTypeShort &&
prop->length == 2)
+ value = *(SHORT *)prop->value;
+
+ GdipFree(prop);
}
IWICMetadataReader_Release(reader);
}
@@ -3262,6 +3286,7 @@
static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT
active_frame)
{
+ static const WCHAR delayW[] = {
'D','e','l','a','y',0 };
HRESULT hr;
IWICBitmapFrameDecode *frame;
IWICMetadataBlockReader *block_reader;
@@ -3290,7 +3315,7 @@
hr = IWICBitmapDecoder_GetFrame(decoder, i, &frame);
if (hr == S_OK)
{
- value[i] = get_gif_frame_delay(frame);
+ value[i] = get_gif_frame_property(frame, &GUID_MetadataFormatGCE,
delayW);
IWICBitmapFrameDecode_Release(frame);
}
else value[i] = 0;
@@ -3384,15 +3409,174 @@
IWICBitmapFrameDecode_Release(frame);
}
+static PropertyItem* create_prop(PROPID propid, PROPVARIANT* value)
+{
+ PropertyItem *item = NULL;
+ UINT item_size = propvariant_size(value);
+
+ if (item_size)
+ {
+ item_size += sizeof(*item);
+ item = GdipAlloc(item_size);
+ if (propvariant_to_item(value, item, item_size, propid) != Ok)
+ {
+ GdipFree(item);
+ item = NULL;
+ }
+ }
+
+ return item;
+}
+
+static ULONG get_ulong_by_index(IWICMetadataReader* reader, ULONG index)
+{
+ PROPVARIANT value;
+ HRESULT hr;
+ ULONG result=0;
+
+ hr = IWICMetadataReader_GetValueByIndex(reader, index, NULL, NULL, &value);
+ if (SUCCEEDED(hr))
+ {
+ switch (value.vt)
+ {
+ case VT_UI4:
+ result = value.u.ulVal;
+ break;
+ default:
+ ERR("unhandled case %u\n", value.vt);
+ break;
+ }
+ PropVariantClear(&value);
+ }
+ return result;
+}
+
+static void png_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT
active_frame)
+{
+ HRESULT hr;
+ IWICBitmapFrameDecode *frame;
+ IWICMetadataBlockReader *block_reader;
+ IWICMetadataReader *reader;
+ UINT block_count, i, j;
+ struct keyword_info {
+ const char* name;
+ PROPID propid;
+ BOOL seen;
+ } keywords[] = {
+ { "Title", PropertyTagImageTitle },
+ { "Author", PropertyTagArtist },
+ { "Description", PropertyTagImageDescription },
+ { "Copyright", PropertyTagCopyright },
+ { "Software", PropertyTagSoftwareUsed },
+ { "Source", PropertyTagEquipModel },
+ { "Comment", PropertyTagExifUserComment },
+ };
+ BOOL seen_gamma=FALSE;
+
+ hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &frame);
+ if (hr != S_OK) return;
+
+ hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader,
(void **)&block_reader);
+ if (hr == S_OK)
+ {
+ hr = IWICMetadataBlockReader_GetCount(block_reader, &block_count);
+ if (hr == S_OK)
+ {
+ for (i = 0; i < block_count; i++)
+ {
+ hr = IWICMetadataBlockReader_GetReaderByIndex(block_reader, i,
&reader);
+ if (hr == S_OK)
+ {
+ GUID format;
+
+ hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
+ if (SUCCEEDED(hr) &&
IsEqualGUID(&GUID_MetadataFormatChunktEXt, &format))
+ {
+ PROPVARIANT name, value;
+ PropertyItem* item;
+
+ hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL,
&name, &value);
+
+ if (SUCCEEDED(hr))
+ {
+ if (name.vt == VT_LPSTR)
+ {
+ for (j=0; j<sizeof(keywords)/sizeof(keywords[0]);
j++)
+ if (!strcmp(keywords[j].name, name.u.pszVal))
+ break;
+ if (j < sizeof(keywords)/sizeof(keywords[0])
&& !keywords[j].seen)
+ {
+ keywords[j].seen = TRUE;
+ item = create_prop(keywords[j].propid, &value);
+ if (item)
+ add_property(bitmap, item);
+ GdipFree(item);
+ }
+ }
+
+ PropVariantClear(&name);
+ PropVariantClear(&value);
+ }
+ }
+ else if (SUCCEEDED(hr) &&
IsEqualGUID(&GUID_MetadataFormatChunkgAMA, &format))
+ {
+ PropertyItem* item;
+
+ if (!seen_gamma)
+ {
+ item = GdipAlloc(sizeof(PropertyItem) + sizeof(ULONG) * 2);
+ if (item)
+ {
+ ULONG *rational;
+ item->length = sizeof(ULONG) * 2;
+ item->type = PropertyTagTypeRational;
+ item->id = PropertyTagGamma;
+ rational = item->value = item + 1;
+ rational[0] = 100000;
+ rational[1] = get_ulong_by_index(reader, 0);
+ add_property(bitmap, item);
+ seen_gamma = TRUE;
+ GdipFree(item);
+ }
+ }
+ }
+
+ IWICMetadataReader_Release(reader);
+ }
+ }
+ }
+ IWICMetadataBlockReader_Release(block_reader);
+ }
+
+ IWICBitmapFrameDecode_Release(frame);
+}
+
+static GpStatus initialize_decoder_wic(IStream *stream, REFGUID container,
IWICBitmapDecoder **decoder)
+{
+ IWICImagingFactory *factory;
+ HRESULT hr;
+
+ TRACE("%p,%s\n", stream, wine_dbgstr_guid(container));
+
+ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
+ if (FAILED(hr)) return hresult_to_status(hr);
+ hr = IWICImagingFactory_CreateDecoder(factory, container, NULL, decoder);
+ IWICImagingFactory_Release(factory);
+ if (FAILED(hr)) return hresult_to_status(hr);
+
+ hr = IWICBitmapDecoder_Initialize(*decoder, stream, WICDecodeMetadataCacheOnLoad);
+ if (FAILED(hr)) return hresult_to_status(hr);
+ return Ok;
+}
+
typedef void (*metadata_reader_func)(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT
frame);
-static GpStatus decode_image_wic(IStream *stream, GDIPCONST CLSID *clsid,
+static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder, BOOL force_conversion,
UINT active_frame, metadata_reader_func metadata_reader, GpImage **image)
{
GpStatus status=Ok;
GpBitmap *bitmap;
HRESULT hr;
- IWICBitmapDecoder *decoder;
IWICBitmapFrameDecode *frame;
IWICBitmapSource *source=NULL;
IWICMetadataBlockReader *block_reader;
@@ -3404,48 +3588,36 @@
UINT width, height, frame_count;
BitmapData lockeddata;
WICRect wrc;
- HRESULT initresult;
-
- TRACE("%p,%s,%u,%p\n", stream, wine_dbgstr_guid(clsid), active_frame,
image);
-
- initresult = CoInitialize(NULL);
-
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
- &IID_IWICBitmapDecoder, (void**)&decoder);
- if (FAILED(hr)) goto end;
-
- hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
- if (SUCCEEDED(hr))
- {
- IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
- hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &frame);
- }
-
+
+ TRACE("%p,%u,%p\n", decoder, active_frame, image);
+
+ IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+ hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &frame);
if (SUCCEEDED(hr)) /* got frame */
{
hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &wic_format);
if (SUCCEEDED(hr))
{
- IWICBitmapSource *bmp_source;
- IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICBitmapSource, (void
**)&bmp_source);
-
- for (i=0; pixel_formats[i].wic_format; i++)
+ if (!force_conversion)
{
- if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format))
+ for (i=0; pixel_formats[i].wic_format; i++)
{
- source = bmp_source;
- gdip_format = pixel_formats[i].gdip_format;
- palette_type = pixel_formats[i].palette_type;
- break;
+ if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format))
+ {
+ source = (IWICBitmapSource*)frame;
+ IWICBitmapSource_AddRef(source);
+ gdip_format = pixel_formats[i].gdip_format;
+ palette_type = pixel_formats[i].palette_type;
+ break;
+ }
}
}
if (!source)
{
/* unknown format; fall back on 32bppARGB */
- hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
bmp_source, &source);
+ hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
(IWICBitmapSource*)frame, &source);
gdip_format = PixelFormat32bppARGB;
- IWICBitmapSource_Release(bmp_source);
}
TRACE("%s => %#x\n", wine_dbgstr_guid(&wic_format),
gdip_format);
}
@@ -3520,11 +3692,6 @@
}
}
- IWICBitmapDecoder_Release(decoder);
-
-end:
- if (SUCCEEDED(initresult)) CoUninitialize();
-
if (FAILED(hr) && status == Ok) status = hresult_to_status(hr);
if (status == Ok)
@@ -3533,7 +3700,8 @@
bitmap->image.flags |=
ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
bitmap->image.frame_count = frame_count;
bitmap->image.current_frame = active_frame;
- bitmap->image.stream = stream;
+ bitmap->image.decoder = decoder;
+ IWICBitmapDecoder_AddRef(decoder);
if (palette)
{
GdipFree(bitmap->image.palette);
@@ -3544,25 +3712,214 @@
if (IsEqualGUID(&wic_format, &GUID_WICPixelFormatBlackWhite))
bitmap->image.palette->Flags = 0;
}
- /* Pin the source stream */
- IStream_AddRef(stream);
TRACE("=> %p\n", *image);
}
return status;
}
-static GpStatus decode_image_icon(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
-{
- return decode_image_wic(stream, &CLSID_WICIcoDecoder, active_frame, NULL,
image);
-}
-
-static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
+static GpStatus decode_image_wic(IStream *stream, REFGUID container,
+ metadata_reader_func metadata_reader, GpImage **image)
+{
+ IWICBitmapDecoder *decoder;
+ GpStatus status;
+
+ status = initialize_decoder_wic(stream, container, &decoder);
+ if(status != Ok)
+ return status;
+
+ status = decode_frame_wic(decoder, FALSE, 0, metadata_reader, image);
+ IWICBitmapDecoder_Release(decoder);
+ return status;
+}
+
+static GpStatus select_frame_wic(GpImage *image, UINT active_frame)
+{
+ GpImage *new_image;
+ GpStatus status;
+
+ status = decode_frame_wic(image->decoder, FALSE, active_frame, NULL,
&new_image);
+ if(status != Ok)
+ return status;
+
+ memcpy(&new_image->format, &image->format, sizeof(GUID));
+ free_image_data(image);
+ if (image->type == ImageTypeBitmap)
+ *(GpBitmap *)image = *(GpBitmap *)new_image;
+ else if (image->type == ImageTypeMetafile)
+ *(GpMetafile *)image = *(GpMetafile *)new_image;
+ new_image->type = ~0;
+ GdipFree(new_image);
+ return Ok;
+}
+
+static HRESULT get_gif_frame_rect(IWICBitmapFrameDecode *frame,
+ UINT *left, UINT *top, UINT *width, UINT *height)
+{
+ static const WCHAR leftW[] = {'L','e','f','t',0};
+ static const WCHAR topW[] = {'T','o','p',0};
+
+ *left = get_gif_frame_property(frame, &GUID_MetadataFormatIMD, leftW);
+ *top = get_gif_frame_property(frame, &GUID_MetadataFormatIMD, topW);
+
+ return IWICBitmapFrameDecode_GetSize(frame, width, height);
+}
+
+static HRESULT blit_gif_frame(GpBitmap *bitmap, IWICBitmapFrameDecode *frame, BOOL
first_frame)
+{
+ UINT i, j, left, top, width, height;
+ IWICBitmapSource *source;
+ BYTE *new_bits;
+ HRESULT hr;
+
+ hr = get_gif_frame_rect(frame, &left, &top, &width, &height);
+ if(FAILED(hr))
+ return hr;
+
+ hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
(IWICBitmapSource*)frame, &source);
+ if(FAILED(hr))
+ return hr;
+
+ new_bits = GdipAlloc(width*height*4);
+ if(!new_bits)
+ return E_OUTOFMEMORY;
+
+ hr = IWICBitmapSource_CopyPixels(source, NULL, width*4, width*height*4, new_bits);
+ IWICBitmapSource_Release(source);
+ if(FAILED(hr)) {
+ GdipFree(new_bits);
+ return hr;
+ }
+
+ for(i=0; i<height && i+top<bitmap->height; i++) {
+ for(j=0; j<width && j+left<bitmap->width; j++) {
+ DWORD *src = (DWORD*)(new_bits+i*width*4+j*4);
+ DWORD *dst = (DWORD*)(bitmap->bits+(i+top)*bitmap->stride+(j+left)*4);
+
+ if(first_frame || *src>>24 != 0)
+ *dst = *src;
+ }
+ }
+ GdipFree(new_bits);
+ return hr;
+}
+
+static DWORD get_gif_background_color(GpBitmap *bitmap)
+{
+ BYTE bgcolor_idx = 0;
+ UINT i;
+
+ for(i=0; i<bitmap->prop_count; i++) {
+ if(bitmap->prop_item[i].id == PropertyTagIndexBackground) {
+ bgcolor_idx = *(BYTE*)bitmap->prop_item[i].value;
+ break;
+ }
+ }
+
+ for(i=0; i<bitmap->prop_count; i++) {
+ if(bitmap->prop_item[i].id == PropertyTagIndexTransparent) {
+ BYTE transparent_idx;
+ transparent_idx = *(BYTE*)bitmap->prop_item[i].value;
+
+ if(transparent_idx == bgcolor_idx)
+ return 0;
+ }
+ }
+
+ for(i=0; i<bitmap->prop_count; i++) {
+ if(bitmap->prop_item[i].id == PropertyTagGlobalPalette) {
+ if(bitmap->prop_item[i].length/3 > bgcolor_idx) {
+ BYTE *color = ((BYTE*)bitmap->prop_item[i].value)+bgcolor_idx*3;
+ return color[2] + (color[1]<<8) + (color[0]<<16) +
(0xff<<24);
+ }
+ break;
+ }
+ }
+
+ FIXME("can't get gif background color\n");
+ return 0xffffffff;
+}
+
+static GpStatus select_frame_gif(GpImage* image, UINT active_frame)
+{
+ static const WCHAR disposalW[] =
{'D','i','s','p','o','s','a','l',0};
+
+ GpBitmap *bitmap = (GpBitmap*)image;
+ IWICBitmapFrameDecode *frame;
+ int cur_frame=0, disposal;
+ BOOL bgcolor_set = FALSE;
+ DWORD bgcolor = 0;
+ HRESULT hr;
+
+ if(active_frame > image->current_frame) {
+ hr = IWICBitmapDecoder_GetFrame(bitmap->image.decoder,
image->current_frame, &frame);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+ disposal = get_gif_frame_property(frame, &GUID_MetadataFormatGCE,
disposalW);
+ IWICBitmapFrameDecode_Release(frame);
+
+ if(disposal == GIF_DISPOSE_RESTORE_TO_BKGND)
+ cur_frame = image->current_frame;
+ else if(disposal != GIF_DISPOSE_RESTORE_TO_PREV)
+ cur_frame = image->current_frame+1;
+ }
+
+ while(cur_frame != active_frame) {
+ hr = IWICBitmapDecoder_GetFrame(bitmap->image.decoder, cur_frame,
&frame);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+ disposal = get_gif_frame_property(frame, &GUID_MetadataFormatGCE,
disposalW);
+
+ if(disposal==GIF_DISPOSE_UNSPECIFIED || disposal==GIF_DISPOSE_DO_NOT_DISPOSE) {
+ hr = blit_gif_frame(bitmap, frame, cur_frame==0);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+ }else if(disposal == GIF_DISPOSE_RESTORE_TO_BKGND) {
+ UINT left, top, width, height, i, j;
+
+ if(!bgcolor_set) {
+ bgcolor = get_gif_background_color(bitmap);
+ bgcolor_set = TRUE;
+ }
+
+ hr = get_gif_frame_rect(frame, &left, &top, &width,
&height);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+ for(i=top; i<top+height && i<bitmap->height; i++) {
+ DWORD *bits = (DWORD*)(bitmap->bits+i*bitmap->stride);
+ for(j=left; j<left+width && j<bitmap->width; j++)
+ bits[j] = bgcolor;
+ }
+ }
+
+ IWICBitmapFrameDecode_Release(frame);
+ cur_frame++;
+ }
+
+ hr = IWICBitmapDecoder_GetFrame(bitmap->image.decoder, active_frame, &frame);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+
+ hr = blit_gif_frame(bitmap, frame, cur_frame==0);
+ IWICBitmapFrameDecode_Release(frame);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+
+ image->current_frame = active_frame;
+ return Ok;
+}
+
+static GpStatus decode_image_icon(IStream* stream, GpImage **image)
+{
+ return decode_image_wic(stream, &GUID_ContainerFormatIco, NULL, image);
+}
+
+static GpStatus decode_image_bmp(IStream* stream, GpImage **image)
{
GpStatus status;
GpBitmap* bitmap;
- status = decode_image_wic(stream, &CLSID_WICBmpDecoder, active_frame, NULL,
image);
+ status = decode_image_wic(stream, &GUID_ContainerFormatBmp, NULL, image);
bitmap = (GpBitmap*)*image;
@@ -3575,27 +3932,49 @@
return status;
}
-static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
-{
- return decode_image_wic(stream, &CLSID_WICJpegDecoder, active_frame, NULL,
image);
-}
-
-static GpStatus decode_image_png(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
-{
- return decode_image_wic(stream, &CLSID_WICPngDecoder, active_frame, NULL,
image);
-}
-
-static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
-{
- return decode_image_wic(stream, &CLSID_WICGifDecoder, active_frame,
gif_metadata_reader, image);
-}
-
-static GpStatus decode_image_tiff(IStream* stream, REFCLSID clsid, UINT active_frame,
GpImage **image)
-{
- return decode_image_wic(stream, &CLSID_WICTiffDecoder, active_frame, NULL,
image);
-}
-
-static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, UINT
active_frame, GpImage **image)
+static GpStatus decode_image_jpeg(IStream* stream, GpImage **image)
+{
+ return decode_image_wic(stream, &GUID_ContainerFormatJpeg, NULL, image);
+}
+
+static GpStatus decode_image_png(IStream* stream, GpImage **image)
+{
+ return decode_image_wic(stream, &GUID_ContainerFormatPng, png_metadata_reader,
image);
+}
+
+static GpStatus decode_image_gif(IStream* stream, GpImage **image)
+{
+ IWICBitmapDecoder *decoder;
+ UINT frame_count;
+ GpStatus status;
+ HRESULT hr;
+
+ status = initialize_decoder_wic(stream, &GUID_ContainerFormatGif, &decoder);
+ if(status != Ok)
+ return status;
+
+ hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+
+ status = decode_frame_wic(decoder, frame_count > 1, 0, gif_metadata_reader,
image);
+ IWICBitmapDecoder_Release(decoder);
+ if(status != Ok)
+ return status;
+
+ if(frame_count > 1) {
+ GdipFree((*image)->palette);
+ (*image)->palette = NULL;
+ }
+ return Ok;
+}
+
+static GpStatus decode_image_tiff(IStream* stream, GpImage **image)
+{
+ return decode_image_wic(stream, &GUID_ContainerFormatTiff, NULL, image);
+}
+
+static GpStatus decode_image_olepicture_metafile(IStream* stream, GpImage **image)
{
IPicture *pic;
@@ -3614,7 +3993,7 @@
*image = GdipAlloc(sizeof(GpMetafile));
if(!*image) return OutOfMemory;
(*image)->type = ImageTypeMetafile;
- (*image)->stream = NULL;
+ (*image)->decoder = NULL;
(*image)->picture = pic;
(*image)->flags = ImageFlagsNone;
(*image)->frame_count = 1;
@@ -3629,12 +4008,15 @@
typedef GpStatus (*encode_image_func)(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params);
-typedef GpStatus (*decode_image_func)(IStream *stream, REFCLSID clsid, UINT active_frame,
GpImage **image);
+typedef GpStatus (*decode_image_func)(IStream *stream, GpImage **image);
+
+typedef GpStatus (*select_image_func)(GpImage *image, UINT active_frame);
typedef struct image_codec {
ImageCodecInfo info;
encode_image_func encode_func;
decode_image_func decode_func;
+ select_image_func select_func;
} image_codec;
typedef enum {
@@ -3699,14 +4081,28 @@
return GenericError;
}
+static GpStatus get_decoder_info_from_image(GpImage *image, const struct image_codec
**result)
+{
+ int i;
+
+ for (i = 0; i < NUM_CODECS; i++) {
+ if ((codecs[i].info.Flags & ImageCodecFlagsDecoder) &&
+ IsEqualIID(&codecs[i].info.FormatID, &image->format))
+ {
+ *result = &codecs[i];
+ return Ok;
+ }
+ }
+
+ TRACE("no match for format: %s\n",
wine_dbgstr_guid(&image->format));
+ return GenericError;
+}
+
GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID
*dimensionID,
UINT frame)
{
GpStatus stat;
- LARGE_INTEGER seek;
- HRESULT hr;
const struct image_codec *codec = NULL;
- GpImage *new_image;
TRACE("(%p,%s,%u)\n", image, debugstr_guid(dimensionID), frame);
@@ -3728,43 +4124,21 @@
if (image->current_frame == frame)
return Ok;
- if (!image->stream)
- {
- TRACE("image doesn't have an associated stream\n");
+ if (!image->decoder)
+ {
+ TRACE("image doesn't have an associated decoder\n");
return Ok;
}
/* choose an appropriate image decoder */
- stat = get_decoder_info(image->stream, &codec);
+ stat = get_decoder_info_from_image(image, &codec);
if (stat != Ok)
{
WARN("can't find decoder info\n");
return stat;
}
- /* seek to the start of the stream */
- seek.QuadPart = 0;
- hr = IStream_Seek(image->stream, seek, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- return hresult_to_status(hr);
-
- /* call on the image decoder to do the real work */
- stat = codec->decode_func(image->stream, &codec->info.Clsid, frame,
&new_image);
-
- if (stat == Ok)
- {
- memcpy(&new_image->format, &codec->info.FormatID, sizeof(GUID));
- free_image_data(image);
- if (image->type == ImageTypeBitmap)
- *(GpBitmap *)image = *(GpBitmap *)new_image;
- else if (image->type == ImageTypeMetafile)
- *(GpMetafile *)image = *(GpMetafile *)new_image;
- new_image->type = ~0;
- GdipFree(new_image);
- return Ok;
- }
-
- return stat;
+ return codec->select_func(image, frame);
}
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image)
@@ -3784,7 +4158,7 @@
if (FAILED(hr)) return hresult_to_status(hr);
/* call on the image decoder to do the real work */
- stat = codec->decode_func(stream, &codec->info.Clsid, 0, image);
+ stat = codec->decode_func(stream, image);
/* take note of the original data format */
if (stat == Ok)
@@ -3860,11 +4234,12 @@
* These functions encode an image in different image file formats.
*/
-static GpStatus encode_image_WIC(GpImage *image, IStream* stream,
- GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
+static GpStatus encode_image_wic(GpImage *image, IStream* stream,
+ REFGUID container, GDIPCONST EncoderParameters* params)
{
GpStatus stat;
GpBitmap *bitmap;
+ IWICImagingFactory *factory;
IWICBitmapEncoder *encoder;
IWICBitmapFrameEncode *frameencode;
IPropertyBag2 *encoderoptions;
@@ -3875,7 +4250,6 @@
WICPixelFormatGUID wicformat;
GpRect rc;
BitmapData lockeddata;
- HRESULT initresult;
UINT i;
if (image->type != ImageTypeBitmap)
@@ -3891,15 +4265,13 @@
rc.Width = width;
rc.Height = height;
- initresult = CoInitialize(NULL);
-
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
- &IID_IWICBitmapEncoder, (void**)&encoder);
+ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
if (FAILED(hr))
- {
- if (SUCCEEDED(initresult)) CoUninitialize();
return hresult_to_status(hr);
- }
+ hr = IWICImagingFactory_CreateEncoder(factory, container, NULL, &encoder);
+ IWICImagingFactory_Release(factory);
+ if (FAILED(hr))
+ return hresult_to_status(hr);
hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
@@ -3994,34 +4366,37 @@
hr = IWICBitmapEncoder_Commit(encoder);
IWICBitmapEncoder_Release(encoder);
-
- if (SUCCEEDED(initresult)) CoUninitialize();
-
return hresult_to_status(hr);
}
static GpStatus encode_image_BMP(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
- return encode_image_WIC(image, stream, &CLSID_WICBmpEncoder, params);
+ return encode_image_wic(image, stream, &GUID_ContainerFormatBmp, params);
}
static GpStatus encode_image_tiff(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
- return encode_image_WIC(image, stream, &CLSID_WICTiffEncoder, params);
+ return encode_image_wic(image, stream, &GUID_ContainerFormatTiff, params);
}
static GpStatus encode_image_png(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
- return encode_image_WIC(image, stream, &CLSID_WICPngEncoder, params);
+ return encode_image_wic(image, stream, &GUID_ContainerFormatPng, params);
}
static GpStatus encode_image_jpeg(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
- return encode_image_WIC(image, stream, &CLSID_WICJpegEncoder, params);
+ return encode_image_wic(image, stream, &GUID_ContainerFormatJpeg, params);
+}
+
+static GpStatus encode_image_gif(GpImage *image, IStream* stream,
+ GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
+{
+ return encode_image_wic(image, stream, &CLSID_WICGifEncoder, params);
}
/*****************************************************************************
@@ -4202,7 +4577,8 @@
/* SigMask */ bmp_sig_mask,
},
encode_image_BMP,
- decode_image_bmp
+ decode_image_bmp,
+ select_frame_wic
},
{
{ /* JPEG */
@@ -4221,7 +4597,8 @@
/* SigMask */ jpeg_sig_mask,
},
encode_image_jpeg,
- decode_image_jpeg
+ decode_image_jpeg,
+ select_frame_wic
},
{
{ /* GIF */
@@ -4232,15 +4609,16 @@
/* FormatDescription */ gif_format,
/* FilenameExtension */ gif_extension,
/* MimeType */ gif_mimetype,
- /* Flags */ ImageCodecFlagsDecoder |
ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
+ /* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsEncoder |
ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Version */ 1,
/* SigCount */ 2,
/* SigSize */ 6,
/* SigPattern */ gif_sig_pattern,
/* SigMask */ gif_sig_mask,
},
- NULL,
- decode_image_gif
+ encode_image_gif,
+ decode_image_gif,
+ select_frame_gif
},
{
{ /* TIFF */
@@ -4259,7 +4637,8 @@
/* SigMask */ tiff_sig_mask,
},
encode_image_tiff,
- decode_image_tiff
+ decode_image_tiff,
+ select_frame_wic
},
{
{ /* EMF */
@@ -4278,7 +4657,8 @@
/* SigMask */ emf_sig_mask,
},
NULL,
- decode_image_olepicture_metafile
+ decode_image_olepicture_metafile,
+ NULL
},
{
{ /* WMF */
@@ -4297,7 +4677,8 @@
/* SigMask */ wmf_sig_mask,
},
NULL,
- decode_image_olepicture_metafile
+ decode_image_olepicture_metafile,
+ NULL
},
{
{ /* PNG */
@@ -4316,7 +4697,8 @@
/* SigMask */ png_sig_mask,
},
encode_image_png,
- decode_image_png
+ decode_image_png,
+ select_frame_wic
},
{
{ /* ICO */
@@ -4335,7 +4717,8 @@
/* SigMask */ ico_sig_mask,
},
NULL,
- decode_image_icon
+ decode_image_icon,
+ select_frame_wic
},
};
@@ -4850,3 +5233,12 @@
return stat;
}
+
+/*****************************************************************************
+ * GdipImageSetAbort [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipImageSetAbort(GpImage *image, GdiplusAbort *pabort)
+{
+ FIXME("(%p, %p): stub\n", image, pabort);
+ return NotImplemented;
+}
Modified: trunk/reactos/dll/win32/gdiplus/metafile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/metafile…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/metafile.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/metafile.c [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -1105,10 +1105,11 @@
TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
debugstr_w(description), out_metafile);
- if(!ref || !metafile || !out_metafile)
- return InvalidParameter;
-
- *succ = FALSE;
+ if(!ref || !metafile || !out_metafile || emfType < EmfTypeEmfOnly || emfType >
EmfTypeEmfPlusDual)
+ return InvalidParameter;
+
+ if(succ)
+ *succ = FALSE;
*out_metafile = NULL;
if(!(calls++))
Modified: trunk/reactos/dll/win32/gdiplus/region.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/region.c…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/region.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/region.c [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -532,224 +532,6 @@
return GdipCreateRegionRect(&rectf, region);
}
-
-static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT
size)
-{
- mbuf->buffer = buffer;
- mbuf->size = size;
- mbuf->pos = 0;
-}
-
-static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
-{
- if (mbuf->size - mbuf->pos >= size)
- {
- const void *data = mbuf->buffer + mbuf->pos;
- mbuf->pos += size;
- return data;
- }
- return NULL;
-}
-
-static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element
*node, INT *count)
-{
- GpStatus status;
- const DWORD *type;
-
- type = buffer_read(mbuf, sizeof(DWORD));
- if (!type) return Ok;
-
- TRACE("type %#x\n", *type);
-
- node->type = *type;
-
- switch (node->type)
- {
- case CombineModeReplace:
- case CombineModeIntersect:
- case CombineModeUnion:
- case CombineModeXor:
- case CombineModeExclude:
- case CombineModeComplement:
- {
- region_element *left, *right;
-
- left = GdipAlloc(sizeof(region_element));
- if (!left) return OutOfMemory;
- right = GdipAlloc(sizeof(region_element));
- if (!right)
- {
- GdipFree(left);
- return OutOfMemory;
- }
-
- status = read_element(mbuf, region, left, count);
- if (status == Ok)
- {
- status = read_element(mbuf, region, right, count);
- if (status == Ok)
- {
- node->elementdata.combine.left = left;
- node->elementdata.combine.right = right;
- region->num_children += 2;
- return Ok;
- }
- }
-
- GdipFree(left);
- GdipFree(right);
- return status;
- }
-
- case RegionDataRect:
- {
- const GpRectF *rc;
-
- rc = buffer_read(mbuf, sizeof(GpRectF));
- if (!rc)
- {
- ERR("failed to read rect data\n");
- return InvalidParameter;
- }
-
- node->elementdata.rect = *rc;
- *count += 1;
- return Ok;
- }
-
- case RegionDataPath:
- {
- GpPath *path;
- const struct path_header *path_header;
- const BYTE *types;
-
- path_header = buffer_read(mbuf, sizeof(struct path_header));
- if (!path_header)
- {
- ERR("failed to read path header\n");
- return InvalidParameter;
- }
- if (path_header->magic != VERSION_MAGIC)
- {
- ERR("invalid path header magic %#x\n", path_header->magic);
- return InvalidParameter;
- }
-
- /* Windows always fails to create an empty path in a region */
- if (!path_header->count)
- {
- TRACE("refusing to create an empty path in a region\n");
- return GenericError;
- }
-
- status = GdipCreatePath(FillModeAlternate, &path);
- if (status) return status;
-
- node->elementdata.path = path;
-
- if (!lengthen_path(path, path_header->count))
- return OutOfMemory;
-
- path->pathdata.Count = path_header->count;
-
- if (path_header->flags & ~FLAGS_INTPATH)
- FIXME("unhandled path flags %#x\n", path_header->flags);
-
- if (path_header->flags & FLAGS_INTPATH)
- {
- const packed_point *pt;
- DWORD i;
-
- pt = buffer_read(mbuf, sizeof(packed_point) * path_header->count);
- if (!pt)
- {
- ERR("failed to read packed %u path points\n",
path_header->count);
- return InvalidParameter;
- }
-
- for (i = 0; i < path_header->count; i++)
- {
- path->pathdata.Points[i].X = (REAL)pt[i].X;
- path->pathdata.Points[i].Y = (REAL)pt[i].Y;
- }
- }
- else
- {
- const GpPointF *ptf;
-
- ptf = buffer_read(mbuf, sizeof(GpPointF) * path_header->count);
- if (!ptf)
- {
- ERR("failed to read %u path points\n", path_header->count);
- return InvalidParameter;
- }
- memcpy(path->pathdata.Points, ptf, sizeof(GpPointF) *
path_header->count);
- }
-
- types = buffer_read(mbuf, path_header->count);
- if (!types)
- {
- ERR("failed to read %u path types\n", path_header->count);
- return InvalidParameter;
- }
- memcpy(path->pathdata.Types, types, path_header->count);
- if (path_header->count & 3)
- {
- if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
- {
- ERR("failed to read rounding %u bytes\n", 4 -
(path_header->count & 3));
- return InvalidParameter;
- }
- }
-
- *count += 1;
- return Ok;
- }
-
- case RegionDataEmptyRect:
- case RegionDataInfiniteRect:
- *count += 1;
- return Ok;
-
- default:
- FIXME("element type %#x is not supported\n", *type);
- break;
- }
-
- return InvalidParameter;
-}
-
-GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion
**region)
-{
- GpStatus status;
- struct memory_buffer mbuf;
- const struct region_header *region_header;
- INT count;
-
- if (!data || !size) return InvalidParameter;
-
- TRACE("%p, %d, %p\n", data, size, region);
-
- init_memory_buffer(&mbuf, data, size);
-
- region_header = buffer_read(&mbuf, sizeof(struct region_header));
- if (!region_header || region_header->magic != VERSION_MAGIC)
- return InvalidParameter;
-
- status = GdipCreateRegion(region);
- if (status != Ok) return status;
-
- count = 0;
- status = read_element(&mbuf, *region, &(*region)->node, &count);
- if (status == Ok && !count)
- status = InvalidParameter;
-
- if (status != Ok)
- GdipDeleteRegion(*region);
-
- return status;
-}
-
/******************************************************************************
* GdipCreateRegionHrgn [GDIPLUS.@]
@@ -1071,6 +853,232 @@
return Ok;
}
+static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT
size)
+{
+ mbuf->buffer = buffer;
+ mbuf->size = size;
+ mbuf->pos = 0;
+}
+
+static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
+{
+ if (mbuf->size - mbuf->pos >= size)
+ {
+ const void *data = mbuf->buffer + mbuf->pos;
+ mbuf->pos += size;
+ return data;
+ }
+ return NULL;
+}
+
+static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element
*node, INT *count)
+{
+ GpStatus status;
+ const DWORD *type;
+
+ type = buffer_read(mbuf, sizeof(*type));
+ if (!type) return Ok;
+
+ TRACE("type %#x\n", *type);
+
+ node->type = *type;
+
+ switch (node->type)
+ {
+ case CombineModeReplace:
+ case CombineModeIntersect:
+ case CombineModeUnion:
+ case CombineModeXor:
+ case CombineModeExclude:
+ case CombineModeComplement:
+ {
+ region_element *left, *right;
+
+ left = GdipAlloc(sizeof(region_element));
+ if (!left) return OutOfMemory;
+ right = GdipAlloc(sizeof(region_element));
+ if (!right)
+ {
+ GdipFree(left);
+ return OutOfMemory;
+ }
+
+ status = read_element(mbuf, region, left, count);
+ if (status == Ok)
+ {
+ status = read_element(mbuf, region, right, count);
+ if (status == Ok)
+ {
+ node->elementdata.combine.left = left;
+ node->elementdata.combine.right = right;
+ region->num_children += 2;
+ return Ok;
+ }
+ }
+
+ GdipFree(left);
+ GdipFree(right);
+ return status;
+ }
+
+ case RegionDataRect:
+ {
+ const GpRectF *rc;
+
+ rc = buffer_read(mbuf, sizeof(*rc));
+ if (!rc)
+ {
+ ERR("failed to read rect data\n");
+ return InvalidParameter;
+ }
+
+ node->elementdata.rect = *rc;
+ *count += 1;
+ return Ok;
+ }
+
+ case RegionDataPath:
+ {
+ GpPath *path;
+ const struct path_header *path_header;
+ const BYTE *types;
+
+ path_header = buffer_read(mbuf, sizeof(*path_header));
+ if (!path_header)
+ {
+ ERR("failed to read path header\n");
+ return InvalidParameter;
+ }
+ if (path_header->magic != VERSION_MAGIC)
+ {
+ ERR("invalid path header magic %#x\n", path_header->magic);
+ return InvalidParameter;
+ }
+
+ /* Windows always fails to create an empty path in a region */
+ if (!path_header->count)
+ {
+ TRACE("refusing to create an empty path in a region\n");
+ return GenericError;
+ }
+
+ status = GdipCreatePath(FillModeAlternate, &path);
+ if (status) return status;
+
+ node->elementdata.path = path;
+
+ if (!lengthen_path(path, path_header->count))
+ return OutOfMemory;
+
+ path->pathdata.Count = path_header->count;
+
+ if (path_header->flags & ~FLAGS_INTPATH)
+ FIXME("unhandled path flags %#x\n", path_header->flags);
+
+ if (path_header->flags & FLAGS_INTPATH)
+ {
+ const packed_point *pt;
+ DWORD i;
+
+ pt = buffer_read(mbuf, sizeof(*pt) * path_header->count);
+ if (!pt)
+ {
+ ERR("failed to read packed %u path points\n",
path_header->count);
+ return InvalidParameter;
+ }
+
+ for (i = 0; i < path_header->count; i++)
+ {
+ path->pathdata.Points[i].X = (REAL)pt[i].X;
+ path->pathdata.Points[i].Y = (REAL)pt[i].Y;
+ }
+ }
+ else
+ {
+ const GpPointF *ptf;
+
+ ptf = buffer_read(mbuf, sizeof(*ptf) * path_header->count);
+ if (!ptf)
+ {
+ ERR("failed to read %u path points\n", path_header->count);
+ return InvalidParameter;
+ }
+ memcpy(path->pathdata.Points, ptf, sizeof(*ptf) * path_header->count);
+ }
+
+ types = buffer_read(mbuf, path_header->count);
+ if (!types)
+ {
+ ERR("failed to read %u path types\n", path_header->count);
+ return InvalidParameter;
+ }
+ memcpy(path->pathdata.Types, types, path_header->count);
+ if (path_header->count & 3)
+ {
+ if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
+ {
+ ERR("failed to read rounding %u bytes\n", 4 -
(path_header->count & 3));
+ return InvalidParameter;
+ }
+ }
+
+ *count += 1;
+ return Ok;
+ }
+
+ case RegionDataEmptyRect:
+ case RegionDataInfiniteRect:
+ *count += 1;
+ return Ok;
+
+ default:
+ FIXME("element type %#x is not supported\n", *type);
+ break;
+ }
+
+ return InvalidParameter;
+}
+
+/*****************************************************************************
+ * GdipCreateRegionRgnData [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion
**region)
+{
+ const struct region_header *region_header;
+ struct memory_buffer mbuf;
+ GpStatus status;
+ INT count;
+
+ TRACE("(%p, %d, %p)\n", data, size, region);
+
+ if (!data || !size)
+ return InvalidParameter;
+
+ init_memory_buffer(&mbuf, data, size);
+
+ region_header = buffer_read(&mbuf, sizeof(*region_header));
+ if (!region_header || (region_header->magic != VERSION_MAGIC &&
+ region_header->magic != VERSION_MAGIC2))
+ return InvalidParameter;
+
+ status = GdipCreateRegion(region);
+ if (status != Ok)
+ return status;
+
+ count = 0;
+ status = read_element(&mbuf, *region, &(*region)->node, &count);
+ if (status == Ok && !count)
+ status = InvalidParameter;
+
+ if (status != Ok)
+ {
+ GdipDeleteRegion(*region);
+ *region = NULL;
+ }
+
+ return status;
+}
+
/*****************************************************************************
* GdipGetRegionDataSize [GDIPLUS.@]
*/
@@ -1098,16 +1106,12 @@
{
new_hdc = CreateCompatibleDC(0);
if (!new_hdc)
- {
- ERR("CreateCompatibleDC failed\n");
return OutOfMemory;
- }
stat = GdipCreateFromHDC(new_hdc, &new_graphics);
graphics = new_graphics;
if (stat != Ok)
{
- ERR("GdipCreateFromHDC failed: 0x%x\n", stat);
DeleteDC(new_hdc);
return stat;
}
@@ -1116,10 +1120,7 @@
{
graphics->hdc = new_hdc = CreateCompatibleDC(0);
if (!new_hdc)
- {
- ERR("CreateCompatibleDC failed\n");
return OutOfMemory;
- }
}
save_state = SaveDC(graphics->hdc);
@@ -1132,15 +1133,7 @@
if (stat == Ok)
{
*hrgn = PathToRegion(graphics->hdc);
- if (*hrgn == NULL)
- {
- ERR("PathToRegion failed\n");
- }
stat = *hrgn ? Ok : OutOfMemory;
- }
- else
- {
- ERR("trace_path failed: 0x%x\n", stat);
}
RestoreDC(graphics->hdc, save_state);
@@ -1176,18 +1169,11 @@
stat = GdipCreatePath(FillModeAlternate, &path);
if (stat != Ok)
- {
- ERR("GdipCreatePath failed: 0x%x\n", stat);
return stat;
- }
stat = GdipAddPathRectangle(path, rc->X, rc->Y, rc->Width,
rc->Height);
if (stat == Ok)
stat = get_path_hrgn(path, graphics, hrgn);
- else
- {
- ERR("GdipAddPathRectangle failed: 0x%x\n", stat);
- }
GdipDeletePath(path);
@@ -1218,7 +1204,7 @@
case CombineModeIntersect:
return get_region_hrgn(element->elementdata.combine.right,
graphics, hrgn);
case CombineModeXor: case CombineModeExclude:
- left = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
+ left = CreateRectRgn(-(1 << 22), -(1 << 22), 1
<< 22, 1 << 22);
break;
case CombineModeUnion: case CombineModeComplement:
*hrgn = NULL;
@@ -1243,7 +1229,7 @@
*hrgn = left;
return Ok;
case CombineModeXor: case CombineModeComplement:
- right = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
+ right = CreateRectRgn(-(1 << 22), -(1 << 22), 1
<< 22, 1 << 22);
break;
case CombineModeUnion: case CombineModeExclude:
DeleteObject(left);
@@ -1297,18 +1283,12 @@
*/
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN
*hrgn)
{
- GpStatus status;
TRACE("(%p, %p, %p)\n", region, graphics, hrgn);
if (!region || !hrgn)
return InvalidParameter;
- status = get_region_hrgn(®ion->node, graphics, hrgn);
- if (status != Ok)
- {
- ERR("get_region_hrgn() failed. region->node.type = 0x%x\n",
region->node.type);
- }
- return status;
+ return get_region_hrgn(®ion->node, graphics, hrgn);
}
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
Modified: trunk/reactos/media/doc/README.WINE
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sun Jul 19 13:31:15 2015
@@ -70,7 +70,7 @@
reactos/dll/win32/faultrep # Synced to WineStaging-1.7.37
reactos/dll/win32/fltlib # Synced to WineStaging-1.7.47
reactos/dll/win32/fusion # Synced to WineStaging-1.7.47
-reactos/dll/win32/gdiplus # Synced to WineStaging-1.7.37
+reactos/dll/win32/gdiplus # Synced to WineStaging-1.7.47
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-1.7.47
reactos/dll/win32/hlink # Synced to WineStaging-1.7.37
reactos/dll/win32/hnetcfg # Synced to WineStaging-1.7.37