Open Serized opened 7 years ago
To anyone wondering, this is how you do the epub thumbnails https://wiki.mobileread.com/wiki/Thumbnails
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.epub\shellex]
[HKEY_CLASSES_ROOT\.epub\shellex\{00021500-0000-0000-C000-000000000046}]
@="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}"
[HKEY_CLASSES_ROOT\.epub\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}]
@="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}"
Just save this as something.reg, run it and you should have thumbnails. If you do not see the thumbnails right away, toggle the "Sort Images Alphabetically", that made it work for me, no reboot.
I wrote this a while back to correctly handle epubs, displaying the right cover image even if it's not the first file in the epub (zip).
In cbxArchive.h
:
#define CBXTYPE_EPUB 5
at line 45.
Add this to CCBXArchive::OnExtract function, as the first case
in the switch
(has to be before the ZIP and CBZ, so it falls back in case of a bad EPUB file) :
...
switch (m_cbxType)
{
case CBXTYPE_EPUB:
{
CUnzip _z;
if (!_z.Open(m_cbxFile)) return E_FAIL;
j = _z.GetItemCount();
if (j == 0) return E_FAIL;
size_t posStart, posEnd;
CString prevname;//helper vars
int thumbindex = -1;
USES_CONVERSION;
std::string xmlContent, rootpath, rootfile, coverfile;
// Find
for (i = 0; i < j; i++)
{
if (!_z.GetItem(i)) break;
if (_z.ItemIsDirectory() || (_z.GetItemUnpackedSize() > CBXMEM_MAXBUFFER_SIZE)) continue;
std::string name = T2A(_z.GetItemName());
if (_stricmp(name.c_str(), "META-INF/container.xml") == 0) {
// Extract container.xml and retrieve rootfile location
HGLOBAL hGContainer = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (SIZE_T)_z.GetItemUnpackedSize());
if (hGContainer)
{
bool b = false;
LPVOID pBuf = ::GlobalLock(hGContainer);
if (pBuf)
b = _z.UnzipItemToMembuffer(i, pBuf, _z.GetItemUnpackedSize());
if (::GlobalUnlock(hGContainer) == 0 && GetLastError() == NO_ERROR)
{
if (b)
{
xmlContent = (char *)pBuf;
posStart = xmlContent.find("rootfile ");
if (posStart == std::string::npos) {
break;
}
posStart = xmlContent.find("full-path=\"", posStart);
if (posStart == std::string::npos) {
break;
}
posStart += 11;
posEnd = xmlContent.find("\"", posStart);
rootfile = xmlContent.substr(posStart, posEnd - posStart);
break;
}
}
//GlobalFree(hGContainer);//autofreed
}
}
}
if (rootfile.length() > 0) {
posStart = rootfile.find('/');
if (posStart != std::string::npos) {
rootpath = rootfile.substr(0, posStart + 1);
}
for (i = 0; i < j; i++)
{
if (!_z.GetItem(i)) break;
if (_z.ItemIsDirectory() || (_z.GetItemUnpackedSize() > CBXMEM_MAXBUFFER_SIZE)) continue;
std::string name;
name = CT2A(_z.GetItemName());
if (name.compare(rootfile) == 0) {
HGLOBAL hGContainer = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (SIZE_T)_z.GetItemUnpackedSize());
if (hGContainer)
{
bool b = false;
LPVOID pBuf = ::GlobalLock(hGContainer);
if (pBuf)
b = _z.UnzipItemToMembuffer(i, pBuf, _z.GetItemUnpackedSize());
if (::GlobalUnlock(hGContainer) == 0 && GetLastError() == NO_ERROR)
{
if (b)
{
// Find meta tag for cover
std::string xmlContent, coverTag, coverId, itemTag;
xmlContent = (char *)pBuf;
posStart = xmlContent.find("name=\"cover\"");
if (posStart == std::string::npos) {
break;
}
posStart = xmlContent.find_last_of("<", posStart);
posEnd = xmlContent.find(">", posStart);
coverTag = xmlContent.substr(posStart, posEnd - posStart + 1);
// Find cover item id
posStart = coverTag.find("content=\"");
if (posStart == std::string::npos) {
break;
}
posStart += 9;
posEnd = coverTag.find("\"", posStart);
coverId = coverTag.substr(posStart, posEnd - posStart);
// Find item tag in original opf file contents
posStart = xmlContent.find("id=\"" + coverId);
if (posStart == std::string::npos) {
break;
}
posStart = xmlContent.find_last_of("<", posStart);
posEnd = xmlContent.find(">", posStart);
itemTag = xmlContent.substr(posStart, posEnd - posStart + 1);
// Find cover path in item tag
posStart = itemTag.find("href=\"");
if (posStart == std::string::npos) {
break;
}
posStart += 6;
posEnd = itemTag.find("\"", posStart);
if (posEnd == std::string::npos) {
break;
}
coverfile = rootpath + itemTag.substr(posStart, posEnd - posStart);
ReplaceStringInPlace(coverfile, "%20", " ");
break;
}
}
}
}
}
}
if (coverfile.length() > 0) {
for (i = 0; i < j; i++) {
if (!_z.GetItem(i)) break;
if (_z.ItemIsDirectory() || (_z.GetItemUnpackedSize() > CBXMEM_MAXBUFFER_SIZE)) continue;
if ((_z.GetItemPackedSize() == 0) || (_z.GetItemUnpackedSize() == 0)) continue;
if (_stricmp(T2A(_z.GetItemName()), coverfile.c_str()) == 0 && IsImage(_z.GetItemName()))
{
if (thumbindex < 0) thumbindex = i;// assign thumbindex if already sorted
if (!m_bSort) break;//if NoSort
if (prevname.IsEmpty()) prevname = _z.GetItemName();//can't compare empty string
//take only first alphabetical name
if (-1 == StrCmpLogicalW(_z.GetItemName(), prevname))
{
thumbindex = i;
prevname = _z.GetItemName();
}
}
}//for loop
if (thumbindex < 0) return E_FAIL;
//go to thumb index
if (!_z.GetItem(thumbindex)) return E_FAIL;
//create thumb //GHND
HGLOBAL hG = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (SIZE_T)_z.GetItemUnpackedSize());
if (hG)
{
bool b = false;
LPVOID pBuf = ::GlobalLock(hG);
if (pBuf)
b = _z.UnzipItemToMembuffer(thumbindex, pBuf, _z.GetItemUnpackedSize());
if (::GlobalUnlock(hG) == 0 && GetLastError() == NO_ERROR)
{
if (b)
{
IStream* pIs = NULL;
if (S_OK == CreateStreamOnHGlobal(hG, TRUE, (LPSTREAM*)&pIs))//autofree hG
{
*phBmpThumbnail = ThumbnailFromIStream(pIs, &m_thumbSize);
pIs->Release();
pIs = NULL;
}
}
}
}
//GlobalFree(hG);//autofreed
return ((*phBmpThumbnail) ? S_OK : E_FAIL);
}
// something wrong with the epub, try falling back on first image in zip
}
case CBXTYPE_ZIP:
case CBXTYPE_CBZ:
{
...
In the GetInfoTip function add this case at the end (the last lines already exist).
case CBXTYPE_EPUB:
if (_fs == 0) tip = _T("EPUB File\nSize: 0 bytes");
else
{
std::string title = GetEpubTitle(m_cbxFile);
ATL::CAtlStringW titleW = CA2W(title.c_str());
if (title.length() > 0)
tip.Format(_T("EPUB File\n%s\nSize: %s"),
titleW, StrFormatByteSize64(_fs, _tf, 16));
else tip.Format(_T("EPUB File\nSize: %s"), StrFormatByteSize64(_fs, _tf, 16));
}
break;
default: ATLTRACE("IQueryInfo::GetInfoTip : CBXTYPE_NONE\n");return E_FAIL;
}
...
In GetCBXType
add:
//by popular demand
if (StrEqual(szExt, _T(".epub"))) return CBXTYPE_EPUB;
I think that's all I did. Could probably write it a bit better today, given time.
Feel free to add to the project if you want.
To anyone wondering, this is how you do the epub thumbnails https://wiki.mobileread.com/wiki/Thumbnails
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.epub\shellex] [HKEY_CLASSES_ROOT\.epub\shellex\{00021500-0000-0000-C000-000000000046}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}" [HKEY_CLASSES_ROOT\.epub\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}"
Just save this as something.reg, run it and you should have thumbnails. If you do not see the thumbnails right away, toggle the "Sort Images Alphabetically", that made it work for me, no reboot.
Tried works, but shows a small pdf banner on the right bottom of the epub file thumbnail in explorer, because of sumatra reader association. Changed the default app to calibre viewer and got a generic icon at the bootm of thumbnail. Thanks for the tip.
To anyone wondering, this is how you do the epub thumbnails https://wiki.mobileread.com/wiki/Thumbnails
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.epub\shellex] [HKEY_CLASSES_ROOT\.epub\shellex\{00021500-0000-0000-C000-000000000046}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}" [HKEY_CLASSES_ROOT\.epub\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}"
Just save this as something.reg, run it and you should have thumbnails. If you do not see the thumbnails right away, toggle the "Sort Images Alphabetically", that made it work for me, no reboot.
Tried works, but shows a small pdf banner on the right bottom of the epub file thumbnail in explorer, because of sumatra reader association. Changed the default app to calibre viewer and got a generic icon at the bootm of thumbnail. Thanks for the tip.
Working on having a new version of CBXShell made with native ePub compatibility and better image parsing. Give me a few days.
To anyone wondering, this is how you do the epub thumbnails https://wiki.mobileread.com/wiki/Thumbnails
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.epub\shellex] [HKEY_CLASSES_ROOT\.epub\shellex\{00021500-0000-0000-C000-000000000046}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}" [HKEY_CLASSES_ROOT\.epub\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}] @="{9E6ECB90-5A61-42BD-B851-D3297D9C7F39}"
Just save this as something.reg, run it and you should have thumbnails. If you do not see the thumbnails right away, toggle the "Sort Images Alphabetically", that made it work for me, no reboot.
Tried works, but shows a small pdf banner on the right bottom of the epub file thumbnail in explorer, because of sumatra reader association. Changed the default app to calibre viewer and got a generic icon at the bootm of thumbnail. Thanks for the tip.
Working on having a new version of CBXShell made with native ePub compatibility and better image parsing. Give me a few days.
Cool, Ok. Please consider adding WebP preview support as well if possible. https://github.com/T800G/CBXShell/issues/5
Do you have any idea how to do this? Any code example snippets? My coder is currently working on it as we speak. Can you write up a simple example of what you are talking about and paste it here, I will send him the link!
Do you have any idea how to do this? Any code example snippets? My coder is currently working on it as we speak. Can you write up a simple example of what you are talking about and paste it here, I will send him the link!
In cbxArchive.h: have to add in the line in bold as below:
BOOL IsImage(LPCTSTR szFile) { LPWSTR _e=PathFindExtension(szFile); if (StrEqual(_e, _T(".bmp"))) return TRUE; if (StrEqual(_e, _T(".ico"))) return TRUE; if (StrEqual(_e, _T(".gif"))) return TRUE; if (StrEqual(_e, _T(".jpg"))) return TRUE; if (StrEqual(_e, _T(".jpe"))) return TRUE; if (StrEqual(_e, _T(".jfif"))) return TRUE; if (StrEqual(_e, _T(".jpeg"))) return TRUE; 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; return FALSE; }
Released a new program that fully supports EPUB files. We could not get WebP to work, but if someone figures out how to, they are more then welcome to suggest a change!
I'd like add GGB extension but I do not know how to compile the source code can somebody help me for this?
Hi!
Thanks for this great software. I'm currently using it on windows 10 to display thumbnails for epub files. Would you consider adding an option to display epub thumbnails directly in the UI if it's not too complicated?
Thanks!