Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An Image Decoder Based on IImgCtx

0.00/5 (No votes)
25 May 2004 4  
This article shows how to decode image with IImgCtx interface provided by IE

1. Why do I use IImgCtx to decode images?

If you want to develop a image viewer or processor in Windows, the first thing you have to face is image decoding. Now there are some free image decoders, with full source code:

If you'd like all decoders in one project, you may try CxImage, which is developed by Davide Pizzolato.

But after I tried all of above decoders, I also found some problems:

  • They were difficult to use. I had to configure or tailor source code before I could compile them.
  • They were difficult to debug. Most free decoders were written in C, with poor comments.
  • All decoders would be embedded in EXE or DLL and make install package so big. Of cause, if the final user would like to buy a "big" package, it could be another story.

So I (just like other "lazy" programmers) wondered if there was such an image decoder: easy to use, small footprint, one decoder for all images.

According to the information I got from Internet, the first toy I tried is IPicture interface, which was well documented in MSDN, and discussed in codeguru and CodeProject. The good news was: though MSDN said IPicture only could decode BMP, WMF and ICO files, it really worked fine with GIF and JPG. The bad news was: it really couldn't decode PNG and TIFF.

Then when I reinstalled my Windows OS, I found that the default viewer of GIF, JPG, PNF files was Microsoft Internet Explorer (IE). Since all kinds of these images are often used in web pages, it is reasonable if IE supported them. So is there any interface provided by IE that can decode images, just like I use IHTMLDocument interface to parse HTML code?

The answer is: Yes, it's IImgCtx interface. It can decode all images that can be shown in IE, including JPEG, PNG, GIF, BMP, WMF, ICO, and sometime TIFF (I'll explain why I say "sometime" later).

2. How to use IImgCtx interface to decode images?

In IE 5.5 SDK, which is the only IE SDK I have, I found the definition of IImgCtx interface in IImgCtx.h. In VC++ 6, I also found that file. The difference between two files is just one line: In IE 5.5 SDK, it defines one more constant value named DWN_MIRRORIMAGE. I think this is also the difference between IE 4 and IE 5.5.

But when I searched IImgCtx in MSDN, I got nothing. Then I tried it in Google, the result was the same. Fortunately, the interface was relatively simple and I might guess its usage:

DECLARE_INTERFACE_(IImgCtx, IUnknown)
{
#ifndef NO_BASEINTERFACE_FUNCS

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, 
      LPVOID FAR* ppvObj) PURE;
    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
    STDMETHOD_(ULONG, Release)(THIS) PURE;
#endif

    /* IImgCtx methods */

    /* Initialization/Download methods */
    STDMETHOD(Load)(THIS_ LPCWSTR pszUrl, DWORD dwFlags) PURE;
    STDMETHOD(SelectChanges)(THIS_ ULONG ulChgOn, 
      ULONG ulChgOff, BOOL fSignal) PURE;
    STDMETHOD(SetCallback)(THIS_ PFNIMGCTXCALLBACK pfn, 
      void * pvPrivateData) PURE;
    STDMETHOD(Disconnect)(THIS) PURE;

    /* Query methods */
    STDMETHOD(GetUpdateRects)(THIS_ struct tagRECT FAR* prc, 
      struct tagRECT FAR* prcImg, long FAR* pcrc) PURE;
    STDMETHOD(GetStateInfo)(THIS_ ULONG FAR* pulState, 
      struct tagSIZE FAR* psize, BOOL fClearChanges) PURE;
    STDMETHOD(GetPalette)(THIS_ HPALETTE FAR* phpal) PURE;

    /* Rendering methods */
    STDMETHOD(Draw)(THIS_ HDC hdc, 
      struct tagRECT FAR* prcBounds) PURE;
    STDMETHOD(Tile)(THIS_ HDC hdc, struct tagPOINT FAR* pptBackOrg, 
      struct tagRECT FAR* prcClip, struct tagSIZE FAR* psize) PURE;
    STDMETHOD(StretchBlt)(THIS_ HDC hdc, int dstX, int dstY, int dstXE, 
      int dstYE, int srcX, int srcY, int srcXE, int srcYE, 
      DWORD dwROP) PURE;
};
According to the definition of IImgCtx, I can use Load method to read image file after I create IImgCtx object. And I can use Draw method to show decoded image. But
  • The parameter of Load method is a URL (for IE?) in Unicode. So I have to convert local path name into file://local path.
  • Just like other interfaces in IE, IImgCtx also works asynchronously. This is the reason why it defines SetCallback method to set call back function, and SelectChanges method to monitor status. Since there is no any document about IImgCtx, I don't know how to use them. I only know that I have to build a message pump to drive asynchronous process.
  • Draw method uses a HDC as target DC. If this is a memory DC, it can decode image without show it. Decoded image is a DDB (Device Dependent Bitmap). If you want to process it, you'd better convert it into DIB (Device Independent Bitmap).

The full process of using IImgCtx interface to decode image is shown in WndImgCtx.cpp, in sample project.

3. How to use IImgCtx in your project?

The sample code of this document is ImgViewer.zip. Download and unzip it, you'll get a VC++ 6 project of a simple (really quite simple) image viewer. Besides image decoder, it also shows how to search and sort files in a folder so you can view images one by one.

If you just want a image decoder, you can include WndImgCtx.h and WndImgCtx.cpp into your project, and add this line at the beginning of you CPP file:

#include "WndImgCtx.h"

Then you can call

HBITMAP GetBitmapFromFile(LPCTSTR pszFilename);

to decode image. It will return a DDB identified by a HBITMAP.

4. Why is TIFF an exception?

IE supports most image files, including JPEG, PNG and GIF. But in the "File Open" dialog of IE, I can't find TIFF files. I tested ImgViewer with the sample files provided by libtiff organization. The result was: In Windows 98/Me/XP, none of them could be shown. In Windows 2000, about half of them could, others couldn't.

In Windows 2000, I compiled and run ImgViewer in Debug mode in VC++ 6, opened a TIFF file, then exited it. I found these lines in the Output window of VC++:

Loaded 'C:\WINNT\system32\imgutil.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\tifflt.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\oieng400.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\mscms.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\winspool.drv', no matching symbolic information found.

I did the same thing in Windows XP but I only could see the first line.

In Windows 2000, I searched key word "tifflt.dll" in regedit and found it belonged to "TIFFilter Class", whose CLSID was {EBD0F6B6-4AED-11D1-9CDB-00805F0C62F5}. Then I searched this CLSID again, and found it was the value of "Image Filter CLSID" key, in "HKEY_CLASSES_ROOT\MIME\Database\Content Type\image/tiff" item. Before this item, I also saw "image/png" and "image/jpeg" items. Both of them had "Image Filter CLSID" key. Documented in MSDN, "HKEY_CLASSES_ROOT\MIME\Database\Content Type" items record all MIME types that can be recognized by IE.

By the name of "Image Filter CLSID", I guess this is the CLSID of image filter. In Windows 98/Me/XP, I can't find it under "image/tiff" item. But I can found it under "image/png" and "image/jpeg" items. Maybe this is the reason why IE can't show TIFF in Windows 98/Me/XP: there is no image filter for it.

I tried to move tifflt.dll and oieng400.dll into XP but failed because of DLL conflict. Maybe the only hope is: Microsoft provides an image filter for TIFF.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here