2 * Copyright (C) 2007 Google (Evan Stade)
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "gdiplus_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus
);
37 typedef void ImageItemData
;
39 #define PIXELFORMATBPP(x) ((x) ? ((x) >> 8) & 255 : 24)
41 static INT
ipicture_pixel_height(IPicture
*pic
)
46 IPicture_get_Height(pic
, &y
);
50 y
= (UINT
)(((REAL
)y
) * ((REAL
)GetDeviceCaps(hdcref
, LOGPIXELSY
)) /
51 ((REAL
)INCH_HIMETRIC
));
57 static INT
ipicture_pixel_width(IPicture
*pic
)
62 IPicture_get_Width(pic
, &x
);
66 x
= (UINT
)(((REAL
)x
) * ((REAL
)GetDeviceCaps(hdcref
, LOGPIXELSX
)) /
67 ((REAL
)INCH_HIMETRIC
));
74 GpStatus WINGDIPAPI
GdipBitmapGetPixel(GpBitmap
* bitmap
, INT x
, INT y
,
78 TRACE("%p %d %d %p\n", bitmap
, x
, y
, color
);
81 return InvalidParameter
;
84 FIXME("not implemented\n");
88 return NotImplemented
;
91 GpStatus WINGDIPAPI
GdipCreateBitmapFromScan0(INT width
, INT height
, INT stride
,
92 PixelFormat format
, BYTE
* scan0
, GpBitmap
** bitmap
)
94 BITMAPFILEHEADER
*bmfh
;
95 BITMAPINFOHEADER
*bmih
;
97 INT datalen
= stride
* height
, size
;
100 TRACE("%d %d %d %d %p %p\n", width
, height
, stride
, format
, scan0
, bitmap
);
102 if(!scan0
|| !bitmap
)
103 return InvalidParameter
;
105 *bitmap
= GdipAlloc(sizeof(GpBitmap
));
106 if(!*bitmap
) return OutOfMemory
;
108 size
= sizeof(BITMAPFILEHEADER
) + sizeof(BITMAPINFOHEADER
) + datalen
;
109 buff
= GdipAlloc(size
);
115 bmfh
= (BITMAPFILEHEADER
*) buff
;
116 bmih
= (BITMAPINFOHEADER
*) (bmfh
+ 1);
118 bmfh
->bfType
= (((WORD
)'M') << 8) + (WORD
)'B';
120 bmfh
->bfOffBits
= size
- datalen
;
122 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
123 bmih
->biWidth
= width
;
124 bmih
->biHeight
= height
;
125 /* FIXME: use the rest of the data from format */
126 bmih
->biBitCount
= PIXELFORMATBPP(format
);
127 bmih
->biCompression
= BI_RGB
;
129 memcpy(bmih
+ 1, scan0
, datalen
);
131 if(CreateStreamOnHGlobal(buff
, TRUE
, &stream
) != S_OK
){
132 ERR("could not make stream\n");
138 if(OleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
,
139 (LPVOID
*) &((*bitmap
)->image
.picture
)) != S_OK
){
140 TRACE("Could not load picture\n");
141 IStream_Release(stream
);
147 (*bitmap
)->image
.type
= ImageTypeBitmap
;
148 (*bitmap
)->width
= width
;
149 (*bitmap
)->height
= height
;
150 (*bitmap
)->format
= format
;
155 GpStatus WINGDIPAPI
GdipCreateBitmapFromStream(IStream
* stream
,
159 BITMAPCOREHEADER
* bmch
;
164 stat
= GdipLoadImageFromStream(stream
, (GpImage
**) bitmap
);
169 /* FIXME: make sure it's actually a bitmap */
170 (*bitmap
)->image
.type
= ImageTypeBitmap
;
171 (*bitmap
)->width
= ipicture_pixel_width((*bitmap
)->image
.picture
);
172 (*bitmap
)->height
= ipicture_pixel_height((*bitmap
)->image
.picture
);
174 /* get the pixel format */
175 IPicture_get_Handle((*bitmap
)->image
.picture
, &hbm
);
176 IPicture_get_CurDC((*bitmap
)->image
.picture
, &hdc
);
178 bmch
= (BITMAPCOREHEADER
*) (&bmi
.bmiHeader
);
179 bmch
->bcSize
= sizeof(BITMAPCOREHEADER
);
184 old
= SelectObject(hdc
, (HBITMAP
)hbm
);
185 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, 0, NULL
, &bmi
, DIB_RGB_COLORS
);
186 SelectObject(hdc
, old
);
190 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, 0, NULL
, &bmi
, DIB_RGB_COLORS
);
192 (*bitmap
)->format
= (bmch
->bcBitCount
<< 8) | PixelFormatGDI
;
198 GpStatus WINGDIPAPI
GdipCreateBitmapFromStreamICM(IStream
* stream
,
201 return GdipCreateBitmapFromStream(stream
, bitmap
);
204 GpStatus WINGDIPAPI
GdipDisposeImage(GpImage
*image
)
207 return InvalidParameter
;
209 IPicture_Release(image
->picture
);
215 GpStatus WINGDIPAPI
GdipFindFirstImageItem(GpImage
*image
, ImageItemData
* item
)
218 return InvalidParameter
;
220 return NotImplemented
;
223 GpStatus WINGDIPAPI
GdipGetImageBounds(GpImage
*image
, GpRectF
*srcRect
,
226 if(!image
|| !srcRect
|| !srcUnit
)
227 return InvalidParameter
;
228 if(image
->type
== ImageTypeMetafile
){
229 memcpy(srcRect
, &((GpMetafile
*)image
)->bounds
, sizeof(GpRectF
));
230 *srcUnit
= ((GpMetafile
*)image
)->unit
;
232 else if(image
->type
== ImageTypeBitmap
){
233 srcRect
->X
= srcRect
->Y
= 0.0;
234 srcRect
->Width
= (REAL
) ((GpBitmap
*)image
)->width
;
235 srcRect
->Height
= (REAL
) ((GpBitmap
*)image
)->height
;
236 *srcUnit
= UnitPixel
;
239 srcRect
->X
= srcRect
->Y
= 0.0;
240 srcRect
->Width
= ipicture_pixel_width(image
->picture
);
241 srcRect
->Height
= ipicture_pixel_height(image
->picture
);
242 *srcUnit
= UnitPixel
;
245 TRACE("returning (%f, %f) (%f, %f) unit type %d\n", srcRect
->X
, srcRect
->Y
,
246 srcRect
->Width
, srcRect
->Height
, *srcUnit
);
251 GpStatus WINGDIPAPI
GdipGetImageHeight(GpImage
*image
, UINT
*height
)
253 if(!image
|| !height
)
254 return InvalidParameter
;
256 if(image
->type
== ImageTypeMetafile
){
257 FIXME("not implemented for metafiles\n");
258 return NotImplemented
;
260 else if(image
->type
== ImageTypeBitmap
)
261 *height
= ((GpBitmap
*)image
)->height
;
263 *height
= ipicture_pixel_height(image
->picture
);
265 TRACE("returning %d\n", *height
);
270 GpStatus WINGDIPAPI
GdipGetImageHorizontalResolution(GpImage
*image
, REAL
*res
)
275 return InvalidParameter
;
278 FIXME("not implemented\n");
280 return NotImplemented
;
283 /* FIXME: test this function for non-bitmap types */
284 GpStatus WINGDIPAPI
GdipGetImagePixelFormat(GpImage
*image
, PixelFormat
*format
)
286 if(!image
|| !format
)
287 return InvalidParameter
;
289 if(image
->type
!= ImageTypeBitmap
)
290 *format
= PixelFormat24bppRGB
;
292 *format
= ((GpBitmap
*) image
)->format
;
297 GpStatus WINGDIPAPI
GdipGetImageRawFormat(GpImage
*image
, GUID
*format
)
301 if(!image
|| !format
)
302 return InvalidParameter
;
305 FIXME("not implemented\n");
307 return NotImplemented
;
310 GpStatus WINGDIPAPI
GdipGetImageType(GpImage
*image
, ImageType
*type
)
313 return InvalidParameter
;
320 GpStatus WINGDIPAPI
GdipGetImageVerticalResolution(GpImage
*image
, REAL
*res
)
325 return InvalidParameter
;
328 FIXME("not implemented\n");
330 return NotImplemented
;
333 GpStatus WINGDIPAPI
GdipGetImageWidth(GpImage
*image
, UINT
*width
)
336 return InvalidParameter
;
338 if(image
->type
== ImageTypeMetafile
){
339 FIXME("not implemented for metafiles\n");
340 return NotImplemented
;
342 else if(image
->type
== ImageTypeBitmap
)
343 *width
= ((GpBitmap
*)image
)->width
;
345 *width
= ipicture_pixel_width(image
->picture
);
347 TRACE("returning %d\n", *width
);
352 GpStatus WINGDIPAPI
GdipGetMetafileHeaderFromMetafile(GpMetafile
* metafile
,
353 MetafileHeader
* header
)
357 if(!metafile
|| !header
)
358 return InvalidParameter
;
361 FIXME("not implemented\n");
363 return NotImplemented
;
366 GpStatus WINGDIPAPI
GdipGetPropertyItemSize(GpImage
*image
, PROPID pid
,
371 TRACE("%p %x %p\n", image
, pid
, size
);
374 return InvalidParameter
;
377 FIXME("not implemented\n");
379 return NotImplemented
;
382 GpStatus WINGDIPAPI
GdipImageGetFrameCount(GpImage
*image
,
383 GDIPCONST GUID
* dimensionID
, UINT
* count
)
387 if(!image
|| !dimensionID
|| !count
)
388 return InvalidParameter
;
391 FIXME("not implemented\n");
393 return NotImplemented
;
396 GpStatus WINGDIPAPI
GdipImageGetFrameDimensionsList(GpImage
* image
,
397 GUID
* dimensionIDs
, UINT count
)
401 if(!image
|| !dimensionIDs
)
402 return InvalidParameter
;
405 FIXME("not implemented\n");
410 GpStatus WINGDIPAPI
GdipImageSelectActiveFrame(GpImage
*image
,
411 GDIPCONST GUID
* dimensionID
, UINT frameidx
)
415 if(!image
|| !dimensionID
)
416 return InvalidParameter
;
419 FIXME("not implemented\n");
424 GpStatus WINGDIPAPI
GdipLoadImageFromStream(IStream
* stream
, GpImage
**image
)
426 if(!stream
|| !image
)
427 return InvalidParameter
;
429 *image
= GdipAlloc(sizeof(GpImage
));
430 if(!*image
) return OutOfMemory
;
432 if(OleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
,
433 (LPVOID
*) &((*image
)->picture
)) != S_OK
){
434 TRACE("Could not load picture\n");
439 /* FIXME: use IPicture_get_Type to get image type? */
440 (*image
)->type
= ImageTypeUnknown
;
446 GpStatus WINGDIPAPI
GdipLoadImageFromStreamICM(IStream
* stream
, GpImage
**image
)
448 return GdipLoadImageFromStream(stream
, image
);
451 GpStatus WINGDIPAPI
GdipRemovePropertyItem(GpImage
*image
, PROPID propId
)
456 return InvalidParameter
;
459 FIXME("not implemented\n");
461 return NotImplemented
;
464 GpStatus WINGDIPAPI
GdipSaveImageToStream(GpImage
*image
, IStream
* stream
,
465 GDIPCONST CLSID
* clsid
, GDIPCONST EncoderParameters
* params
)
467 if(!image
|| !stream
)
468 return InvalidParameter
;
470 /* FIXME: CLSID, EncoderParameters not used */
472 IPicture_SaveAsFile(image
->picture
, stream
, FALSE
, NULL
);