ReactOS 0.4.15-dev-8241-g63935f8
metadata.c File Reference
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <assert.h>
#include "windef.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "propvarutil.h"
#include "wine/test.h"
#include "initguid.h"
#include "pshpack2.h"
#include "poppack.h"
Include dependency graph for metadata.c:

Go to the source code of this file.

Classes

struct  IFD_entry
 
struct  IFD_rational
 
struct  ifd_data
 
struct  test_data
 
struct  metadata_item
 
struct  metadata_block
 
struct  metadata
 

Macros

#define COBJMACROS
 
#define expect_blob(propvar, data, length)
 
#define IFD_BYTE   1
 
#define IFD_ASCII   2
 
#define IFD_SHORT   3
 
#define IFD_LONG   4
 
#define IFD_RATIONAL   5
 
#define IFD_SBYTE   6
 
#define IFD_UNDEFINED   7
 
#define IFD_SSHORT   8
 
#define IFD_SLONG   9
 
#define IFD_SRATIONAL   10
 
#define IFD_FLOAT   11
 
#define IFD_DOUBLE   12
 
#define IFD_IFD   13
 

Functions

 DEFINE_GUID (IID_MdbrUnknown, 0x00240e6f, 0x3f23, 0x4432, 0xb0, 0xcc, 0x48, 0xd5, 0xbb, 0xff, 0x6c, 0x36)
 
static IStreamcreate_stream (const char *data, int data_size)
 
static void load_stream (IUnknown *reader, const char *data, int data_size, DWORD persist_options)
 
static void test_metadata_unknown (void)
 
static void test_metadata_tEXt (void)
 
static void test_metadata_gAMA (void)
 
static void test_metadata_cHRM (void)
 
static USHORT ushort_bswap (USHORT s)
 
static ULONG ulong_bswap (ULONG l)
 
static ULONGLONG ulonglong_bswap (ULONGLONG ll)
 
static void byte_swap_ifd_data (char *data)
 
static void compare_metadata (IWICMetadataReader *reader, const struct test_data *td, ULONG count)
 
static void test_metadata_IFD (void)
 
static void test_metadata_Exif (void)
 
static void test_create_reader (void)
 
static void test_metadata_png (void)
 
static void test_metadata_gif (void)
 
static void test_metadata_LSD (void)
 
static void test_metadata_IMD (void)
 
static void test_metadata_GCE (void)
 
static void test_metadata_APE (void)
 
static void test_metadata_GIF_comment (void)
 
static void test_WICMapGuidToShortName (void)
 
static void test_WICMapShortNameToGuid (void)
 
static void test_WICMapSchemaToName (void)
 
static HRESULT WINAPI mdr_QueryInterface (IWICMetadataReader *iface, REFIID iid, void **out)
 
static ULONG WINAPI mdr_AddRef (IWICMetadataReader *iface)
 
static ULONG WINAPI mdr_Release (IWICMetadataReader *iface)
 
static HRESULT WINAPI mdr_GetMetadataFormat (IWICMetadataReader *iface, GUID *format)
 
static HRESULT WINAPI mdr_GetMetadataHandlerInfo (IWICMetadataReader *iface, IWICMetadataHandlerInfo **handler)
 
static HRESULT WINAPI mdr_GetCount (IWICMetadataReader *iface, UINT *count)
 
static HRESULT WINAPI mdr_GetValueByIndex (IWICMetadataReader *iface, UINT index, PROPVARIANT *schema, PROPVARIANT *id, PROPVARIANT *value)
 
static charget_temp_buffer (int size)
 
static const charwine_dbgstr_propvariant (const PROPVARIANT *var)
 
static int propvar_cmp (const PROPVARIANT *v1, LONGLONG value2)
 
static HRESULT WINAPI mdr_GetValue (IWICMetadataReader *iface, const PROPVARIANT *schema, const PROPVARIANT *id, PROPVARIANT *value)
 
static HRESULT WINAPI mdr_GetEnumerator (IWICMetadataReader *iface, IWICEnumMetadataItem **enumerator)
 
static HRESULT WINAPI mdbr_QueryInterface (IWICMetadataBlockReader *iface, REFIID iid, void **out)
 
static ULONG WINAPI mdbr_AddRef (IWICMetadataBlockReader *iface)
 
static ULONG WINAPI mdbr_Release (IWICMetadataBlockReader *iface)
 
static HRESULT WINAPI mdbr_GetContainerFormat (IWICMetadataBlockReader *iface, GUID *format)
 
static HRESULT WINAPI mdbr_GetCount (IWICMetadataBlockReader *iface, UINT *count)
 
static HRESULT WINAPI mdbr_GetReaderByIndex (IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **out)
 
static HRESULT WINAPI mdbr_GetEnumerator (IWICMetadataBlockReader *iface, IEnumUnknown **enumerator)
 
static void test_queryreader (void)
 
 START_TEST (metadata)
 

Variables

static const struct ifd_data IFD_data
 
static const char metadata_unknown [] = "lalala"
 
static const char metadata_tEXt []
 
static const char metadata_gAMA []
 
static const char metadata_cHRM []
 
static const char pngimage [285]
 
static const char gifimage [35]
 
static const char animatedgif []
 
static const GUIDguid_list []
 
static WCHAR rdf_scheme [] = { 'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/','1','9','9','9','/','0','2','/','2','2','-','r','d','f','-','s','y','n','t','a','x','-','n','s','#',0 }
 
static WCHAR dc_scheme [] = { 'h','t','t','p',':','/','/','p','u','r','l','.','o','r','g','/','d','c','/','e','l','e','m','e','n','t','s','/','1','.','1','/',0 }
 
static WCHAR xmp_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }
 
static WCHAR xmpidq_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','I','d','e','n','t','i','f','i','e','r','/','q','u','a','l','/','1','.','0','/',0 }
 
static WCHAR xmpRights_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','r','i','g','h','t','s','/',0 }
 
static WCHAR xmpMM_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','m','m','/',0 }
 
static WCHAR xmpBJ_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','b','j','/',0 }
 
static WCHAR xmpTPg_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','t','/','p','g','/',0 }
 
static WCHAR pdf_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','d','f','/','1','.','3','/',0 }
 
static WCHAR photoshop_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','h','o','t','o','s','h','o','p','/','1','.','0','/',0 }
 
static WCHAR tiff_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','t','i','f','f','/','1','.','0','/',0 }
 
static WCHAR exif_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/',0 }
 
static WCHAR stDim_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','D','i','m','e','n','s','i','o','n','s','#',0 }
 
static WCHAR xapGImg_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','g','/','i','m','g','/',0 }
 
static WCHAR stEvt_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','E','v','e','n','t','#',0 }
 
static WCHAR stRef_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','R','e','f','#',0 }
 
static WCHAR stVer_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','V','e','r','s','i','o','n','#',0 }
 
static WCHAR stJob_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','J','o','b','#',0 }
 
static WCHAR aux_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/','a','u','x','/',0 }
 
static WCHAR crs_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','c','a','m','e','r','a','-','r','a','w','-','s','e','t','t','i','n','g','s','/','1','.','0','/',0 }
 
static WCHAR xmpDM_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','1','.','0','/','D','y','n','a','m','i','c','M','e','d','i','a','/',0 }
 
static WCHAR Iptc4xmpCore_scheme [] = { 'h','t','t','p',':','/','/','i','p','t','c','.','o','r','g','/','s','t','d','/','I','p','t','c','4','x','m','p','C','o','r','e','/','1','.','0','/','x','m','l','n','s','/',0 }
 
static WCHAR MicrosoftPhoto_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','0','/',0 }
 
static WCHAR MP_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/',0 }
 
static WCHAR MPRI_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','I','n','f','o','#',0 }
 
static WCHAR MPReg_scheme [] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','#',0 }
 
static WCHARschema_list []
 
static const struct metadatacurrent_metadata
 
static const struct metadata_blockcurrent_metadata_block
 
static char the_best [] = "The Best"
 
static char the_worst [] = "The Worst"
 
static const IWICMetadataReaderVtbl mdr_vtbl
 
static IWICMetadataReader mdr = { &mdr_vtbl }
 
static const IWICMetadataBlockReaderVtbl mdbr_vtbl
 
static IWICMetadataBlockReader mdbr = { &mdbr_vtbl }
 
static const char xmp [] = "http://ns.adobe.com/xap/1.0/"
 
static const char dc [] = "http://purl.org/dc/elements/1.1/"
 
static const char tiff [] = "http://ns.adobe.com/tiff/1.0/"
 
static const struct metadata_item item1 []
 
static const struct metadata_item item2 []
 
static const struct metadata_item item3 []
 
static const struct metadata_item item4 []
 
static const struct metadata_block block1 []
 
static const struct metadata_block block2 []
 
static const struct metadata_block block3 []
 
static const struct metadata data1
 
static const struct metadata data2
 
static const struct metadata data3
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 25 of file metadata.c.

◆ expect_blob

#define expect_blob (   propvar,
  data,
  length 
)
Value:
do { \
ok((propvar).vt == VT_BLOB, "unexpected vt: %i\n", (propvar).vt); \
if ((propvar).vt == VT_BLOB) { \
ok(U(propvar).blob.cbSize == (length), "expected size %u, got %u\n", (ULONG)(length), U(propvar).blob.cbSize); \
if (U(propvar).blob.cbSize == (length)) { \
ok(!memcmp(U(propvar).blob.pBlobData, (data), (length)), "unexpected data\n"); \
} \
} \
} while (0)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define U(x)
Definition: wordpad.c:45
@ VT_BLOB
Definition: compat.h:2330
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:86
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
Definition: image.c:134
uint32_t ULONG
Definition: typedefs.h:59

Definition at line 40 of file metadata.c.

◆ IFD_ASCII

#define IFD_ASCII   2

Definition at line 51 of file metadata.c.

◆ IFD_BYTE

#define IFD_BYTE   1

Definition at line 50 of file metadata.c.

◆ IFD_DOUBLE

#define IFD_DOUBLE   12

Definition at line 61 of file metadata.c.

◆ IFD_FLOAT

#define IFD_FLOAT   11

Definition at line 60 of file metadata.c.

◆ IFD_IFD

#define IFD_IFD   13

Definition at line 62 of file metadata.c.

◆ IFD_LONG

#define IFD_LONG   4

Definition at line 53 of file metadata.c.

◆ IFD_RATIONAL

#define IFD_RATIONAL   5

Definition at line 54 of file metadata.c.

◆ IFD_SBYTE

#define IFD_SBYTE   6

Definition at line 55 of file metadata.c.

◆ IFD_SHORT

#define IFD_SHORT   3

Definition at line 52 of file metadata.c.

◆ IFD_SLONG

#define IFD_SLONG   9

Definition at line 58 of file metadata.c.

◆ IFD_SRATIONAL

#define IFD_SRATIONAL   10

Definition at line 59 of file metadata.c.

◆ IFD_SSHORT

#define IFD_SSHORT   8

Definition at line 57 of file metadata.c.

◆ IFD_UNDEFINED

#define IFD_UNDEFINED   7

Definition at line 56 of file metadata.c.

Function Documentation

◆ byte_swap_ifd_data()

static void byte_swap_ifd_data ( char data)
static

Definition at line 553 of file metadata.c.

554{
555 USHORT number_of_entries, i;
556 struct IFD_entry *entry;
557 char *data_start = data;
558
559 number_of_entries = *(USHORT *)data;
561 data += sizeof(USHORT);
562
563 for (i = 0; i < number_of_entries; i++)
564 {
565 entry = (struct IFD_entry *)data;
566
567 switch (entry->type)
568 {
569 case IFD_BYTE:
570 case IFD_SBYTE:
571 case IFD_ASCII:
572 case IFD_UNDEFINED:
573 if (entry->count > 4)
574 entry->value = ulong_bswap(entry->value);
575 break;
576
577 case IFD_SHORT:
578 case IFD_SSHORT:
579 if (entry->count > 2)
580 {
581 ULONG j, count = entry->count;
582 USHORT *us = (USHORT *)(data_start + entry->value);
583 if (!count) count = 1;
584 for (j = 0; j < count; j++)
585 us[j] = ushort_bswap(us[j]);
586
587 entry->value = ulong_bswap(entry->value);
588 }
589 else
590 {
591 ULONG j, count = entry->count;
592 USHORT *us = (USHORT *)&entry->value;
593 if (!count) count = 1;
594 for (j = 0; j < count; j++)
595 us[j] = ushort_bswap(us[j]);
596 }
597 break;
598
599 case IFD_LONG:
600 case IFD_SLONG:
601 case IFD_FLOAT:
602 if (entry->count > 1)
603 {
604 ULONG j, count = entry->count;
605 ULONG *ul = (ULONG *)(data_start + entry->value);
606 if (!count) count = 1;
607 for (j = 0; j < count; j++)
608 ul[j] = ulong_bswap(ul[j]);
609 }
610 entry->value = ulong_bswap(entry->value);
611 break;
612
613 case IFD_RATIONAL:
614 case IFD_SRATIONAL:
615 {
616 ULONG j;
617 ULONG *ul = (ULONG *)(data_start + entry->value);
618 for (j = 0; j < entry->count * 2; j++)
619 ul[j] = ulong_bswap(ul[j]);
620 }
621 entry->value = ulong_bswap(entry->value);
622 break;
623
624 case IFD_DOUBLE:
625 {
626 ULONG j;
627 ULONGLONG *ull = (ULONGLONG *)(data_start + entry->value);
628 for (j = 0; j < entry->count; j++)
629 ull[j] = ulonglong_bswap(ull[j]);
630 }
631 entry->value = ulong_bswap(entry->value);
632 break;
633
634 default:
635 assert(0);
636 break;
637 }
638
639 entry->id = ushort_bswap(entry->id);
640 entry->type = ushort_bswap(entry->type);
641 entry->count = ulong_bswap(entry->count);
642 data += sizeof(*entry);
643 }
644}
#define assert(x)
Definition: debug.h:53
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
uint32_t entry
Definition: isohybrid.c:63
if(dx< 0)
Definition: linetemp.h:194
static const BYTE us[]
Definition: encode.c:689
#define IFD_BYTE
Definition: metadata.c:50
#define IFD_SBYTE
Definition: metadata.c:55
#define IFD_UNDEFINED
Definition: metadata.c:56
static ULONG ulong_bswap(ULONG l)
Definition: metadata.c:543
#define IFD_SRATIONAL
Definition: metadata.c:59
#define IFD_SLONG
Definition: metadata.c:58
#define IFD_SHORT
Definition: metadata.c:52
#define IFD_SSHORT
Definition: metadata.c:57
static USHORT ushort_bswap(USHORT s)
Definition: metadata.c:538
#define IFD_DOUBLE
Definition: metadata.c:61
#define IFD_RATIONAL
Definition: metadata.c:54
static ULONGLONG ulonglong_bswap(ULONGLONG ll)
Definition: metadata.c:548
#define IFD_ASCII
Definition: metadata.c:51
#define IFD_LONG
Definition: metadata.c:53
#define IFD_FLOAT
Definition: metadata.c:60
unsigned short USHORT
Definition: pedump.c:61
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by test_metadata_IFD().

◆ compare_metadata()

static void compare_metadata ( IWICMetadataReader reader,
const struct test_data td,
ULONG  count 
)
static

Definition at line 655 of file metadata.c.

656{
657 HRESULT hr;
658 IWICEnumMetadataItem *enumerator;
659 PROPVARIANT schema, id, value;
660 ULONG items_returned, i;
661
662 hr = IWICMetadataReader_GetEnumerator(reader, NULL);
663 ok(hr == E_INVALIDARG, "GetEnumerator error %#x\n", hr);
664
665 hr = IWICMetadataReader_GetEnumerator(reader, &enumerator);
666 ok(hr == S_OK, "GetEnumerator error %#x\n", hr);
667
668 PropVariantInit(&schema);
669 PropVariantInit(&id);
670 PropVariantInit(&value);
671
672 for (i = 0; i < count; i++)
673 {
674 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
675 ok(hr == S_OK, "Next error %#x\n", hr);
676 ok(items_returned == 1, "unexpected item count %u\n", items_returned);
677
678 ok(schema.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, schema.vt);
679 ok(id.vt == VT_UI2 || id.vt == VT_LPWSTR || id.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, id.vt);
680 if (id.vt == VT_UI2)
681 ok(U(id).uiVal == td[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, U(id).uiVal);
682 else if (id.vt == VT_LPWSTR)
683 ok(!lstrcmpW(td[i].id_string, U(id).pwszVal),
684 "%u: expected %s, got %s\n", i, wine_dbgstr_w(td[i].id_string), wine_dbgstr_w(U(id).pwszVal));
685
686 ok(value.vt == td[i].type, "%u: expected vt %#x, got %#x\n", i, td[i].type, value.vt);
687 if (value.vt & VT_VECTOR)
688 {
689 ULONG j;
690 switch (value.vt & ~VT_VECTOR)
691 {
692 case VT_I1:
693 case VT_UI1:
694 ok(td[i].count == U(value).caub.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems);
695 for (j = 0; j < U(value).caub.cElems; j++)
696 ok(td[i].value[j] == U(value).caub.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caub.pElems[j]);
697 break;
698 case VT_I2:
699 case VT_UI2:
700 ok(td[i].count == U(value).caui.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caui.cElems);
701 for (j = 0; j < U(value).caui.cElems; j++)
702 ok(td[i].value[j] == U(value).caui.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caui.pElems[j]);
703 break;
704 case VT_I4:
705 case VT_UI4:
706 case VT_R4:
707 ok(td[i].count == U(value).caul.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caul.cElems);
708 for (j = 0; j < U(value).caul.cElems; j++)
709 ok(td[i].value[j] == U(value).caul.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caul.pElems[j]);
710 break;
711 case VT_I8:
712 case VT_UI8:
713 case VT_R8:
714 ok(td[i].count == U(value).cauh.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).cauh.cElems);
715 for (j = 0; j < U(value).cauh.cElems; j++)
716 ok(td[i].value[j] == U(value).cauh.pElems[j].QuadPart, "%u: expected value[%d] %08x/%08x, got %08x/%08x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).cauh.pElems[j].u.LowPart, U(value).cauh.pElems[j].u.HighPart);
717 break;
718 case VT_LPSTR:
719 ok(td[i].count == U(value).calpstr.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems);
720 for (j = 0; j < U(value).calpstr.cElems; j++)
721 trace("%u: %s\n", j, U(value).calpstr.pElems[j]);
722 /* fall through to not handled message */
723 default:
724 ok(0, "%u: array of type %d is not handled\n", i, value.vt & ~VT_VECTOR);
725 break;
726 }
727 }
728 else if (value.vt == VT_LPSTR)
729 {
730 ok(td[i].count == strlen(U(value).pszVal) ||
731 broken(td[i].count == strlen(U(value).pszVal) + 1), /* before Win7 */
732 "%u: expected count %d, got %d\n", i, td[i].count, lstrlenA(U(value).pszVal));
733 if (td[i].count == strlen(U(value).pszVal))
734 ok(!strcmp(td[i].string, U(value).pszVal),
735 "%u: expected %s, got %s\n", i, td[i].string, U(value).pszVal);
736 }
737 else if (value.vt == VT_BLOB)
738 {
739 ok(td[i].count == U(value).blob.cbSize, "%u: expected count %d, got %d\n", i, td[i].count, U(value).blob.cbSize);
740 ok(!memcmp(td[i].string, U(value).blob.pBlobData, td[i].count), "%u: expected %s, got %s\n", i, td[i].string, U(value).blob.pBlobData);
741 }
742 else
743 ok(U(value).uhVal.QuadPart == td[i].value[0], "%u: expected value %#x/%#x got %#x/%#x\n",
744 i, (UINT)td[i].value[0], (UINT)(td[i].value[0] >> 32), U(value).uhVal.u.LowPart, U(value).uhVal.u.HighPart);
745
747 PropVariantClear(&id);
749 }
750
751 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
752 ok(hr == S_FALSE, "Next should fail\n");
753 ok(items_returned == 0, "unexpected item count %u\n", items_returned);
754
755 IWICEnumMetadataItem_Release(enumerator);
756}
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
@ VT_UI8
Definition: compat.h:2315
@ VT_LPSTR
Definition: compat.h:2324
@ VT_R4
Definition: compat.h:2299
@ VT_UI2
Definition: compat.h:2312
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_R8
Definition: compat.h:2300
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
@ VT_VECTOR
Definition: compat.h:2340
@ VT_UI1
Definition: compat.h:2311
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
GLuint id
Definition: glext.h:5910
#define S_OK
Definition: intsafe.h:52
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const WCHAR * schema
unsigned int UINT
Definition: ndis.h:50
HRESULT hr
Definition: shlfolder.c:183
char * value
Definition: compiler.c:67
Definition: reader.h:84
LONGLONG value[13]
Definition: metadata.c:650
Definition: pdh_main.c:94
#define S_FALSE
Definition: winerror.h:2357

Referenced by test_metadata_APE(), test_metadata_GCE(), test_metadata_gif(), test_metadata_GIF_comment(), test_metadata_IFD(), test_metadata_IMD(), test_metadata_LSD(), and test_metadata_png().

◆ create_stream()

static IStream * create_stream ( const char data,
int  data_size 
)
static

Definition at line 204 of file metadata.c.

205{
206 HRESULT hr;
208 HGLOBAL hdata;
209 void *locked_data;
210
211 hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
212 ok(hdata != 0, "GlobalAlloc failed\n");
213 if (!hdata) return NULL;
214
215 locked_data = GlobalLock(hdata);
216 memcpy(locked_data, data, data_size);
217 GlobalUnlock(hdata);
218
220 ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
221
222 return stream;
223}
#define TRUE
Definition: types.h:120
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: parse.h:23
#define GMEM_MOVEABLE
Definition: winbase.h:294

Referenced by load_stream(), test_create_reader(), test_metadata_APE(), test_metadata_GCE(), test_metadata_gif(), test_metadata_GIF_comment(), test_metadata_IMD(), test_metadata_LSD(), and test_metadata_png().

◆ DEFINE_GUID()

DEFINE_GUID ( IID_MdbrUnknown  ,
0x00240e6f  ,
0x3f23  ,
0x4432  ,
0xb0  ,
0xcc  ,
0x48  ,
0xd5  ,
0xbb  ,
0xff  ,
0x6c  ,
0x36   
)

◆ get_temp_buffer()

static char * get_temp_buffer ( int  size)
static

Definition at line 2542 of file metadata.c.

2543{
2544 static char buf[16][256];
2545 static int idx;
2546 char *p;
2547
2548 assert(size < 256);
2549
2550 p = buf[idx & 0x0f];
2551 idx++;
2552 return p;
2553}
unsigned int idx
Definition: utils.c:41
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902

◆ load_stream()

static void load_stream ( IUnknown reader,
const char data,
int  data_size,
DWORD  persist_options 
)
static

Definition at line 225 of file metadata.c.

226{
227 HRESULT hr;
228 IWICPersistStream *persist;
231 ULARGE_INTEGER cur_pos;
232
233 stream = create_stream(data, data_size);
234 if (!stream)
235 return;
236
237 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist);
238 ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
239
240 if (SUCCEEDED(hr))
241 {
242 hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options);
243 ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
244
245 IWICPersistStream_Release(persist);
246 }
247
248 pos.QuadPart = 0;
249 hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
250 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
251 /* IFD metadata reader doesn't rewind the stream to the start */
252 ok(cur_pos.QuadPart == 0 || cur_pos.QuadPart <= data_size,
253 "current stream pos is at %x/%x, data size %x\n", cur_pos.u.LowPart, cur_pos.u.HighPart, data_size);
254
255 IStream_Release(stream);
256}
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define SEEK_CUR
Definition: util.h:63
static IStream * create_stream(const char *data, int data_size)
Definition: metadata.c:204
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
struct _ULARGE_INTEGER::@4153 u

Referenced by test_metadata_cHRM(), test_metadata_gAMA(), test_metadata_IFD(), test_metadata_tEXt(), and test_metadata_unknown().

◆ mdbr_AddRef()

static ULONG WINAPI mdbr_AddRef ( IWICMetadataBlockReader iface)
static

Definition at line 2727 of file metadata.c.

2728{
2729 return 2;
2730}

◆ mdbr_GetContainerFormat()

static HRESULT WINAPI mdbr_GetContainerFormat ( IWICMetadataBlockReader iface,
GUID format 
)
static

Definition at line 2737 of file metadata.c.

2738{
2739 trace("%p,%p\n", iface, format);
2740
2741 ok(current_metadata != NULL, "current_metadata can't be NULL\n");
2742 if (!current_metadata) return E_POINTER;
2743
2744 *format = *current_metadata->container_format;
2745 return S_OK;
2746}
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static const struct metadata * current_metadata
Definition: metadata.c:2475
#define E_POINTER
Definition: winerror.h:2365

◆ mdbr_GetCount()

static HRESULT WINAPI mdbr_GetCount ( IWICMetadataBlockReader iface,
UINT count 
)
static

Definition at line 2748 of file metadata.c.

2749{
2750 trace("%p,%p\n", iface, count);
2751
2752 ok(current_metadata != NULL, "current_metadata can't be NULL\n");
2753 if (!current_metadata) return E_POINTER;
2754
2755 *count = current_metadata->count;
2756 return S_OK;
2757}

◆ mdbr_GetEnumerator()

static HRESULT WINAPI mdbr_GetEnumerator ( IWICMetadataBlockReader iface,
IEnumUnknown **  enumerator 
)
static

Definition at line 2779 of file metadata.c.

2780{
2781 ok(0, "not implemented\n");
2782 return E_NOTIMPL;
2783}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ mdbr_GetReaderByIndex()

static HRESULT WINAPI mdbr_GetReaderByIndex ( IWICMetadataBlockReader iface,
UINT  index,
IWICMetadataReader **  out 
)
static

Definition at line 2759 of file metadata.c.

2760{
2761 trace("%p,%u,%p\n", iface, index, out);
2762
2763 *out = NULL;
2764
2765 ok(current_metadata != NULL, "current_metadata can't be NULL\n");
2766 if (!current_metadata) return E_POINTER;
2767
2768 if (index < current_metadata->count)
2769 {
2771 *out = &mdr;
2772 return S_OK;
2773 }
2774
2776 return E_INVALIDARG;
2777}
#define index(s, c)
Definition: various.h:29
GLuint index
Definition: glext.h:6031
static IWICMetadataReader mdr
Definition: metadata.c:2708
static const struct metadata_block * current_metadata_block
Definition: metadata.c:2476
static FILE * out
Definition: regtests2xml.c:44

◆ mdbr_QueryInterface()

static HRESULT WINAPI mdbr_QueryInterface ( IWICMetadataBlockReader iface,
REFIID  iid,
void **  out 
)
static

Definition at line 2710 of file metadata.c.

2711{
2712 if (IsEqualIID(iid, &IID_IUnknown) ||
2713 IsEqualIID(iid, &IID_IWICMetadataBlockReader))
2714 {
2715 *out = iface;
2716 return S_OK;
2717 }
2718
2719 /* Windows 8/10 query for some undocumented IID */
2720 if (!IsEqualIID(iid, &IID_MdbrUnknown))
2721 ok(0, "unknown iid %s\n", wine_dbgstr_guid(iid));
2722
2723 *out = NULL;
2724 return E_NOINTERFACE;
2725}
const GUID IID_IUnknown
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ mdbr_Release()

static ULONG WINAPI mdbr_Release ( IWICMetadataBlockReader iface)
static

Definition at line 2732 of file metadata.c.

2733{
2734 return 1;
2735}

◆ mdr_AddRef()

static ULONG WINAPI mdr_AddRef ( IWICMetadataReader iface)
static

Definition at line 2498 of file metadata.c.

2499{
2500 return 2;
2501}

◆ mdr_GetCount()

static HRESULT WINAPI mdr_GetCount ( IWICMetadataReader iface,
UINT count 
)
static

Definition at line 2525 of file metadata.c.

2526{
2527 trace("%p,%p\n", iface, count);
2528
2529 ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n");
2530 if (!current_metadata_block) return E_POINTER;
2531
2532 *count = current_metadata_block->count;
2533 return S_OK;
2534}

◆ mdr_GetEnumerator()

static HRESULT WINAPI mdr_GetEnumerator ( IWICMetadataReader iface,
IWICEnumMetadataItem **  enumerator 
)
static

Definition at line 2689 of file metadata.c.

2690{
2691 ok(0, "not implemented\n");
2692 return E_NOTIMPL;
2693}

◆ mdr_GetMetadataFormat()

static HRESULT WINAPI mdr_GetMetadataFormat ( IWICMetadataReader iface,
GUID format 
)
static

Definition at line 2508 of file metadata.c.

2509{
2510 trace("%p,%p\n", iface, format);
2511
2512 ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n");
2513 if (!current_metadata_block) return E_POINTER;
2514
2515 *format = *current_metadata_block->metadata_format;
2516 return S_OK;
2517}

◆ mdr_GetMetadataHandlerInfo()

static HRESULT WINAPI mdr_GetMetadataHandlerInfo ( IWICMetadataReader iface,
IWICMetadataHandlerInfo **  handler 
)
static

Definition at line 2519 of file metadata.c.

2520{
2521 ok(0, "not implemented\n");
2522 return E_NOTIMPL;
2523}

◆ mdr_GetValue()

static HRESULT WINAPI mdr_GetValue ( IWICMetadataReader iface,
const PROPVARIANT *  schema,
const PROPVARIANT *  id,
PROPVARIANT *  value 
)
static

Definition at line 2593 of file metadata.c.

2594{
2595 UINT i;
2596
2598
2599 ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n");
2600 if (!current_metadata_block) return E_POINTER;
2601
2602 ok(schema != NULL && id != NULL && value != NULL, "%p, %p, %p should not be NULL\n", schema, id, value);
2603
2604 for (i = 0; i < current_metadata_block->count; i++)
2605 {
2606 if (schema->vt != VT_EMPTY)
2607 {
2608 if (!current_metadata_block->item[i].schema)
2609 continue;
2610
2611 switch (schema->vt)
2612 {
2613 case VT_LPSTR:
2614 if (lstrcmpA(U(*schema).pszVal, current_metadata_block->item[i].schema) != 0)
2615 continue;
2616 break;
2617
2618 case VT_LPWSTR:
2619 {
2620 char schemaA[256];
2621 WideCharToMultiByte(CP_ACP, 0, U(*schema).pwszVal, -1, schemaA, sizeof(schemaA), NULL, NULL);
2622 if (lstrcmpA(schemaA, current_metadata_block->item[i].schema) != 0)
2623 continue;
2624 break;
2625 }
2626
2627 default:
2628 ok(0, "unsupported schema vt %u\n", schema->vt);
2629 continue;
2630 }
2631 }
2632 else if (current_metadata_block->item[i].schema)
2633 continue;
2634
2635 switch (id->vt)
2636 {
2637 case VT_LPSTR:
2638 if (current_metadata_block->item[i].id_str)
2639 {
2640 if (!lstrcmpA(U(*id).pszVal, current_metadata_block->item[i].id_str))
2641 {
2642 value->vt = VT_LPSTR;
2643 U(*value).pszVal = the_best;
2644 return S_OK;
2645 }
2646 break;
2647 }
2648 break;
2649
2650 case VT_LPWSTR:
2651 if (current_metadata_block->item[i].id_str)
2652 {
2653 char idA[256];
2654 WideCharToMultiByte(CP_ACP, 0, U(*id).pwszVal, -1, idA, sizeof(idA), NULL, NULL);
2655 if (!lstrcmpA(idA, current_metadata_block->item[i].id_str))
2656 {
2657 value->vt = VT_LPSTR;
2658 U(*value).pszVal = the_worst;
2659 return S_OK;
2660 }
2661 break;
2662 }
2663 break;
2664
2665 case VT_CLSID:
2666 if (IsEqualGUID(U(*id).puuid, &GUID_MetadataFormatXMP) ||
2667 IsEqualGUID(U(*id).puuid, &GUID_ContainerFormatTiff))
2668 {
2669 value->vt = VT_UNKNOWN;
2670 value->punkVal = (IUnknown *)iface;
2671 return S_OK;
2672 }
2673 break;
2674
2675 default:
2676 if (!propvar_cmp(id, current_metadata_block->item[i].id))
2677 {
2678 value->vt = current_metadata_block->item[i].type;
2679 U(*value).uiVal = current_metadata_block->item[i].value;
2680 return S_OK;
2681 }
2682 break;
2683 }
2684 }
2685
2686 return 0xdeadbeef;
2687}
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_CLSID
Definition: compat.h:2337
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4194
static const char * wine_dbgstr_propvariant(const PROPVARIANT *var)
Definition: metadata.c:2555
static char the_worst[]
Definition: metadata.c:2479
static int propvar_cmp(const PROPVARIANT *v1, LONGLONG value2)
Definition: metadata.c:2582
static char the_best[]
Definition: metadata.c:2478
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147

◆ mdr_GetValueByIndex()

static HRESULT WINAPI mdr_GetValueByIndex ( IWICMetadataReader iface,
UINT  index,
PROPVARIANT *  schema,
PROPVARIANT *  id,
PROPVARIANT *  value 
)
static

Definition at line 2536 of file metadata.c.

2537{
2538 ok(0, "not implemented\n");
2539 return E_NOTIMPL;
2540}

◆ mdr_QueryInterface()

static HRESULT WINAPI mdr_QueryInterface ( IWICMetadataReader iface,
REFIID  iid,
void **  out 
)
static

Definition at line 2481 of file metadata.c.

2482{
2483 trace("%p,%s,%p\n", iface, wine_dbgstr_guid(iid), out);
2484
2485 if (IsEqualIID(iid, &IID_IUnknown) ||
2486 IsEqualIID(iid, &IID_IWICMetadataReader))
2487 {
2488 *out = iface;
2489 return S_OK;
2490 }
2491
2492 ok(0, "unknown iid %s\n", wine_dbgstr_guid(iid));
2493
2494 *out = NULL;
2495 return E_NOINTERFACE;
2496}

◆ mdr_Release()

static ULONG WINAPI mdr_Release ( IWICMetadataReader iface)
static

Definition at line 2503 of file metadata.c.

2504{
2505 return 1;
2506}

◆ propvar_cmp()

static int propvar_cmp ( const PROPVARIANT *  v1,
LONGLONG  value2 
)
static

Definition at line 2582 of file metadata.c.

2583{
2584 LONGLONG value1;
2585
2586 if (PropVariantToInt64(v1, &value1) != S_OK) return -1;
2587
2588 value1 -= value2;
2589 if (value1) return value1 < 0 ? -1 : 1;
2590 return 0;
2591}
HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
Definition: propvar.c:198
GLfloat GLfloat v1
Definition: glext.h:6062
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by mdr_GetValue().

◆ START_TEST()

START_TEST ( metadata  )

Definition at line 3055 of file metadata.c.

3056{
3058
3077
3079}
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
static void test_metadata_IMD(void)
Definition: metadata.c:1848
static void test_create_reader(void)
Definition: metadata.c:958
static void test_metadata_GCE(void)
Definition: metadata.c:1926
static void test_metadata_GIF_comment(void)
Definition: metadata.c:2086
static void test_metadata_Exif(void)
Definition: metadata.c:930
static void test_queryreader(void)
Definition: metadata.c:2871
static void test_WICMapSchemaToName(void)
Definition: metadata.c:2365
static void test_metadata_png(void)
Definition: metadata.c:1029
static void test_WICMapShortNameToGuid(void)
Definition: metadata.c:2225
static void test_metadata_gAMA(void)
Definition: metadata.c:432
static void test_metadata_unknown(void)
Definition: metadata.c:258
static void test_metadata_APE(void)
Definition: metadata.c:2001
static void test_metadata_tEXt(void)
Definition: metadata.c:314
static void test_metadata_cHRM(void)
Definition: metadata.c:477
static void test_metadata_IFD(void)
Definition: metadata.c:758
static void test_metadata_LSD(void)
Definition: metadata.c:1769
static void test_WICMapGuidToShortName(void)
Definition: metadata.c:2168
static void test_metadata_gif(void)
Definition: metadata.c:1152
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278

◆ test_create_reader()

static void test_create_reader ( void  )
static

Definition at line 958 of file metadata.c.

959{
960 HRESULT hr;
964 UINT count=0;
965 GUID format;
966
967 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
968 &IID_IWICComponentFactory, (void**)&factory);
969 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
970
972
973 hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
975 stream, &reader);
976 ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
977
978 hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
979 &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault,
980 NULL, &reader);
981 ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
982
983 hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
984 &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault,
985 stream, NULL);
986 ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
987
988 hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
989 &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault,
990 stream, &reader);
991 ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
992
993 if (SUCCEEDED(hr))
994 {
995 hr = IWICMetadataReader_GetCount(reader, &count);
996 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
997 ok(count == 1, "unexpected count %i\n", count);
998
999 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1000 ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
1001 ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format));
1002
1003 IWICMetadataReader_Release(reader);
1004 }
1005
1006 hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
1007 &GUID_ContainerFormatWmp, NULL, WICPersistOptionDefault,
1008 stream, &reader);
1009 ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
1010
1011 if (SUCCEEDED(hr))
1012 {
1013 hr = IWICMetadataReader_GetCount(reader, &count);
1014 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
1015 ok(count == 1, "unexpected count %i\n", count);
1016
1017 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1018 ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
1019 ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "unexpected format %s\n", wine_dbgstr_guid(&format));
1020
1021 IWICMetadataReader_Release(reader);
1022 }
1023
1024 IStream_Release(stream);
1025
1026 IWICComponentFactory_Release(factory);
1027}
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
static const char metadata_tEXt[]
Definition: metadata.c:139
Definition: main.c:439
@ WICPersistOptionDefault
Definition: wincodecsdk.idl:23

Referenced by START_TEST().

◆ test_metadata_APE()

static void test_metadata_APE ( void  )
static

Definition at line 2001 of file metadata.c.

2002{
2003 static const WCHAR APE_name[] = {'A','p','p','l','i','c','a','t','i','o','n',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0};
2004 static const char APE_data[] = { 0x21,0xff,0x0b,'H','e','l','l','o',' ','W','o','r','l','d',
2005 /*sub-block*/1,0x11,
2006 /*sub-block*/2,0x22,0x33,
2007 /*sub-block*/4,0x44,0x55,0x66,0x77,
2008 /*terminator*/0 };
2009 static const struct test_data td[2] =
2010 {
2011 { VT_UI1|VT_VECTOR, 0, 11, { 'H','e','l','l','o',' ','W','o','r','l','d' }, NULL, { 'A','p','p','l','i','c','a','t','i','o','n',0 } },
2012 { VT_UI1|VT_VECTOR, 0, 10, { 1,0x11,2,0x22,0x33,4,0x44,0x55,0x66,0x77 }, NULL, { 'D','a','t','a',0 } }
2013 };
2014 WCHAR dataW[] = { 'd','a','t','a',0 };
2015 HRESULT hr;
2016 IStream *stream;
2017 IWICPersistStream *persist;
2020 WCHAR name[64];
2021 UINT count, dummy, i;
2022 GUID format;
2023 CLSID clsid;
2024 PROPVARIANT id, value;
2025
2026 hr = CoCreateInstance(&CLSID_WICAPEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
2027 &IID_IWICMetadataReader, (void **)&reader);
2028 ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
2029 "CoCreateInstance error %#x\n", hr);
2030
2031 stream = create_stream(APE_data, sizeof(APE_data));
2032
2033 if (SUCCEEDED(hr))
2034 {
2035 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
2036 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
2037
2038 hr = IWICPersistStream_Load(persist, stream);
2039 ok(hr == S_OK, "Load error %#x\n", hr);
2040
2041 IWICPersistStream_Release(persist);
2042 }
2043
2044 if (SUCCEEDED(hr))
2045 {
2046 hr = IWICMetadataReader_GetCount(reader, &count);
2047 ok(hr == S_OK, "GetCount error %#x\n", hr);
2048 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
2049
2051
2052 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
2053 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
2054 ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), "wrong format %s\n", wine_dbgstr_guid(&format));
2055
2056 PropVariantInit(&value);
2057 id.vt = VT_LPWSTR;
2058 U(id).pwszVal = dataW;
2059
2060 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
2061 ok(hr == S_OK, "GetValue error %#x\n", hr);
2062 ok(value.vt == (VT_UI1|VT_VECTOR), "unexpected vt: %i\n", id.vt);
2063 ok(td[1].count == U(value).caub.cElems, "expected cElems %d, got %d\n", td[1].count, U(value).caub.cElems);
2064 for (i = 0; i < U(value).caub.cElems; i++)
2065 ok(td[1].value[i] == U(value).caub.pElems[i], "%u: expected value %#x/%#x, got %#x\n", i, (ULONG)td[1].value[i], (ULONG)(td[1].value[i] >> 32), U(value).caub.pElems[i]);
2067
2068 hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info);
2069 ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr);
2070
2071 hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid);
2072 ok(hr == S_OK, "GetCLSID error %#x\n", hr);
2073 ok(IsEqualGUID(&clsid, &CLSID_WICAPEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid));
2074
2075 hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy);
2076 ok(hr == S_OK, "GetFriendlyName error %#x\n", hr);
2077 ok(lstrcmpW(name, APE_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name));
2078
2079 IWICMetadataHandlerInfo_Release(info);
2080 IWICMetadataReader_Release(reader);
2081 }
2082
2083 IStream_Release(stream);
2084}
#define ARRAY_SIZE(A)
Definition: main.h:33
static void compare_metadata(IWICMetadataReader *reader, const struct test_data *td, ULONG count)
Definition: metadata.c:655
REFCLSID clsid
Definition: msctf.c:82
Definition: name.c:39
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_metadata_cHRM()

static void test_metadata_cHRM ( void  )
static

Definition at line 477 of file metadata.c.

478{
479 HRESULT hr;
481 PROPVARIANT schema, id, value;
482 ULONG count;
483 GUID format;
484 int i;
485 static const WCHAR expected_names[8][12] = {
486 {'W','h','i','t','e','P','o','i','n','t','X',0},
487 {'W','h','i','t','e','P','o','i','n','t','Y',0},
488 {'R','e','d','X',0},
489 {'R','e','d','Y',0},
490 {'G','r','e','e','n','X',0},
491 {'G','r','e','e','n','Y',0},
492 {'B','l','u','e','X',0},
493 {'B','l','u','e','Y',0},
494 };
495 static const ULONG expected_vals[8] = {
496 31270,32900, 64000,33000, 30000,60000, 15000,6000
497 };
498
499 PropVariantInit(&schema);
500 PropVariantInit(&id);
501 PropVariantInit(&value);
502
503 hr = CoCreateInstance(&CLSID_WICPngChrmMetadataReader, NULL, CLSCTX_INPROC_SERVER,
504 &IID_IWICMetadataReader, (void**)&reader);
505 ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr);
506 if (FAILED(hr)) return;
507
509
510 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
511 ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
512 ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkcHRM), "unexpected format %s\n", wine_dbgstr_guid(&format));
513
514 hr = IWICMetadataReader_GetCount(reader, &count);
515 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
516 ok(count == 8, "unexpected count %i\n", count);
517
518 for (i=0; i<8; i++)
519 {
520 hr = IWICMetadataReader_GetValueByIndex(reader, i, &schema, &id, &value);
521 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
522
523 ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
525
526 ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt);
527 ok(!lstrcmpW(U(id).pwszVal, expected_names[i]), "got %s, expected %s\n", wine_dbgstr_w(U(id).pwszVal), wine_dbgstr_w(expected_names[i]));
528 PropVariantClear(&id);
529
530 ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt);
531 ok(U(value).ulVal == expected_vals[i], "got %u, expected %u\n", U(value).ulVal, expected_vals[i]);
533 }
534
535 IWICMetadataReader_Release(reader);
536}
#define FAILED(hr)
Definition: intsafe.h:51
static void load_stream(IUnknown *reader, const char *data, int data_size, DWORD persist_options)
Definition: metadata.c:225
static const char metadata_cHRM[]
Definition: metadata.c:154

Referenced by START_TEST().

◆ test_metadata_Exif()

static void test_metadata_Exif ( void  )
static

Definition at line 930 of file metadata.c.

931{
932 HRESULT hr;
934 IWICMetadataBlockReader *blockreader;
935 UINT count=0;
936
937 hr = CoCreateInstance(&CLSID_WICExifMetadataReader, NULL, CLSCTX_INPROC_SERVER,
938 &IID_IWICMetadataReader, (void**)&reader);
939 todo_wine ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
940 if (FAILED(hr)) return;
941
942 hr = IWICMetadataReader_GetCount(reader, NULL);
943 ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr);
944
945 hr = IWICMetadataReader_GetCount(reader, &count);
946 ok(hr == S_OK, "GetCount error %#x\n", hr);
947 ok(count == 0, "unexpected count %u\n", count);
948
949 hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader);
950 ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr);
951
952 if (SUCCEEDED(hr))
953 IWICMetadataBlockReader_Release(blockreader);
954
955 IWICMetadataReader_Release(reader);
956}
#define todo_wine
Definition: custom.c:79

Referenced by START_TEST().

◆ test_metadata_gAMA()

static void test_metadata_gAMA ( void  )
static

Definition at line 432 of file metadata.c.

433{
434 HRESULT hr;
436 PROPVARIANT schema, id, value;
437 ULONG count;
438 GUID format;
439 static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0};
440
441 PropVariantInit(&schema);
442 PropVariantInit(&id);
443 PropVariantInit(&value);
444
445 hr = CoCreateInstance(&CLSID_WICPngGamaMetadataReader, NULL, CLSCTX_INPROC_SERVER,
446 &IID_IWICMetadataReader, (void**)&reader);
447 ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr);
448 if (FAILED(hr)) return;
449
451
452 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
453 ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
454 ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkgAMA), "unexpected format %s\n", wine_dbgstr_guid(&format));
455
456 hr = IWICMetadataReader_GetCount(reader, &count);
457 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
458 ok(count == 1, "unexpected count %i\n", count);
459
460 hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, &id, &value);
461 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
462
463 ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
465
466 ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt);
467 ok(!lstrcmpW(U(id).pwszVal, ImageGamma), "unexpected value: %s\n", wine_dbgstr_w(U(id).pwszVal));
468 PropVariantClear(&id);
469
470 ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt);
471 ok(U(value).ulVal == 33333, "unexpected value: %u\n", U(value).ulVal);
473
474 IWICMetadataReader_Release(reader);
475}
static const char metadata_gAMA[]
Definition: metadata.c:147

Referenced by START_TEST().

◆ test_metadata_GCE()

static void test_metadata_GCE ( void  )
static

Definition at line 1926 of file metadata.c.

1927{
1928 static const WCHAR GCE_name[] = {'G','r','a','p','h','i','c',' ','C','o','n','t','r','o','l',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0};
1929 static const char GCE_data[] = "hello world!\xa\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf";
1930 static const struct test_data td[5] =
1931 {
1932 { VT_UI1, 0, 0, { 2 }, NULL, { 'D','i','s','p','o','s','a','l',0 } },
1933 { VT_BOOL, 0, 0, { 1 }, NULL, { 'U','s','e','r','I','n','p','u','t','F','l','a','g',0 } },
1934 { VT_BOOL, 0, 0, { 0 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','c','y','F','l','a','g',0 } },
1935 { VT_UI2, 0, 0, { 0x302 }, NULL, { 'D','e','l','a','y',0 } },
1936 { VT_UI1, 0, 0, { 4 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','t','C','o','l','o','r','I','n','d','e','x',0 } }
1937 };
1939 HRESULT hr;
1940 IStream *stream;
1941 IWICPersistStream *persist;
1944 WCHAR name[64];
1945 UINT count, dummy;
1946 GUID format;
1947 CLSID id;
1948
1949 hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
1950 &IID_IWICMetadataReader, (void **)&reader);
1951 ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
1952 "CoCreateInstance error %#x\n", hr);
1953
1954 stream = create_stream(GCE_data, sizeof(GCE_data));
1955
1956 if (SUCCEEDED(hr))
1957 {
1958 pos.QuadPart = 12;
1959 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1960 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1961
1962 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
1963 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1964
1965 hr = IWICPersistStream_Load(persist, stream);
1966 ok(hr == S_OK, "Load error %#x\n", hr);
1967
1968 IWICPersistStream_Release(persist);
1969 }
1970
1971 if (SUCCEEDED(hr))
1972 {
1973 hr = IWICMetadataReader_GetCount(reader, &count);
1974 ok(hr == S_OK, "GetCount error %#x\n", hr);
1975 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
1976
1978
1979 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1980 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
1981 ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), "wrong format %s\n", wine_dbgstr_guid(&format));
1982
1983 hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info);
1984 ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr);
1985
1986 hr = IWICMetadataHandlerInfo_GetCLSID(info, &id);
1987 ok(hr == S_OK, "GetCLSID error %#x\n", hr);
1988 ok(IsEqualGUID(&id, &CLSID_WICGCEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id));
1989
1990 hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy);
1991 ok(hr == S_OK, "GetFriendlyName error %#x\n", hr);
1992 ok(lstrcmpW(name, GCE_name) == 0, "wrong GCE reader name %s\n", wine_dbgstr_w(name));
1993
1994 IWICMetadataHandlerInfo_Release(info);
1995 IWICMetadataReader_Release(reader);
1996 }
1997
1998 IStream_Release(stream);
1999}
@ VT_BOOL
Definition: compat.h:2306
#define SEEK_SET
Definition: jmemansi.c:26

Referenced by START_TEST().

◆ test_metadata_gif()

static void test_metadata_gif ( void  )
static

Definition at line 1152 of file metadata.c.

1153{
1154 static const struct test_data gif_LSD[9] =
1155 {
1156 { VT_UI1|VT_VECTOR, 0, 6, {'G','I','F','8','7','a'}, NULL, { 'S','i','g','n','a','t','u','r','e',0 } },
1157 { VT_UI2, 0, 0, { 1 }, NULL, { 'W','i','d','t','h',0 } },
1158 { VT_UI2, 0, 0, { 1 }, NULL, { 'H','e','i','g','h','t',0 } },
1159 { VT_BOOL, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1160 { VT_UI1, 0, 0, { 0 }, NULL, { 'C','o','l','o','r','R','e','s','o','l','u','t','i','o','n',0 } },
1161 { VT_BOOL, 0, 0, { 0 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1162 { VT_UI1, 0, 0, { 0 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } },
1163 { VT_UI1, 0, 0, { 0 }, NULL, { 'B','a','c','k','g','r','o','u','n','d','C','o','l','o','r','I','n','d','e','x',0 } },
1164 { VT_UI1, 0, 0, { 0 }, NULL, { 'P','i','x','e','l','A','s','p','e','c','t','R','a','t','i','o',0 } }
1165 };
1166 static const struct test_data gif_IMD[8] =
1167 {
1168 { VT_UI2, 0, 0, { 0 }, NULL, { 'L','e','f','t',0 } },
1169 { VT_UI2, 0, 0, { 0 }, NULL, { 'T','o','p',0 } },
1170 { VT_UI2, 0, 0, { 1 }, NULL, { 'W','i','d','t','h',0 } },
1171 { VT_UI2, 0, 0, { 1 }, NULL, { 'H','e','i','g','h','t',0 } },
1172 { VT_BOOL, 0, 0, { 0 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1173 { VT_BOOL, 0, 0, { 0 }, NULL, { 'I','n','t','e','r','l','a','c','e','F','l','a','g',0 } },
1174 { VT_BOOL, 0, 0, { 0 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1175 { VT_UI1, 0, 0, { 0 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } }
1176 };
1177 static const struct test_data animated_gif_LSD[9] =
1178 {
1179 { VT_UI1|VT_VECTOR, 0, 6, {'G','I','F','8','9','a'}, NULL, { 'S','i','g','n','a','t','u','r','e',0 } },
1180 { VT_UI2, 0, 0, { 1 }, NULL, { 'W','i','d','t','h',0 } },
1181 { VT_UI2, 0, 0, { 1 }, NULL, { 'H','e','i','g','h','t',0 } },
1182 { VT_BOOL, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1183 { VT_UI1, 0, 0, { 2 }, NULL, { 'C','o','l','o','r','R','e','s','o','l','u','t','i','o','n',0 } },
1184 { VT_BOOL, 0, 0, { 0 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1185 { VT_UI1, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } },
1186 { VT_UI1, 0, 0, { 0 }, NULL, { 'B','a','c','k','g','r','o','u','n','d','C','o','l','o','r','I','n','d','e','x',0 } },
1187 { VT_UI1, 0, 0, { 0 }, NULL, { 'P','i','x','e','l','A','s','p','e','c','t','R','a','t','i','o',0 } }
1188 };
1189 static const struct test_data animated_gif_IMD[8] =
1190 {
1191 { VT_UI2, 0, 0, { 0 }, NULL, { 'L','e','f','t',0 } },
1192 { VT_UI2, 0, 0, { 0 }, NULL, { 'T','o','p',0 } },
1193 { VT_UI2, 0, 0, { 1 }, NULL, { 'W','i','d','t','h',0 } },
1194 { VT_UI2, 0, 0, { 1 }, NULL, { 'H','e','i','g','h','t',0 } },
1195 { VT_BOOL, 0, 0, { 1 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1196 { VT_BOOL, 0, 0, { 0 }, NULL, { 'I','n','t','e','r','l','a','c','e','F','l','a','g',0 } },
1197 { VT_BOOL, 0, 0, { 0 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1198 { VT_UI1, 0, 0, { 1 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } }
1199 };
1200 static const struct test_data animated_gif_GCE[5] =
1201 {
1202 { VT_UI1, 0, 0, { 0 }, NULL, { 'D','i','s','p','o','s','a','l',0 } },
1203 { VT_BOOL, 0, 0, { 0 }, NULL, { 'U','s','e','r','I','n','p','u','t','F','l','a','g',0 } },
1204 { VT_BOOL, 0, 0, { 1 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','c','y','F','l','a','g',0 } },
1205 { VT_UI2, 0, 0, { 10 }, NULL, { 'D','e','l','a','y',0 } },
1206 { VT_UI1, 0, 0, { 1 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','t','C','o','l','o','r','I','n','d','e','x',0 } }
1207 };
1208 static const struct test_data animated_gif_APE[2] =
1209 {
1210 { VT_UI1|VT_VECTOR, 0, 11, { 'A','N','I','M','E','X','T','S','1','.','0' }, NULL, { 'A','p','p','l','i','c','a','t','i','o','n',0 } },
1211 { VT_UI1|VT_VECTOR, 0, 4, { 0x03,0x01,0x05,0x00 }, NULL, { 'D','a','t','a',0 } }
1212 };
1213 static const struct test_data animated_gif_comment_1[1] =
1214 {
1215 { VT_LPSTR, 0, 12, { 0 }, "Hello World!", { 'T','e','x','t','E','n','t','r','y',0 } }
1216 };
1217 static const struct test_data animated_gif_comment_2[1] =
1218 {
1219 { VT_LPSTR, 0, 8, { 0 }, "image #1", { 'T','e','x','t','E','n','t','r','y',0 } }
1220 };
1221 static const struct test_data animated_gif_plain_1[1] =
1222 {
1223 { VT_BLOB, 0, 17, { 0 }, "\x21\x01\x0d\x61nimation.gif" }
1224 };
1225 static const struct test_data animated_gif_plain_2[1] =
1226 {
1227 { VT_BLOB, 0, 16, { 0 }, "\x21\x01\x0cplaintext #1" }
1228 };
1229 IStream *stream;
1230 IWICBitmapDecoder *decoder;
1231 IWICBitmapFrameDecode *frame;
1232 IWICMetadataBlockReader *blockreader;
1234 IWICMetadataQueryReader *queryreader;
1235 GUID format;
1236 HRESULT hr;
1237 UINT count;
1238
1239 /* 1x1 pixel gif */
1241
1242 hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER,
1243 &IID_IWICBitmapDecoder, (void **)&decoder);
1244 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1245 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
1246 ok(hr == S_OK, "Initialize error %#x\n", hr);
1247
1248 IStream_Release(stream);
1249
1250 /* global metadata block */
1251 hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader);
1252 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
1253
1254 if (SUCCEEDED(hr))
1255 {
1256 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format);
1257 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1258 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1259 "wrong container format %s\n", wine_dbgstr_guid(&format));
1260
1261 hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
1262 ok(hr == S_OK, "GetCount error %#x\n", hr);
1263 ok(count == 1, "expected 1, got %u\n", count);
1264
1265 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
1266 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1267
1268 if (SUCCEEDED(hr))
1269 {
1270 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1271 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1272 ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */
1273 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1274
1275 hr = IWICMetadataReader_GetCount(reader, &count);
1276 ok(hr == S_OK, "GetCount error %#x\n", hr);
1277 ok(count == ARRAY_SIZE(gif_LSD), "unexpected count %u\n", count);
1278
1279 compare_metadata(reader, gif_LSD, count);
1280
1281 IWICMetadataReader_Release(reader);
1282 }
1283
1284 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
1285 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1286
1287 IWICMetadataBlockReader_Release(blockreader);
1288 }
1289
1290 /* frame metadata block */
1291 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
1292 ok(hr == S_OK, "GetFrame error %#x\n", hr);
1293
1294 hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader);
1295 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
1296
1297 if (SUCCEEDED(hr))
1298 {
1299 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL);
1300 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1301
1302 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format);
1303 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1304 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1305 "wrong container format %s\n", wine_dbgstr_guid(&format));
1306
1307 hr = IWICMetadataBlockReader_GetCount(blockreader, NULL);
1308 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1309
1310 hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
1311 ok(hr == S_OK, "GetCount error %#x\n", hr);
1312 ok(count == 1, "expected 1, got %u\n", count);
1313
1314 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
1315 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1316
1317 if (SUCCEEDED(hr))
1318 {
1319 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1320 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1321 ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */
1322 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1323
1324 hr = IWICMetadataReader_GetCount(reader, &count);
1325 ok(hr == S_OK, "GetCount error %#x\n", hr);
1326 ok(count == ARRAY_SIZE(gif_IMD), "unexpected count %u\n", count);
1327
1328 compare_metadata(reader, gif_IMD, count);
1329
1330 IWICMetadataReader_Release(reader);
1331 }
1332
1333 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
1334 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1335
1336 IWICMetadataBlockReader_Release(blockreader);
1337 }
1338
1339 IWICBitmapFrameDecode_Release(frame);
1340 IWICBitmapDecoder_Release(decoder);
1341
1342 /* 1x1 pixel gif, 2 frames */
1344
1345 hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER,
1346 &IID_IWICBitmapDecoder, (void **)&decoder);
1347 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1348 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
1349 ok(hr == S_OK, "Initialize error %#x\n", hr);
1350
1351 IStream_Release(stream);
1352
1353 /* global metadata block */
1354 hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader);
1355 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
1356
1357 if (SUCCEEDED(hr))
1358 {
1359 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format);
1360 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1361 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1362 "wrong container format %s\n", wine_dbgstr_guid(&format));
1363
1364 hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
1365 ok(hr == S_OK, "GetCount error %#x\n", hr);
1366 ok(count == 4, "expected 4, got %u\n", count);
1367
1368 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
1369 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1370
1371 if (SUCCEEDED(hr))
1372 {
1373 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1374 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1375 ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */
1376 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1377
1378 hr = IWICMetadataReader_GetCount(reader, &count);
1379 ok(hr == S_OK, "GetCount error %#x\n", hr);
1380 ok(count == ARRAY_SIZE(animated_gif_LSD), "unexpected count %u\n", count);
1381
1382 compare_metadata(reader, animated_gif_LSD, count);
1383
1384 IWICMetadataReader_Release(reader);
1385 }
1386
1387 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
1388 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1389
1390 if (SUCCEEDED(hr))
1391 {
1392 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1393 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1394 ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), /* Application Extension */
1395 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1396
1397 hr = IWICMetadataReader_GetCount(reader, &count);
1398 ok(hr == S_OK, "GetCount error %#x\n", hr);
1399 ok(count == ARRAY_SIZE(animated_gif_APE), "unexpected count %u\n", count);
1400
1401 compare_metadata(reader, animated_gif_APE, count);
1402
1403 IWICMetadataReader_Release(reader);
1404 }
1405
1406 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader);
1407 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1408
1409 if (SUCCEEDED(hr))
1410 {
1411 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1412 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1413 ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */
1414 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1415
1416 hr = IWICMetadataReader_GetCount(reader, &count);
1417 ok(hr == S_OK, "GetCount error %#x\n", hr);
1418 ok(count == ARRAY_SIZE(animated_gif_comment_1), "unexpected count %u\n", count);
1419
1420 compare_metadata(reader, animated_gif_comment_1, count);
1421
1422 IWICMetadataReader_Release(reader);
1423 }
1424
1425 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader);
1426 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1427
1428 if (SUCCEEDED(hr))
1429 {
1430 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1431 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1432 ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown),
1433 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1434
1435 hr = IWICMetadataReader_GetCount(reader, &count);
1436 ok(hr == S_OK, "GetCount error %#x\n", hr);
1437 ok(count == ARRAY_SIZE(animated_gif_plain_1), "unexpected count %u\n", count);
1438
1439 compare_metadata(reader, animated_gif_plain_1, count);
1440
1441 IWICMetadataReader_Release(reader);
1442 }
1443
1444 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader);
1445 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1446
1447 IWICMetadataBlockReader_Release(blockreader);
1448 }
1449
1450 /* frame metadata block */
1451 hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
1452 ok(hr == S_OK, "GetFrame error %#x\n", hr);
1453
1454 hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader);
1455 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
1456
1457 if (SUCCEEDED(hr))
1458 {
1459 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL);
1460 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1461
1462 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format);
1463 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1464 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1465 "wrong container format %s\n", wine_dbgstr_guid(&format));
1466
1467 hr = IWICMetadataBlockReader_GetCount(blockreader, NULL);
1468 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1469
1470 hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
1471 ok(hr == S_OK, "GetCount error %#x\n", hr);
1472 ok(count == 4, "expected 4, got %u\n", count);
1473
1474 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
1475 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1476
1477 if (SUCCEEDED(hr))
1478 {
1479 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1480 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1481 ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */
1482 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1483
1484 hr = IWICMetadataReader_GetCount(reader, &count);
1485 ok(hr == S_OK, "GetCount error %#x\n", hr);
1486 ok(count == ARRAY_SIZE(animated_gif_IMD), "unexpected count %u\n", count);
1487
1488 compare_metadata(reader, animated_gif_IMD, count);
1489
1490 IWICMetadataReader_Release(reader);
1491 }
1492
1493 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
1494 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1495
1496 if (SUCCEEDED(hr))
1497 {
1498 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1499 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1500 ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */
1501 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1502
1503 hr = IWICMetadataReader_GetCount(reader, &count);
1504 ok(hr == S_OK, "GetCount error %#x\n", hr);
1505 ok(count == ARRAY_SIZE(animated_gif_comment_2), "unexpected count %u\n", count);
1506
1507 if (count == 1)
1508 compare_metadata(reader, animated_gif_comment_2, count);
1509
1510 IWICMetadataReader_Release(reader);
1511 }
1512
1513 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader);
1514 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1515
1516 if (SUCCEEDED(hr))
1517 {
1518 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1519 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1520 ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown),
1521 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1522
1523 hr = IWICMetadataReader_GetCount(reader, &count);
1524 ok(hr == S_OK, "GetCount error %#x\n", hr);
1525 ok(count == ARRAY_SIZE(animated_gif_plain_2), "unexpected count %u\n", count);
1526
1527 compare_metadata(reader, animated_gif_plain_2, count);
1528
1529 IWICMetadataReader_Release(reader);
1530 }
1531
1532 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader);
1533 ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
1534
1535 if (SUCCEEDED(hr))
1536 {
1537 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1538 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1539 ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), /* Graphic Control Extension */
1540 "wrong metadata format %s\n", wine_dbgstr_guid(&format));
1541
1542 hr = IWICMetadataReader_GetCount(reader, &count);
1543 ok(hr == S_OK, "GetCount error %#x\n", hr);
1544 ok(count == ARRAY_SIZE(animated_gif_GCE), "unexpected count %u\n", count);
1545
1546 compare_metadata(reader, animated_gif_GCE, count);
1547
1548 IWICMetadataReader_Release(reader);
1549 }
1550
1551 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader);
1552 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1553
1554 IWICMetadataBlockReader_Release(blockreader);
1555 }
1556
1557 hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader);
1558 ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */,
1559 "GetMetadataQueryReader error %#x\n", hr);
1560 if (SUCCEEDED(hr))
1561 {
1562 static const struct
1563 {
1564 const char *query;
1565 HRESULT hr;
1566 UINT vt;
1567 } decoder_data[] =
1568 {
1569 { "/logscrdesc/Signature", S_OK, VT_UI1 | VT_VECTOR },
1570 { "/[0]logscrdesc/Signature", S_OK, VT_UI1 | VT_VECTOR },
1571 { "/logscrdesc/\\Signature", S_OK, VT_UI1 | VT_VECTOR },
1572 { "/Logscrdesc/\\signature", S_OK, VT_UI1 | VT_VECTOR },
1573 { "/logscrdesc/{str=signature}", S_OK, VT_UI1 | VT_VECTOR },
1574 { "/[0]logscrdesc/{str=signature}", S_OK, VT_UI1 | VT_VECTOR },
1575 { "/logscrdesc/{wstr=signature}", S_OK, VT_UI1 | VT_VECTOR },
1576 { "/[0]logscrdesc/{wstr=signature}", S_OK, VT_UI1 | VT_VECTOR },
1577 { "/appext/Application", S_OK, VT_UI1 | VT_VECTOR },
1578 { "/appext/{STR=APPlication}", S_OK, VT_UI1 | VT_VECTOR },
1579 { "/appext/{WSTR=APPlication}", S_OK, VT_UI1 | VT_VECTOR },
1580 { "/LogSCRdesC", S_OK, VT_UNKNOWN },
1581 { "/[0]LogSCRdesC", S_OK, VT_UNKNOWN },
1582 { "/appEXT", S_OK, VT_UNKNOWN },
1583 { "/[0]appEXT", S_OK, VT_UNKNOWN },
1584 { "grctlext", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 },
1585 { "/imgdesc", WINCODEC_ERR_PROPERTYNOTFOUND, 0 },
1586 };
1587 static const WCHAR rootW[] = {'/',0};
1588 WCHAR name[256];
1589 UINT len, i, j;
1590 PROPVARIANT value;
1591 IWICMetadataQueryReader *meta_reader;
1592
1593 hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format);
1594 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1595 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1596 "wrong container format %s\n", wine_dbgstr_guid(&format));
1597
1598 name[0] = 0;
1599 len = 0xdeadbeef;
1600 hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len);
1601 ok(hr == S_OK, "GetLocation error %#x\n", hr);
1602 ok(len == 2, "expected 2, got %u\n", len);
1603 ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name));
1604
1605 for (i = 0; i < ARRAY_SIZE(decoder_data); i++)
1606 {
1607 WCHAR queryW[256];
1608
1609 if (winetest_debug > 1)
1610 trace("query: %s\n", decoder_data[i].query);
1611 MultiByteToWideChar(CP_ACP, 0, decoder_data[i].query, -1, queryW, 256);
1612
1613 hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, NULL);
1614 ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr);
1615
1616 PropVariantInit(&value);
1617 hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value);
1618 ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr);
1619 ok(value.vt == decoder_data[i].vt, "expected %#x, got %#x\n", decoder_data[i].vt, value.vt);
1620 if (hr == S_OK && value.vt == VT_UNKNOWN)
1621 {
1622 hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader);
1623 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1624
1625 name[0] = 0;
1626 len = 0xdeadbeef;
1627 hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len);
1628 ok(hr == S_OK, "GetLocation error %#x\n", hr);
1629 ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len);
1630 ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name));
1631
1632 for (j = 0; j < ARRAY_SIZE(decoder_data); j++)
1633 {
1634 MultiByteToWideChar(CP_ACP, 0, decoder_data[j].query, -1, queryW, 256);
1635
1636 if (CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, queryW, len-1, name, len-1) == CSTR_EQUAL && decoder_data[j].query[len - 1] != 0)
1637 {
1638 if (winetest_debug > 1)
1639 trace("query: %s\n", wine_dbgstr_w(queryW + len - 1));
1641 hr = IWICMetadataQueryReader_GetMetadataByName(meta_reader, queryW + len - 1, &value);
1642 ok(hr == decoder_data[j].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW + len - 1), hr, decoder_data[j].hr);
1643 ok(value.vt == decoder_data[j].vt, "expected %#x, got %#x\n", decoder_data[j].vt, value.vt);
1644 }
1645 }
1646
1647 IWICMetadataQueryReader_Release(meta_reader);
1648 }
1649
1651 }
1652
1653 IWICMetadataQueryReader_Release(queryreader);
1654 }
1655
1656 hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader);
1657 ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */,
1658 "GetMetadataQueryReader error %#x\n", hr);
1659 if (SUCCEEDED(hr))
1660 {
1661 static const struct
1662 {
1663 const char *query;
1664 HRESULT hr;
1665 UINT vt;
1666 } frame_data[] =
1667 {
1668 { "/grctlext/Delay", S_OK, VT_UI2 },
1669 { "/[0]grctlext/Delay", S_OK, VT_UI2 },
1670 { "/grctlext/{str=delay}", S_OK, VT_UI2 },
1671 { "/[0]grctlext/{str=delay}", S_OK, VT_UI2 },
1672 { "/grctlext/{wstr=delay}", S_OK, VT_UI2 },
1673 { "/[0]grctlext/{wstr=delay}", S_OK, VT_UI2 },
1674 { "/imgdesc/InterlaceFlag", S_OK, VT_BOOL },
1675 { "/imgdesc/{STR=interlaceFLAG}", S_OK, VT_BOOL },
1676 { "/imgdesc/{WSTR=interlaceFLAG}", S_OK, VT_BOOL },
1677 { "/grctlext", S_OK, VT_UNKNOWN },
1678 { "/[0]grctlext", S_OK, VT_UNKNOWN },
1679 { "/imgdesc", S_OK, VT_UNKNOWN },
1680 { "/[0]imgdesc", S_OK, VT_UNKNOWN },
1681 { "/LogSCRdesC", WINCODEC_ERR_PROPERTYNOTFOUND, 0 },
1682 { "/appEXT", WINCODEC_ERR_PROPERTYNOTFOUND, 0 },
1683 { "/grctlext/{\\str=delay}", WINCODEC_ERR_WRONGSTATE, 0 },
1684 { "/grctlext/{str=\\delay}", S_OK, VT_UI2 },
1685 { "grctlext/Delay", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 },
1686 };
1687 static const WCHAR rootW[] = {'/',0};
1688 static const WCHAR guidW[] = {'/','{','g','u','i','d','=','\\',0};
1689 static const WCHAR imgdescW[] = {'i','m','g','d','e','s','c',0};
1690 static const WCHAR ImgDescW[] = {'I','m','g','D','e','s','c',0};
1691 WCHAR name[256], queryW[256];
1692 UINT len, i;
1693 PROPVARIANT value;
1694 IWICMetadataQueryReader *meta_reader;
1695
1696 hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format);
1697 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
1698 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
1699 "wrong container format %s\n", wine_dbgstr_guid(&format));
1700
1701 name[0] = 0;
1702 len = 0xdeadbeef;
1703 hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len);
1704 ok(hr == S_OK, "GetLocation error %#x\n", hr);
1705 ok(len == 2, "expected 2, got %u\n", len);
1706 ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name));
1707
1708 for (i = 0; i < ARRAY_SIZE(frame_data); i++)
1709 {
1710 if (winetest_debug > 1)
1711 trace("query: %s\n", frame_data[i].query);
1712 MultiByteToWideChar(CP_ACP, 0, frame_data[i].query, -1, queryW, 256);
1713 PropVariantInit(&value);
1714 hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value);
1715 ok(hr == frame_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, frame_data[i].hr);
1716 ok(value.vt == frame_data[i].vt, "expected %#x, got %#x\n", frame_data[i].vt, value.vt);
1717 if (hr == S_OK && value.vt == VT_UNKNOWN)
1718 {
1719 hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader);
1720 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1721
1722 name[0] = 0;
1723 len = 0xdeadbeef;
1724 hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len);
1725 ok(hr == S_OK, "GetLocation error %#x\n", hr);
1726 ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len);
1727 ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name));
1728
1729 IWICMetadataQueryReader_Release(meta_reader);
1730 }
1731
1733 }
1734
1735 name[0] = 0;
1736 len = 0xdeadbeef;
1737 hr = WICMapGuidToShortName(&GUID_MetadataFormatIMD, 256, name, &len);
1738 ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr);
1739 ok(!lstrcmpW(name, imgdescW), "wrong short name %s\n", wine_dbgstr_w(name));
1740
1741 format = GUID_NULL;
1743 ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr);
1744 ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format));
1745
1746 format = GUID_NULL;
1747 hr = WICMapShortNameToGuid(ImgDescW, &format);
1748 ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr);
1749 ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format));
1750
1751 lstrcpyW(queryW, guidW);
1752 StringFromGUID2(&GUID_MetadataFormatIMD, queryW + lstrlenW(queryW) - 1, 39);
1753 memcpy(queryW, guidW, sizeof(guidW) - 2);
1754 if (winetest_debug > 1)
1755 trace("query: %s\n", wine_dbgstr_w(queryW));
1756 PropVariantInit(&value);
1757 hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value);
1758 ok(hr == S_OK, "GetMetadataByName(%s) error %#x\n", wine_dbgstr_w(queryW), hr);
1759 ok(value.vt == VT_UNKNOWN, "expected VT_UNKNOWN, got %#x\n", value.vt);
1761
1762 IWICMetadataQueryReader_Release(queryreader);
1763 }
1764
1765 IWICBitmapFrameDecode_Release(frame);
1766 IWICBitmapDecoder_Release(decoder);
1767}
static const WCHAR rootW[]
Definition: chain.c:69
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4013
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
GLenum GLsizei len
Definition: glext.h:6722
#define GUID_NULL
Definition: ks.h:106
HRESULT WINAPI WICMapGuidToShortName(REFGUID guid, UINT len, WCHAR *name, UINT *ret_len)
static const WCHAR imgdescW[]
HRESULT WINAPI WICMapShortNameToGuid(PCWSTR name, GUID *guid)
static const char gifimage[35]
Definition: metadata.c:175
static const char animatedgif[]
Definition: metadata.c:182
#define LOCALE_NEUTRAL
int winetest_debug
@ WICDecodeMetadataCacheOnLoad
Definition: wincodec.idl:29
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3281
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
Definition: winerror.h:3308
#define WINCODEC_ERR_PROPERTYNOTSUPPORTED
Definition: winerror.h:3288
#define WINCODEC_ERR_PROPERTYNOTFOUND
Definition: winerror.h:3287
#define NORM_IGNORECASE
Definition: winnls.h:176
#define CSTR_EQUAL
Definition: winnls.h:456

Referenced by START_TEST().

◆ test_metadata_GIF_comment()

static void test_metadata_GIF_comment ( void  )
static

Definition at line 2086 of file metadata.c.

2087{
2088 static const WCHAR GIF_comment_name[] = {'C','o','m','m','e','n','t',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0};
2089 static const char GIF_comment_data[] = { 0x21,0xfe,
2090 /*sub-block*/5,'H','e','l','l','o',
2091 /*sub-block*/1,' ',
2092 /*sub-block*/6,'W','o','r','l','d','!',
2093 /*terminator*/0 };
2094 static const struct test_data td[1] =
2095 {
2096 { VT_LPSTR, 0, 12, { 0 }, "Hello World!", { 'T','e','x','t','E','n','t','r','y',0 } }
2097 };
2098 WCHAR text_entryW[] = { 'T','E','X','T','E','N','T','R','Y',0 };
2099 HRESULT hr;
2100 IStream *stream;
2101 IWICPersistStream *persist;
2104 WCHAR name[64];
2105 UINT count, dummy;
2106 GUID format;
2107 CLSID clsid;
2108 PROPVARIANT id, value;
2109
2110 hr = CoCreateInstance(&CLSID_WICGifCommentMetadataReader, NULL, CLSCTX_INPROC_SERVER,
2111 &IID_IWICMetadataReader, (void **)&reader);
2112 ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
2113 "CoCreateInstance error %#x\n", hr);
2114
2115 stream = create_stream(GIF_comment_data, sizeof(GIF_comment_data));
2116
2117 if (SUCCEEDED(hr))
2118 {
2119 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
2120 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
2121
2122 hr = IWICPersistStream_Load(persist, stream);
2123 ok(hr == S_OK, "Load error %#x\n", hr);
2124
2125 IWICPersistStream_Release(persist);
2126 }
2127
2128 if (SUCCEEDED(hr))
2129 {
2130 hr = IWICMetadataReader_GetCount(reader, &count);
2131 ok(hr == S_OK, "GetCount error %#x\n", hr);
2132 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
2133
2135
2136 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
2137 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
2138 ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), "wrong format %s\n", wine_dbgstr_guid(&format));
2139
2140 PropVariantInit(&value);
2141 id.vt = VT_LPWSTR;
2142 U(id).pwszVal = text_entryW;
2143
2144 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
2145 ok(hr == S_OK, "GetValue error %#x\n", hr);
2146 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
2147 ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal);
2149
2150 hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info);
2151 ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr);
2152
2153 hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid);
2154 ok(hr == S_OK, "GetCLSID error %#x\n", hr);
2155 ok(IsEqualGUID(&clsid, &CLSID_WICGifCommentMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid));
2156
2157 hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy);
2158 ok(hr == S_OK, "GetFriendlyName error %#x\n", hr);
2159 ok(lstrcmpW(name, GIF_comment_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name));
2160
2161 IWICMetadataHandlerInfo_Release(info);
2162 IWICMetadataReader_Release(reader);
2163 }
2164
2165 IStream_Release(stream);
2166}

Referenced by START_TEST().

◆ test_metadata_IFD()

static void test_metadata_IFD ( void  )
static

Definition at line 758 of file metadata.c.

759{
760 static const struct test_data td[28] =
761 {
762 { VT_UI2, 0xfe, 0, { 1 } },
763 { VT_UI4, 0x100, 0, { 222 } },
764 { VT_UI4, 0x101, 0, { 333 } },
765 { VT_UI2, 0x102, 0, { 24 } },
766 { VT_UI4, 0x103, 0, { 32773 } },
767 { VT_UI8, 0x11a, 0, { ((LONGLONG)3 << 32) | 900 } },
768 { VT_UI1, 0xf001, 0, { 0x44 } },
769 { VT_UI1|VT_VECTOR, 0xf002, 4, { 0x44, 0x33, 0x22, 0x11 } },
770 { VT_I1, 0xf003, 0, { 0x44 } },
771 { VT_I2, 0xf004, 0, { 0x3344 } },
772 { VT_I2|VT_VECTOR, 0xf005, 2, { 0x3344, 0x1122 } },
773 { VT_I4, 0xf006, 0, { 0x11223344 } },
774 { VT_R4, 0xf007, 0, { 0x11223344 } },
775 { VT_R8, 0xf008, 0, { ((LONGLONG)0x41d26580 << 32) | 0xb486522c } },
776 { VT_I8, 0xf009, 0, { ((LONGLONG)0x5a6b7c8d << 32) | 0x1a2b3c4d } },
777 { VT_UI1|VT_VECTOR, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
778 { VT_I2|VT_VECTOR, 0xf00b, 4, { 0x0101, 0x0202, 0x0303, 0x0404 } },
779 { VT_I4|VT_VECTOR, 0xf00c, 2, { 0x11223344, 0x55667788 } },
780 { VT_R4|VT_VECTOR, 0xf00d, 2, { 0x449a522b, 0x4608f5ba } },
781 { VT_LPSTR, 0xf00e, 12, { 0 }, "Hello World!" },
782 { VT_LPSTR, 0xf00f, 4, { 0 }, "abcd" },
783 { VT_BLOB, 0xf010, 13, { 0 }, "Hello World!" },
784 { VT_BLOB, 0xf011, 4, { 0 }, "abcd" },
785 { VT_UI1, 0xf012, 0, { 0x44 } },
786 { VT_UI2, 0xf013, 0, { 0x3344 } },
787 { VT_UI4, 0xf014, 0, { 0x11223344 } },
788 { VT_R4, 0xf015, 0, { 0x11223344 } },
789 { VT_I8|VT_VECTOR, 0xf016, 3,
790 { ((LONGLONG)0x05060708 << 32) | 0x01020304,
791 ((LONGLONG)0x50607080 << 32) | 0x10203040,
792 ((LONGLONG)0x55667788 << 32) | 0x11223344 } },
793 };
794 HRESULT hr;
796 IWICMetadataBlockReader *blockreader;
797 PROPVARIANT schema, id, value;
798 ULONG count;
799 GUID format;
800 char *IFD_data_swapped;
801#ifdef WORDS_BIGENDIAN
802 DWORD persist_options = WICPersistOptionBigEndian;
803#else
804 DWORD persist_options = WICPersistOptionLittleEndian;
805#endif
806
807 hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER,
808 &IID_IWICMetadataReader, (void**)&reader);
809 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
810
811 hr = IWICMetadataReader_GetCount(reader, NULL);
812 ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr);
813
814 hr = IWICMetadataReader_GetCount(reader, &count);
815 ok(hr == S_OK, "GetCount error %#x\n", hr);
816 ok(count == 0, "unexpected count %u\n", count);
817
818 load_stream((IUnknown*)reader, (const char *)&IFD_data, sizeof(IFD_data), persist_options);
819
820 hr = IWICMetadataReader_GetCount(reader, &count);
821 ok(hr == S_OK, "GetCount error %#x\n", hr);
822 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
823
825
826 /* test IFD data with different endianness */
827 if (persist_options == WICPersistOptionLittleEndian)
828 persist_options = WICPersistOptionBigEndian;
829 else
830 persist_options = WICPersistOptionLittleEndian;
831
832 IFD_data_swapped = HeapAlloc(GetProcessHeap(), 0, sizeof(IFD_data));
833 memcpy(IFD_data_swapped, &IFD_data, sizeof(IFD_data));
834 byte_swap_ifd_data(IFD_data_swapped);
835 load_stream((IUnknown *)reader, IFD_data_swapped, sizeof(IFD_data), persist_options);
836 hr = IWICMetadataReader_GetCount(reader, &count);
837 ok(hr == S_OK, "GetCount error %#x\n", hr);
838 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
840 HeapFree(GetProcessHeap(), 0, IFD_data_swapped);
841
842 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
843 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
844 ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "unexpected format %s\n", wine_dbgstr_guid(&format));
845
846 hr = IWICMetadataReader_GetMetadataFormat(reader, NULL);
847 ok(hr == E_INVALIDARG, "GetMetadataFormat should fail\n");
848
849 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL);
850 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
851
852 PropVariantInit(&schema);
853 PropVariantInit(&id);
854 PropVariantInit(&value);
855
856 hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, NULL, NULL, NULL);
857 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
858
859 hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL);
860 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
861 ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt);
862
863 hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, &schema, NULL, NULL);
864 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
865 ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt);
866
867 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL);
868 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
869 ok(id.vt == VT_UI2, "unexpected vt: %u\n", id.vt);
870 ok(U(id).uiVal == 0xfe, "unexpected id: %#x\n", U(id).uiVal);
871 PropVariantClear(&id);
872
873 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value);
874 ok(hr == S_OK, "GetValueByIndex error %#x\n", hr);
875 ok(value.vt == VT_UI2, "unexpected vt: %u\n", value.vt);
876 ok(U(value).uiVal == 1, "unexpected id: %#x\n", U(value).uiVal);
878
879 hr = IWICMetadataReader_GetValueByIndex(reader, count, &schema, NULL, NULL);
880 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
881
882 PropVariantInit(&schema);
883 PropVariantInit(&id);
884 PropVariantInit(&value);
885
886 hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value);
887 ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr);
888
889 hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL);
890 ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr);
891
892 hr = IWICMetadataReader_GetValue(reader, &schema, NULL, NULL);
893 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
894
895 hr = IWICMetadataReader_GetValue(reader, &schema, &id, NULL);
896 ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr);
897
898 hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value);
899 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
900
901 id.vt = VT_UI2;
902 U(id).uiVal = 0xf00e;
903 hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL);
904 ok(hr == S_OK, "GetValue error %#x\n", hr);
905
906 /* schema is ignored by Ifd metadata reader */
907 schema.vt = VT_UI4;
908 U(schema).ulVal = 0xdeadbeef;
909 hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value);
910 ok(hr == S_OK, "GetValue error %#x\n", hr);
911 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
912 ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal);
914
915 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
916 ok(hr == S_OK, "GetValue error %#x\n", hr);
917 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
918 ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal);
920
921 hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader);
922 ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr);
923
924 if (SUCCEEDED(hr))
925 IWICMetadataBlockReader_Release(blockreader);
926
927 IWICMetadataReader_Release(reader);
928}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned long DWORD
Definition: ntddk_ex.h:95
static const struct ifd_data IFD_data
static void byte_swap_ifd_data(char *data)
Definition: metadata.c:553
@ WICPersistOptionBigEndian
Definition: wincodecsdk.idl:25
@ WICPersistOptionLittleEndian
Definition: wincodecsdk.idl:24

Referenced by START_TEST().

◆ test_metadata_IMD()

static void test_metadata_IMD ( void  )
static

Definition at line 1848 of file metadata.c.

1849{
1850 static const WCHAR IMD_name[] = {'I','m','a','g','e',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0};
1851 static const char IMD_data[] = "hello world!\x1\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf";
1852 static const struct test_data td[8] =
1853 {
1854 { VT_UI2, 0, 0, { 0x201 }, NULL, { 'L','e','f','t',0 } },
1855 { VT_UI2, 0, 0, { 0x403 }, NULL, { 'T','o','p',0 } },
1856 { VT_UI2, 0, 0, { 0x605 }, NULL, { 'W','i','d','t','h',0 } },
1857 { VT_UI2, 0, 0, { 0x807 }, NULL, { 'H','e','i','g','h','t',0 } },
1858 { VT_BOOL, 0, 0, { 1 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1859 { VT_BOOL, 0, 0, { 1 }, NULL, { 'I','n','t','e','r','l','a','c','e','F','l','a','g',0 } },
1860 { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1861 { VT_UI1, 0, 0, { 5 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } }
1862 };
1864 HRESULT hr;
1865 IStream *stream;
1866 IWICPersistStream *persist;
1869 WCHAR name[64];
1870 UINT count, dummy;
1871 GUID format;
1872 CLSID id;
1873
1874 hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, NULL, CLSCTX_INPROC_SERVER,
1875 &IID_IWICMetadataReader, (void **)&reader);
1876 ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
1877 "CoCreateInstance error %#x\n", hr);
1878
1879 stream = create_stream(IMD_data, sizeof(IMD_data));
1880
1881 if (SUCCEEDED(hr))
1882 {
1883 pos.QuadPart = 12;
1884 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1885 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1886
1887 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
1888 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1889
1890 hr = IWICPersistStream_Load(persist, stream);
1891 ok(hr == S_OK, "Load error %#x\n", hr);
1892
1893 IWICPersistStream_Release(persist);
1894 }
1895
1896 if (SUCCEEDED(hr))
1897 {
1898 hr = IWICMetadataReader_GetCount(reader, &count);
1899 ok(hr == S_OK, "GetCount error %#x\n", hr);
1900 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
1901
1903
1904 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1905 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
1906 ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong format %s\n", wine_dbgstr_guid(&format));
1907
1908 hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info);
1909 ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr);
1910
1911 hr = IWICMetadataHandlerInfo_GetCLSID(info, &id);
1912 ok(hr == S_OK, "GetCLSID error %#x\n", hr);
1913 ok(IsEqualGUID(&id, &CLSID_WICIMDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id));
1914
1915 hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy);
1916 ok(hr == S_OK, "GetFriendlyName error %#x\n", hr);
1917 ok(lstrcmpW(name, IMD_name) == 0, "wrong IMD reader name %s\n", wine_dbgstr_w(name));
1918
1919 IWICMetadataHandlerInfo_Release(info);
1920 IWICMetadataReader_Release(reader);
1921 }
1922
1923 IStream_Release(stream);
1924}

Referenced by START_TEST().

◆ test_metadata_LSD()

static void test_metadata_LSD ( void  )
static

Definition at line 1769 of file metadata.c.

1770{
1771 static const WCHAR LSD_name[] = {'L','o','g','i','c','a','l',' ','S','c','r','e','e','n',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0};
1772 static const char LSD_data[] = "hello world!\x1\x2\x3\x4\xab\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf";
1773 static const struct test_data td[9] =
1774 {
1775 { VT_UI1|VT_VECTOR, 0, 6, {'w','o','r','l','d','!'}, NULL, { 'S','i','g','n','a','t','u','r','e',0 } },
1776 { VT_UI2, 0, 0, { 0x201 }, NULL, { 'W','i','d','t','h',0 } },
1777 { VT_UI2, 0, 0, { 0x403 }, NULL, { 'H','e','i','g','h','t',0 } },
1778 { VT_BOOL, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } },
1779 { VT_UI1, 0, 0, { 2 }, NULL, { 'C','o','l','o','r','R','e','s','o','l','u','t','i','o','n',0 } },
1780 { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } },
1781 { VT_UI1, 0, 0, { 3 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } },
1782 { VT_UI1, 0, 0, { 6 }, NULL, { 'B','a','c','k','g','r','o','u','n','d','C','o','l','o','r','I','n','d','e','x',0 } },
1783 { VT_UI1, 0, 0, { 7 }, NULL, { 'P','i','x','e','l','A','s','p','e','c','t','R','a','t','i','o',0 } }
1784 };
1786 HRESULT hr;
1787 IStream *stream;
1788 IWICPersistStream *persist;
1791 WCHAR name[64];
1792 UINT count, dummy;
1793 GUID format;
1794 CLSID id;
1795
1796 hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, NULL, CLSCTX_INPROC_SERVER,
1797 &IID_IWICMetadataReader, (void **)&reader);
1798 ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
1799 "CoCreateInstance error %#x\n", hr);
1800
1801 stream = create_stream(LSD_data, sizeof(LSD_data));
1802
1803 if (SUCCEEDED(hr))
1804 {
1805 pos.QuadPart = 6;
1806 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1807 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1808
1809 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
1810 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1811
1812 hr = IWICPersistStream_Load(persist, stream);
1813 ok(hr == S_OK, "Load error %#x\n", hr);
1814
1815 IWICPersistStream_Release(persist);
1816 }
1817
1818 if (SUCCEEDED(hr))
1819 {
1820 hr = IWICMetadataReader_GetCount(reader, &count);
1821 ok(hr == S_OK, "GetCount error %#x\n", hr);
1822 ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count);
1823
1825
1826 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
1827 ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr);
1828 ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), "wrong format %s\n", wine_dbgstr_guid(&format));
1829
1830 hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info);
1831 ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr);
1832
1833 hr = IWICMetadataHandlerInfo_GetCLSID(info, &id);
1834 ok(hr == S_OK, "GetCLSID error %#x\n", hr);
1835 ok(IsEqualGUID(&id, &CLSID_WICLSDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id));
1836
1837 hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy);
1838 ok(hr == S_OK, "GetFriendlyName error %#x\n", hr);
1839 ok(lstrcmpW(name, LSD_name) == 0, "wrong LSD reader name %s\n", wine_dbgstr_w(name));
1840
1841 IWICMetadataHandlerInfo_Release(info);
1842 IWICMetadataReader_Release(reader);
1843 }
1844
1845 IStream_Release(stream);
1846}

Referenced by START_TEST().

◆ test_metadata_png()

static void test_metadata_png ( void  )
static

Definition at line 1029 of file metadata.c.

1030{
1031 static const struct test_data td[6] =
1032 {
1033 { VT_UI2, 0, 0, { 2005 }, NULL, { 'Y','e','a','r',0 } },
1034 { VT_UI1, 0, 0, { 6 }, NULL, { 'M','o','n','t','h',0 } },
1035 { VT_UI1, 0, 0, { 3 }, NULL, { 'D','a','y',0 } },
1036 { VT_UI1, 0, 0, { 15 }, NULL, { 'H','o','u','r',0 } },
1037 { VT_UI1, 0, 0, { 7 }, NULL, { 'M','i','n','u','t','e',0 } },
1038 { VT_UI1, 0, 0, { 45 }, NULL, { 'S','e','c','o','n','d',0 } }
1039 };
1040 IStream *stream;
1041 IWICBitmapDecoder *decoder;
1042 IWICBitmapFrameDecode *frame;
1043 IWICMetadataBlockReader *blockreader;
1045 IWICMetadataQueryReader *queryreader;
1047 GUID containerformat;
1048 HRESULT hr;
1049 UINT count=0xdeadbeef;
1050
1051 hr = CoCreateInstance(&CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER,
1052 &IID_IWICBitmapDecoder, (void**)&decoder);
1053 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1054
1055 if (FAILED(hr)) return;
1056
1058
1059 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
1060 ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
1061
1062 hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void**)&blockreader);
1063 ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr);
1064
1065 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
1066 ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr);
1067
1068 hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void**)&blockreader);
1069 ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
1070
1071 if (SUCCEEDED(hr))
1072 {
1073 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL);
1074 ok(hr == E_INVALIDARG, "GetContainerFormat failed, hr=%x\n", hr);
1075
1076 hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &containerformat);
1077 ok(hr == S_OK, "GetContainerFormat failed, hr=%x\n", hr);
1078 ok(IsEqualGUID(&containerformat, &GUID_ContainerFormatPng), "unexpected container format\n");
1079
1080 hr = IWICMetadataBlockReader_GetCount(blockreader, NULL);
1081 ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr);
1082
1083 hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
1084 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
1085 ok(count == 1, "unexpected count %d\n", count);
1086
1087 if (0)
1088 {
1089 /* Crashes on Windows XP */
1090 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, NULL);
1091 ok(hr == E_INVALIDARG, "GetReaderByIndex failed, hr=%x\n", hr);
1092 }
1093
1094 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
1095 ok(hr == S_OK, "GetReaderByIndex failed, hr=%x\n", hr);
1096
1097 if (SUCCEEDED(hr))
1098 {
1099 hr = IWICMetadataReader_GetMetadataFormat(reader, &containerformat);
1100 ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr);
1101 todo_wine ok(IsEqualGUID(&containerformat, &GUID_MetadataFormatChunktIME) ||
1102 broken(IsEqualGUID(&containerformat, &GUID_MetadataFormatUnknown)) /* Windows XP */,
1103 "unexpected container format\n");
1104
1105 hr = IWICMetadataReader_GetCount(reader, &count);
1106 ok(hr == S_OK, "GetCount error %#x\n", hr);
1107 todo_wine ok(count == 6 || broken(count == 1) /* XP */, "expected 6, got %u\n", count);
1108 if (count == 6)
1110
1111 IWICMetadataReader_Release(reader);
1112 }
1113
1114 hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
1115 todo_wine ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "GetReaderByIndex failed, hr=%x\n", hr);
1116
1117 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1118 &IID_IWICComponentFactory, (void**)&factory);
1119 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1120
1121 hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, NULL, &queryreader);
1122 ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr);
1123
1124 hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, NULL);
1125 ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr);
1126
1127 hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, &queryreader);
1128 ok(hr == S_OK, "CreateQueryReaderFromBlockReader failed: %08x\n", hr);
1129
1130 IWICMetadataQueryReader_Release(queryreader);
1131
1132 IWICComponentFactory_Release(factory);
1133
1134 IWICMetadataBlockReader_Release(blockreader);
1135 }
1136
1137 hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader);
1138 ok(hr == S_OK, "GetMetadataQueryReader failed: %08x\n", hr);
1139
1140 if (SUCCEEDED(hr))
1141 {
1142 IWICMetadataQueryReader_Release(queryreader);
1143 }
1144
1145 IWICBitmapFrameDecode_Release(frame);
1146
1147 IWICBitmapDecoder_Release(decoder);
1148
1149 IStream_Release(stream);
1150}
static const char pngimage[285]
Definition: metadata.c:164
#define WINCODEC_ERR_VALUEOUTOFRANGE
Definition: winerror.h:3282

Referenced by START_TEST().

◆ test_metadata_tEXt()

static void test_metadata_tEXt ( void  )
static

Definition at line 314 of file metadata.c.

315{
316 HRESULT hr;
318 IWICEnumMetadataItem *enumerator;
319 PROPVARIANT schema, id, value;
320 ULONG items_returned, count;
321 GUID format;
322
323 PropVariantInit(&schema);
324 PropVariantInit(&id);
325 PropVariantInit(&value);
326
327 hr = CoCreateInstance(&CLSID_WICPngTextMetadataReader, NULL, CLSCTX_INPROC_SERVER,
328 &IID_IWICMetadataReader, (void**)&reader);
329 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
330 if (FAILED(hr)) return;
331
332 hr = IWICMetadataReader_GetCount(reader, NULL);
333 ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr);
334
335 hr = IWICMetadataReader_GetCount(reader, &count);
336 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
337 ok(count == 0, "unexpected count %i\n", count);
338
340
341 hr = IWICMetadataReader_GetCount(reader, &count);
342 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
343 ok(count == 1, "unexpected count %i\n", count);
344
345 hr = IWICMetadataReader_GetEnumerator(reader, NULL);
346 ok(hr == E_INVALIDARG, "GetEnumerator failed, hr=%x\n", hr);
347
348 hr = IWICMetadataReader_GetEnumerator(reader, &enumerator);
349 ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr);
350
351 if (SUCCEEDED(hr))
352 {
353 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
354 ok(hr == S_OK, "Next failed, hr=%x\n", hr);
355 ok(items_returned == 1, "unexpected item count %i\n", items_returned);
356
357 if (hr == S_OK && items_returned == 1)
358 {
359 ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
360 ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
361 ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal);
362 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt);
363 ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal);
364
366 PropVariantClear(&id);
368 }
369
370 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
371 ok(hr == S_FALSE, "Next failed, hr=%x\n", hr);
372 ok(items_returned == 0, "unexpected item count %i\n", items_returned);
373
374 IWICEnumMetadataItem_Release(enumerator);
375 }
376
377 hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
378 ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
379 ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format));
380
381 hr = IWICMetadataReader_GetMetadataFormat(reader, NULL);
382 ok(hr == E_INVALIDARG, "GetMetadataFormat failed, hr=%x\n", hr);
383
384 id.vt = VT_LPSTR;
385 U(id).pszVal = CoTaskMemAlloc(strlen("winetest") + 1);
386 strcpy(U(id).pszVal, "winetest");
387
388 hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL);
389 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
390
391 hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value);
392 ok(hr == E_INVALIDARG, "GetValue failed, hr=%x\n", hr);
393
394 hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value);
395 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
396 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
397 ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal);
399
400 strcpy(U(id).pszVal, "test");
401
402 hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value);
403 ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "GetValue failed, hr=%x\n", hr);
404
405 PropVariantClear(&id);
406
407 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL);
408 ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr);
409
410 hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL);
411 ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr);
412 ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
413
414 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL);
415 ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr);
416 ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
417 ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal);
418 PropVariantClear(&id);
419
420 hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value);
421 ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr);
422 ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt);
423 ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal);
425
426 hr = IWICMetadataReader_GetValueByIndex(reader, 1, NULL, NULL, NULL);
427 ok(hr == E_INVALIDARG, "GetValueByIndex failed, hr=%x\n", hr);
428
429 IWICMetadataReader_Release(reader);
430}
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426

Referenced by START_TEST().

◆ test_metadata_unknown()

static void test_metadata_unknown ( void  )
static

Definition at line 258 of file metadata.c.

259{
260 HRESULT hr;
262 IWICEnumMetadataItem *enumerator;
263 IWICMetadataBlockReader *blockreader;
264 PROPVARIANT schema, id, value;
265 ULONG items_returned;
266
267 hr = CoCreateInstance(&CLSID_WICUnknownMetadataReader, NULL, CLSCTX_INPROC_SERVER,
268 &IID_IWICMetadataReader, (void**)&reader);
269 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
270 if (FAILED(hr)) return;
271
273
274 hr = IWICMetadataReader_GetEnumerator(reader, &enumerator);
275 ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr);
276
277 if (SUCCEEDED(hr))
278 {
279 PropVariantInit(&schema);
280 PropVariantInit(&id);
281 PropVariantInit(&value);
282
283 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
284 ok(hr == S_OK, "Next failed, hr=%x\n", hr);
285 ok(items_returned == 1, "unexpected item count %i\n", items_returned);
286
287 if (hr == S_OK && items_returned == 1)
288 {
289 ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
290 ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt);
292
294 PropVariantClear(&id);
296 }
297
298 hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
299 ok(hr == S_FALSE, "Next failed, hr=%x\n", hr);
300 ok(items_returned == 0, "unexpected item count %i\n", items_returned);
301
302 IWICEnumMetadataItem_Release(enumerator);
303 }
304
305 hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader);
306 ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr);
307
308 if (SUCCEEDED(hr))
309 IWICMetadataBlockReader_Release(blockreader);
310
311 IWICMetadataReader_Release(reader);
312}
#define expect_blob(propvar, data, length)
Definition: metadata.c:40
static const char metadata_unknown[]
Definition: metadata.c:137

Referenced by START_TEST().

◆ test_queryreader()

static void test_queryreader ( void  )
static

Definition at line 2871 of file metadata.c.

2872{
2873 static const char q1[] = "/ifd/{uchar=1}";
2874 static const char q2[] = "/ifd/xmp:{long=4}";
2875 static const char q3[] = "/ifd/{str=xmp}:{uint=4}";
2876 static const char q4[] = "/xmp/{char=7}";
2877 static const char q5[] = "/[1]xmp/{short=7}";
2878 static const char q6[] = "/[1]ifd/{str=dc}:{uint=7}";
2879 static const char q7[] = "/[1]ifd/{str=http://purl.org/dc/elements/1.1/}:{longlong=7}";
2880 static const char q8[] = "/[1]ifd/{str=http://ns.adobe.com/tiff/1.0/}:{int=10}";
2881 static const char q9[] = "/[2]xmp/xmp:{ulong=4}";
2882 static const char q10[] = "/[2]xmp/{str=xmp}:{ulong=4}";
2883 static const char q11[] = "/xmp";
2884 static const char q12[] = "/ifd/xmp";
2885 static const char q13[] = "/ifd/xmp/tiff";
2886 static const char q14[] = "/[0]ifd/[0]xmp/[0]tiff";
2887 static const char q15[] = "/[*]xmp";
2888
2889 static const char q20[] = "/ifd/\\Rating";
2890 static const char q21[] = "/[0]ifd/Rating";
2891 static const char q22[] = "/[2]xmp/xmp:{str=Rating}";
2892 static const char q23[] = "/[2]xmp/xmp:Rating";
2893
2894 static const char q24[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:Rating";
2895 static const char q25[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:{str=Rating}";
2896 static const char q26[] = "/[1]ifd/{wstr=\\RATING}";
2897 static const char q27[] = "/[1]ifd/{str=R\\ATING}";
2898 static const char q28[] = "/[1]ifd/{str=R\\}ATING}";
2899
2900 static const char q40[] = "[0]/ifd/Rating";
2901 static const char q41[] = "/[+1]ifd/Rating";
2902 static const char q42[] = "/[-1]ifd/Rating";
2903 static const char q43[] = "/ifd/{\\str=Rating}";
2904 static const char q44[] = "/ifd/{badtype=0}";
2905 static const char q45[] = "/ifd/{uint=0x1234}";
2906 static const char q46[] = "/ifd/[0]Rating";
2907 static const char q47[] = "/ifd/[*]Rating";
2908 static const struct
2909 {
2910 BOOL todo;
2911 const struct metadata *data;
2912 const char *query;
2913 HRESULT hr;
2914 UINT vt, value;
2915 const char *str_value;
2916 } test_data[] =
2917 {
2918 { FALSE, &data1, q1, S_OK, 2, 3, NULL },
2919 { FALSE, &data2, q2, S_OK, 5, 6, NULL },
2920 { FALSE, &data2, q3, S_OK, 5, 6, NULL },
2921 { FALSE, &data3, q4, 0xdeadbeef },
2922 { FALSE, &data3, q5, S_OK, 8, 9, NULL },
2923 { FALSE, &data3, q6, 0xdeadbeef },
2924 { FALSE, &data3, q7, S_OK, 8, 9, NULL },
2925 { FALSE, &data3, q8, S_OK, 11, 12, NULL },
2926 { FALSE, &data3, q9, S_OK, 5, 6, NULL },
2927 { FALSE, &data3, q10, 0xdeadbeef },
2928
2929 { FALSE, &data3, q11, S_OK, VT_UNKNOWN, 0, NULL },
2930 { FALSE, &data3, q12, S_OK, VT_UNKNOWN, 0, NULL },
2931 { FALSE, &data3, q13, S_OK, VT_UNKNOWN, 0, NULL },
2932 { FALSE, &data3, q14, S_OK, VT_UNKNOWN, 0, NULL },
2933 { TRUE, &data3, q15, S_OK, VT_LPSTR, 0, the_worst },
2934
2935 { FALSE, &data3, q20, S_OK, VT_LPSTR, 0, the_worst },
2936 { FALSE, &data3, q21, S_OK, VT_LPSTR, 0, the_worst },
2937 { FALSE, &data3, q22, S_OK, VT_LPSTR, 0, the_best },
2938 { FALSE, &data3, q23, S_OK, VT_LPSTR, 0, the_worst },
2939 { FALSE, &data3, q24, S_OK, VT_LPSTR, 0, the_worst },
2940 { FALSE, &data3, q25, S_OK, VT_LPSTR, 0, the_best },
2941 { FALSE, &data3, q26, S_OK, VT_LPSTR, 0, the_worst },
2942 { FALSE, &data3, q27, S_OK, VT_LPSTR, 0, the_best },
2943 { FALSE, &data3, q28, S_OK, VT_LPSTR, 0, the_best },
2944
2950 { TRUE, &data1, q45, DISP_E_TYPEMISMATCH },
2951 { TRUE, &data1, q46, E_INVALIDARG },
2953 };
2954 WCHAR queryW[256];
2955 HRESULT hr;
2958 GUID format;
2959 PROPVARIANT value;
2960 UINT i;
2961
2962 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
2963 &IID_IWICComponentFactory, (void **)&factory);
2964 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
2965
2966 hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &mdbr, &reader);
2967 ok(hr == S_OK, "CreateQueryReaderFromBlockReader error %#x\n", hr);
2968
2969 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2970 {
2972
2973 hr = IWICMetadataQueryReader_GetContainerFormat(reader, &format);
2974 ok(hr == S_OK, "%u: GetContainerFormat error %#x\n", i, hr);
2975 ok(IsEqualGUID(&format, test_data[i].data->container_format), "%u: expected %s, got %s\n",
2976 i, wine_dbgstr_guid(test_data[i].data->container_format), wine_dbgstr_guid(&format));
2977