summaryrefslogtreecommitdiffstats
path: root/fbreader/src/formats/pdb/PalmDocStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fbreader/src/formats/pdb/PalmDocStream.cpp')
-rw-r--r--fbreader/src/formats/pdb/PalmDocStream.cpp209
1 files changed, 0 insertions, 209 deletions
diff --git a/fbreader/src/formats/pdb/PalmDocStream.cpp b/fbreader/src/formats/pdb/PalmDocStream.cpp
deleted file mode 100644
index e699d47..0000000
--- a/fbreader/src/formats/pdb/PalmDocStream.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <cstring>
-#include <algorithm>
-
-#include <ZLFile.h>
-#include <ZLResource.h>
-#include <ZLZDecompressor.h>
-
-#include "PalmDocStream.h"
-#include "DocDecompressor.h"
-#include "HuffDecompressor.h"
-
-PalmDocStream::PalmDocStream(const ZLFile &file) : PalmDocLikeStream(file) {
-}
-
-PalmDocStream::~PalmDocStream() {
- close();
-}
-
-bool PalmDocStream::processRecord() {
- const std::size_t currentOffset = recordOffset(myRecordIndex);
- if (currentOffset < myBase->offset()) {
- return false;
- }
- myBase->seek(currentOffset, true);
- const std::size_t nextOffset = recordOffset(myRecordIndex + 1);
- if (nextOffset < currentOffset) {
- return false;
- }
- const unsigned short recordSize = nextOffset - currentOffset;
- switch(myCompressionVersion) {
- case 17480://'DH' // HuffCDic compression
- myBufferLength = myHuffDecompressorPtr->decompress(*myBase, myBuffer, recordSize, myMaxRecordSize);
- //if (myHuffDecompressorPtr->error()) {
- // myErrorCode = ERROR_UNKNOWN;
- //}
- break;
- case 2: // PalmDoc compression
- myBufferLength = DocDecompressor().decompress(*myBase, myBuffer, recordSize, myMaxRecordSize);
- break;
- case 1: // No compression
- myBufferLength = myBase->read(myBuffer, std::min(recordSize, myMaxRecordSize));
- break;
- }
- myBufferOffset = 0;
- return true;
-}
-
-bool PalmDocStream::processZeroRecord() {
- // Uses with offset presetting to zero record offset value
- PdbUtil::readUnsignedShort(*myBase, myCompressionVersion); // myBase offset: ^ + 2
- switch (myCompressionVersion) {
- case 1:
- case 2:
- case 17480:
- break;
- default:
- myErrorCode = ERROR_COMPRESSION;
- return false;
- }
- myBase->seek(2, false); // myBase offset: ^ + 4
- PdbUtil::readUnsignedLongBE(*myBase, myTextLength); // myBase offset: ^ + 8
- PdbUtil::readUnsignedShort(*myBase, myTextRecordNumber); // myBase offset: ^ + 10
-
- unsigned short endSectionIndex = header().Offsets.size();
- myMaxRecordIndex = std::min(myTextRecordNumber, (unsigned short)(endSectionIndex - 1));
- //TODO Insert in this point error message about uncompatible records and numRecords from Header
-
- PdbUtil::readUnsignedShort(*myBase, myMaxRecordSize); // myBase offset: ^ + 12
- if (myMaxRecordSize == 0) {
- myErrorCode = ERROR_UNKNOWN;
- return false;
- }
-
- /*
- std::cerr << "PalmDocStream::processRecord0():\n";
- std::cerr << "PDB header indentificator : " << header().Id << "\n";
- std::cerr << "PDB file system: sizeof opened : " << myBaseSize << "\n";
- std::cerr << "PDB header/record[0] max index : " << myMaxRecordIndex << "\n";
- std::cerr << "PDB record[0][0..2] compression : " << myCompressionVersion << "\n";
- std::cerr << "PDB record[0][2..4] spare : " << mySpare << "\n";
- std::cerr << "PDB record[0][4..8] text length : " << myTextLength << "\n";
- std::cerr << "PDB record[0][8..10] text records : " << myTextRecords << "\n";
- std::cerr << "PDB record[0][10..12] max record size: " << myMaxRecordSize << "\n";
- */
-
- if (header().Id == "BOOKMOBI") {
- unsigned short encrypted = 0;
- PdbUtil::readUnsignedShort(*myBase, encrypted); // myBase offset: ^ + 14
- if (encrypted) { //Always = 2, if encrypted
- myErrorCode = ERROR_ENCRYPTION;
- return false;
- }
- } else {
- myBase->seek(2, false);
- }
-
-
- if (myCompressionVersion == 17480) {
- unsigned long mobiHeaderLength;
- unsigned long huffSectionIndex;
- unsigned long huffSectionNumber;
- unsigned short extraFlags;
- unsigned long initialOffset = header().Offsets[0]; // myBase offset: ^
-
- myBase->seek(6, false); // myBase offset: ^ + 20
- PdbUtil::readUnsignedLongBE(*myBase, mobiHeaderLength); // myBase offset: ^ + 24
-
- myBase->seek(0x70 - 24, false); // myBase offset: ^ + 102 (0x70)
- PdbUtil::readUnsignedLongBE(*myBase, huffSectionIndex); // myBase offset: ^ + 106 (0x74)
- PdbUtil::readUnsignedLongBE(*myBase, huffSectionNumber); // myBase offset: ^ + 110 (0x78)
-
- if (mobiHeaderLength >= 244) {
- myBase->seek(0xF2 - 0x78, false); // myBase offset: ^ + 242 (0xF2)
- PdbUtil::readUnsignedShort(*myBase, extraFlags); // myBase offset: ^ + 244 (0xF4)
- } else {
- extraFlags = 0;
- }
- /*
- std::cerr << "mobi header length: " << mobiHeaderLength << "\n";
- std::cerr << "Huff's start record : " << huffSectionIndex << " from " << endSectionIndex - 1 << "\n";
- std::cerr << "Huff's records number: " << huffSectionNumber << "\n";
- std::cerr << "Huff's extraFlags : " << extraFlags << "\n";
- */
- const unsigned long endHuffSectionIndex = huffSectionIndex + huffSectionNumber;
- if (endHuffSectionIndex > endSectionIndex || huffSectionNumber <= 1) {
- myErrorCode = ERROR_COMPRESSION;
- return false;
- }
- const unsigned long endHuffDataOffset = recordOffset(endHuffSectionIndex);
- std::vector<unsigned long>::const_iterator beginHuffSectionOffsetIt = header().Offsets.begin() + huffSectionIndex;
- // point to first Huff section
- std::vector<unsigned long>::const_iterator endHuffSectionOffsetIt = header().Offsets.begin() + endHuffSectionIndex;
- // point behind last Huff section
-
-
- myHuffDecompressorPtr = new HuffDecompressor(*myBase, beginHuffSectionOffsetIt, endHuffSectionOffsetIt, endHuffDataOffset, extraFlags);
- myBase->seek(initialOffset, true); // myBase offset: ^ + 14
- }
- return true;
-}
-
-bool PalmDocStream::hasExtraSections() const {
- return myMaxRecordIndex < header().Offsets.size() - 1;
-}
-
-std::pair<int,int> PalmDocStream::imageLocation(const PdbHeader &header, int index) const {
- index += myMaxRecordIndex + 1;
- int recordNumber = header.Offsets.size();
- if (index > recordNumber - 1) {
- return std::make_pair(-1, -1);
- } else {
- int start = header.Offsets[index];
- int end = (index < recordNumber - 1) ?
- header.Offsets[index + 1] : myBase->offset();
- return std::make_pair(start, end - start);
- }
-}
-
-int PalmDocStream::firstImageLocationIndex(const std::string &fileName) {
- shared_ptr<ZLInputStream> fileStream = ZLFile(fileName).inputStream();
- if (fileStream.isNull() || !fileStream->open()) {
- return -1;
- }
-
- bool found = false;
- int index = 0;
- char bu[5] = { 0 };
- std::pair<int,int> firstImageLocation = imageLocation(header(), 0);
- fileStream->seek(firstImageLocation.first, false);
- while ((firstImageLocation.first > 0) && (firstImageLocation.second > 0)) {
- if (firstImageLocation.second > 4) {
- fileStream->read(bu, 4);
- static const char jpegStart[2] = { (char)0xFF, (char)0xd8 };
- if (std::strncmp(bu, "BM", 2) == 0 ||
- std::strncmp(bu, "GIF8", 4) == 0 ||
- std::strncmp(bu, jpegStart, 2) == 0) {
- found = true;
- break;
- }
- fileStream->seek(firstImageLocation.second - 4, false);
- } else {
- fileStream->seek(firstImageLocation.second, false);
- }
- index++;
- firstImageLocation = imageLocation(header(), index);
- }
-
- fileStream->close();
- return found ? index : -1;
-}