Image loading with Imaging API

Image loading with Imaging API
 

Introduction

There is a number of different ways for image loading exists on Windows Mobile. The oldest one is to use not officially documented in SDK imgdecmp.dll. This library now considered is deprecated and it will disappear in one of upcoming Windows Mobile versions. Moreover Microsoft claims that using of this library may get caught in an infinite loop in some conditions. Starting from Windows Mobile 2003 new set of functions appeared (SHLoadImageFile, SHLoadImageResource) but these functions are more limited comparing to DecompressImageIndirect from imgdecmp.dll. Particularly I face some problems with PNG files loading as with imgdecmp.dll as SHLoadImageFile on Windows Mobile 5.0.

Fortunately Windows Mobile 5.0 devices contain new set of API known as Imaging API. This API has quite rich functionality, and in future when Pocket PC with operating system version less then WM05 will be in small minority it will not any questions which API to use, but still we need support users with old devices. So I have tried to create image loading code that behaves differently according to operating system version. When it is loaded on older devices (starting from Pocket PC 2002) it uses imgdecmp.dll but when it is run on newer devices it uses Imaging API.

What You Need


Solution

In older devices LoadImageWithImgdecmp function is used:
Code:

static DWORD CALLBACK GetImageData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam)
{
   FILE* f = (FILE*)lParam;
   size_t c = fread(szBuffer, 1, dwBufferMax, f);
   return c;
}

#ifndef DecompressImageInfo

class IImageRender;
typedef void (CALLBACK *PROGRESSFUNC)(IImageRender *pRender, BOOL bComplete, LPARAM lParam);
typedef DWORD (CALLBACK *GETDATAFUNC)(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam);

typedef struct tagDecompressImageInfo {
   DWORD dwSize;                                 
   LPBYTE pbBuffer;
   DWORD dwBufferMax;
   DWORD dwBufferCurrent;
   HBITMAP* phBM;                                   
   IImageRender **ppImageRender;                 
   int iBitDepth;     
   LPARAM lParam;                 
   HDC hdc;           
   int iScale;         
   int iMaxWidth;     
   int iMaxHeight;     
   GETDATAFUNC pfnGetData;       
   PROGRESSFUNC pfnImageProgress;         
   COLORREF crTransparentOverride;
} DecompressImageInfo;

#endif

HBITMAP LoadImageWithImgdecmp(const CString &strFileName)
{
   FILE* f = _tfopen(strFileName, TEXT("rb"));
   if (! f) {
      return 0;
   }

   CWindowDC dc(0);

   DecompressImageInfo dii;
   
   HBITMAP hBitmap = 0;
   
   const int nBuffSize = 4096;
   BYTE buff[nBuffSize];
   
   dii.dwSize = sizeof(DecompressImageInfo);
   dii.pbBuffer = buff;               
   dii.dwBufferMax = nBuffSize;            
   dii.dwBufferCurrent = 0;               
   dii.phBM = &hBitmap;                  
   dii.ppImageRender = NULL;               
   dii.iBitDepth = GetDeviceCaps(dc.m_hDC, BITSPIXEL);
   dii.lParam = LPARAM(f);
   dii.hdc = 0;                              
   dii.iScale = 100;                              
   dii.iMaxWidth = 10000;                        
   dii.iMaxHeight = 10000;                        
   dii.pfnGetData = GetImageData;            
   dii.pfnImageProgress = 0;            
   dii.crTransparentOverride = (UINT) -1;   
   
   HINSTANCE hDll = LoadLibrary(TEXT("imgdecmp.dll"));
   if (!hDll) {
      fclose(f);
      return 0;
   }
   typedef HRESULT (*DecompressImageIndirect_t)(DecompressImageInfo *pParams);
   DecompressImageIndirect_t proc = (DecompressImageIndirect_t)GetProcAddress(hDll, TEXT("DecompressImageIndirect"));
   if (! proc) {
      FreeLibrary(hDll);
      fclose(f);
      return 0;
   }
   HRESULT hr = proc(&dii);

   fclose(f);
   FreeLibrary(hDll);

   if (FAILED(hr)) {
      return 0;
   } else {
      return hBitmap;
   }
}

As Microsoft warn us about that in some upcoming versions of Windows Mobile imgdecmp.dll disappear we should invoke DecompressImageIndirect dynamically but not linking with imgdecmp.lib.

This code works on modern platforms:
Code:

HBITMAP LoadImageWithImagingApi(const CString &strFileName)
{
    IImagingFactory *pImgFactory = NULL;
    IImage *pImage = NULL;
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
   HBITMAP hResult = 0;
    if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory,
                                    NULL,
                                    CLSCTX_INPROC_SERVER,
                                    IID_IImagingFactory,
                                    (void **)&pImgFactory)))
    {
      ImageInfo imageInfo;
        if (SUCCEEDED(pImgFactory->CreateImageFromFile(strFileName, &pImage))
         && SUCCEEDED(pImage->GetImageInfo(&imageInfo)))
        {
         CWindowDC dc(0);
         CDC dcBitmap;
         dcBitmap.CreateCompatibleDC(&dc);
         hResult = CreateCompatibleBitmap(dc.GetSafeHdc(), imageInfo.Width, imageInfo.Height);
         if (hResult) {
            HGDIOBJ hOldBitmap = dcBitmap.SelectObject(hResult);
              pImage->Draw(dcBitmap.GetSafeHdc(), CRect(0, 0, imageInfo.Width, imageInfo.Height), NULL);
            dcBitmap.SelectObject(hOldBitmap);
         }
         pImage->Release();
        }
        pImgFactory->Release();
    }
    CoUninitialize();

   return hResult;
}


And finally we should invoke right function according to operating system version our program run on:
Code:

HBITMAP LoadImageFromFile(const CString &strFileName)
{
   OSVERSIONINFO vi;
   memset(&vi, 0, sizeof(vi));
   vi.dwOSVersionInfoSize = sizeof(vi);
   VERIFY(GetVersionEx(&vi));
   if (vi.dwMajorVersion>=5) {
      return LoadImageWithImagingApi(strFileName);
   } else {
      return LoadImageWithImgdecmp(strFileName);
   }
}

In order we could use Imaging API in eMbedded Visual C++ we should add Windows Mobile 5.0 SDK includes folder to standard include folders for eVC (Tools->Options…->Directories), but ensure that this folder added after include folder for Pocket PC 2002 or 2003 SDK.

Conclusion

This sample doesn’t show full power of these SDKs it just loads image from file into HBITMAP without scaling.
You can download a sample evc project there.
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值