2008-03-25 17:34:57 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007 Google (Evan Stade)
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
2009-02-14 08:14:34 +00:00
|
|
|
#define NONAMELESSUNION
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "wingdi.h"
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
#include "objbase.h"
|
|
|
|
#include "olectl.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
#include "initguid.h"
|
2009-09-03 15:07:25 +00:00
|
|
|
#include "wincodec.h"
|
2008-03-25 17:34:57 +00:00
|
|
|
#include "gdiplus.h"
|
|
|
|
#include "gdiplus_private.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
|
|
|
|
|
|
|
|
#define PIXELFORMATBPP(x) ((x) ? ((x) >> 8) & 255 : 24)
|
|
|
|
|
|
|
|
static INT ipicture_pixel_height(IPicture *pic)
|
|
|
|
{
|
|
|
|
HDC hdcref;
|
|
|
|
OLE_YSIZE_HIMETRIC y;
|
|
|
|
|
|
|
|
IPicture_get_Height(pic, &y);
|
|
|
|
|
|
|
|
hdcref = GetDC(0);
|
|
|
|
|
|
|
|
y = MulDiv(y, GetDeviceCaps(hdcref, LOGPIXELSY), INCH_HIMETRIC);
|
|
|
|
ReleaseDC(0, hdcref);
|
|
|
|
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
static INT ipicture_pixel_width(IPicture *pic)
|
|
|
|
{
|
|
|
|
HDC hdcref;
|
|
|
|
OLE_XSIZE_HIMETRIC x;
|
|
|
|
|
|
|
|
IPicture_get_Width(pic, &x);
|
|
|
|
|
|
|
|
hdcref = GetDC(0);
|
|
|
|
|
|
|
|
x = MulDiv(x, GetDeviceCaps(hdcref, LOGPIXELSX), INCH_HIMETRIC);
|
|
|
|
|
|
|
|
ReleaseDC(0, hdcref);
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2009-06-07 07:59:56 +00:00
|
|
|
GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap* bitmap, CGpEffect* effect,
|
|
|
|
RECT* roi, BOOL useAuxData, VOID** auxData, INT* auxDataSize)
|
|
|
|
{
|
|
|
|
FIXME("(%p %p %p %d %p %p): stub\n", bitmap, effect, roi, useAuxData, auxData, auxDataSize);
|
|
|
|
/*
|
|
|
|
* Note: According to Jose Roca's GDI+ docs, this function is not
|
|
|
|
* implemented in Windows's GDI+.
|
|
|
|
*/
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap** inputBitmaps,
|
|
|
|
INT numInputs, CGpEffect* effect, RECT* roi, RECT* outputRect,
|
|
|
|
GpBitmap** outputBitmap, BOOL useAuxData, VOID** auxData, INT* auxDataSize)
|
|
|
|
{
|
|
|
|
FIXME("(%p %d %p %p %p %p %d %p %p): stub\n", inputBitmaps, numInputs, effect, roi, outputRect, outputBitmap, useAuxData, auxData, auxDataSize);
|
|
|
|
/*
|
|
|
|
* Note: According to Jose Roca's GDI+ docs, this function is not
|
|
|
|
* implemented in Windows's GDI+.
|
|
|
|
*/
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
static inline void getpixel_1bppIndexed(BYTE *index, const BYTE *row, UINT x)
|
|
|
|
{
|
|
|
|
*index = (row[x/8]>>(7-x%8)) & 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void getpixel_4bppIndexed(BYTE *index, const BYTE *row, UINT x)
|
|
|
|
{
|
|
|
|
if (x & 1)
|
|
|
|
*index = row[x/2]&0xf;
|
|
|
|
else
|
|
|
|
*index = row[x/2]>>4;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void getpixel_8bppIndexed(BYTE *index, const BYTE *row, UINT x)
|
|
|
|
{
|
|
|
|
*index = row[x];
|
|
|
|
}
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
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)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
WORD pixel = *((const WORD*)(row)+x);
|
2009-11-28 15:26:02 +00:00
|
|
|
*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)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
WORD pixel = *((const WORD*)(row)+x);
|
2009-11-28 15:26:02 +00:00
|
|
|
*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)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
WORD pixel = *((const WORD*)(row)+x);
|
2009-11-28 15:26:02 +00:00
|
|
|
*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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
|
|
|
|
ARGB *color)
|
|
|
|
{
|
2009-11-28 15:26:02 +00:00
|
|
|
BYTE r, g, b, a;
|
2010-03-04 13:34:05 +00:00
|
|
|
BYTE index;
|
2009-11-28 15:26:02 +00:00
|
|
|
BYTE *row;
|
2008-03-25 17:34:57 +00:00
|
|
|
TRACE("%p %d %d %p\n", bitmap, x, y, color);
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
if(!bitmap || !color ||
|
|
|
|
x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
|
2008-03-25 17:34:57 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
row = bitmap->bits+bitmap->stride*y;
|
|
|
|
|
|
|
|
switch (bitmap->format)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
case PixelFormat1bppIndexed:
|
|
|
|
getpixel_1bppIndexed(&index,row,x);
|
|
|
|
break;
|
|
|
|
case PixelFormat4bppIndexed:
|
|
|
|
getpixel_4bppIndexed(&index,row,x);
|
|
|
|
break;
|
|
|
|
case PixelFormat8bppIndexed:
|
|
|
|
getpixel_8bppIndexed(&index,row,x);
|
|
|
|
break;
|
2009-11-28 15:26:02 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (bitmap->format & PixelFormatIndexed)
|
|
|
|
*color = bitmap->image.palette_entries[index];
|
|
|
|
else
|
|
|
|
*color = a<<24|r<<16|g<<8|b;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
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;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2009-05-09 09:26:16 +00:00
|
|
|
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
|
|
|
|
ARGB color)
|
|
|
|
{
|
2009-11-28 15:26:02 +00:00
|
|
|
BYTE a, r, g, b;
|
|
|
|
BYTE *row;
|
2009-05-09 09:26:16 +00:00
|
|
|
TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color);
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
|
2009-05-09 09:26:16 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
a = color>>24;
|
|
|
|
r = color>>16;
|
|
|
|
g = color>>8;
|
|
|
|
b = color;
|
2009-05-09 09:26:16 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
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;
|
2009-05-09 09:26:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
GpStatus convert_pixels(UINT width, UINT height,
|
|
|
|
INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
|
|
|
|
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ARGB *src_palette)
|
|
|
|
{
|
|
|
|
UINT x, y;
|
|
|
|
|
|
|
|
if (src_format == dst_format ||
|
|
|
|
(dst_format == PixelFormat32bppRGB && PIXELFORMATBPP(src_format) == 32))
|
|
|
|
{
|
|
|
|
UINT widthbytes = PIXELFORMATBPP(src_format) * width / 8;
|
|
|
|
for (y=0; y<height; y++)
|
|
|
|
memcpy(dst_bits+dst_stride*y, src_bits+src_stride*y, widthbytes);
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define convert_indexed_to_rgb(getpixel_function, setpixel_function) do { \
|
|
|
|
for (x=0; x<width; x++) \
|
|
|
|
for (y=0; y<height; y++) { \
|
|
|
|
BYTE index; \
|
|
|
|
BYTE *color; \
|
|
|
|
getpixel_function(&index, src_bits+src_stride*y, x); \
|
|
|
|
color = (BYTE*)(&src_palette[index]); \
|
|
|
|
setpixel_function(color[2], color[1], color[0], color[3], dst_bits+dst_stride*y, x); \
|
|
|
|
} \
|
|
|
|
return Ok; \
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
#define convert_rgb_to_rgb(getpixel_function, setpixel_function) do { \
|
|
|
|
for (x=0; x<width; x++) \
|
|
|
|
for (y=0; y<height; y++) { \
|
|
|
|
BYTE r, g, b, a; \
|
|
|
|
getpixel_function(&r, &g, &b, &a, src_bits+src_stride*y, x); \
|
|
|
|
setpixel_function(r, g, b, a, dst_bits+dst_stride*y, x); \
|
|
|
|
} \
|
|
|
|
return Ok; \
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
switch (src_format)
|
|
|
|
{
|
|
|
|
case PixelFormat1bppIndexed:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_1bppIndexed, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat4bppIndexed:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_4bppIndexed, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat8bppIndexed:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_indexed_to_rgb(getpixel_8bppIndexed, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppGrayScale, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB555, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppRGB565, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_16bppARGB1555, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_24bppRGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppRGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_32bppARGB_to_32bppPARGB(width, height, dst_bits, dst_stride, src_bits, src_stride);
|
|
|
|
return Ok;
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppARGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_32bppPARGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_48bppRGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppARGB, setpixel_48bppRGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PixelFormat64bppPARGB:
|
|
|
|
switch (dst_format)
|
|
|
|
{
|
|
|
|
case PixelFormat16bppGrayScale:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppGrayScale);
|
|
|
|
case PixelFormat16bppRGB555:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB555);
|
|
|
|
case PixelFormat16bppRGB565:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppRGB565);
|
|
|
|
case PixelFormat16bppARGB1555:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_16bppARGB1555);
|
|
|
|
case PixelFormat24bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_24bppRGB);
|
|
|
|
case PixelFormat32bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppRGB);
|
|
|
|
case PixelFormat32bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppARGB);
|
|
|
|
case PixelFormat32bppPARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_32bppPARGB);
|
|
|
|
case PixelFormat48bppRGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_48bppRGB);
|
|
|
|
case PixelFormat64bppARGB:
|
|
|
|
convert_rgb_to_rgb(getpixel_64bppPARGB, setpixel_64bppARGB);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef convert_indexed_to_rgb
|
|
|
|
#undef convert_rgb_to_rgb
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
/* This function returns a pointer to an array of pixels that represents the
|
|
|
|
* bitmap. The *entire* bitmap is locked according to the lock mode specified by
|
|
|
|
* flags. It is correct behavior that a user who calls this function with write
|
|
|
|
* privileges can write to the whole bitmap (not just the area in rect).
|
|
|
|
*
|
|
|
|
* FIXME: only used portion of format is bits per pixel. */
|
|
|
|
GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
|
|
|
|
UINT flags, PixelFormat format, BitmapData* lockeddata)
|
|
|
|
{
|
|
|
|
INT stride, bitspp = PIXELFORMATBPP(format);
|
|
|
|
BYTE *buff = NULL;
|
|
|
|
UINT abs_height;
|
2008-07-02 08:19:00 +00:00
|
|
|
GpRect act_rect; /* actual rect to be used */
|
2010-03-04 13:34:05 +00:00
|
|
|
GpStatus stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("%p %p %d 0x%x %p\n", bitmap, rect, flags, format, lockeddata);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!lockeddata || !bitmap)
|
2008-03-25 17:34:57 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(rect){
|
|
|
|
if(rect->X < 0 || rect->Y < 0 || (rect->X + rect->Width > bitmap->width) ||
|
|
|
|
(rect->Y + rect->Height > bitmap->height) || !flags)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
act_rect = *rect;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
act_rect.X = act_rect.Y = 0;
|
|
|
|
act_rect.Width = bitmap->width;
|
|
|
|
act_rect.Height = bitmap->height;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if(flags & ImageLockModeUserInputBuf)
|
2010-03-04 13:34:05 +00:00
|
|
|
{
|
|
|
|
static int fixme=0;
|
|
|
|
if (!fixme++) FIXME("ImageLockModeUserInputBuf not implemented\n");
|
2008-03-25 17:34:57 +00:00
|
|
|
return NotImplemented;
|
2010-03-04 13:34:05 +00:00
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if(bitmap->lockmode)
|
2010-03-04 13:34:05 +00:00
|
|
|
{
|
|
|
|
WARN("bitmap is already locked and cannot be locked again\n");
|
2008-03-25 17:34:57 +00:00
|
|
|
return WrongState;
|
2010-03-04 13:34:05 +00:00
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (bitmap->bits && bitmap->format == format)
|
|
|
|
{
|
|
|
|
/* no conversion is necessary; just use the bits directly */
|
|
|
|
lockeddata->Width = act_rect.Width;
|
|
|
|
lockeddata->Height = act_rect.Height;
|
|
|
|
lockeddata->PixelFormat = format;
|
|
|
|
lockeddata->Reserved = flags;
|
|
|
|
lockeddata->Stride = bitmap->stride;
|
|
|
|
lockeddata->Scan0 = bitmap->bits + (bitspp / 8) * act_rect.X +
|
|
|
|
bitmap->stride * act_rect.Y;
|
|
|
|
|
|
|
|
bitmap->lockmode = flags;
|
|
|
|
bitmap->numlocks++;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
/* Make sure we can convert to the requested format. */
|
|
|
|
stat = convert_pixels(0, 0, 0, NULL, format, 0, NULL, bitmap->format, NULL);
|
|
|
|
if (stat == NotImplemented)
|
|
|
|
{
|
|
|
|
FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
|
|
|
|
return NotImplemented;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
/* If we're opening for writing, make sure we'll be able to write back in
|
|
|
|
* the original format. */
|
|
|
|
if (flags & ImageLockModeWrite)
|
|
|
|
{
|
|
|
|
stat = convert_pixels(0, 0, 0, NULL, bitmap->format, 0, NULL, format, NULL);
|
|
|
|
if (stat == NotImplemented)
|
|
|
|
{
|
|
|
|
FIXME("cannot write bitmap from %x to %x\n", format, bitmap->format);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
abs_height = bitmap->height;
|
|
|
|
stride = (bitmap->width * bitspp + 7) / 8;
|
2008-03-25 17:34:57 +00:00
|
|
|
stride = (stride + 3) & ~3;
|
|
|
|
|
|
|
|
buff = GdipAlloc(stride * abs_height);
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (!buff) return OutOfMemory;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
stat = convert_pixels(bitmap->width, bitmap->height,
|
|
|
|
stride, buff, format,
|
|
|
|
bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
GdipFree(buff);
|
|
|
|
return stat;
|
2008-12-06 09:26:01 +00:00
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
lockeddata->Width = act_rect.Width;
|
|
|
|
lockeddata->Height = act_rect.Height;
|
2008-03-25 17:34:57 +00:00
|
|
|
lockeddata->PixelFormat = format;
|
|
|
|
lockeddata->Reserved = flags;
|
2010-03-04 13:34:05 +00:00
|
|
|
lockeddata->Stride = stride;
|
|
|
|
lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
bitmap->lockmode = flags;
|
|
|
|
bitmap->numlocks++;
|
|
|
|
bitmap->bitmapbits = buff;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-05-05 15:35:05 +00:00
|
|
|
GpStatus WINGDIPAPI GdipBitmapSetResolution(GpBitmap* bitmap, REAL xdpi, REAL ydpi)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p, %.2f, %.2f)\n", bitmap, xdpi, ydpi);
|
2009-05-05 15:35:05 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (!bitmap || xdpi == 0.0 || ydpi == 0.0)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
bitmap->image.xres = xdpi;
|
|
|
|
bitmap->image.yres = ydpi;
|
|
|
|
|
|
|
|
return Ok;
|
2009-05-05 15:35:05 +00:00
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
|
|
|
|
BitmapData* lockeddata)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
GpStatus stat;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n", bitmap, lockeddata);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if(!bitmap || !lockeddata)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!bitmap->lockmode)
|
|
|
|
return WrongState;
|
|
|
|
|
|
|
|
if(lockeddata->Reserved & ImageLockModeUserInputBuf)
|
|
|
|
return NotImplemented;
|
|
|
|
|
|
|
|
if(lockeddata->Reserved & ImageLockModeRead){
|
|
|
|
if(!(--bitmap->numlocks))
|
|
|
|
bitmap->lockmode = 0;
|
|
|
|
|
|
|
|
GdipFree(bitmap->bitmapbits);
|
|
|
|
bitmap->bitmapbits = NULL;
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (!bitmap->bitmapbits)
|
|
|
|
{
|
|
|
|
/* we passed a direct reference; no need to do anything */
|
|
|
|
bitmap->lockmode = 0;
|
2010-03-04 13:34:05 +00:00
|
|
|
bitmap->numlocks = 0;
|
2009-09-03 15:07:25 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
stat = convert_pixels(bitmap->width, bitmap->height,
|
|
|
|
bitmap->stride, bitmap->bits, bitmap->format,
|
|
|
|
lockeddata->Stride, bitmap->bitmapbits, lockeddata->PixelFormat, NULL);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
ERR("failed to convert pixels; this should never happen\n");
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GdipFree(bitmap->bitmapbits);
|
|
|
|
bitmap->bitmapbits = NULL;
|
|
|
|
bitmap->lockmode = 0;
|
2010-03-04 13:34:05 +00:00
|
|
|
bitmap->numlocks = 0;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
return stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2009-06-07 07:59:56 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
|
|
|
|
PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
|
|
|
|
{
|
2010-01-03 10:54:14 +00:00
|
|
|
BitmapData lockeddata_src, lockeddata_dst;
|
|
|
|
int i;
|
|
|
|
UINT row_size;
|
|
|
|
Rect area;
|
|
|
|
GpStatus stat;
|
2009-06-07 07:59:56 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%f,%f,%f,%f,0x%x,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
|
2010-01-03 10:54:14 +00:00
|
|
|
|
|
|
|
if (!srcBitmap || !dstBitmap || srcBitmap->image.type != ImageTypeBitmap ||
|
|
|
|
x < 0 || y < 0 ||
|
|
|
|
x + width > srcBitmap->width || y + height > srcBitmap->height)
|
|
|
|
{
|
|
|
|
TRACE("<-- InvalidParameter\n");
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (format == PixelFormatDontCare)
|
|
|
|
format = srcBitmap->format;
|
|
|
|
|
|
|
|
area.X = roundr(x);
|
|
|
|
area.Y = roundr(y);
|
|
|
|
area.Width = roundr(width);
|
|
|
|
area.Height = roundr(height);
|
|
|
|
|
|
|
|
stat = GdipBitmapLockBits(srcBitmap, &area, ImageLockModeRead, format,
|
|
|
|
&lockeddata_src);
|
|
|
|
if (stat != Ok) return stat;
|
|
|
|
|
|
|
|
stat = GdipCreateBitmapFromScan0(lockeddata_src.Width, lockeddata_src.Height,
|
|
|
|
0, lockeddata_src.PixelFormat, NULL, dstBitmap);
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipBitmapLockBits(*dstBitmap, NULL, ImageLockModeWrite,
|
|
|
|
lockeddata_src.PixelFormat, &lockeddata_dst);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
/* copy the image data */
|
|
|
|
row_size = (lockeddata_src.Width * PIXELFORMATBPP(lockeddata_src.PixelFormat) +7)/8;
|
|
|
|
for (i=0; i<lockeddata_src.Height; i++)
|
|
|
|
memcpy((BYTE*)lockeddata_dst.Scan0+lockeddata_dst.Stride*i,
|
|
|
|
(BYTE*)lockeddata_src.Scan0+lockeddata_src.Stride*i,
|
|
|
|
row_size);
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(*dstBitmap, &lockeddata_dst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
GdipDisposeImage((GpImage*)*dstBitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(srcBitmap, &lockeddata_src);
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
*dstBitmap = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return stat;
|
2009-06-07 07:59:56 +00:00
|
|
|
}
|
|
|
|
|
2009-04-06 14:58:12 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height,
|
|
|
|
PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%i,%i,%i,%i,0x%x,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
|
2009-04-06 14:58:12 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
return GdipCloneBitmapArea(x, y, width, height, format, srcBitmap, dstBitmap);
|
2009-04-06 14:58:12 +00:00
|
|
|
}
|
|
|
|
|
2008-07-06 16:35:30 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus stat = GenericError;
|
2008-07-06 16:35:30 +00:00
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("%p, %p\n", image, cloneImage);
|
2008-07-06 16:35:30 +00:00
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
if (!image || !cloneImage)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (image->picture)
|
2008-09-07 10:32:49 +00:00
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
IStream* stream;
|
|
|
|
HRESULT hr;
|
|
|
|
INT size;
|
|
|
|
LARGE_INTEGER move;
|
2008-09-07 10:32:49 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
hr = CreateStreamOnHGlobal(0, TRUE, &stream);
|
|
|
|
if (FAILED(hr))
|
|
|
|
return GenericError;
|
2008-09-07 10:32:49 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
hr = IPicture_SaveAsFile(image->picture, stream, FALSE, &size);
|
|
|
|
if(FAILED(hr))
|
|
|
|
{
|
|
|
|
WARN("Failed to save image on stream\n");
|
|
|
|
goto out;
|
|
|
|
}
|
2008-12-06 09:26:01 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
/* Set seek pointer back to the beginning of the picture */
|
|
|
|
move.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(stream, move, STREAM_SEEK_SET, NULL);
|
|
|
|
if (FAILED(hr))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
stat = GdipLoadImageFromStream(stream, cloneImage);
|
|
|
|
if (stat != Ok) WARN("Failed to load image from stream\n");
|
|
|
|
|
|
|
|
out:
|
|
|
|
IStream_Release(stream);
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
else if (image->type == ImageTypeBitmap)
|
|
|
|
{
|
|
|
|
GpBitmap *bitmap = (GpBitmap*)image;
|
|
|
|
BitmapData lockeddata_src, lockeddata_dst;
|
|
|
|
int i;
|
|
|
|
UINT row_size;
|
|
|
|
|
|
|
|
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format,
|
|
|
|
&lockeddata_src);
|
|
|
|
if (stat != Ok) return stat;
|
|
|
|
|
|
|
|
stat = GdipCreateBitmapFromScan0(lockeddata_src.Width, lockeddata_src.Height,
|
|
|
|
0, lockeddata_src.PixelFormat, NULL, (GpBitmap**)cloneImage);
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipBitmapLockBits((GpBitmap*)*cloneImage, NULL, ImageLockModeWrite,
|
|
|
|
lockeddata_src.PixelFormat, &lockeddata_dst);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
/* copy the image data */
|
|
|
|
row_size = (lockeddata_src.Width * PIXELFORMATBPP(lockeddata_src.PixelFormat) +7)/8;
|
|
|
|
for (i=0; i<lockeddata_src.Height; i++)
|
|
|
|
memcpy((BYTE*)lockeddata_dst.Scan0+lockeddata_dst.Stride*i,
|
|
|
|
(BYTE*)lockeddata_src.Scan0+lockeddata_src.Stride*i,
|
|
|
|
row_size);
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits((GpBitmap*)*cloneImage, &lockeddata_dst);
|
|
|
|
}
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (stat != Ok)
|
|
|
|
GdipDisposeImage(*cloneImage);
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
GdipBitmapUnlockBits(bitmap, &lockeddata_src);
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
*cloneImage = NULL;
|
|
|
|
}
|
2009-11-28 15:26:02 +00:00
|
|
|
else memcpy(&(*cloneImage)->format, &image->format, sizeof(GUID));
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("GpImage with no IPicture or bitmap?!\n");
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
2008-07-06 16:35:30 +00:00
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename,
|
|
|
|
GpBitmap **bitmap)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
IStream *stream;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%s) %p\n", debugstr_w(filename), bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!filename || !bitmap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
stat = GdipCreateStreamOnFile(filename, GENERIC_READ, &stream);
|
|
|
|
|
|
|
|
if(stat != Ok)
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
stat = GdipCreateBitmapFromStream(stream, bitmap);
|
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO* info,
|
|
|
|
VOID *bits, GpBitmap **bitmap)
|
|
|
|
{
|
|
|
|
DWORD height, stride;
|
|
|
|
PixelFormat format;
|
|
|
|
|
|
|
|
FIXME("(%p, %p, %p) - partially implemented\n", info, bits, bitmap);
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
if (!info || !bits || !bitmap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
height = abs(info->bmiHeader.biHeight);
|
|
|
|
stride = ((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) >> 3) & ~3;
|
|
|
|
|
|
|
|
if(info->bmiHeader.biHeight > 0) /* bottom-up */
|
|
|
|
{
|
|
|
|
bits = (BYTE*)bits + (height - 1) * stride;
|
|
|
|
stride = -stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(info->bmiHeader.biBitCount) {
|
|
|
|
case 1:
|
|
|
|
format = PixelFormat1bppIndexed;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
format = PixelFormat4bppIndexed;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
format = PixelFormat8bppIndexed;
|
|
|
|
break;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case 16:
|
|
|
|
format = PixelFormat16bppRGB555;
|
|
|
|
break;
|
2008-08-05 12:23:58 +00:00
|
|
|
case 24:
|
|
|
|
format = PixelFormat24bppRGB;
|
|
|
|
break;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case 32:
|
|
|
|
format = PixelFormat32bppRGB;
|
|
|
|
break;
|
2008-08-05 12:23:58 +00:00
|
|
|
default:
|
|
|
|
FIXME("don't know how to handle %d bpp\n", info->bmiHeader.biBitCount);
|
|
|
|
*bitmap = NULL;
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GdipCreateBitmapFromScan0(info->bmiHeader.biWidth, height, stride, format,
|
|
|
|
bits, bitmap);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
/* FIXME: no icm */
|
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename,
|
|
|
|
GpBitmap **bitmap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%s) %p\n", debugstr_w(filename), bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return GdipCreateBitmapFromFile(filename, bitmap);
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromResource(HINSTANCE hInstance,
|
|
|
|
GDIPCONST WCHAR* lpBitmapName, GpBitmap** bitmap)
|
|
|
|
{
|
|
|
|
HBITMAP hbm;
|
|
|
|
GpStatus stat = InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p (%s) %p\n", hInstance, debugstr_w(lpBitmapName), bitmap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!lpBitmapName || !bitmap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
/* load DIB */
|
2008-12-06 09:26:01 +00:00
|
|
|
hbm = LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0,
|
|
|
|
LR_CREATEDIBSECTION);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if(hbm){
|
|
|
|
stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, bitmap);
|
|
|
|
DeleteObject(hbm);
|
|
|
|
}
|
|
|
|
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
|
|
|
|
HBITMAP* hbmReturn, ARGB background)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
GpStatus stat;
|
|
|
|
HBITMAP result, oldbitmap;
|
|
|
|
UINT width, height;
|
|
|
|
HDC hdc;
|
|
|
|
GpGraphics *graphics;
|
|
|
|
BITMAPINFOHEADER bih;
|
|
|
|
void *bits;
|
|
|
|
TRACE("(%p,%p,%x)\n", bitmap, hbmReturn, background);
|
|
|
|
|
|
|
|
if (!bitmap || !hbmReturn) return InvalidParameter;
|
|
|
|
|
|
|
|
GdipGetImageWidth((GpImage*)bitmap, &width);
|
|
|
|
GdipGetImageHeight((GpImage*)bitmap, &height);
|
|
|
|
|
|
|
|
bih.biSize = sizeof(bih);
|
|
|
|
bih.biWidth = width;
|
|
|
|
bih.biHeight = height;
|
|
|
|
bih.biPlanes = 1;
|
|
|
|
bih.biBitCount = 32;
|
|
|
|
bih.biCompression = BI_RGB;
|
|
|
|
bih.biSizeImage = 0;
|
|
|
|
bih.biXPelsPerMeter = 0;
|
|
|
|
bih.biYPelsPerMeter = 0;
|
|
|
|
bih.biClrUsed = 0;
|
|
|
|
bih.biClrImportant = 0;
|
|
|
|
|
|
|
|
hdc = CreateCompatibleDC(NULL);
|
|
|
|
if (!hdc) return GenericError;
|
|
|
|
|
|
|
|
result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &bits,
|
|
|
|
NULL, 0);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
oldbitmap = SelectObject(hdc, result);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
stat = GdipCreateFromHDC(hdc, &graphics);
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipGraphicsClear(graphics, background);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (stat == Ok)
|
|
|
|
stat = GdipDrawImage(graphics, (GpImage*)bitmap, 0, 0);
|
|
|
|
|
|
|
|
GdipDeleteGraphics(graphics);
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectObject(hdc, oldbitmap);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
stat = GenericError;
|
|
|
|
|
|
|
|
DeleteDC(hdc);
|
|
|
|
|
|
|
|
if (stat != Ok && result)
|
|
|
|
{
|
|
|
|
DeleteObject(result);
|
|
|
|
result = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*hbmReturn = result;
|
|
|
|
|
|
|
|
return stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipConvertToEmfPlus(const GpGraphics* ref,
|
|
|
|
GpMetafile* metafile, BOOL* succ, EmfType emfType,
|
|
|
|
const WCHAR* description, GpMetafile** out_metafile)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%p,%p,%u,%s,%p)\n", ref, metafile, succ, emfType,
|
|
|
|
debugstr_w(description), out_metafile);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!ref || !metafile || !out_metafile)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*succ = FALSE;
|
|
|
|
*out_metafile = NULL;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: this should create a bitmap in the given size with the attributes
|
|
|
|
* (resolution etc.) of the graphics object */
|
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height,
|
|
|
|
GpGraphics* target, GpBitmap** bitmap)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
GpStatus ret;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%d, %d, %p, %p)\n", width, height, target, bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!target || !bitmap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("hacked stub\n");
|
|
|
|
|
|
|
|
ret = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat24bppRGB,
|
|
|
|
NULL, bitmap);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-02-14 08:14:34 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
GpStatus stat;
|
2009-02-14 08:14:34 +00:00
|
|
|
ICONINFO iinfo;
|
2009-09-03 15:07:25 +00:00
|
|
|
BITMAP bm;
|
|
|
|
int ret;
|
|
|
|
UINT width, height;
|
|
|
|
GpRect rect;
|
|
|
|
BitmapData lockeddata;
|
|
|
|
HDC screendc;
|
|
|
|
BOOL has_alpha;
|
|
|
|
int x, y;
|
|
|
|
BYTE *bits;
|
|
|
|
BITMAPINFOHEADER bih;
|
|
|
|
DWORD *src;
|
|
|
|
BYTE *dst_row;
|
|
|
|
DWORD *dst;
|
2009-02-14 08:14:34 +00:00
|
|
|
|
|
|
|
TRACE("%p, %p\n", hicon, bitmap);
|
|
|
|
|
|
|
|
if(!bitmap || !GetIconInfo(hicon, &iinfo))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
/* get the size of the icon */
|
|
|
|
ret = GetObjectA(iinfo.hbmColor ? iinfo.hbmColor : iinfo.hbmMask, sizeof(bm), &bm);
|
|
|
|
if (ret == 0) {
|
|
|
|
DeleteObject(iinfo.hbmColor);
|
|
|
|
DeleteObject(iinfo.hbmMask);
|
|
|
|
return GenericError;
|
|
|
|
}
|
2009-02-14 08:14:34 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
width = bm.bmWidth;
|
2009-02-14 08:14:34 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (iinfo.hbmColor)
|
|
|
|
height = abs(bm.bmHeight);
|
|
|
|
else /* combined bitmap + mask */
|
|
|
|
height = abs(bm.bmHeight) / 2;
|
|
|
|
|
|
|
|
bits = HeapAlloc(GetProcessHeap(), 0, 4*width*height);
|
|
|
|
if (!bits) {
|
|
|
|
DeleteObject(iinfo.hbmColor);
|
|
|
|
DeleteObject(iinfo.hbmMask);
|
|
|
|
return OutOfMemory;
|
2009-02-14 08:14:34 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
stat = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppARGB, NULL, bitmap);
|
|
|
|
if (stat != Ok) {
|
|
|
|
DeleteObject(iinfo.hbmColor);
|
|
|
|
DeleteObject(iinfo.hbmMask);
|
|
|
|
HeapFree(GetProcessHeap(), 0, bits);
|
|
|
|
return stat;
|
|
|
|
}
|
2009-02-14 08:14:34 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
rect.X = 0;
|
|
|
|
rect.Y = 0;
|
|
|
|
rect.Width = width;
|
|
|
|
rect.Height = height;
|
|
|
|
|
|
|
|
stat = GdipBitmapLockBits(*bitmap, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &lockeddata);
|
|
|
|
if (stat != Ok) {
|
|
|
|
DeleteObject(iinfo.hbmColor);
|
|
|
|
DeleteObject(iinfo.hbmMask);
|
|
|
|
HeapFree(GetProcessHeap(), 0, bits);
|
|
|
|
GdipDisposeImage((GpImage*)*bitmap);
|
|
|
|
return stat;
|
2009-02-14 08:14:34 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
bih.biSize = sizeof(bih);
|
|
|
|
bih.biWidth = width;
|
|
|
|
bih.biHeight = -height;
|
|
|
|
bih.biPlanes = 1;
|
|
|
|
bih.biBitCount = 32;
|
|
|
|
bih.biCompression = BI_RGB;
|
|
|
|
bih.biSizeImage = 0;
|
|
|
|
bih.biXPelsPerMeter = 0;
|
|
|
|
bih.biYPelsPerMeter = 0;
|
|
|
|
bih.biClrUsed = 0;
|
|
|
|
bih.biClrImportant = 0;
|
|
|
|
|
|
|
|
screendc = GetDC(0);
|
|
|
|
if (iinfo.hbmColor)
|
|
|
|
{
|
|
|
|
GetDIBits(screendc, iinfo.hbmColor, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
|
|
|
|
|
|
|
|
if (bm.bmBitsPixel == 32)
|
|
|
|
{
|
|
|
|
has_alpha = FALSE;
|
|
|
|
|
|
|
|
/* If any pixel has a non-zero alpha, ignore hbmMask */
|
|
|
|
src = (DWORD*)bits;
|
|
|
|
for (x=0; x<width && !has_alpha; x++)
|
|
|
|
for (y=0; y<height && !has_alpha; y++)
|
|
|
|
if ((*src++ & 0xff000000) != 0)
|
|
|
|
has_alpha = TRUE;
|
|
|
|
}
|
|
|
|
else has_alpha = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetDIBits(screendc, iinfo.hbmMask, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
|
|
|
|
has_alpha = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy the image data to the Bitmap */
|
|
|
|
src = (DWORD*)bits;
|
|
|
|
dst_row = lockeddata.Scan0;
|
|
|
|
for (y=0; y<height; y++)
|
|
|
|
{
|
|
|
|
memcpy(dst_row, src, width*4);
|
|
|
|
src += width;
|
|
|
|
dst_row += lockeddata.Stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!has_alpha)
|
|
|
|
{
|
|
|
|
if (iinfo.hbmMask)
|
|
|
|
{
|
|
|
|
/* read alpha data from the mask */
|
|
|
|
if (iinfo.hbmColor)
|
|
|
|
GetDIBits(screendc, iinfo.hbmMask, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
|
|
|
|
else
|
|
|
|
GetDIBits(screendc, iinfo.hbmMask, height, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
|
|
|
|
|
|
|
|
src = (DWORD*)bits;
|
|
|
|
dst_row = lockeddata.Scan0;
|
|
|
|
for (y=0; y<height; y++)
|
|
|
|
{
|
|
|
|
dst = (DWORD*)dst_row;
|
|
|
|
for (x=0; x<height; x++)
|
|
|
|
{
|
|
|
|
DWORD src_value = *src++;
|
|
|
|
if (src_value)
|
|
|
|
*dst++ = 0;
|
|
|
|
else
|
|
|
|
*dst++ |= 0xff000000;
|
|
|
|
}
|
|
|
|
dst_row += lockeddata.Stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* set constant alpha of 255 */
|
|
|
|
dst_row = bits;
|
|
|
|
for (y=0; y<height; y++)
|
|
|
|
{
|
|
|
|
dst = (DWORD*)dst_row;
|
|
|
|
for (x=0; x<height; x++)
|
|
|
|
*dst++ |= 0xff000000;
|
|
|
|
dst_row += lockeddata.Stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReleaseDC(0, screendc);
|
2009-02-14 08:14:34 +00:00
|
|
|
|
|
|
|
DeleteObject(iinfo.hbmColor);
|
|
|
|
DeleteObject(iinfo.hbmMask);
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
GdipBitmapUnlockBits(*bitmap, &lockeddata);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, bits);
|
|
|
|
|
2009-02-14 08:14:34 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
static void generate_halftone_palette(ARGB *entries, UINT count)
|
|
|
|
{
|
|
|
|
static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
|
|
|
|
UINT i;
|
|
|
|
|
|
|
|
for (i=0; i<8 && i<count; i++)
|
|
|
|
{
|
|
|
|
entries[i] = 0xff000000;
|
|
|
|
if (i&1) entries[i] |= 0x800000;
|
|
|
|
if (i&2) entries[i] |= 0x8000;
|
|
|
|
if (i&4) entries[i] |= 0x80;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (8 < count)
|
|
|
|
entries[i] = 0xffc0c0c0;
|
|
|
|
|
|
|
|
for (i=9; i<16 && i<count; i++)
|
|
|
|
{
|
|
|
|
entries[i] = 0xff000000;
|
|
|
|
if (i&1) entries[i] |= 0xff0000;
|
|
|
|
if (i&2) entries[i] |= 0xff00;
|
|
|
|
if (i&4) entries[i] |= 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=16; i<40 && i<count; i++)
|
|
|
|
{
|
|
|
|
entries[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=40; i<256 && i<count; i++)
|
|
|
|
{
|
|
|
|
entries[i] = 0xff000000;
|
|
|
|
entries[i] |= halftone_values[(i-40)%6];
|
|
|
|
entries[i] |= halftone_values[((i-40)/6)%6] << 8;
|
|
|
|
entries[i] |= halftone_values[((i-40)/36)%6] << 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
static GpStatus get_screen_resolution(REAL *xres, REAL *yres)
|
|
|
|
{
|
|
|
|
HDC screendc = GetDC(0);
|
|
|
|
|
|
|
|
if (!screendc) return GenericError;
|
|
|
|
|
|
|
|
*xres = (REAL)GetDeviceCaps(screendc, LOGPIXELSX);
|
|
|
|
*yres = (REAL)GetDeviceCaps(screendc, LOGPIXELSY);
|
|
|
|
|
|
|
|
ReleaseDC(0, screendc);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
|
|
|
|
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
|
|
|
|
{
|
2010-03-06 12:15:38 +00:00
|
|
|
BITMAPINFO* pbmi;
|
2010-11-20 11:24:17 +00:00
|
|
|
HBITMAP hbitmap=NULL;
|
2009-09-03 15:07:25 +00:00
|
|
|
INT row_size, dib_stride;
|
|
|
|
HDC hdc;
|
2010-11-20 11:24:17 +00:00
|
|
|
BYTE *bits=NULL, *own_bits=NULL;
|
2010-03-04 13:34:05 +00:00
|
|
|
REAL xres, yres;
|
|
|
|
GpStatus stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("%d %d %d 0x%x %p %p\n", width, height, stride, format, scan0, bitmap);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if (!bitmap) return InvalidParameter;
|
|
|
|
|
|
|
|
if(width <= 0 || height <= 0 || (scan0 && (stride % 4))){
|
2008-03-25 17:34:57 +00:00
|
|
|
*bitmap = NULL;
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(scan0 && !stride)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
stat = get_screen_resolution(&xres, &yres);
|
|
|
|
if (stat != Ok) return stat;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
row_size = (width * PIXELFORMATBPP(format)+7) / 8;
|
|
|
|
dib_stride = (row_size + 3) & ~3;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if(stride == 0)
|
|
|
|
stride = dib_stride;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (format & PixelFormatGDI && !(format & (PixelFormatAlpha|PixelFormatIndexed)) && !scan0)
|
|
|
|
{
|
|
|
|
pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
|
|
|
if (!pbmi)
|
|
|
|
return OutOfMemory;
|
2010-03-06 12:15:38 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
pbmi->bmiHeader.biWidth = width;
|
|
|
|
pbmi->bmiHeader.biHeight = -height;
|
|
|
|
pbmi->bmiHeader.biPlanes = 1;
|
|
|
|
/* FIXME: use the rest of the data from format */
|
|
|
|
pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
|
|
|
|
pbmi->bmiHeader.biCompression = BI_RGB;
|
|
|
|
pbmi->bmiHeader.biSizeImage = 0;
|
|
|
|
pbmi->bmiHeader.biXPelsPerMeter = 0;
|
|
|
|
pbmi->bmiHeader.biYPelsPerMeter = 0;
|
|
|
|
pbmi->bmiHeader.biClrUsed = 0;
|
|
|
|
pbmi->bmiHeader.biClrImportant = 0;
|
|
|
|
|
|
|
|
hdc = CreateCompatibleDC(NULL);
|
|
|
|
if (!hdc) {
|
|
|
|
GdipFree(pbmi);
|
|
|
|
return GenericError;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
|
|
|
|
|
|
|
DeleteDC(hdc);
|
2010-03-06 12:15:38 +00:00
|
|
|
GdipFree(pbmi);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (!hbitmap) return GenericError;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
stride = dib_stride;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Not a GDI format; don't try to make an HBITMAP. */
|
|
|
|
if (scan0)
|
|
|
|
bits = scan0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
INT size = abs(stride) * height;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
own_bits = bits = GdipAlloc(size);
|
|
|
|
if (!own_bits) return OutOfMemory;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (stride < 0)
|
|
|
|
bits += stride * (1 - height);
|
|
|
|
}
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
*bitmap = GdipAlloc(sizeof(GpBitmap));
|
|
|
|
if(!*bitmap)
|
|
|
|
{
|
|
|
|
DeleteObject(hbitmap);
|
2010-11-20 11:24:17 +00:00
|
|
|
GdipFree(own_bits);
|
2009-09-03 15:07:25 +00:00
|
|
|
return OutOfMemory;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
(*bitmap)->image.type = ImageTypeBitmap;
|
2009-11-28 15:26:02 +00:00
|
|
|
memcpy(&(*bitmap)->image.format, &ImageFormatMemoryBMP, sizeof(GUID));
|
2008-06-01 13:14:02 +00:00
|
|
|
(*bitmap)->image.flags = ImageFlagsNone;
|
2010-01-03 10:54:14 +00:00
|
|
|
(*bitmap)->image.palette_flags = 0;
|
|
|
|
(*bitmap)->image.palette_count = 0;
|
|
|
|
(*bitmap)->image.palette_size = 0;
|
|
|
|
(*bitmap)->image.palette_entries = NULL;
|
2010-03-04 13:34:05 +00:00
|
|
|
(*bitmap)->image.xres = xres;
|
|
|
|
(*bitmap)->image.yres = yres;
|
2008-03-25 17:34:57 +00:00
|
|
|
(*bitmap)->width = width;
|
|
|
|
(*bitmap)->height = height;
|
|
|
|
(*bitmap)->format = format;
|
2009-09-03 15:07:25 +00:00
|
|
|
(*bitmap)->image.picture = NULL;
|
|
|
|
(*bitmap)->hbitmap = hbitmap;
|
|
|
|
(*bitmap)->hdc = NULL;
|
|
|
|
(*bitmap)->bits = bits;
|
2010-11-20 11:24:17 +00:00
|
|
|
(*bitmap)->stride = stride;
|
|
|
|
(*bitmap)->own_bits = own_bits;
|
|
|
|
|
|
|
|
/* set format-related flags */
|
|
|
|
if (format & (PixelFormatAlpha|PixelFormatPAlpha|PixelFormatIndexed))
|
|
|
|
(*bitmap)->image.flags |= ImageFlagsHasAlpha;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (format == PixelFormat1bppIndexed ||
|
|
|
|
format == PixelFormat4bppIndexed ||
|
|
|
|
format == PixelFormat8bppIndexed)
|
|
|
|
{
|
|
|
|
(*bitmap)->image.palette_size = (*bitmap)->image.palette_count = 1 << PIXELFORMATBPP(format);
|
|
|
|
(*bitmap)->image.palette_entries = GdipAlloc(sizeof(ARGB) * ((*bitmap)->image.palette_size));
|
|
|
|
|
|
|
|
if (!(*bitmap)->image.palette_entries)
|
|
|
|
{
|
|
|
|
GdipDisposeImage(&(*bitmap)->image);
|
|
|
|
*bitmap = NULL;
|
|
|
|
return OutOfMemory;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (format == PixelFormat1bppIndexed)
|
|
|
|
{
|
|
|
|
(*bitmap)->image.palette_flags = PaletteFlagsGrayScale;
|
|
|
|
(*bitmap)->image.palette_entries[0] = 0xff000000;
|
|
|
|
(*bitmap)->image.palette_entries[1] = 0xffffffff;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (format == PixelFormat8bppIndexed)
|
|
|
|
(*bitmap)->image.palette_flags = PaletteFlagsHalftone;
|
|
|
|
|
|
|
|
generate_halftone_palette((*bitmap)->image.palette_entries,
|
|
|
|
(*bitmap)->image.palette_count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream* stream,
|
|
|
|
GpBitmap **bitmap)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", stream, bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
stat = GdipLoadImageFromStream(stream, (GpImage**) bitmap);
|
|
|
|
|
|
|
|
if(stat != Ok)
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
if((*bitmap)->image.type != ImageTypeBitmap){
|
2009-09-03 15:07:25 +00:00
|
|
|
GdipDisposeImage(&(*bitmap)->image);
|
|
|
|
*bitmap = NULL;
|
2008-03-25 17:34:57 +00:00
|
|
|
return GenericError; /* FIXME: what error to return? */
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: no icm */
|
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromStreamICM(IStream* stream,
|
|
|
|
GpBitmap **bitmap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", stream, bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return GdipCreateBitmapFromStream(stream, bitmap);
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateCachedBitmap(GpBitmap *bitmap, GpGraphics *graphics,
|
|
|
|
GpCachedBitmap **cachedbmp)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
|
|
|
|
TRACE("%p %p %p\n", bitmap, graphics, cachedbmp);
|
|
|
|
|
|
|
|
if(!bitmap || !graphics || !cachedbmp)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*cachedbmp = GdipAlloc(sizeof(GpCachedBitmap));
|
|
|
|
if(!*cachedbmp)
|
|
|
|
return OutOfMemory;
|
|
|
|
|
|
|
|
stat = GdipCloneImage(&(bitmap->image), &(*cachedbmp)->image);
|
|
|
|
if(stat != Ok){
|
|
|
|
GdipFree(*cachedbmp);
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-06-07 07:59:56 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateHICONFromBitmap(GpBitmap *bitmap, HICON *hicon)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
GpStatus stat;
|
|
|
|
BitmapData lockeddata;
|
|
|
|
ULONG andstride, xorstride, bitssize;
|
|
|
|
LPBYTE andbits, xorbits, androw, xorrow, srcrow;
|
|
|
|
UINT x, y;
|
2009-06-07 07:59:56 +00:00
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p)\n", bitmap, hicon);
|
|
|
|
|
|
|
|
if (!bitmap || !hicon)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead,
|
|
|
|
PixelFormat32bppPARGB, &lockeddata);
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
andstride = ((lockeddata.Width+31)/32)*4;
|
|
|
|
xorstride = lockeddata.Width*4;
|
|
|
|
bitssize = (andstride + xorstride) * lockeddata.Height;
|
|
|
|
|
|
|
|
andbits = GdipAlloc(bitssize);
|
|
|
|
|
|
|
|
if (andbits)
|
|
|
|
{
|
|
|
|
xorbits = andbits + andstride * lockeddata.Height;
|
|
|
|
|
|
|
|
for (y=0; y<lockeddata.Height; y++)
|
|
|
|
{
|
|
|
|
srcrow = ((LPBYTE)lockeddata.Scan0) + lockeddata.Stride * y;
|
|
|
|
|
|
|
|
androw = andbits + andstride * y;
|
|
|
|
for (x=0; x<lockeddata.Width; x++)
|
|
|
|
if (srcrow[3+4*x] >= 128)
|
|
|
|
androw[x/8] |= 1 << (7-x%8);
|
|
|
|
|
|
|
|
xorrow = xorbits + xorstride * y;
|
|
|
|
memcpy(xorrow, srcrow, xorstride);
|
|
|
|
}
|
|
|
|
|
|
|
|
*hicon = CreateIcon(NULL, lockeddata.Width, lockeddata.Height, 1, 32,
|
|
|
|
andbits, xorbits);
|
|
|
|
|
|
|
|
GdipFree(andbits);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
stat = OutOfMemory;
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(bitmap, &lockeddata);
|
|
|
|
}
|
|
|
|
|
|
|
|
return stat;
|
2009-06-07 07:59:56 +00:00
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipDeleteCachedBitmap(GpCachedBitmap *cachedbmp)
|
|
|
|
{
|
|
|
|
TRACE("%p\n", cachedbmp);
|
|
|
|
|
|
|
|
if(!cachedbmp)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
GdipDisposeImage(cachedbmp->image);
|
|
|
|
GdipFree(cachedbmp);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipDrawCachedBitmap(GpGraphics *graphics,
|
|
|
|
GpCachedBitmap *cachedbmp, INT x, INT y)
|
|
|
|
{
|
|
|
|
TRACE("%p %p %d %d\n", graphics, cachedbmp, x, y);
|
|
|
|
|
|
|
|
if(!graphics || !cachedbmp)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return GdipDrawImage(graphics, cachedbmp->image, (REAL)x, (REAL)y);
|
|
|
|
}
|
|
|
|
|
2009-06-07 07:59:56 +00:00
|
|
|
GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16,
|
|
|
|
LPBYTE pData16, INT iMapMode, INT eFlags)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %d, %p, %d, %d): stub\n", hemf, cbData16, pData16, iMapMode, eFlags);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
/* Internal utility function: Replace the image data of dst with that of src,
|
|
|
|
* and free src. */
|
|
|
|
static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
|
|
|
|
{
|
|
|
|
GdipFree(dst->bitmapbits);
|
|
|
|
DeleteDC(dst->hdc);
|
|
|
|
DeleteObject(dst->hbitmap);
|
|
|
|
|
|
|
|
if (clobber_palette)
|
|
|
|
{
|
|
|
|
GdipFree(dst->image.palette_entries);
|
|
|
|
dst->image.palette_flags = src->image.palette_flags;
|
|
|
|
dst->image.palette_count = src->image.palette_count;
|
|
|
|
dst->image.palette_entries = src->image.palette_entries;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
GdipFree(src->image.palette_entries);
|
|
|
|
|
|
|
|
dst->image.xres = src->image.xres;
|
|
|
|
dst->image.yres = src->image.yres;
|
|
|
|
dst->width = src->width;
|
|
|
|
dst->height = src->height;
|
|
|
|
dst->format = src->format;
|
|
|
|
dst->hbitmap = src->hbitmap;
|
|
|
|
dst->hdc = src->hdc;
|
|
|
|
dst->bits = src->bits;
|
|
|
|
dst->stride = src->stride;
|
2010-11-20 11:24:17 +00:00
|
|
|
dst->own_bits = src->own_bits;
|
2010-04-20 08:30:10 +00:00
|
|
|
|
|
|
|
GdipFree(src);
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p\n", image);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if (image->type == ImageTypeBitmap)
|
2009-09-03 15:07:25 +00:00
|
|
|
{
|
2008-03-25 17:34:57 +00:00
|
|
|
GdipFree(((GpBitmap*)image)->bitmapbits);
|
2010-11-20 11:24:17 +00:00
|
|
|
GdipFree(((GpBitmap*)image)->own_bits);
|
2009-09-03 15:07:25 +00:00
|
|
|
DeleteDC(((GpBitmap*)image)->hdc);
|
2010-03-06 12:15:38 +00:00
|
|
|
DeleteObject(((GpBitmap*)image)->hbitmap);
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
2010-11-20 11:24:17 +00:00
|
|
|
else if (image->type != ImageTypeMetafile)
|
|
|
|
{
|
|
|
|
WARN("invalid image: %p\n", image);
|
|
|
|
return ObjectBusy;
|
|
|
|
}
|
|
|
|
if (image->picture)
|
|
|
|
IPicture_Release(image->picture);
|
2010-01-03 10:54:14 +00:00
|
|
|
GdipFree(image->palette_entries);
|
2010-11-20 11:24:17 +00:00
|
|
|
image->type = ~0;
|
2008-03-25 17:34:57 +00:00
|
|
|
GdipFree(image);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipFindFirstImageItem(GpImage *image, ImageItemData* item)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n", image, item);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !item)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if (!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2010-03-06 12:15:38 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImageItemData(GpImage *image, ImageItemData *item)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n", image, item);
|
|
|
|
|
|
|
|
if (!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImageBounds(GpImage *image, GpRectF *srcRect,
|
|
|
|
GpUnit *srcUnit)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p %p\n", image, srcRect, srcUnit);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !srcRect || !srcUnit)
|
|
|
|
return InvalidParameter;
|
|
|
|
if(image->type == ImageTypeMetafile){
|
|
|
|
*srcRect = ((GpMetafile*)image)->bounds;
|
|
|
|
*srcUnit = ((GpMetafile*)image)->unit;
|
|
|
|
}
|
|
|
|
else if(image->type == ImageTypeBitmap){
|
|
|
|
srcRect->X = srcRect->Y = 0.0;
|
|
|
|
srcRect->Width = (REAL) ((GpBitmap*)image)->width;
|
|
|
|
srcRect->Height = (REAL) ((GpBitmap*)image)->height;
|
|
|
|
*srcUnit = UnitPixel;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
srcRect->X = srcRect->Y = 0.0;
|
|
|
|
srcRect->Width = ipicture_pixel_width(image->picture);
|
|
|
|
srcRect->Height = ipicture_pixel_height(image->picture);
|
|
|
|
*srcUnit = UnitPixel;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("returning (%f, %f) (%f, %f) unit type %d\n", srcRect->X, srcRect->Y,
|
|
|
|
srcRect->Width, srcRect->Height, *srcUnit);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width,
|
|
|
|
REAL *height)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p %p\n", image, width, height);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !height || !width)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(image->type == ImageTypeMetafile){
|
|
|
|
HDC hdc = GetDC(0);
|
2010-11-20 11:24:17 +00:00
|
|
|
REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
|
|
|
|
*height = convert_unit(res, ((GpMetafile*)image)->unit) *
|
2008-03-25 17:34:57 +00:00
|
|
|
((GpMetafile*)image)->bounds.Height;
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
*width = convert_unit(res, ((GpMetafile*)image)->unit) *
|
2008-03-25 17:34:57 +00:00
|
|
|
((GpMetafile*)image)->bounds.Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(image->type == ImageTypeBitmap){
|
|
|
|
*height = ((GpBitmap*)image)->height;
|
|
|
|
*width = ((GpBitmap*)image)->width;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*height = ipicture_pixel_height(image->picture);
|
|
|
|
*width = ipicture_pixel_width(image->picture);
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("returning (%f, %f)\n", *height, *width);
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
|
|
|
|
GpGraphics **graphics)
|
|
|
|
{
|
|
|
|
HDC hdc;
|
2010-04-20 08:30:10 +00:00
|
|
|
GpStatus stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, graphics);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !graphics)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(image->type != ImageTypeBitmap){
|
|
|
|
FIXME("not implemented for image type %d\n", image->type);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (((GpBitmap*)image)->hbitmap)
|
|
|
|
{
|
|
|
|
hdc = ((GpBitmap*)image)->hdc;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if(!hdc){
|
|
|
|
hdc = CreateCompatibleDC(0);
|
|
|
|
SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
|
|
|
|
((GpBitmap*)image)->hdc = hdc;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
stat = GdipCreateFromHDC(hdc, graphics);
|
2010-04-20 08:30:10 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (stat == Ok)
|
|
|
|
(*graphics)->image = image;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
stat = graphics_from_image(image, graphics);
|
2010-04-20 08:30:10 +00:00
|
|
|
|
|
|
|
return stat;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, height);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !height)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(image->type == ImageTypeMetafile){
|
|
|
|
HDC hdc = GetDC(0);
|
2010-11-20 11:24:17 +00:00
|
|
|
REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
ReleaseDC(0, hdc);
|
2010-11-20 11:24:17 +00:00
|
|
|
|
|
|
|
*height = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
|
|
|
|
((GpMetafile*)image)->bounds.Height);
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
else if(image->type == ImageTypeBitmap)
|
|
|
|
*height = ((GpBitmap*)image)->height;
|
|
|
|
else
|
|
|
|
*height = ipicture_pixel_height(image->picture);
|
|
|
|
|
|
|
|
TRACE("returning %d\n", *height);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage *image, REAL *res)
|
|
|
|
{
|
|
|
|
if(!image || !res)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
*res = image->xres;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p) <-- %0.2f\n", image, *res);
|
|
|
|
|
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage *image, INT *size)
|
|
|
|
{
|
2010-01-03 10:54:14 +00:00
|
|
|
TRACE("%p %p\n", image, size);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
if(!image || !size)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (image->palette_count == 0)
|
|
|
|
*size = sizeof(ColorPalette);
|
|
|
|
else
|
|
|
|
*size = sizeof(UINT)*2 + sizeof(ARGB)*image->palette_count;
|
|
|
|
|
|
|
|
TRACE("<-- %u\n", *size);
|
|
|
|
|
|
|
|
return Ok;
|
2008-12-06 09:26:01 +00:00
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
/* FIXME: test this function for non-bitmap types */
|
|
|
|
GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage *image, PixelFormat *format)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, format);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !format)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(image->type != ImageTypeBitmap)
|
|
|
|
*format = PixelFormat24bppRGB;
|
|
|
|
else
|
|
|
|
*format = ((GpBitmap*) image)->format;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage *image, GUID *format)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p)\n", image, format);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !format)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
memcpy(format, &image->format, sizeof(GUID));
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageType(GpImage *image, ImageType *type)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, type);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !type)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*type = image->type;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageVerticalResolution(GpImage *image, REAL *res)
|
|
|
|
{
|
|
|
|
if(!image || !res)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
*res = image->yres;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p) <-- %0.2f\n", image, *res);
|
|
|
|
|
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, width);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !width)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(image->type == ImageTypeMetafile){
|
|
|
|
HDC hdc = GetDC(0);
|
2010-11-20 11:24:17 +00:00
|
|
|
REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
ReleaseDC(0, hdc);
|
2010-11-20 11:24:17 +00:00
|
|
|
|
|
|
|
*width = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
|
|
|
|
((GpMetafile*)image)->bounds.Width);
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
else if(image->type == ImageTypeBitmap)
|
|
|
|
*width = ((GpBitmap*)image)->width;
|
|
|
|
else
|
|
|
|
*width = ipicture_pixel_width(image->picture);
|
|
|
|
|
|
|
|
TRACE("returning %d\n", *width);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile * metafile,
|
|
|
|
MetafileHeader * header)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p)\n", metafile, header);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!metafile || !header)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
2010-03-21 19:20:42 +00:00
|
|
|
memset(header, 0, sizeof(MetafileHeader));
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hEmf,
|
|
|
|
MetafileHeader *header)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
if(!hEmf || !header)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
memset(header, 0, sizeof(MetafileHeader));
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromFile(GDIPCONST WCHAR *filename,
|
|
|
|
MetafileHeader *header)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%s,%p)\n", debugstr_w(filename), header);
|
|
|
|
|
|
|
|
if(!filename || !header)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
memset(header, 0, sizeof(MetafileHeader));
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromStream(IStream *stream,
|
|
|
|
MetafileHeader *header)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n", stream, header);
|
|
|
|
|
|
|
|
if(!stream || !header)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
memset(header, 0, sizeof(MetafileHeader));
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetAllPropertyItems(GpImage *image, UINT size,
|
|
|
|
UINT num, PropertyItem* items)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %u, %u, %p)\n", image, size, num, items);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPropertyCount(GpImage *image, UINT* num)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p)\n", image, num);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPropertyIdList(GpImage *image, UINT num, PROPID* list)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %u, %p)\n", image, num, list);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage *image, PROPID id, UINT size,
|
|
|
|
PropertyItem* buffer)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %u, %u, %p)\n", image, id, size, buffer);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPropertyItemSize(GpImage *image, PROPID pid,
|
|
|
|
UINT* size)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("%p %x %p\n", image, pid, size);
|
|
|
|
|
|
|
|
if(!size || !image)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPropertySize(GpImage *image, UINT* size, UINT* num)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%p,%p)\n", image, size, num);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
struct image_format_dimension
|
|
|
|
{
|
|
|
|
const GUID *format;
|
|
|
|
const GUID *dimension;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct image_format_dimension image_format_dimensions[] =
|
|
|
|
{
|
|
|
|
{&ImageFormatGIF, &FrameDimensionTime},
|
|
|
|
{&ImageFormatIcon, &FrameDimensionResolution},
|
|
|
|
{NULL}
|
|
|
|
};
|
|
|
|
|
2010-03-21 19:20:42 +00:00
|
|
|
/* FIXME: Need to handle multi-framed images */
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image,
|
|
|
|
GDIPCONST GUID* dimensionID, UINT* count)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%s,%p)\n", image, debugstr_guid(dimensionID), count);
|
|
|
|
|
2010-03-21 19:20:42 +00:00
|
|
|
if(!image || !count)
|
2008-03-25 17:34:57 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
2010-03-21 19:20:42 +00:00
|
|
|
FIXME("returning frame count of 1\n");
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-21 19:20:42 +00:00
|
|
|
*count = 1;
|
|
|
|
|
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image,
|
|
|
|
UINT* count)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %p)\n", image, count);
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
/* Native gdiplus 1.1 does not yet support multiple frame dimensions. */
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!image || !count)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*count = 1;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage* image,
|
|
|
|
GUID* dimensionIDs, UINT count)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
int i;
|
|
|
|
const GUID *result=NULL;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%u)\n", image, dimensionIDs, count);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
if(!image || !dimensionIDs || count != 1)
|
2008-03-25 17:34:57 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
for (i=0; image_format_dimensions[i].format; i++)
|
|
|
|
{
|
|
|
|
if (IsEqualGUID(&image->format, image_format_dimensions[i].format))
|
|
|
|
{
|
|
|
|
result = image_format_dimensions[i].dimension;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
result = &FrameDimensionPage;
|
|
|
|
|
|
|
|
memcpy(dimensionIDs, result, sizeof(GUID));
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image,
|
|
|
|
GDIPCONST GUID* dimensionID, UINT frameidx)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("(%p, %s, %u)\n", image, debugstr_guid(dimensionID), frameidx);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !dimensionID)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipLoadImageFromFile(GDIPCONST WCHAR* filename,
|
|
|
|
GpImage **image)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
IStream *stream;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%s) %p\n", debugstr_w(filename), image);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if (!filename || !image)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
stat = GdipCreateStreamOnFile(filename, GENERIC_READ, &stream);
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
stat = GdipLoadImageFromStream(stream, image);
|
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
2008-06-01 13:14:02 +00:00
|
|
|
/* FIXME: no icm handling */
|
|
|
|
GpStatus WINGDIPAPI GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename,GpImage **image)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%s) %p\n", debugstr_w(filename), image);
|
|
|
|
|
2008-06-01 13:14:02 +00:00
|
|
|
return GdipLoadImageFromFile(filename, image);
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
static const WICPixelFormatGUID *wic_pixel_formats[] = {
|
|
|
|
&GUID_WICPixelFormat16bppBGR555,
|
|
|
|
&GUID_WICPixelFormat24bppBGR,
|
|
|
|
&GUID_WICPixelFormat32bppBGR,
|
|
|
|
&GUID_WICPixelFormat32bppBGRA,
|
|
|
|
&GUID_WICPixelFormat32bppPBGRA,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const PixelFormat wic_gdip_formats[] = {
|
|
|
|
PixelFormat16bppRGB555,
|
|
|
|
PixelFormat24bppRGB,
|
|
|
|
PixelFormat32bppRGB,
|
|
|
|
PixelFormat32bppARGB,
|
|
|
|
PixelFormat32bppPARGB,
|
|
|
|
};
|
|
|
|
|
|
|
|
static GpStatus decode_image_wic(IStream* stream, REFCLSID clsid, GpImage **image)
|
|
|
|
{
|
|
|
|
GpStatus status=Ok;
|
|
|
|
GpBitmap *bitmap;
|
|
|
|
HRESULT hr;
|
|
|
|
IWICBitmapDecoder *decoder;
|
|
|
|
IWICBitmapFrameDecode *frame;
|
|
|
|
IWICBitmapSource *source=NULL;
|
|
|
|
WICPixelFormatGUID wic_format;
|
|
|
|
PixelFormat gdip_format=0;
|
|
|
|
int i;
|
|
|
|
UINT width, height;
|
|
|
|
BitmapData lockeddata;
|
|
|
|
WICRect wrc;
|
|
|
|
HRESULT initresult;
|
|
|
|
|
|
|
|
initresult = CoInitialize(NULL);
|
|
|
|
|
|
|
|
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
|
|
|
|
&IID_IWICBitmapDecoder, (void**)&decoder);
|
|
|
|
if (FAILED(hr)) goto end;
|
|
|
|
|
|
|
|
hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)stream, WICDecodeMetadataCacheOnLoad);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr)) /* got frame */
|
|
|
|
{
|
|
|
|
hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &wic_format);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for (i=0; wic_pixel_formats[i]; i++)
|
|
|
|
{
|
|
|
|
if (IsEqualGUID(&wic_format, wic_pixel_formats[i]))
|
|
|
|
{
|
|
|
|
source = (IWICBitmapSource*)frame;
|
|
|
|
IWICBitmapSource_AddRef(source);
|
|
|
|
gdip_format = wic_gdip_formats[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!source)
|
|
|
|
{
|
|
|
|
/* unknown format; fall back on 32bppARGB */
|
|
|
|
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, (IWICBitmapSource*)frame, &source);
|
|
|
|
gdip_format = PixelFormat32bppARGB;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr)) /* got source */
|
|
|
|
{
|
|
|
|
hr = IWICBitmapSource_GetSize(source, &width, &height);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
status = GdipCreateBitmapFromScan0(width, height, 0, gdip_format,
|
|
|
|
NULL, &bitmap);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && status == Ok) /* created bitmap */
|
|
|
|
{
|
|
|
|
status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeWrite,
|
|
|
|
gdip_format, &lockeddata);
|
|
|
|
if (status == Ok) /* locked bitmap */
|
|
|
|
{
|
|
|
|
wrc.X = 0;
|
|
|
|
wrc.Width = width;
|
|
|
|
wrc.Height = 1;
|
|
|
|
for (i=0; i<height; i++)
|
|
|
|
{
|
|
|
|
wrc.Y = i;
|
|
|
|
hr = IWICBitmapSource_CopyPixels(source, &wrc, abs(lockeddata.Stride),
|
|
|
|
abs(lockeddata.Stride), (BYTE*)lockeddata.Scan0+lockeddata.Stride*i);
|
|
|
|
if (FAILED(hr)) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(bitmap, &lockeddata);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && status == Ok)
|
|
|
|
*image = (GpImage*)bitmap;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*image = NULL;
|
|
|
|
GdipDisposeImage((GpImage*)bitmap);
|
|
|
|
}
|
2010-11-20 11:24:17 +00:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && status == Ok)
|
|
|
|
{
|
|
|
|
double dpix, dpiy;
|
|
|
|
hr = IWICBitmapSource_GetResolution(source, &dpix, &dpiy);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
bitmap->image.xres = dpix;
|
|
|
|
bitmap->image.yres = dpiy;
|
|
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
}
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
IWICBitmapSource_Release(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
IWICBitmapFrameDecode_Release(frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
IWICBitmapDecoder_Release(decoder);
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (SUCCEEDED(initresult)) CoUninitialize();
|
|
|
|
|
|
|
|
if (FAILED(hr) && status == Ok) status = hresult_to_status(hr);
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
if (status == Ok)
|
|
|
|
{
|
|
|
|
/* Native GDI+ used to be smarter, but since Win7 it just sets these flags. */
|
|
|
|
bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GpStatus decode_image_icon(IStream* stream, REFCLSID clsid, GpImage **image)
|
|
|
|
{
|
|
|
|
return decode_image_wic(stream, &CLSID_WICIcoDecoder, image);
|
|
|
|
}
|
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, GpImage **image)
|
2009-09-03 15:07:25 +00:00
|
|
|
{
|
2009-11-28 15:26:02 +00:00
|
|
|
GpStatus status;
|
|
|
|
GpBitmap* bitmap;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
status = decode_image_wic(stream, &CLSID_WICBmpDecoder, image);
|
2009-01-27 18:03:33 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
bitmap = (GpBitmap*)*image;
|
2009-09-03 15:07:25 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
if (status == Ok && bitmap->format == PixelFormat32bppARGB)
|
2009-09-03 15:07:25 +00:00
|
|
|
{
|
2009-11-28 15:26:02 +00:00
|
|
|
/* WIC supports bmp files with alpha, but gdiplus does not */
|
|
|
|
bitmap->format = PixelFormat32bppRGB;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
2009-09-03 15:07:25 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
return status;
|
|
|
|
}
|
2009-09-03 15:07:25 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image)
|
|
|
|
{
|
|
|
|
return decode_image_wic(stream, &CLSID_WICJpegDecoder, image);
|
|
|
|
}
|
2009-09-03 15:07:25 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
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);
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
static GpStatus decode_image_tiff(IStream* stream, REFCLSID clsid, GpImage **image)
|
|
|
|
{
|
|
|
|
return decode_image_wic(stream, &CLSID_WICTiffDecoder, image);
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage **image)
|
|
|
|
{
|
|
|
|
IPicture *pic;
|
|
|
|
|
|
|
|
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;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
/* FIXME: missing initialization code */
|
|
|
|
*image = GdipAlloc(sizeof(GpMetafile));
|
|
|
|
if(!*image) return OutOfMemory;
|
|
|
|
(*image)->type = ImageTypeMetafile;
|
2008-03-25 17:34:57 +00:00
|
|
|
(*image)->picture = pic;
|
2008-06-01 13:14:02 +00:00
|
|
|
(*image)->flags = ImageFlagsNone;
|
2010-01-03 10:54:14 +00:00
|
|
|
(*image)->palette_flags = 0;
|
|
|
|
(*image)->palette_count = 0;
|
|
|
|
(*image)->palette_size = 0;
|
|
|
|
(*image)->palette_entries = NULL;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *image);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
typedef GpStatus (*encode_image_func)(GpImage *image, IStream* stream,
|
|
|
|
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params);
|
|
|
|
|
|
|
|
typedef GpStatus (*decode_image_func)(IStream *stream, REFCLSID clsid, GpImage** image);
|
|
|
|
|
|
|
|
typedef struct image_codec {
|
|
|
|
ImageCodecInfo info;
|
|
|
|
encode_image_func encode_func;
|
|
|
|
decode_image_func decode_func;
|
|
|
|
} image_codec;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
BMP,
|
|
|
|
JPEG,
|
|
|
|
GIF,
|
2010-04-20 08:30:10 +00:00
|
|
|
TIFF,
|
2009-09-03 15:07:25 +00:00
|
|
|
EMF,
|
|
|
|
WMF,
|
|
|
|
PNG,
|
|
|
|
ICO,
|
|
|
|
NUM_CODECS
|
|
|
|
} ImageFormat;
|
|
|
|
|
|
|
|
static const struct image_codec codecs[NUM_CODECS];
|
|
|
|
|
|
|
|
static GpStatus get_decoder_info(IStream* stream, const struct image_codec **result)
|
|
|
|
{
|
|
|
|
BYTE signature[8];
|
2010-04-20 08:30:10 +00:00
|
|
|
const BYTE *pattern, *mask;
|
2009-09-03 15:07:25 +00:00
|
|
|
LARGE_INTEGER seek;
|
|
|
|
HRESULT hr;
|
|
|
|
UINT bytesread;
|
2010-04-20 08:30:10 +00:00
|
|
|
int i, j, sig;
|
2009-09-03 15:07:25 +00:00
|
|
|
|
|
|
|
/* seek to the start of the stream */
|
|
|
|
seek.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
|
|
|
|
if (FAILED(hr)) return hresult_to_status(hr);
|
|
|
|
|
|
|
|
/* read the first 8 bytes */
|
2010-04-20 08:30:10 +00:00
|
|
|
/* FIXME: This assumes all codecs have signatures <= 8 bytes in length */
|
2009-09-03 15:07:25 +00:00
|
|
|
hr = IStream_Read(stream, signature, 8, &bytesread);
|
|
|
|
if (FAILED(hr)) return hresult_to_status(hr);
|
|
|
|
if (hr == S_FALSE || bytesread == 0) return GenericError;
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_CODECS; i++) {
|
|
|
|
if ((codecs[i].info.Flags & ImageCodecFlagsDecoder) &&
|
|
|
|
bytesread >= codecs[i].info.SigSize)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
for (sig=0; sig<codecs[i].info.SigCount; sig++)
|
2009-09-03 15:07:25 +00:00
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
pattern = &codecs[i].info.SigPattern[codecs[i].info.SigSize*sig];
|
|
|
|
mask = &codecs[i].info.SigMask[codecs[i].info.SigSize*sig];
|
|
|
|
for (j=0; j<codecs[i].info.SigSize; j++)
|
|
|
|
if ((signature[j] & mask[j]) != pattern[j])
|
|
|
|
break;
|
|
|
|
if (j == codecs[i].info.SigSize)
|
|
|
|
{
|
|
|
|
*result = &codecs[i];
|
|
|
|
return Ok;
|
|
|
|
}
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("no match for %i byte signature %x %x %x %x %x %x %x %x\n", bytesread,
|
|
|
|
signature[0],signature[1],signature[2],signature[3],
|
|
|
|
signature[4],signature[5],signature[6],signature[7]);
|
|
|
|
|
|
|
|
return GenericError;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream* stream, GpImage **image)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
LARGE_INTEGER seek;
|
|
|
|
HRESULT hr;
|
|
|
|
const struct image_codec *codec=NULL;
|
|
|
|
|
|
|
|
/* choose an appropriate image decoder */
|
|
|
|
stat = get_decoder_info(stream, &codec);
|
|
|
|
if (stat != Ok) return stat;
|
|
|
|
|
|
|
|
/* seek to the start of the stream */
|
|
|
|
seek.QuadPart = 0;
|
|
|
|
hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
|
|
|
|
if (FAILED(hr)) return hresult_to_status(hr);
|
|
|
|
|
|
|
|
/* call on the image decoder to do the real work */
|
2009-11-28 15:26:02 +00:00
|
|
|
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;
|
2009-09-03 15:07:25 +00:00
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
/* FIXME: no ICM */
|
|
|
|
GpStatus WINGDIPAPI GdipLoadImageFromStreamICM(IStream* stream, GpImage **image)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", stream, image);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return GdipLoadImageFromStream(stream, image);
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipRemovePropertyItem(GpImage *image, PROPID propId)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%u)\n", image, propId);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPropertyItem(GpImage *image, GDIPCONST PropertyItem* item)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%p)\n", image, item);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filename,
|
|
|
|
GDIPCONST CLSID *clsidEncoder,
|
|
|
|
GDIPCONST EncoderParameters *encoderParams)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
|
|
|
IStream *stream;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p (%s) %p %p\n", image, debugstr_w(filename), clsidEncoder, encoderParams);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if (!image || !filename|| !clsidEncoder)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
stat = GdipCreateStreamOnFile(filename, GENERIC_WRITE, &stream);
|
|
|
|
if (stat != Ok)
|
|
|
|
return GenericError;
|
|
|
|
|
|
|
|
stat = GdipSaveImageToStream(image, stream, clsidEncoder, encoderParams);
|
|
|
|
|
|
|
|
IStream_Release(stream);
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Encoding functions -
|
|
|
|
* These functions encode an image in different image file formats.
|
|
|
|
*/
|
|
|
|
#define BITMAP_FORMAT_BMP 0x4d42 /* "BM" */
|
|
|
|
#define BITMAP_FORMAT_JPEG 0xd8ff
|
|
|
|
#define BITMAP_FORMAT_GIF 0x4947
|
|
|
|
#define BITMAP_FORMAT_PNG 0x5089
|
|
|
|
#define BITMAP_FORMAT_APM 0xcdd7
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
static GpStatus encode_image_WIC(GpImage *image, IStream* stream,
|
|
|
|
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
|
2008-03-25 17:34:57 +00:00
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
GpStatus stat;
|
|
|
|
GpBitmap *bitmap;
|
|
|
|
IWICBitmapEncoder *encoder;
|
|
|
|
IWICBitmapFrameEncode *frameencode;
|
|
|
|
IPropertyBag2 *encoderoptions;
|
|
|
|
HRESULT hr;
|
|
|
|
UINT width, height;
|
|
|
|
PixelFormat gdipformat=0;
|
|
|
|
WICPixelFormatGUID wicformat;
|
|
|
|
GpRect rc;
|
|
|
|
BitmapData lockeddata;
|
|
|
|
HRESULT initresult;
|
|
|
|
UINT i;
|
|
|
|
|
|
|
|
if (image->type != ImageTypeBitmap)
|
|
|
|
return GenericError;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
bitmap = (GpBitmap*)image;
|
|
|
|
|
|
|
|
GdipGetImageWidth(image, &width);
|
|
|
|
GdipGetImageHeight(image, &height);
|
|
|
|
|
|
|
|
rc.X = 0;
|
|
|
|
rc.Y = 0;
|
|
|
|
rc.Width = width;
|
|
|
|
rc.Height = height;
|
|
|
|
|
|
|
|
initresult = CoInitialize(NULL);
|
|
|
|
|
|
|
|
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
|
|
|
|
&IID_IWICBitmapEncoder, (void**)&encoder);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
if (SUCCEEDED(initresult)) CoUninitialize();
|
|
|
|
return hresult_to_status(hr);
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &encoderoptions);
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (SUCCEEDED(hr)) /* created frame */
|
|
|
|
{
|
|
|
|
hr = IWICBitmapFrameEncode_Initialize(frameencode, encoderoptions);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
hr = IWICBitmapFrameEncode_SetSize(frameencode, width, height);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
/* FIXME: use the resolution from the image */
|
|
|
|
hr = IWICBitmapFrameEncode_SetResolution(frameencode, 96.0, 96.0);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for (i=0; wic_pixel_formats[i]; i++)
|
|
|
|
{
|
|
|
|
if (wic_gdip_formats[i] == bitmap->format)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (wic_pixel_formats[i])
|
|
|
|
memcpy(&wicformat, wic_pixel_formats[i], sizeof(GUID));
|
|
|
|
else
|
|
|
|
memcpy(&wicformat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
|
|
|
|
|
|
|
|
hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &wicformat);
|
|
|
|
|
|
|
|
for (i=0; wic_pixel_formats[i]; i++)
|
|
|
|
{
|
|
|
|
if (IsEqualGUID(&wicformat, wic_pixel_formats[i]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (wic_pixel_formats[i])
|
|
|
|
gdipformat = wic_gdip_formats[i];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("cannot provide pixel format %s\n", debugstr_guid(&wicformat));
|
|
|
|
hr = E_FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
stat = GdipBitmapLockBits(bitmap, &rc, ImageLockModeRead, gdipformat,
|
|
|
|
&lockeddata);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
UINT row_size = (lockeddata.Width * PIXELFORMATBPP(gdipformat) + 7)/8;
|
|
|
|
BYTE *row;
|
|
|
|
|
|
|
|
/* write one row at a time in case stride is negative */
|
|
|
|
row = lockeddata.Scan0;
|
|
|
|
for (i=0; i<lockeddata.Height; i++)
|
|
|
|
{
|
|
|
|
hr = IWICBitmapFrameEncode_WritePixels(frameencode, 1, row_size, row_size, row);
|
|
|
|
if (FAILED(hr)) break;
|
|
|
|
row += lockeddata.Stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(bitmap, &lockeddata);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
hr = E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
hr = IWICBitmapFrameEncode_Commit(frameencode);
|
|
|
|
|
|
|
|
IWICBitmapFrameEncode_Release(frameencode);
|
|
|
|
IPropertyBag2_Release(encoderoptions);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
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);
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-11-28 15:26:02 +00:00
|
|
|
static GpStatus encode_image_png(GpImage *image, IStream* stream,
|
|
|
|
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
|
|
|
|
{
|
|
|
|
return encode_image_WIC(image, stream, &CLSID_WICPngEncoder, params);
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipSaveImageToStream [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
|
|
|
|
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
|
|
|
|
{
|
|
|
|
GpStatus stat;
|
2009-09-03 15:07:25 +00:00
|
|
|
encode_image_func encode_image;
|
2008-03-25 17:34:57 +00:00
|
|
|
int i;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p %p %p\n", image, stream, clsid, params);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!image || !stream)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
/* select correct encoder */
|
|
|
|
encode_image = NULL;
|
2009-09-03 15:07:25 +00:00
|
|
|
for (i = 0; i < NUM_CODECS; i++) {
|
|
|
|
if ((codecs[i].info.Flags & ImageCodecFlagsEncoder) &&
|
|
|
|
IsEqualCLSID(clsid, &codecs[i].info.Clsid))
|
|
|
|
encode_image = codecs[i].encode_func;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
if (encode_image == NULL)
|
|
|
|
return UnknownImageFormat;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
stat = encode_image(image, stream, clsid, params);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
return stat;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImagePalette [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size)
|
|
|
|
{
|
2010-01-03 10:54:14 +00:00
|
|
|
TRACE("(%p,%p,%i)\n", image, palette, size);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (!image || !palette)
|
2009-09-03 15:07:25 +00:00
|
|
|
return InvalidParameter;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (size < (sizeof(UINT)*2+sizeof(ARGB)*image->palette_count))
|
|
|
|
{
|
|
|
|
TRACE("<-- InsufficientBuffer\n");
|
|
|
|
return InsufficientBuffer;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
palette->Flags = image->palette_flags;
|
|
|
|
palette->Count = image->palette_count;
|
|
|
|
memcpy(palette->Entries, image->palette_entries, sizeof(ARGB)*image->palette_count);
|
|
|
|
|
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipSetImagePalette [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image,
|
|
|
|
GDIPCONST ColorPalette *palette)
|
|
|
|
{
|
2010-01-03 10:54:14 +00:00
|
|
|
TRACE("(%p,%p)\n", image, palette);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if(!image || !palette || palette->Count > 256)
|
2008-03-25 17:34:57 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
if (palette->Count > image->palette_size)
|
|
|
|
{
|
|
|
|
ARGB *new_palette;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
new_palette = GdipAlloc(sizeof(ARGB) * palette->Count);
|
|
|
|
if (!new_palette) return OutOfMemory;
|
|
|
|
|
|
|
|
GdipFree(image->palette_entries);
|
|
|
|
image->palette_entries = new_palette;
|
|
|
|
image->palette_size = palette->Count;
|
|
|
|
}
|
|
|
|
|
|
|
|
image->palette_flags = palette->Flags;
|
|
|
|
image->palette_count = palette->Count;
|
|
|
|
memcpy(image->palette_entries, palette->Entries, sizeof(ARGB)*palette->Count);
|
|
|
|
|
|
|
|
return Ok;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Encoders -
|
|
|
|
* Structures that represent which formats we support for encoding.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* ImageCodecInfo creation routines taken from libgdiplus */
|
|
|
|
static const WCHAR bmp_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'B', 'M', 'P', 0}; /* Built-in BMP */
|
|
|
|
static const WCHAR bmp_extension[] = {'*','.','B', 'M', 'P',';', '*','.', 'D','I', 'B',';', '*','.', 'R', 'L', 'E',0}; /* *.BMP;*.DIB;*.RLE */
|
|
|
|
static const WCHAR bmp_mimetype[] = {'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p', 0}; /* image/bmp */
|
|
|
|
static const WCHAR bmp_format[] = {'B', 'M', 'P', 0}; /* BMP */
|
|
|
|
static const BYTE bmp_sig_pattern[] = { 0x42, 0x4D };
|
|
|
|
static const BYTE bmp_sig_mask[] = { 0xFF, 0xFF };
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
static const WCHAR jpeg_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'J','P','E','G', 0};
|
|
|
|
static const WCHAR jpeg_extension[] = {'*','.','J','P','G',';', '*','.','J','P','E','G',';', '*','.','J','P','E',';', '*','.','J','F','I','F',0};
|
|
|
|
static const WCHAR jpeg_mimetype[] = {'i','m','a','g','e','/','j','p','e','g', 0};
|
|
|
|
static const WCHAR jpeg_format[] = {'J','P','E','G',0};
|
|
|
|
static const BYTE jpeg_sig_pattern[] = { 0xFF, 0xD8 };
|
|
|
|
static const BYTE jpeg_sig_mask[] = { 0xFF, 0xFF };
|
|
|
|
|
|
|
|
static const WCHAR gif_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'G','I','F', 0};
|
|
|
|
static const WCHAR gif_extension[] = {'*','.','G','I','F',0};
|
|
|
|
static const WCHAR gif_mimetype[] = {'i','m','a','g','e','/','g','i','f', 0};
|
|
|
|
static const WCHAR gif_format[] = {'G','I','F',0};
|
|
|
|
static const BYTE gif_sig_pattern[4] = "GIF8";
|
|
|
|
static const BYTE gif_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
static const WCHAR tiff_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'T','I','F','F', 0};
|
|
|
|
static const WCHAR tiff_extension[] = {'*','.','T','I','F','F',';','*','.','T','I','F',0};
|
|
|
|
static const WCHAR tiff_mimetype[] = {'i','m','a','g','e','/','t','i','f','f', 0};
|
|
|
|
static const WCHAR tiff_format[] = {'T','I','F','F',0};
|
|
|
|
static const BYTE tiff_sig_pattern[] = {0x49,0x49,42,0,0x4d,0x4d,0,42};
|
|
|
|
static const BYTE tiff_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
static const WCHAR emf_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'E','M','F', 0};
|
|
|
|
static const WCHAR emf_extension[] = {'*','.','E','M','F',0};
|
|
|
|
static const WCHAR emf_mimetype[] = {'i','m','a','g','e','/','x','-','e','m','f', 0};
|
|
|
|
static const WCHAR emf_format[] = {'E','M','F',0};
|
|
|
|
static const BYTE emf_sig_pattern[] = { 0x01, 0x00, 0x00, 0x00 };
|
|
|
|
static const BYTE emf_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
|
|
|
|
|
|
static const WCHAR wmf_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'W','M','F', 0};
|
|
|
|
static const WCHAR wmf_extension[] = {'*','.','W','M','F',0};
|
|
|
|
static const WCHAR wmf_mimetype[] = {'i','m','a','g','e','/','x','-','w','m','f', 0};
|
|
|
|
static const WCHAR wmf_format[] = {'W','M','F',0};
|
|
|
|
static const BYTE wmf_sig_pattern[] = { 0xd7, 0xcd };
|
|
|
|
static const BYTE wmf_sig_mask[] = { 0xFF, 0xFF };
|
|
|
|
|
|
|
|
static const WCHAR png_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'P','N','G', 0};
|
|
|
|
static const WCHAR png_extension[] = {'*','.','P','N','G',0};
|
|
|
|
static const WCHAR png_mimetype[] = {'i','m','a','g','e','/','p','n','g', 0};
|
|
|
|
static const WCHAR png_format[] = {'P','N','G',0};
|
|
|
|
static const BYTE png_sig_pattern[] = { 137, 80, 78, 71, 13, 10, 26, 10, };
|
|
|
|
static const BYTE png_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
|
|
|
|
|
|
|
static const WCHAR ico_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'I','C','O', 0};
|
|
|
|
static const WCHAR ico_extension[] = {'*','.','I','C','O',0};
|
|
|
|
static const WCHAR ico_mimetype[] = {'i','m','a','g','e','/','x','-','i','c','o','n', 0};
|
|
|
|
static const WCHAR ico_format[] = {'I','C','O',0};
|
|
|
|
static const BYTE ico_sig_pattern[] = { 0x00, 0x00, 0x01, 0x00 };
|
|
|
|
static const BYTE ico_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
|
|
|
|
|
|
static const struct image_codec codecs[NUM_CODECS] = {
|
2008-03-25 17:34:57 +00:00
|
|
|
{
|
|
|
|
{ /* BMP */
|
|
|
|
/* Clsid */ { 0x557cf400, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cabU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ bmp_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ bmp_format,
|
|
|
|
/* FilenameExtension */ bmp_extension,
|
|
|
|
/* MimeType */ bmp_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 2,
|
|
|
|
/* SigPattern */ bmp_sig_pattern,
|
|
|
|
/* SigMask */ bmp_sig_mask,
|
|
|
|
},
|
2009-09-03 15:07:25 +00:00
|
|
|
encode_image_BMP,
|
2009-11-28 15:26:02 +00:00
|
|
|
decode_image_bmp
|
2009-09-03 15:07:25 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{ /* JPEG */
|
|
|
|
/* Clsid */ { 0x557cf401, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3caeU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ jpeg_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ jpeg_format,
|
|
|
|
/* FilenameExtension */ jpeg_extension,
|
|
|
|
/* MimeType */ jpeg_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 2,
|
|
|
|
/* SigPattern */ jpeg_sig_pattern,
|
|
|
|
/* SigMask */ jpeg_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_jpeg
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ /* GIF */
|
|
|
|
/* Clsid */ { 0x557cf402, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cb0U, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ gif_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ gif_format,
|
|
|
|
/* FilenameExtension */ gif_extension,
|
|
|
|
/* MimeType */ gif_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 4,
|
|
|
|
/* SigPattern */ gif_sig_pattern,
|
|
|
|
/* SigMask */ gif_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_gif
|
|
|
|
},
|
2010-04-20 08:30:10 +00:00
|
|
|
{
|
|
|
|
{ /* TIFF */
|
|
|
|
/* Clsid */ { 0x557cf405, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cb1U, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ tiff_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ tiff_format,
|
|
|
|
/* FilenameExtension */ tiff_extension,
|
|
|
|
/* MimeType */ tiff_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 2,
|
|
|
|
/* SigSize */ 4,
|
|
|
|
/* SigPattern */ tiff_sig_pattern,
|
|
|
|
/* SigMask */ tiff_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_tiff
|
|
|
|
},
|
2009-09-03 15:07:25 +00:00
|
|
|
{
|
|
|
|
{ /* EMF */
|
|
|
|
/* Clsid */ { 0x557cf403, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cacU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ emf_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ emf_format,
|
|
|
|
/* FilenameExtension */ emf_extension,
|
|
|
|
/* MimeType */ emf_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportVector | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 4,
|
|
|
|
/* SigPattern */ emf_sig_pattern,
|
|
|
|
/* SigMask */ emf_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_olepicture_metafile
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ /* WMF */
|
|
|
|
/* Clsid */ { 0x557cf404, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cadU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ wmf_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ wmf_format,
|
|
|
|
/* FilenameExtension */ wmf_extension,
|
|
|
|
/* MimeType */ wmf_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportVector | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 2,
|
|
|
|
/* SigPattern */ wmf_sig_pattern,
|
|
|
|
/* SigMask */ wmf_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_olepicture_metafile
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{ /* PNG */
|
|
|
|
/* Clsid */ { 0x557cf406, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cafU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ png_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ png_format,
|
|
|
|
/* FilenameExtension */ png_extension,
|
|
|
|
/* MimeType */ png_mimetype,
|
2009-11-28 15:26:02 +00:00
|
|
|
/* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
2009-09-03 15:07:25 +00:00
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 8,
|
|
|
|
/* SigPattern */ png_sig_pattern,
|
|
|
|
/* SigMask */ png_sig_mask,
|
|
|
|
},
|
2009-11-28 15:26:02 +00:00
|
|
|
encode_image_png,
|
|
|
|
decode_image_png
|
2009-09-03 15:07:25 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{ /* ICO */
|
|
|
|
/* Clsid */ { 0x557cf407, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
|
|
|
|
/* FormatID */ { 0xb96b3cabU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
|
|
|
|
/* CodecName */ ico_codecname,
|
|
|
|
/* DllName */ NULL,
|
|
|
|
/* FormatDescription */ ico_format,
|
|
|
|
/* FilenameExtension */ ico_extension,
|
|
|
|
/* MimeType */ ico_mimetype,
|
|
|
|
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
|
|
|
/* Version */ 1,
|
|
|
|
/* SigCount */ 1,
|
|
|
|
/* SigSize */ 4,
|
|
|
|
/* SigPattern */ ico_sig_pattern,
|
|
|
|
/* SigMask */ ico_sig_mask,
|
|
|
|
},
|
|
|
|
NULL,
|
|
|
|
decode_image_icon
|
|
|
|
},
|
|
|
|
};
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageDecodersSize [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageDecodersSize(UINT *numDecoders, UINT *size)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
int decoder_count=0;
|
|
|
|
int i;
|
|
|
|
TRACE("%p %p\n", numDecoders, size);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
if (!numDecoders || !size)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
for (i=0; i<NUM_CODECS; i++)
|
|
|
|
{
|
|
|
|
if (codecs[i].info.Flags & ImageCodecFlagsDecoder)
|
|
|
|
decoder_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*numDecoders = decoder_count;
|
|
|
|
*size = decoder_count * sizeof(ImageCodecInfo);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageDecoders [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageDecoders(UINT numDecoders, UINT size, ImageCodecInfo *decoders)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
int i, decoder_count=0;
|
|
|
|
TRACE("%u %u %p\n", numDecoders, size, decoders);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
if (!decoders ||
|
|
|
|
size != numDecoders * sizeof(ImageCodecInfo))
|
2008-12-06 09:26:01 +00:00
|
|
|
return GenericError;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
for (i=0; i<NUM_CODECS; i++)
|
|
|
|
{
|
|
|
|
if (codecs[i].info.Flags & ImageCodecFlagsDecoder)
|
|
|
|
{
|
|
|
|
if (decoder_count == numDecoders) return GenericError;
|
|
|
|
memcpy(&decoders[decoder_count], &codecs[i].info, sizeof(ImageCodecInfo));
|
|
|
|
decoder_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (decoder_count < numDecoders) return GenericError;
|
|
|
|
|
|
|
|
return Ok;
|
2008-12-06 09:26:01 +00:00
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageEncodersSize [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
int encoder_count=0;
|
|
|
|
int i;
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", numEncoders, size);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if (!numEncoders || !size)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
for (i=0; i<NUM_CODECS; i++)
|
|
|
|
{
|
|
|
|
if (codecs[i].info.Flags & ImageCodecFlagsEncoder)
|
|
|
|
encoder_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*numEncoders = encoder_count;
|
|
|
|
*size = encoder_count * sizeof(ImageCodecInfo);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageEncoders [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders)
|
|
|
|
{
|
2009-09-03 15:07:25 +00:00
|
|
|
int i, encoder_count=0;
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%u %u %p\n", numEncoders, size, encoders);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if (!encoders ||
|
2009-09-03 15:07:25 +00:00
|
|
|
size != numEncoders * sizeof(ImageCodecInfo))
|
2008-03-25 17:34:57 +00:00
|
|
|
return GenericError;
|
|
|
|
|
2009-09-03 15:07:25 +00:00
|
|
|
for (i=0; i<NUM_CODECS; i++)
|
|
|
|
{
|
|
|
|
if (codecs[i].info.Flags & ImageCodecFlagsEncoder)
|
|
|
|
{
|
|
|
|
if (encoder_count == numEncoders) return GenericError;
|
|
|
|
memcpy(&encoders[encoder_count], &codecs[i].info, sizeof(ImageCodecInfo));
|
|
|
|
encoder_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (encoder_count < numEncoders) return GenericError;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
2008-08-05 12:23:58 +00:00
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetEncoderParameterListSize(GpImage *image,
|
|
|
|
GDIPCONST CLSID* clsidEncoder, UINT *size)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%s,%p)\n", image, debugstr_guid(clsidEncoder), size);
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
*size = 0;
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipCreateBitmapFromHBITMAP [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBitmap** bitmap)
|
|
|
|
{
|
|
|
|
BITMAP bm;
|
|
|
|
GpStatus retval;
|
|
|
|
PixelFormat format;
|
2010-01-03 10:54:14 +00:00
|
|
|
BitmapData lockeddata;
|
|
|
|
INT y;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p %p\n", hbm, hpal, bitmap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!hbm || !bitmap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
/* TODO: Support for device-dependent bitmaps */
|
|
|
|
if(hpal){
|
|
|
|
FIXME("no support for device-dependent bitmaps\n");
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetObjectA(hbm, sizeof(bm), &bm) != sizeof(bm))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
/* TODO: Figure out the correct format for 16, 32, 64 bpp */
|
|
|
|
switch(bm.bmBitsPixel) {
|
|
|
|
case 1:
|
|
|
|
format = PixelFormat1bppIndexed;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
format = PixelFormat4bppIndexed;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
format = PixelFormat8bppIndexed;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
format = PixelFormat24bppRGB;
|
|
|
|
break;
|
2008-12-06 09:26:01 +00:00
|
|
|
case 32:
|
|
|
|
format = PixelFormat32bppRGB;
|
|
|
|
break;
|
2008-03-25 17:34:57 +00:00
|
|
|
case 48:
|
|
|
|
format = PixelFormat48bppRGB;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
FIXME("don't know how to handle %d bpp\n", bm.bmBitsPixel);
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
retval = GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, 0,
|
|
|
|
format, NULL, bitmap);
|
|
|
|
|
|
|
|
if (retval == Ok)
|
2009-02-26 10:24:00 +00:00
|
|
|
{
|
2010-01-03 10:54:14 +00:00
|
|
|
retval = GdipBitmapLockBits(*bitmap, NULL, ImageLockModeWrite,
|
|
|
|
format, &lockeddata);
|
|
|
|
if (retval == Ok)
|
|
|
|
{
|
|
|
|
if (bm.bmBits)
|
|
|
|
{
|
|
|
|
for (y=0; y<bm.bmHeight; y++)
|
|
|
|
{
|
|
|
|
memcpy((BYTE*)lockeddata.Scan0+lockeddata.Stride*y,
|
|
|
|
(BYTE*)bm.bmBits+bm.bmWidthBytes*(bm.bmHeight-1-y),
|
|
|
|
bm.bmWidthBytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
HBITMAP oldhbm;
|
|
|
|
BITMAPINFO *pbmi;
|
|
|
|
INT src_height, dst_stride;
|
|
|
|
BYTE *dst_bits;
|
|
|
|
|
|
|
|
hdc = CreateCompatibleDC(NULL);
|
|
|
|
oldhbm = SelectObject(hdc, hbm);
|
2009-02-26 10:24:00 +00:00
|
|
|
|
2010-01-03 10:54:14 +00:00
|
|
|
pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
|
|
|
|
|
|
|
if (pbmi)
|
|
|
|
{
|
|
|
|
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
pbmi->bmiHeader.biBitCount = 0;
|
|
|
|
|
|
|
|
GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
|
|
|
|
|
|
|
|
src_height = abs(pbmi->bmiHeader.biHeight);
|
|
|
|
|
|
|
|
if (pbmi->bmiHeader.biHeight > 0)
|
|
|
|
{
|
|
|
|
dst_bits = (BYTE*)lockeddata.Scan0+lockeddata.Stride*(src_height-1);
|
|
|
|
dst_stride = -lockeddata.Stride;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dst_bits = lockeddata.Scan0;
|
|
|
|
dst_stride = lockeddata.Stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (y=0; y<src_height; y++)
|
|
|
|
{
|
|
|
|
GetDIBits(hdc, hbm, y, 1, dst_bits+dst_stride*y,
|
|
|
|
pbmi, DIB_RGB_COLORS);
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipFree(pbmi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
retval = OutOfMemory;
|
|
|
|
|
|
|
|
SelectObject(hdc, oldhbm);
|
|
|
|
DeleteDC(hdc);
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(*bitmap, &lockeddata);
|
|
|
|
}
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2008-04-14 12:53:30 +00:00
|
|
|
|
2009-06-07 07:59:56 +00:00
|
|
|
GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect *effect)
|
|
|
|
{
|
|
|
|
FIXME("(%p): stub\n", effect);
|
|
|
|
/* note: According to Jose Roca's GDI+ Docs, this is not implemented
|
|
|
|
* in Windows's gdiplus */
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipSetEffectParameters [GDIPLUS.@]
|
|
|
|
*/
|
2008-04-14 12:53:30 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect,
|
|
|
|
const VOID *params, const UINT size)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%p,%u)\n", effect, params, size);
|
|
|
|
|
2008-04-14 12:53:30 +00:00
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
2008-06-01 13:14:02 +00:00
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageFlags [GDIPLUS.@]
|
|
|
|
*/
|
2008-06-01 13:14:02 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetImageFlags(GpImage *image, UINT *flags)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p %p\n", image, flags);
|
|
|
|
|
2008-06-01 13:14:02 +00:00
|
|
|
if(!image || !flags)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*flags = image->flags;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipTestControl(GpTestControlEnum control, void *param)
|
|
|
|
{
|
|
|
|
TRACE("(%d, %p)\n", control, param);
|
|
|
|
|
|
|
|
switch(control){
|
|
|
|
case TestControlForceBilinear:
|
|
|
|
if(param)
|
|
|
|
FIXME("TestControlForceBilinear not handled\n");
|
|
|
|
break;
|
|
|
|
case TestControlNoICM:
|
|
|
|
if(param)
|
|
|
|
FIXME("TestControlNoICM not handled\n");
|
|
|
|
break;
|
|
|
|
case TestControlGetBuildNumber:
|
|
|
|
*((DWORD*)param) = 3102;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipRecordMetafileFileName(GDIPCONST WCHAR* fileName,
|
|
|
|
HDC hdc, EmfType type, GDIPCONST GpRectF *pFrameRect,
|
|
|
|
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc,
|
|
|
|
GpMetafile **metafile)
|
|
|
|
{
|
|
|
|
FIXME("%s %p %d %p %d %s %p stub!\n", debugstr_w(fileName), hdc, type, pFrameRect,
|
|
|
|
frameUnit, debugstr_w(desc), metafile);
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipRecordMetafileFileNameI(GDIPCONST WCHAR* fileName, HDC hdc, EmfType type,
|
|
|
|
GDIPCONST GpRect *pFrameRect, MetafileFrameUnit frameUnit,
|
|
|
|
GDIPCONST WCHAR *desc, GpMetafile **metafile)
|
|
|
|
{
|
|
|
|
FIXME("%s %p %d %p %d %s %p stub!\n", debugstr_w(fileName), hdc, type, pFrameRect,
|
|
|
|
frameUnit, debugstr_w(desc), metafile);
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipImageForceValidation(GpImage *image)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
TRACE("%p\n", image);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
2009-05-09 09:26:16 +00:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetImageThumbnail [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage *image, UINT width, UINT height,
|
|
|
|
GpImage **ret_image, GetThumbnailImageAbort cb,
|
|
|
|
VOID * cb_data)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
GpStatus stat;
|
|
|
|
GpGraphics *graphics;
|
|
|
|
UINT srcwidth, srcheight;
|
|
|
|
|
|
|
|
TRACE("(%p %u %u %p %p %p)\n",
|
2009-05-09 09:26:16 +00:00
|
|
|
image, width, height, ret_image, cb, cb_data);
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
|
|
|
|
if (!image || !ret_image)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if (!width) width = 120;
|
|
|
|
if (!height) height = 120;
|
|
|
|
|
|
|
|
GdipGetImageWidth(image, &srcwidth);
|
|
|
|
GdipGetImageHeight(image, &srcheight);
|
|
|
|
|
|
|
|
stat = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppARGB,
|
|
|
|
NULL, (GpBitmap**)ret_image);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipGetImageGraphicsContext(*ret_image, &graphics);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipDrawImageRectRectI(graphics, image,
|
|
|
|
0, 0, width, height, 0, 0, srcwidth, srcheight, UnitPixel,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
|
|
|
|
GdipDeleteGraphics(graphics);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
GdipDisposeImage(*ret_image);
|
|
|
|
*ret_image = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return stat;
|
2009-05-09 09:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipImageRotateFlip [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
GpBitmap *new_bitmap;
|
|
|
|
GpBitmap *bitmap;
|
|
|
|
int bpp, bytesperpixel;
|
|
|
|
int rotate_90, flip_x, flip_y;
|
|
|
|
int src_x_offset, src_y_offset;
|
|
|
|
LPBYTE src_origin;
|
|
|
|
UINT x, y, width, height;
|
|
|
|
BitmapData src_lock, dst_lock;
|
|
|
|
GpStatus stat;
|
|
|
|
|
|
|
|
TRACE("(%p, %u)\n", image, type);
|
|
|
|
|
|
|
|
rotate_90 = type&1;
|
|
|
|
flip_x = (type&6) == 2 || (type&6) == 4;
|
|
|
|
flip_y = (type&3) == 1 || (type&3) == 2;
|
|
|
|
|
|
|
|
if (image->type != ImageTypeBitmap)
|
|
|
|
{
|
|
|
|
FIXME("Not implemented for type %i\n", image->type);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
bitmap = (GpBitmap*)image;
|
|
|
|
bpp = PIXELFORMATBPP(bitmap->format);
|
|
|
|
|
|
|
|
if (bpp < 8)
|
|
|
|
{
|
|
|
|
FIXME("Not implemented for %i bit images\n", bpp);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rotate_90)
|
|
|
|
{
|
|
|
|
width = bitmap->height;
|
|
|
|
height = bitmap->width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = bitmap->width;
|
|
|
|
height = bitmap->height;
|
|
|
|
}
|
|
|
|
|
|
|
|
bytesperpixel = bpp/8;
|
|
|
|
|
|
|
|
stat = GdipCreateBitmapFromScan0(width, height, 0, bitmap->format, NULL, &new_bitmap);
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format, &src_lock);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
stat = GdipBitmapLockBits(new_bitmap, NULL, ImageLockModeWrite, bitmap->format, &dst_lock);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
{
|
|
|
|
LPBYTE src_row, src_pixel;
|
|
|
|
LPBYTE dst_row, dst_pixel;
|
|
|
|
|
|
|
|
src_origin = src_lock.Scan0;
|
|
|
|
if (flip_x) src_origin += bytesperpixel * (bitmap->width - 1);
|
|
|
|
if (flip_y) src_origin += src_lock.Stride * (bitmap->height - 1);
|
|
|
|
|
|
|
|
if (rotate_90)
|
|
|
|
{
|
|
|
|
if (flip_y) src_x_offset = -src_lock.Stride;
|
|
|
|
else src_x_offset = src_lock.Stride;
|
|
|
|
if (flip_x) src_y_offset = -bytesperpixel;
|
|
|
|
else src_y_offset = bytesperpixel;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (flip_x) src_x_offset = -bytesperpixel;
|
|
|
|
else src_x_offset = bytesperpixel;
|
|
|
|
if (flip_y) src_y_offset = -src_lock.Stride;
|
|
|
|
else src_y_offset = src_lock.Stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_row = src_origin;
|
|
|
|
dst_row = dst_lock.Scan0;
|
|
|
|
for (y=0; y<height; y++)
|
|
|
|
{
|
|
|
|
src_pixel = src_row;
|
|
|
|
dst_pixel = dst_row;
|
|
|
|
for (x=0; x<width; x++)
|
|
|
|
{
|
|
|
|
/* FIXME: This could probably be faster without memcpy. */
|
|
|
|
memcpy(dst_pixel, src_pixel, bytesperpixel);
|
|
|
|
dst_pixel += bytesperpixel;
|
|
|
|
src_pixel += src_x_offset;
|
|
|
|
}
|
|
|
|
src_row += src_y_offset;
|
|
|
|
dst_row += dst_lock.Stride;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(new_bitmap, &dst_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipBitmapUnlockBits(bitmap, &src_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
move_bitmap(bitmap, new_bitmap, FALSE);
|
|
|
|
else
|
|
|
|
GdipDisposeImage((GpImage*)new_bitmap);
|
|
|
|
|
|
|
|
return stat;
|
2009-05-09 09:26:16 +00:00
|
|
|
}
|
2010-11-20 11:24:17 +00:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipConvertToEmfPlusToFile [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics* refGraphics,
|
|
|
|
GpMetafile* metafile, BOOL* conversionSuccess,
|
|
|
|
const WCHAR* filename, EmfType emfType,
|
|
|
|
const WCHAR* description, GpMetafile** out_metafile)
|
|
|
|
{
|
|
|
|
FIXME("stub: %p, %p, %p, %p, %u, %p, %p\n", refGraphics, metafile, conversionSuccess, filename, emfType, description, out_metafile);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|