Skip to content

Commit

Permalink
Use WIC for epub, zip thumbnails. Add support for common (codec) imag…
Browse files Browse the repository at this point in the history
…e formats. NOTE: WIC for rar thumbnails not working.
  • Loading branch information
fire-eggs committed Sep 13, 2022
1 parent 69bfc35 commit e83f457
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 31 deletions.
34 changes: 19 additions & 15 deletions CBXShell/cbxArchive.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ inline BOOL StrEqual(LPCTSTR psz1, LPCTSTR psz2);
BOOL IsImage(LPCTSTR szFile);
HBITMAP ThumbnailFromIStream(IStream* pIs, const LPSIZE pThumbSize, bool showIcon);
HRESULT WICCreate32BitsPerPixelHBITMAP(IStream* pstm, HBITMAP* phbmp);
void addIcon(HBITMAP* phBmpThumbnail);

HRESULT ExtractFBCover(CString filepath, HBITMAP* phBmpThumbnail);

Expand Down Expand Up @@ -388,7 +389,11 @@ try {
case CBXTYPE_EPUB:
{
if (ExtractEpub(m_cbxFile, phBmpThumbnail, m_thumbSize, m_showIcon) != E_FAIL)
{
if (m_showIcon)
addIcon(phBmpThumbnail);
return S_OK;
}

// something wrong with the epub, try falling back on first image in zip
logit(_T("__Epub Extract: fallback to ZIP"));
Expand Down Expand Up @@ -438,27 +443,23 @@ try {
{
bool b=false;
LPVOID pBuf=::GlobalLock(hG);

long itemSize = _z.GetItemUnpackedSize();
if (pBuf)
b=_z.UnzipItemToMembuffer(thumbindex, pBuf, _z.GetItemUnpackedSize());
b=_z.UnzipItemToMembuffer(thumbindex, pBuf, itemSize);

if (::GlobalUnlock(hG)==0 && GetLastError()==NO_ERROR)
if (::GlobalUnlock(hG)==0 && GetLastError()==NO_ERROR && b)
{
if (b)
{
IStream* pIs=NULL;
if (S_OK==CreateStreamOnHGlobal(hG, TRUE, (LPSTREAM*)&pIs))//autofree hG
{
*phBmpThumbnail= ThumbnailFromIStream(pIs, &m_thumbSize, m_showIcon);
//HRESULT hr = WICCreate32BitsPerPixelHBITMAP(pIs, phBmpThumbnail);
pIs->Release();
pIs=NULL;
//return hr;
}
}
IStream* pImageStream = SHCreateMemStream((const BYTE *)pBuf, itemSize);
HRESULT hr = WICCreate32BitsPerPixelHBITMAP(pImageStream, phBmpThumbnail);
pImageStream->Release();
}
//GlobalFree(hG);//autofreed
}

if (m_showIcon)
addIcon(phBmpThumbnail);

return ((*phBmpThumbnail) ? S_OK : E_FAIL);
}//dtors!
break;
Expand Down Expand Up @@ -487,6 +488,7 @@ try {
{
//skip solid (long processing time), volumes or encrypted file headers
//if (_r.IsArchiveSolid() || _r.IsArchiveVolume() || _r.IsArchiveEncryptedHeaders()) return E_FAIL;
// Issue #30: allow SOLID archives
if (_r.IsArchiveVolume() || _r.IsArchiveEncryptedHeaders()) return E_FAIL;

while (_r.ReadItemInfo())
Expand All @@ -507,15 +509,17 @@ try {
//create thumb
IStream* pIs = NULL;
HGLOBAL hG = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (SIZE_T)_r.GetItemUnpackedSize64());
//HRESULT hr;
if (hG)
{
if (S_OK==CreateStreamOnHGlobal(hG, TRUE, (LPSTREAM*)&pIs))
{
_r.SetIStream(pIs);
if (_r.ProcessItem())
//if (_r.ProcessItemData((LPBYTE) hG, _r.GetItemUnpackedSize64()))
{
*phBmpThumbnail = ThumbnailFromIStream(pIs, &m_thumbSize, m_showIcon);
//HRESULT hr = WICCreate32BitsPerPixelHBITMAP(pIs, phBmpThumbnail);
//hr = WICCreate32BitsPerPixelHBITMAP(pIs, phBmpThumbnail);
}
}
}
Expand Down
23 changes: 22 additions & 1 deletion CBXShell/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ BOOL IsImage(LPCTSTR szFile)
if (StrEqual(_e, _T(".png"))) return TRUE;
if (StrEqual(_e, _T(".tif"))) return TRUE;
if (StrEqual(_e, _T(".tiff"))) return TRUE;
if (StrEqual(_e, _T(".webp"))) return TRUE; // NOTE: works if a webp codec is installed
if (StrEqual(_e, _T(".svg"))) return TRUE; // NOTE: hopefully works if a codec is installed?

// The following require a WIC codec to be installed
if (StrEqual(_e, _T(".webp"))) return TRUE;
if (StrEqual(_e, _T(".jxr"))) return TRUE;
if (StrEqual(_e, _T(".nrw"))) return TRUE;
if (StrEqual(_e, _T(".nef"))) return TRUE;
if (StrEqual(_e, _T(".dng"))) return TRUE;
if (StrEqual(_e, _T(".cr2"))) return TRUE;

return FALSE;
}

Expand Down Expand Up @@ -243,3 +251,16 @@ HRESULT WICCreate32BitsPerPixelHBITMAP(IStream* pstm, HBITMAP* phbmp)
}
return hr;
}

void addIcon(HBITMAP* phBmpThumbnail)
{
if (*phBmpThumbnail)
{
HDC hdcMem = CreateCompatibleDC(NULL);
HGDIOBJ hbmOld = SelectObject(hdcMem, *phBmpThumbnail);
zipIcon = LoadIcon(_hInstance, MAKEINTRESOURCE(IDI_ICON1));
BOOL res = DrawIconEx(hdcMem, 0, 0, zipIcon, 150, 150, 0, NULL, DI_NORMAL);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
}
}
23 changes: 8 additions & 15 deletions CBXShell/epub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

HBITMAP ThumbnailFromIStream(IStream* pIs, const LPSIZE pThumbSize, bool showIcon);
BOOL IsImage(LPCTSTR szFile);
//HRESULT WICCreate32BitsPerPixelHBITMAP(IStream* pstm, HBITMAP* phbmp);
HRESULT WICCreate32BitsPerPixelHBITMAP(IStream* pstm, HBITMAP* phbmp);


std::string urlDecode(std::string& SRC)
Expand Down Expand Up @@ -207,7 +207,7 @@ CString GetEpubTitle(CString m_cbxFile)

std::string coverImageItem(char* pBuf, std::string rootpath) {

// find a <manifest> entry with id of "cover-image"
// find a <manifest> entry with id of "cover-image" [for Epub V3.0]
// the href is the path, relative to rootpath

std::string xmlContent = (char*)pBuf;
Expand Down Expand Up @@ -390,22 +390,15 @@ HRESULT ExtractEpub(CString m_cbxFile, HBITMAP* phBmpThumbnail, SIZE m_thumbSize
{
bool b = false;
LPVOID pBuf = ::GlobalLock(hG);
long itemSize = _z.GetItemUnpackedSize();
if (pBuf)
b = _z.UnzipItemToMembuffer(thumbindex, pBuf, _z.GetItemUnpackedSize());
b = _z.UnzipItemToMembuffer(thumbindex, pBuf, itemSize);

if (::GlobalUnlock(hG) == 0 && GetLastError() == NO_ERROR)
if (::GlobalUnlock(hG) == 0 && GetLastError() == NO_ERROR && b)
{
if (b)
{
IStream* pIs = NULL;
if (S_OK == CreateStreamOnHGlobal(hG, TRUE, (LPSTREAM*)&pIs))//autofree hG
{
*phBmpThumbnail = ThumbnailFromIStream(pIs, &m_thumbSize, showIcon);
//HRESULT hr = WICCreate32BitsPerPixelHBITMAP(pIs, phBmpThumbnail);
pIs->Release();
pIs = NULL;
}
}
IStream* pImageStream = SHCreateMemStream((const BYTE*)pBuf, itemSize);
HRESULT hr = WICCreate32BitsPerPixelHBITMAP(pImageStream, phBmpThumbnail);
pImageStream->Release();
}
// GlobalFree(hG); KBR: unnecessary, freed as indicated by 2d param of CreateStreamOnHGlobal above
}
Expand Down

0 comments on commit e83f457

Please sign in to comment.