[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