Diffstat (limited to 'noncore/apps/opie-reader/Aportis.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/Aportis.cpp | 125 |
1 files changed, 103 insertions, 22 deletions
diff --git a/noncore/apps/opie-reader/Aportis.cpp b/noncore/apps/opie-reader/Aportis.cpp index 06f44a4..7528e78 100644 --- a/noncore/apps/opie-reader/Aportis.cpp +++ b/noncore/apps/opie-reader/Aportis.cpp @@ -1,17 +1,18 @@ #include <stdio.h> #include <string.h> #include "Aportis.h" #include "my_list.h" #include "Bkmks.h" +#include "static.h" Aportis::Aportis() : peanutfile(false) { /*printf("constructing:%x\n",fin);*/ } void Aportis::dePeanut(int& ch) { if (peanutfile && ch != EOF) { unsigned char c = ch; if (peanutfile) c ^= 0xa5; ch = c; } } @@ -19,32 +20,32 @@ void Aportis::dePeanut(int& ch) CList<Bkmk>* Aportis::getbkmklist() { /* if (peanutfile) { if (nRecs2 > nRecs) { CList<Bkmk>* t = new CList<Bkmk>; for (int i = nRecs; i < nRecs2; i++) { char name[17]; name[16] = '\0'; -// odebug << "Record:" << i << ", Length:" << recordlength(i) << "" << oendl; +// qDebug("Record:%d, Length:%u",i,recordlength(i)); gotorecordnumber(i); fread(name,1,16,fin); unsigned long lcn; fread(&lcn,sizeof(lcn),1,fin); lcn ^= 0xa5a5a5a5; lcn = SwapLong(lcn); -// odebug << "Bookmark:" << name << ":" << lcn << "" << oendl; +// qDebug("Bookmark:%s:%u", name,lcn); tchar tname[17]; memset(tname, 0, sizeof(tname)); for (int i = 0; name[i] != 0; i++) { tname[i] = name[i] ^ 0xa5; } t->push_back(Bkmk(tname, NULL, lcn)); } return t; } else { @@ -85,113 +86,166 @@ CList<Bkmk>* Aportis::getbkmklist() t->push_back(Bkmk(name,lcn)); #endif } } fseek(fin, cur, SEEK_SET); return t; } int Aportis::OpenFile(const char *src) { // printf("In openfile\n"); int ret = 0; + html = false; + mobiimagerec = 0; + if (!Cpdb::openpdbfile(src)) return -1; - if (!Cpdb::openfile(src)) return -1; - - if (head.creator != 0x64414552 // 'dAER' - || head.type != 0x74584554) // 'tXET') + if (head.creator == 0x64414552 // 'dAER' + || head.type == 0x74584554) // 'tXET') { - - if (memcmp(&head.creator, "PPrs", 4) == 0 && memcmp(&head.type, "PNRd", 4) == 0) - { - peanutfile = true; - } - else - { - return -2; - } + } + else if (memcmp(&head.creator, "PPrs", 4) == 0 && memcmp(&head.type, "PNRd", 4) == 0) + { + peanutfile = true; + } + else if (memcmp(&head.creator, "MOBI", 4) == 0 && memcmp(&head.type, "BOOK", 4) == 0) + { + html = true; + unsigned char vsn; + fseek(fin, recordpos(0)+39, SEEK_SET); + fread(&vsn, 1, sizeof(vsn), fin); + qDebug("Mobi version:%x", vsn); + if (vsn > 2) + { + fseek(fin, recordpos(0)+110, SEEK_SET); + fread(&mobiimagerec, 1, sizeof(mobiimagerec), fin); + mobiimagerec = ntohs(mobiimagerec)-1; + } + } + else + { + return -2; } nRecs2 = nRecs = SwapWord(head.recordList.numRecords) - 1; - fseek(fin,0,SEEK_END); - dwLen = ftell(fin); + + struct stat _stat; + stat(src,&_stat); + dwLen = _stat.st_size; + + //fseek(fin,0,SEEK_END); + //dwLen = ftell(fin); if (peanutfile) { PeanutHeader hdr0; gotorecordnumber(0); fread(&hdr0, sizeof(hdr0), 1, fin); -// odebug << "Version:" << ntohs(hdr0.Version) << "" << oendl; +// qDebug("Version:%x", ntohs(hdr0.Version)); if (hdr0.Version && 0x0200) { bCompressed = 2; } else { bCompressed = 1; } BlockSize = 4096; nRecs = SwapWord(hdr0.Records)-1; dwTLen = nRecs*BlockSize; } else { gotorecordnumber(0); tDocRecord0 hdr0; fread(&hdr0, sizeof(hdr0), 1, fin); bCompressed = SwapWord(hdr0.wVersion); if (bCompressed!=1 && bCompressed!=2 && bCompressed != 4) { - ret = bCompressed; + qDebug("ERROR:Unrecognised compression type in Aportis:%u", bCompressed); + ret = bCompressed; bCompressed = 2; } switch (bCompressed) { case 4: { dwTLen = 0; int i; for (i = 0; i < nRecs; i++) { unsigned int bs = GetBS(i); if (bs == 0) break; else dwTLen += bs; } nRecs = i; BlockSize = 0; } break; case 1: case 2: default: nRecs = SwapWord(hdr0.wNumRecs); + if (mobiimagerec == 0 || mobiimagerec > nRecs2) mobiimagerec = nRecs; dwTLen = SwapLong(hdr0.dwStoryLen); BlockSize = SwapWord(hdr0.wRecSize); if (BlockSize == 0) { BlockSize = 4096; printf("WARNING: Blocksize not set in source file\n"); } } } - - + + qDebug("Mobi image rec:%u", mobiimagerec); // this is the main record buffer // it knows how to stretch to accomodate the decompress currentrec = 0; cbptr = 0; outptr = 0; refreshbuffer(); -// odebug << "Number of records:[" << nRecs << "," << nRecs2 << "]" << oendl; + if (!html) + { + int c; + char htmltag[] = "<HTML>"; + char *p = htmltag; + while (1) + { + c = getch(); + char ch = *p++; + if (ch == 0) + { + html = true; + break; + } + if (c != ch) + { + html = false; + break; + } + } + currentrec = 0; + cbptr = 0; + outptr = 0; + refreshbuffer(); + } + /* + for (int i = 0; i < nRecs2; i++) + { + qDebug("Record:%u - %u bytes at position %x", i, recordlength(i), recordpos(i)); + } + */ + + qDebug("Number of records:[%u,%u]", nRecs, nRecs2); return ret; } int Aportis::getch() { if (bCompressed == 1) { if ((dwRecLen == 0) && !refreshbuffer()) return EOF; else { int c = getc(fin); dePeanut(c); @@ -363,12 +417,39 @@ bool Aportis::refreshbuffer() t.Decompress(); t.buf[t.Len()] = '\0'; */ currentpos = 0; currentrec++; return true; } else { return false; } } + +#include <qimage.h> + +QImage* Aportis::getPicture(unsigned long tgt) +{ + unsigned short tgtrec = tgt+mobiimagerec; + if (tgtrec > nRecs2) return NULL; + size_t cur = ftell(fin); + unsigned short reclen = recordlength(tgtrec); + gotorecordnumber(tgtrec); + UInt8* imgbuffer = new UInt8[reclen]; + fread(imgbuffer, 1, reclen, fin); + QByteArray arr; + arr.assign((const char*)imgbuffer, reclen); + + QImage* qimage = new QImage(arr); + fseek(fin, cur, SEEK_SET); + + return qimage; +} + +#ifndef __STATIC +extern "C" +{ + CExpander* newcodec() { return new Aportis; } +} +#endif |