diff --git a/CBXShell/cbxArchive.h b/CBXShell/cbxArchive.h index 79ee825..c74d977 100644 --- a/CBXShell/cbxArchive.h +++ b/CBXShell/cbxArchive.h @@ -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); @@ -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")); @@ -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; @@ -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()) @@ -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); } } } diff --git a/CBXShell/common.cpp b/CBXShell/common.cpp index 8e2e741..eb5205f 100644 --- a/CBXShell/common.cpp +++ b/CBXShell/common.cpp @@ -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; } @@ -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); + } +} diff --git a/CBXShell/epub.cpp b/CBXShell/epub.cpp index 8ddd800..973b38a 100644 --- a/CBXShell/epub.cpp +++ b/CBXShell/epub.cpp @@ -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) @@ -207,7 +207,7 @@ CString GetEpubTitle(CString m_cbxFile) std::string coverImageItem(char* pBuf, std::string rootpath) { - // find a entry with id of "cover-image" + // find a entry with id of "cover-image" [for Epub V3.0] // the href is the path, relative to rootpath std::string xmlContent = (char*)pBuf; @@ -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 }