0

Im trying to create a WIC codec in c. As far as i am concerned, the functions that the different interfaces implement, are recognized and called by them having a specific name.

In this case i am trying to implement the function GetPixelFormat from the IWICBitmapSource interface. This i am trying to do by initializing the function in a header, then defining the body in a source file, and implementing this into an interface with the DECLARE_INTERFACE_ macro.

The problem being that the GetPixelFormat function from the BitmapSource interface shares it's name with the function GetPixelFormat from the wingdi.h file, which is an include in wincodec.h, which is an include i need to create the function in the first place.

So to sum up my question:

Do the functions to be included in the codec interfaces require the same name as the names of the functions in the original WIC interfaces, e.g. does my GetPixelFormat function need to have this name to be recognized as the WIC function GetPixelFormat?

and

if yes : How do i implement this in a way that wont be disturbed by the original implementation?

if no : How do i implement the function into an interface in such a way that WIC will recognize the function as being the GetPixelFormat function?

Example of implementation in headerfile:

#undef INTERFACE
#define INTERFACE MgfFrameDecoder
DECLARE_INTERFACE_(INTERFACE, IUnknown) {

    BEGIN_INTERFACE

    STDMETHOD(QueryInterface)  (THIS_ REFIID riid, void **ppv) PURE;
    STDMETHOD_(ULONG, AddRef)   (THIS) PURE;
    STDMETHOD_(ULONG, Release)  (THIS) PURE;
    STDMETHOD(CopyPalette) (THIS_ IWICPalette* pIPalette) PURE;
    STDMETHOD(CopyPixels) (THIS_ const WICRect* prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) PURE;
    STDMETHOD(GetPixelFormat) (THIS_ WICPixelFormatGUID* pPixelFormat) PURE;
    STDMETHOD(GetResolution) (THIS_ double* pDpiX, double* pDpiY) PURE;
    STDMETHOD(GetSize) (THIS_ UINT* puiWidth, UINT* puiHeight) PURE;
    STDMETHOD(GetColorContexts) (THIS_ UINT cCount, IWICColorContext** ppIColorContexts, UINT* pcActualCount) PURE;
    STDMETHOD(GetMetadataQueryReader) (THIS_ IWICMetadataQueryReader * *ppIMetadataQueryReader) PURE;
    STDMETHOD(GetThumbnail) (THIS_ IWICBitmapSource * *ppIThumbnail) PURE;

    END_INTERFACE
};

Example of implementation in source file:

static HRESULT STDMETHODCALLTYPE GetPixelFormat(WICPixelFormatGUID* pPixelFormat) {

pPixelFormat = &GUID_WICPixelFormat32bppBGRA;

return S_OK;

}
Laplace
  • 1
  • 1
  • No, names don't matter. The DECLARE_INTERFACE macro *declares* a struct to represent the v-table of the interface, the members are function pointers. Missing in the post, in the implementation you have to *define* the struct, that's where you initialize the function pointers to point to the functions. Function names can thus be anything. Be sure to read and understand [this article](https://www.codeproject.com/Articles/13601/COM-in-plain-C). – Hans Passant Nov 11 '21 at 23:32

1 Answers1

0

In your class declaration, you need to derive from the existing IWICBitmapSource interface as well as remove the PURE macro because you are actually implementing the interface, not creating an interface declaration.

class MgfFrameDecoder : public IWICBitmapSource 
{
public:
    STDMETHOD(QueryInterface) (REFIID riid, void **ppv);
    STDMETHOD_(ULONG, AddRef) ();
    STDMETHOD_(ULONG, Release) ();

    STDMETHOD(GetPixelFormat) (WICPixelFormatGUID* pPixelFormat);
};

It's a lot clearer what is going on in C++ to not use the COM macros (which are there to build in both C and C++) and just declare:

class MgfFrameDecoder : public IWICBitmapSource 
{
public:
    HRESULT __stdcall QueryInterface(IID& riid, LPVOID* ppvObj) override;
    HRESULT __stdcall AddRef() override;
    HRESULT __stdcall Release() override;

    HRESULT __stdcall GetPixelFormat(WICPixelFormatGUID* pPixelFormat) override;
}

In the method body, the static is incorrect because it's supposed to be a vtable entry not a static method.

Instead use:

HRESULT MgfFrameDecoder::GetPixelFormat(WICPixelFormatGUID* pPixelFormat)
{
    if (!pPixelFormat)
        return E_INVALIDARG;

    pPixelFormat = &GUID_WICPixelFormat32bppBGRA;

    return S_OK;
}

FAR is a hold-over from 16-bit Windows. It's defined to nothing so don't worry about it.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81