[3/5] gdiplus: Implement GdipGetPropertyItem. Resend.
Dmitry Timoshkov
dmitry at baikal.ru
Wed Jun 27 20:54:16 CDT 2012
---
dlls/gdiplus/image.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 131 insertions(+), 13 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index ba7cbef..83a2e79 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -2475,19 +2475,6 @@ GpStatus WINGDIPAPI GdipGetPropertyIdList(GpImage *image, UINT num, PROPID *list
return hr == S_OK ? Ok : hresult_to_status(hr);
}
-GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage *image, PROPID id, UINT size,
- PropertyItem* buffer)
-{
- static int calls;
-
- TRACE("(%p, %u, %u, %p)\n", image, id, size, buffer);
-
- if(!(calls++))
- FIXME("not implemented\n");
-
- return InvalidParameter;
-}
-
static UINT propvariant_size(PROPVARIANT *value)
{
switch (value->vt & ~VT_VECTOR)
@@ -2553,6 +2540,137 @@ GpStatus WINGDIPAPI GdipGetPropertyItemSize(GpImage *image, PROPID propid, UINT
return Ok;
}
+#ifndef PropertyTagTypeSByte
+#define PropertyTagTypeSByte 6
+#define PropertyTagTypeSShort 8
+#define PropertyTagTypeFloat 11
+#define PropertyTagTypeDouble 12
+#endif
+
+static UINT vt_to_itemtype(UINT vt)
+{
+ static const struct
+ {
+ UINT vt, type;
+ } vt2type[] =
+ {
+ { VT_I1, PropertyTagTypeSByte },
+ { VT_UI1, PropertyTagTypeByte },
+ { VT_I2, PropertyTagTypeSShort },
+ { VT_UI2, PropertyTagTypeShort },
+ { VT_I4, PropertyTagTypeSLONG },
+ { VT_UI4, PropertyTagTypeLong },
+ { VT_I8, PropertyTagTypeSRational },
+ { VT_UI8, PropertyTagTypeRational },
+ { VT_R4, PropertyTagTypeFloat },
+ { VT_R8, PropertyTagTypeDouble },
+ { VT_LPSTR, PropertyTagTypeASCII },
+ { VT_BLOB, PropertyTagTypeUndefined }
+ };
+ UINT i;
+ for (i = 0; i < sizeof(vt2type)/sizeof(vt2type[0]); i++)
+ {
+ if (vt2type[i].vt == vt) return vt2type[i].type;
+ }
+ FIXME("not supported variant type %u\n", vt);
+ return 0;
+}
+
+static GpStatus propvariant_to_item(PROPVARIANT *value, PropertyItem *item,
+ UINT size, PROPID id)
+{
+ UINT item_size, item_type;
+
+ item_size = propvariant_size(value);
+ if (size != item_size + sizeof(PropertyItem)) return InvalidParameter;
+
+ item_type = vt_to_itemtype(value->vt & ~VT_VECTOR);
+ if (!item_type) return InvalidParameter;
+
+ item->value = item + 1;
+
+ switch (value->vt & ~VT_VECTOR)
+ {
+ case VT_I1:
+ case VT_UI1:
+ if (!(value->vt & VT_VECTOR))
+ *(BYTE *)item->value = value->u.bVal;
+ else
+ memcpy(item->value, value->u.caub.pElems, item_size);
+ break;
+ case VT_I2:
+ case VT_UI2:
+ if (!(value->vt & VT_VECTOR))
+ *(USHORT *)item->value = value->u.uiVal;
+ else
+ memcpy(item->value, value->u.caui.pElems, item_size);
+ break;
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ if (!(value->vt & VT_VECTOR))
+ *(ULONG *)item->value = value->u.ulVal;
+ else
+ memcpy(item->value, value->u.caul.pElems, item_size);
+ break;
+ case VT_I8:
+ case VT_UI8:
+ case VT_R8:
+ if (!(value->vt & VT_VECTOR))
+ *(ULONGLONG *)item->value = value->u.uhVal.QuadPart;
+ else
+ memcpy(item->value, value->u.cauh.pElems, item_size);
+ break;
+ case VT_LPSTR:
+ memcpy(item->value, value->u.pszVal, item_size);
+ break;
+ case VT_BLOB:
+ memcpy(item->value, value->u.blob.pBlobData, item_size);
+ break;
+ default:
+ FIXME("not supported variant type %d\n", value->vt);
+ return InvalidParameter;
+ }
+
+ item->length = item_size;
+ item->type = item_type;
+ item->id = id;
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage *image, PROPID propid, UINT size,
+ PropertyItem *buffer)
+{
+ GpStatus stat;
+ HRESULT hr;
+ IWICMetadataReader *reader;
+ PROPVARIANT id, value;
+
+ TRACE("(%p,%#x,%u,%p)\n", image, propid, size, buffer);
+
+ if (!image || !buffer) return InvalidParameter;
+
+ if (image->type != ImageTypeBitmap)
+ {
+ FIXME("Not implemented for type %d\n", image->type);
+ return NotImplemented;
+ }
+
+ reader = ((GpBitmap *)image)->metadata_reader;
+ if (!reader) return PropertyNotFound;
+
+ id.vt = VT_UI2;
+ id.u.uiVal = propid;
+ hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
+ if (FAILED(hr)) return PropertyNotFound;
+
+ stat = propvariant_to_item(&value, buffer, size, propid);
+ PropVariantClear(&value);
+
+ return stat;
+}
+
GpStatus WINGDIPAPI GdipGetPropertySize(GpImage *image, UINT* size, UINT* num)
{
static int calls;
--
1.7.11.1
More information about the wine-patches
mailing list