Author: gschneider
Date: Sat Nov 28 16:26:02 2009
New Revision: 44308
URL:
http://svn.reactos.org/svn/reactos?rev=44308&view=rev
Log:
[gdiplus]
- Update to current Wine sources
- Now routes BMP drawing to gdi instead of doing ole32 magic (bug #3412)
Modified:
trunk/reactos/dll/win32/gdiplus/brush.c
trunk/reactos/dll/win32/gdiplus/gdiplus.c
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
Modified: trunk/reactos/dll/win32/gdiplus/brush.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/brush.c?…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] Sat Nov 28 16:26:02 2009
@@ -143,7 +143,7 @@
}
case BrushTypeLinearGradient:{
GpLineGradient *dest, *src;
- INT count;
+ INT count, pcount;
dest = GdipAlloc(sizeof(GpLineGradient));
if(!dest) return OutOfMemory;
@@ -157,11 +157,20 @@
count = dest->blendcount;
dest->blendfac = GdipAlloc(count * sizeof(REAL));
dest->blendpos = GdipAlloc(count * sizeof(REAL));
-
- if (!dest->blendfac || !dest->blendpos)
+ pcount = dest->pblendcount;
+ if (pcount)
+ {
+ dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
+ dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
+ }
+
+ if (!dest->blendfac || !dest->blendpos ||
+ (pcount && (!dest->pblendcolor || !dest->pblendpos)))
{
GdipFree(dest->blendfac);
GdipFree(dest->blendpos);
+ GdipFree(dest->pblendcolor);
+ GdipFree(dest->pblendpos);
DeleteObject(dest->brush.gdibrush);
GdipFree(dest);
return OutOfMemory;
@@ -169,6 +178,12 @@
memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
+
+ if (pcount)
+ {
+ memcpy(dest->pblendcolor, src->pblendcolor, pcount *
sizeof(ARGB));
+ memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
+ }
*clone = &dest->brush;
break;
@@ -189,19 +204,38 @@
return Ok;
}
-static LONG HatchStyleToHatch(HatchStyle hatchstyle)
-{
- switch (hatchstyle)
- {
- case HatchStyleHorizontal: return HS_HORIZONTAL;
- case HatchStyleVertical: return HS_VERTICAL;
- case HatchStyleForwardDiagonal: return HS_FDIAGONAL;
- case HatchStyleBackwardDiagonal: return HS_BDIAGONAL;
- case HatchStyleCross: return HS_CROSS;
- case HatchStyleDiagonalCross: return HS_DIAGCROSS;
- default: return 0;
- }
-}
+static const char HatchBrushes[][8] = {
+ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
+ { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
+ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
+ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
+ { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
+ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
+ { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
+ { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
+ { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
+ { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
+ { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
+ { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
+ { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
+ { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
+ { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
+ { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
+ { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
+ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /*
HatchStyleLightDownwardDiagonal */
+ { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal
*/
+ { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal
*/
+ { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal
*/
+ { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal
*/
+ { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal
*/
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
+ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
+ { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
+ { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
+ { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
+};
/******************************************************************************
* GdipCreateHatchBrush [GDIPLUS.@]
@@ -209,6 +243,7 @@
GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB
backcol, GpHatch **brush)
{
COLORREF fgcol = ARGB2COLORREF(forecol);
+ GpStatus stat = Ok;
TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
@@ -217,37 +252,79 @@
*brush = GdipAlloc(sizeof(GpHatch));
if (!*brush) return OutOfMemory;
- switch (hatchstyle)
+ if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
{
- case HatchStyleHorizontal:
- case HatchStyleVertical:
- case HatchStyleForwardDiagonal:
- case HatchStyleBackwardDiagonal:
- case HatchStyleCross:
- case HatchStyleDiagonalCross:
- /* Brushes that map to BS_HATCHED */
- (*brush)->brush.lb.lbStyle = BS_HATCHED;
- (*brush)->brush.lb.lbColor = fgcol;
- (*brush)->brush.lb.lbHatch = HatchStyleToHatch(hatchstyle);
- break;
-
- default:
- FIXME("Unimplemented hatch style %d\n", hatchstyle);
-
- (*brush)->brush.lb.lbStyle = BS_SOLID;
- (*brush)->brush.lb.lbColor = fgcol;
- (*brush)->brush.lb.lbHatch = 0;
- break;
- }
-
-
- (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
- (*brush)->brush.bt = BrushTypeHatchFill;
- (*brush)->forecol = forecol;
- (*brush)->backcol = backcol;
- (*brush)->hatchstyle = hatchstyle;
-
- return Ok;
+ HBITMAP hbmp;
+ HDC hdc;
+ BITMAPINFOHEADER bmih;
+ DWORD* bits;
+ int x, y;
+
+ hdc = CreateCompatibleDC(0);
+
+ if (hdc)
+ {
+ bmih.biSize = sizeof(bmih);
+ bmih.biWidth = 8;
+ bmih.biHeight = 8;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 32;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = 0;
+
+ hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS,
(void**)&bits, NULL, 0);
+
+ if (hbmp)
+ {
+ for (y=0; y<8; y++)
+ for (x=0; x<8; x++)
+ if ((HatchBrushes[hatchstyle][y] & (0x80 >> x)) != 0)
+ bits[y*8+x] = forecol;
+ else
+ bits[y*8+x] = backcol;
+ }
+ else
+ stat = GenericError;
+
+ DeleteDC(hdc);
+ }
+ else
+ stat = GenericError;
+
+ if (stat == Ok)
+ {
+ (*brush)->brush.lb.lbStyle = BS_PATTERN;
+ (*brush)->brush.lb.lbColor = 0;
+ (*brush)->brush.lb.lbHatch = (ULONG_PTR)hbmp;
+ (*brush)->brush.gdibrush =
CreateBrushIndirect(&(*brush)->brush.lb);
+
+ DeleteObject(hbmp);
+ }
+ }
+ else
+ {
+ FIXME("Unimplemented hatch style %d\n", hatchstyle);
+
+ (*brush)->brush.lb.lbStyle = BS_SOLID;
+ (*brush)->brush.lb.lbColor = fgcol;
+ (*brush)->brush.lb.lbHatch = 0;
+ (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
+ }
+
+ if (stat == Ok)
+ {
+ (*brush)->brush.bt = BrushTypeHatchFill;
+ (*brush)->forecol = forecol;
+ (*brush)->backcol = backcol;
+ (*brush)->hatchstyle = hatchstyle;
+ }
+ else
+ {
+ GdipFree(*brush);
+ *brush = NULL;
+ }
+
+ return stat;
}
/******************************************************************************
@@ -315,6 +392,10 @@
(*line)->blendfac[0] = 1.0f;
(*line)->blendpos[0] = 1.0f;
+
+ (*line)->pblendcolor = NULL;
+ (*line)->pblendpos = NULL;
+ (*line)->pblendcount = 0;
return Ok;
}
@@ -762,7 +843,7 @@
/* image is flipped */
if(pbmi->bmiHeader.biHeight > 0){
- dibits += pbmi->bmiHeader.biSizeImage;
+ dibits += image_stride * (pbmi->bmiHeader.biHeight - 1);
image_stride *= -1;
textbits += stride * (n_height - 1);
stride *= -1;
@@ -893,6 +974,8 @@
case BrushTypeLinearGradient:
GdipFree(((GpLineGradient*)brush)->blendfac);
GdipFree(((GpLineGradient*)brush)->blendpos);
+ GdipFree(((GpLineGradient*)brush)->pblendcolor);
+ GdipFree(((GpLineGradient*)brush)->pblendpos);
break;
case BrushTypeTextureFill:
GdipDeleteMatrix(((GpTexture*)brush)->transform);
@@ -1601,6 +1684,69 @@
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
{
+ ARGB *new_color;
+ REAL *new_pos;
+ TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count);
+
+ if (!brush || !blend || !positions || count < 2 ||
+ positions[0] != 0.0f || positions[count-1] != 1.0f)
+ {
+ return InvalidParameter;
+ }
+
+ new_color = GdipAlloc(count * sizeof(ARGB));
+ new_pos = GdipAlloc(count * sizeof(REAL));
+ if (!new_color || !new_pos)
+ {
+ GdipFree(new_color);
+ GdipFree(new_pos);
+ return OutOfMemory;
+ }
+
+ memcpy(new_color, blend, sizeof(ARGB) * count);
+ memcpy(new_pos, positions, sizeof(REAL) * count);
+
+ GdipFree(brush->pblendcolor);
+ GdipFree(brush->pblendpos);
+
+ brush->pblendcolor = new_color;
+ brush->pblendpos = new_pos;
+ brush->pblendcount = count;
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush,
+ ARGB *blend, REAL* positions, INT count)
+{
+ if (!brush || !blend || !positions || count < 2)
+ return InvalidParameter;
+
+ if (brush->pblendcount == 0)
+ return GenericError;
+
+ if (count < brush->pblendcount)
+ return InsufficientBuffer;
+
+ memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
+ memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush,
+ INT *count)
+{
+ if (!brush || !count)
+ return InvalidParameter;
+
+ *count = brush->pblendcount;
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
+{
static int calls;
if(!(calls++))
@@ -1611,6 +1757,17 @@
GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
GDIPCONST GpMatrix *matrix)
+{
+ static int calls;
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy,
+ GpMatrixOrder order)
{
static int calls;
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.c [iso-8859-1] Sat Nov 28 16:26:02 2009
@@ -86,7 +86,7 @@
input->DebugEventCallback, input->SuppressBackgroundThread,
input->SuppressExternalCodecs);
- if(input->GdiplusVersion != 1)
+ if(input->GdiplusVersion < 1 || input->GdiplusVersion > 2)
return UnsupportedGdiplusVersion;
if(input->SuppressBackgroundThread){
@@ -211,38 +211,37 @@
INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
REAL startAngle, REAL sweepAngle)
{
- INT i, count;
+ INT i;
REAL end_angle, start_angle, endAngle;
endAngle = startAngle + sweepAngle;
unstretch_angle(&startAngle, x2 / 2.0, y2 / 2.0);
unstretch_angle(&endAngle, x2 / 2.0, y2 / 2.0);
- count = ceilf(fabs(endAngle - startAngle) / M_PI_2) * 3 + 1;
- /* don't make more than a full circle */
- count = min(MAX_ARC_PTS, count);
-
- if(count == 1)
- return 0;
- if(!points)
- return count;
-
/* start_angle and end_angle are the iterative variables */
start_angle = startAngle;
- for(i = 0; i < count - 1; i += 3){
+ for(i = 0; i < MAX_ARC_PTS - 1; i += 3){
/* check if we've overshot the end angle */
if( sweepAngle > 0.0 )
+ {
+ if (start_angle >= endAngle) break;
end_angle = min(start_angle + M_PI_2, endAngle);
+ }
else
+ {
+ if (start_angle <= endAngle) break;
end_angle = max(start_angle - M_PI_2, endAngle);
-
- add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
+ }
+
+ if (points)
+ add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i ==
0);
start_angle += M_PI_2 * (sweepAngle < 0.0 ? -1.0 : 1.0);
}
- return count;
+ if (i == 0) return 0;
+ else return i+1;
}
COLORREF ARGB2COLORREF(ARGB color)
@@ -419,7 +418,7 @@
}
/* recursive deletion of GpRegion nodes */
-inline void delete_element(region_element* element)
+void delete_element(region_element* element)
{
switch(element->type)
{
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] Sat Nov 28 16:26:02 2009
@@ -304,8 +304,8 @@
@ stdcall GdipGetLineBlendCount(ptr ptr)
@ stdcall GdipGetLineColors(ptr ptr)
@ stdcall GdipGetLineGammaCorrection(ptr ptr)
-@ stub GdipGetLinePresetBlend
-@ stub GdipGetLinePresetBlendCount
+@ stdcall GdipGetLinePresetBlend(ptr ptr ptr long)
+@ stdcall GdipGetLinePresetBlendCount(ptr ptr)
@ stdcall GdipGetLineRect(ptr ptr)
@ stdcall GdipGetLineRectI(ptr ptr)
@ stdcall GdipGetLineSpacing(ptr long ptr)
@@ -476,7 +476,7 @@
@ stdcall GdipRemovePropertyItem(ptr long)
@ stdcall GdipResetClip(ptr)
@ stub GdipResetImageAttributes
-@ stub GdipResetLineTransform
+@ stdcall GdipResetLineTransform(ptr)
@ stub GdipResetPageTransform
@ stdcall GdipResetPath(ptr)
@ stub GdipResetPathGradientTransform
@@ -496,7 +496,7 @@
@ stdcall GdipSaveGraphics(ptr ptr)
@ stdcall GdipSaveImageToFile(ptr ptr ptr ptr)
@ stdcall GdipSaveImageToStream(ptr ptr ptr ptr)
-@ stub GdipScaleLineTransform
+@ stdcall GdipScaleLineTransform(ptr long long long)
@ stdcall GdipScaleMatrix(ptr long long long)
@ stub GdipScalePathGradientTransform
@ stdcall GdipScalePenTransform(ptr long long long)
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] Sat Nov 28 16:26:02
2009
@@ -61,7 +61,7 @@
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
typedef struct region_element region_element;
-extern inline void delete_element(region_element *element);
+extern void delete_element(region_element *element);
static inline INT roundr(REAL x)
{
@@ -166,6 +166,9 @@
REAL* blendfac; /* blend factors */
REAL* blendpos; /* blend positions */
INT blendcount;
+ ARGB* pblendcolor; /* preset blend colors */
+ REAL* pblendpos; /* preset blend positions */
+ INT pblendcount;
};
struct GpTexture{
@@ -208,6 +211,7 @@
struct GpImage{
IPicture* picture;
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] Sat Nov 28 16:26:02 2009
@@ -220,7 +220,27 @@
blendfac = (left_blendfac * (right_blendpos - position) +
right_blendfac * (position - left_blendpos)) / range;
}
- return blend_colors(brush->startcolor, brush->endcolor, blendfac);
+
+ if (brush->pblendcount == 0)
+ return blend_colors(brush->startcolor, brush->endcolor, blendfac);
+ else
+ {
+ int i=1;
+ ARGB left_blendcolor, right_blendcolor;
+ REAL left_blendpos, right_blendpos;
+
+ /* locate the blend colors surrounding this position */
+ while (blendfac > brush->pblendpos[i])
+ i++;
+
+ /* interpolate between the blend colors */
+ left_blendpos = brush->pblendpos[i-1];
+ left_blendcolor = brush->pblendcolor[i-1];
+ right_blendpos = brush->pblendpos[i];
+ right_blendcolor = brush->pblendcolor[i];
+ blendfac = (blendfac - left_blendpos) / (right_blendpos - left_blendpos);
+ return blend_colors(left_blendcolor, right_blendcolor, blendfac);
+ }
}
static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
@@ -1235,6 +1255,7 @@
(*metafile)->image.type = ImageTypeMetafile;
+ memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID));
(*metafile)->bounds.X = ((REAL) placeable->BoundingBox.Left) / ((REAL)
placeable->Inch);
(*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Right) / ((REAL)
placeable->Inch);
(*metafile)->bounds.Width = ((REAL) (placeable->BoundingBox.Right
@@ -1795,16 +1816,25 @@
REAL x, REAL y, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
GpUnit srcUnit)
{
- FIXME("(%p, %p, %f, %f, %f, %f, %f, %f, %d): stub\n", graphics, image, x,
y, srcx, srcy, srcwidth, srcheight, srcUnit);
- return NotImplemented;
+ GpPointF points[3];
+ TRACE("(%p, %p, %f, %f, %f, %f, %f, %f, %d)\n", graphics, image, x, y,
srcx, srcy, srcwidth, srcheight, srcUnit);
+
+ points[0].X = points[2].X = x;
+ points[0].Y = points[1].Y = y;
+
+ /* FIXME: convert image coordinates to Graphics coordinates? */
+ points[1].X = x + srcwidth;
+ points[2].Y = y + srcheight;
+
+ return GdipDrawImagePointsRect(graphics, image, points, 3, srcx, srcy,
+ srcwidth, srcheight, srcUnit, NULL, NULL, NULL);
}
GpStatus WINGDIPAPI GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image,
INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight,
GpUnit srcUnit)
{
- FIXME("(%p, %p, %d, %d, %d, %d, %d, %d, %d): stub\n", graphics, image, x,
y, srcx, srcy, srcwidth, srcheight, srcUnit);
- return NotImplemented;
+ return GdipDrawImagePointRect(graphics, image, x, y, srcx, srcy, srcwidth, srcheight,
srcUnit);
}
GpStatus WINGDIPAPI GdipDrawImagePoints(GpGraphics *graphics, GpImage *image,
@@ -1854,15 +1884,6 @@
else
return NotImplemented;
- /* IPicture renders bitmaps with the y-axis reversed
- * FIXME: flipping for unknown image type might not be correct. */
- if(image->type != ImageTypeMetafile){
- INT temp;
- temp = pti[0].y;
- pti[0].y = pti[2].y;
- pti[2].y = temp;
- }
-
if(IPicture_Render(image->picture, graphics->hdc,
pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y,
srcx * dx, srcy * dy,
@@ -2362,7 +2383,7 @@
HFONT gdifont;
LOGFONTW lfw;
TEXTMETRICW textmet;
- GpPointF pt[2], rectcpy[4];
+ GpPointF pt[3], rectcpy[4];
POINT corners[4];
WCHAR* stringdup;
REAL angle, ang_cos, ang_sin, rel_width, rel_height;
@@ -2409,6 +2430,21 @@
SetBkMode(graphics->hdc, TRANSPARENT);
SetTextColor(graphics->hdc, brush->lb.lbColor);
+ pt[0].X = 0.0;
+ pt[0].Y = 0.0;
+ pt[1].X = 1.0;
+ pt[1].Y = 0.0;
+ pt[2].X = 0.0;
+ pt[2].Y = 1.0;
+ GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
+ angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
+ ang_cos = cos(angle);
+ ang_sin = sin(angle);
+ 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));
+ rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
+ (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
+
rectcpy[3].X = rectcpy[0].X = rect->X;
rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety;
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
@@ -2416,30 +2452,14 @@
transform_and_round_points(graphics, corners, rectcpy, 4);
if (roundr(rect->Width) == 0)
- {
- rel_width = 1.0;
nwidth = INT_MAX;
- }
else
- {
- rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) +
- (corners[1].y - corners[0].y) * (corners[1].y - corners[0].y))
- / rect->Width;
nwidth = roundr(rel_width * rect->Width);
- }
if (roundr(rect->Height) == 0)
- {
- rel_height = 1.0;
nheight = INT_MAX;
- }
else
- {
- rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x)
+
- (corners[2].y - corners[1].y) * (corners[2].y - corners[1].y))
- / rect->Height;
nheight = roundr(rel_height * rect->Height);
- }
if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0)
{
@@ -2457,14 +2477,6 @@
lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
- pt[0].X = 0.0;
- pt[0].Y = 0.0;
- pt[1].X = 1.0;
- pt[1].Y = 0.0;
- GdipTransformMatrixPoints(graphics->worldtrans, pt, 2);
- angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
- ang_cos = cos(angle);
- ang_sin = sin(angle);
lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
gdifont = CreateFontIndirectW(&lfw);
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] Sat Nov 28 16:26:02 2009
@@ -94,36 +94,321 @@
return NotImplemented;
}
+static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = *g = *b = row[x*2+1];
+ *a = 255;
+}
+
+static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ WORD pixel = *((WORD*)(row)+x);
+ *r = (pixel>>7&0xf8)|(pixel>>12&0x7);
+ *g = (pixel>>2&0xf8)|(pixel>>6&0x7);
+ *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
+ *a = 255;
+}
+
+static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ WORD pixel = *((WORD*)(row)+x);
+ *r = (pixel>>8&0xf8)|(pixel>>13&0x7);
+ *g = (pixel>>3&0xfc)|(pixel>>9&0x3);
+ *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
+ *a = 255;
+}
+
+static inline void getpixel_16bppARGB1555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ WORD pixel = *((WORD*)(row)+x);
+ *r = (pixel>>7&0xf8)|(pixel>>12&0x7);
+ *g = (pixel>>2&0xf8)|(pixel>>6&0x7);
+ *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
+ if ((pixel&0x8000) == 0x8000)
+ *a = 255;
+ else
+ *a = 0;
+}
+
+static inline void getpixel_24bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = row[x*3+2];
+ *g = row[x*3+1];
+ *b = row[x*3];
+ *a = 255;
+}
+
+static inline void getpixel_32bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = row[x*4+2];
+ *g = row[x*4+1];
+ *b = row[x*4];
+ *a = 255;
+}
+
+static inline void getpixel_32bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = row[x*4+2];
+ *g = row[x*4+1];
+ *b = row[x*4];
+ *a = row[x*4+3];
+}
+
+static inline void getpixel_32bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *a = row[x*4+3];
+ if (*a == 0)
+ *r = *g = *b = 0;
+ else
+ {
+ *r = row[x*4+2] * 255 / *a;
+ *g = row[x*4+1] * 255 / *a;
+ *b = row[x*4] * 255 / *a;
+ }
+}
+
+static inline void getpixel_48bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = row[x*6+5];
+ *g = row[x*6+3];
+ *b = row[x*6+1];
+ *a = 255;
+}
+
+static inline void getpixel_64bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *r = row[x*8+5];
+ *g = row[x*8+3];
+ *b = row[x*8+1];
+ *a = row[x*8+7];
+}
+
+static inline void getpixel_64bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
+ const BYTE *row, UINT x)
+{
+ *a = row[x*8+7];
+ if (*a == 0)
+ *r = *g = *b = 0;
+ else
+ {
+ *r = row[x*8+5] * 255 / *a;
+ *g = row[x*8+3] * 255 / *a;
+ *b = row[x*8+1] * 255 / *a;
+ }
+}
+
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
ARGB *color)
{
- static int calls;
+ BYTE r, g, b, a;
+ BYTE *row;
TRACE("%p %d %d %p\n", bitmap, x, y, color);
- if(!bitmap || !color)
- return InvalidParameter;
-
- if(!(calls++))
- FIXME("not implemented\n");
-
- *color = 0xdeadbeef;
-
- return NotImplemented;
+ if(!bitmap || !color ||
+ x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
+ return InvalidParameter;
+
+ row = bitmap->bits+bitmap->stride*y;
+
+ switch (bitmap->format)
+ {
+ case PixelFormat16bppGrayScale:
+ getpixel_16bppGrayScale(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppRGB555:
+ getpixel_16bppRGB555(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppRGB565:
+ getpixel_16bppRGB565(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat16bppARGB1555:
+ getpixel_16bppARGB1555(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat24bppRGB:
+ getpixel_24bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppRGB:
+ getpixel_32bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppARGB:
+ getpixel_32bppARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat32bppPARGB:
+ getpixel_32bppPARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat48bppRGB:
+ getpixel_48bppRGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat64bppARGB:
+ getpixel_64bppARGB(&r,&g,&b,&a,row,x);
+ break;
+ case PixelFormat64bppPARGB:
+ getpixel_64bppPARGB(&r,&g,&b,&a,row,x);
+ break;
+ default:
+ FIXME("not implemented for format 0x%x\n", bitmap->format);
+ return NotImplemented;
+ }
+
+ *color = a<<24|r<<16|g<<8|b;
+
+ return Ok;
+}
+
+static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((WORD*)(row)+x) = (r+g+b)*85;
+}
+
+static inline void setpixel_16bppRGB555(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((WORD*)(row)+x) = (r<<7&0x7c00)|
+ (g<<2&0x03e0)|
+ (b>>3&0x001f);
+}
+
+static inline void setpixel_16bppRGB565(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((WORD*)(row)+x) = (r<<8&0xf800)|
+ (g<<3&0x07e0)|
+ (b>>3&0x001f);
+}
+
+static inline void setpixel_16bppARGB1555(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((WORD*)(row)+x) = (a<<8&0x8000)|
+ (r<<7&0x7c00)|
+ (g<<2&0x03e0)|
+ (b>>3&0x001f);
+}
+
+static inline void setpixel_24bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ row[x*3+2] = r;
+ row[x*3+1] = g;
+ row[x*3] = b;
+}
+
+static inline void setpixel_32bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((DWORD*)(row)+x) = (r<<16)|(g<<8)|b;
+}
+
+static inline void setpixel_32bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
+}
+
+static inline void setpixel_32bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ r = r * a / 255;
+ g = g * a / 255;
+ b = b * a / 255;
+ *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
+}
+
+static inline void setpixel_48bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ row[x*6+5] = row[x*6+4] = r;
+ row[x*6+3] = row[x*6+2] = g;
+ row[x*6+1] = row[x*6] = b;
+}
+
+static inline void setpixel_64bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ UINT64 a64=a, r64=r, g64=g, b64=b;
+ *((UINT64*)(row)+x) =
(a64<<56)|(a64<<48)|(r64<<40)|(r64<<32)|(g64<<24)|(g64<<16)|(b64<<8)|b64;
+}
+
+static inline void setpixel_64bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x)
+{
+ UINT64 a64, r64, g64, b64;
+ a64 = a * 257;
+ r64 = r * a / 255;
+ g64 = g * a / 255;
+ b64 = b * a / 255;
+ *((UINT64*)(row)+x) = (a64<<48)|(r64<<32)|(g64<<16)|b64;
}
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
ARGB color)
{
- static int calls;
+ BYTE a, r, g, b;
+ BYTE *row;
TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color);
- if(!bitmap)
- return InvalidParameter;
-
- if(!(calls++))
- FIXME("not implemented\n");
-
- return NotImplemented;
+ if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >=
bitmap->height)
+ return InvalidParameter;
+
+ a = color>>24;
+ r = color>>16;
+ g = color>>8;
+ b = color;
+
+ row = bitmap->bits + bitmap->stride * y;
+
+ switch (bitmap->format)
+ {
+ case PixelFormat16bppGrayScale:
+ setpixel_16bppGrayScale(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppRGB555:
+ setpixel_16bppRGB555(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppRGB565:
+ setpixel_16bppRGB565(r,g,b,a,row,x);
+ break;
+ case PixelFormat16bppARGB1555:
+ setpixel_16bppARGB1555(r,g,b,a,row,x);
+ break;
+ case PixelFormat24bppRGB:
+ setpixel_24bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppRGB:
+ setpixel_32bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppARGB:
+ setpixel_32bppARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat32bppPARGB:
+ setpixel_32bppPARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat48bppRGB:
+ setpixel_48bppRGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat64bppARGB:
+ setpixel_64bppARGB(r,g,b,a,row,x);
+ break;
+ case PixelFormat64bppPARGB:
+ setpixel_64bppPARGB(r,g,b,a,row,x);
+ break;
+ default:
+ FIXME("not implemented for format 0x%x\n", bitmap->format);
+ return NotImplemented;
+ }
+
+ return Ok;
}
/* This function returns a pointer to an array of pixels that represents the
@@ -413,6 +698,8 @@
GdipDisposeImage(*cloneImage);
*cloneImage = NULL;
}
+ else memcpy(&(*cloneImage)->format, &image->format, sizeof(GUID));
+
return stat;
}
else
@@ -645,11 +932,7 @@
TRACE("%p, %p\n", hicon, bitmap);
if(!bitmap || !GetIconInfo(hicon, &iinfo))
- {
- DeleteObject(iinfo.hbmColor);
- DeleteObject(iinfo.hbmMask);
- return InvalidParameter;
- }
+ return InvalidParameter;
/* get the size of the icon */
ret = GetObjectA(iinfo.hbmColor ? iinfo.hbmColor : iinfo.hbmMask, sizeof(bm),
&bm);
@@ -858,6 +1141,7 @@
}
(*bitmap)->image.type = ImageTypeBitmap;
+ memcpy(&(*bitmap)->image.format, &ImageFormatMemoryBMP, sizeof(GUID));
(*bitmap)->image.flags = ImageFlagsNone;
(*bitmap)->width = width;
(*bitmap)->height = height;
@@ -1144,23 +1428,11 @@
GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage *image, GUID *format)
{
- static int calls;
-
if(!image || !format)
return InvalidParameter;
- if(!(calls++))
- FIXME("stub\n");
-
- /* FIXME: should be detected from embedded picture or stored separately */
- switch (image->type)
- {
- case ImageTypeBitmap: *format = ImageFormatBMP; break;
- case ImageTypeMetafile: *format = ImageFormatEMF; break;
- default:
- WARN("unknown type %u\n", image->type);
- *format = ImageFormatUndefined;
- }
+ memcpy(format, &image->format, sizeof(GUID));
+
return Ok;
}
@@ -1507,105 +1779,37 @@
return decode_image_wic(stream, &CLSID_WICIcoDecoder, image);
}
+static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, GpImage **image)
+{
+ GpStatus status;
+ GpBitmap* bitmap;
+
+ status = decode_image_wic(stream, &CLSID_WICBmpDecoder, image);
+
+ 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)
{
return decode_image_wic(stream, &CLSID_WICGifDecoder, image);
-}
-
-static GpStatus decode_image_olepicture_bitmap(IStream* stream, REFCLSID clsid, GpImage
**image)
-{
- IPicture *pic;
- BITMAPINFO *pbmi;
- BITMAPCOREHEADER* bmch;
- HBITMAP hbm;
- HDC hdc;
-
- TRACE("%p %p\n", stream, image);
-
- if(!stream || !image)
- return InvalidParameter;
-
- if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
- (LPVOID*) &pic) != S_OK){
- TRACE("Could not load picture\n");
- return GenericError;
- }
-
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- if (!pbmi)
- return OutOfMemory;
- *image = GdipAlloc(sizeof(GpBitmap));
- if(!*image){
- GdipFree(pbmi);
- return OutOfMemory;
- }
- (*image)->type = ImageTypeBitmap;
-
- (*((GpBitmap**) image))->width = ipicture_pixel_width(pic);
- (*((GpBitmap**) image))->height = ipicture_pixel_height(pic);
-
- /* get the pixel format */
- IPicture_get_Handle(pic, (OLE_HANDLE*)&hbm);
- IPicture_get_CurDC(pic, &hdc);
-
- (*((GpBitmap**) image))->hbitmap = hbm;
- (*((GpBitmap**) image))->hdc = hdc;
- (*((GpBitmap**) image))->bits = NULL;
-
- bmch = (BITMAPCOREHEADER*) (&pbmi->bmiHeader);
- bmch->bcSize = sizeof(BITMAPCOREHEADER);
-
- if(!hdc){
- HBITMAP old;
- hdc = CreateCompatibleDC(0);
- old = SelectObject(hdc, hbm);
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
- SelectObject(hdc, old);
- DeleteDC(hdc);
- }
- else
- GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
-
- switch(bmch->bcBitCount)
- {
- case 1:
- (*((GpBitmap**) image))->format = PixelFormat1bppIndexed;
- break;
- case 4:
- (*((GpBitmap**) image))->format = PixelFormat4bppIndexed;
- break;
- case 8:
- (*((GpBitmap**) image))->format = PixelFormat8bppIndexed;
- break;
- case 16:
- (*((GpBitmap**) image))->format = PixelFormat16bppRGB565;
- break;
- case 24:
- (*((GpBitmap**) image))->format = PixelFormat24bppRGB;
- break;
- case 32:
- (*((GpBitmap**) image))->format = PixelFormat32bppRGB;
- break;
- case 48:
- (*((GpBitmap**) image))->format = PixelFormat48bppRGB;
- break;
- default:
- FIXME("Bit depth %d is not fully supported yet\n",
bmch->bcBitCount);
- (*((GpBitmap**) image))->format = (bmch->bcBitCount << 8) |
PixelFormatGDI;
- break;
- }
-
- GdipFree(pbmi);
-
- (*image)->picture = pic;
- (*image)->flags = ImageFlagsNone;
-
- return Ok;
}
static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage
**image)
@@ -1715,7 +1919,15 @@
if (FAILED(hr)) return hresult_to_status(hr);
/* call on the image decoder to do the real work */
- return codec->decode_func(stream, &codec->info.Clsid, image);
+ stat = codec->decode_func(stream, &codec->info.Clsid, image);
+
+ /* take note of the original data format */
+ if (stat == Ok)
+ {
+ memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID));
+ }
+
+ return stat;
}
/* FIXME: no ICM */
@@ -1913,6 +2125,12 @@
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
return encode_image_WIC(image, stream, &CLSID_WICBmpEncoder, 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);
}
/*****************************************************************************
@@ -2051,7 +2269,7 @@
/* SigMask */ bmp_sig_mask,
},
encode_image_BMP,
- decode_image_olepicture_bitmap
+ decode_image_bmp
},
{
{ /* JPEG */
@@ -2138,15 +2356,15 @@
/* FormatDescription */ png_format,
/* FilenameExtension */ png_extension,
/* MimeType */ png_mimetype,
- /* Flags */ ImageCodecFlagsDecoder |
ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
+ /* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder |
ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Version */ 1,
/* SigCount */ 1,
/* SigSize */ 8,
/* SigPattern */ png_sig_pattern,
/* SigMask */ png_sig_mask,
},
- NULL,
- decode_image_olepicture_bitmap
+ encode_image_png,
+ decode_image_png
},
{
{ /* ICO */