diff options
author | Michele Calgaro <[email protected]> | 2024-06-07 23:30:05 +0900 |
---|---|---|
committer | Michele Calgaro <[email protected]> | 2024-06-07 23:30:05 +0900 |
commit | 17b259df9cb6b28779d4881b2b6c805ee2e48eea (patch) | |
tree | 5ed61937459cb7081089111b0242c01ec178f1f3 /fbreader/src/formats/chm | |
parent | 1cba8bce178eb2d6719c6f7f21e2c9352c5513a6 (diff) | |
download | tde-ebook-reader-17b259df9cb6b28779d4881b2b6c805ee2e48eea.tar.gz tde-ebook-reader-17b259df9cb6b28779d4881b2b6c805ee2e48eea.zip |
Rename to tde-ebook-reader
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'fbreader/src/formats/chm')
21 files changed, 0 insertions, 2278 deletions
diff --git a/fbreader/src/formats/chm/BitStream.cpp b/fbreader/src/formats/chm/BitStream.cpp deleted file mode 100644 index bf6c642..0000000 --- a/fbreader/src/formats/chm/BitStream.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 "BitStream.h" - -const int BitStream::BufferSize = sizeof(unsigned int) * 8; - -unsigned int BitStream::get4BytesDirect() { - if (myByteStream + 4 > myByteStreamEnd) { - return 0; - } - unsigned int bytes = *myByteStream++ << 24; - bytes += *myByteStream++ << 16; - bytes += *myByteStream++ << 8; - bytes += *myByteStream++; - return bytes; -} - -bool BitStream::getBytesDirect(unsigned char *buffer, unsigned int length) { - if (myByteStream + length > myByteStreamEnd) { - return false; - } - std::memcpy(buffer, myByteStream, length); - myByteStream += length; - return true; -} diff --git a/fbreader/src/formats/chm/BitStream.h b/fbreader/src/formats/chm/BitStream.h deleted file mode 100644 index 80c1e25..0000000 --- a/fbreader/src/formats/chm/BitStream.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __BITSTREAM_H__ -#define __BITSTREAM_H__ - -#include <string> - -class BitStream { - -public: - static const int BufferSize; - -public: - BitStream(); - void setData(const std::string &data); - void reset(); - unsigned int peek(unsigned char length); - void remove(unsigned char length); - unsigned int get(unsigned char length); - unsigned int bytesLeft() const; - - unsigned int get4BytesDirect(); - bool getBytesDirect(unsigned char *buffer, unsigned int length); - -private: - bool ensure(unsigned char length); - -private: - unsigned int myBuffer; - unsigned char myBitCounter; - const unsigned char *myByteStream; - const unsigned char *myByteStreamEnd; - -private: - BitStream(const BitStream&); - const BitStream &operator = (const BitStream&); -}; - -inline BitStream::BitStream() : myBuffer(0), myBitCounter(0) { -} - -inline void BitStream::setData(const std::string &data) { - myByteStream = (const unsigned char*)data.data(); - myByteStreamEnd = myByteStream + data.length(); - myBuffer = 0; - myBitCounter = 0; -} - -inline void BitStream::reset() { - myByteStream -= myBitCounter / 8; - myBuffer = 0; - myBitCounter = 0; -} - -inline bool BitStream::ensure(unsigned char length) { - while ((myBitCounter < length) && (bytesLeft() >= 2)) { - myBuffer |= ((myByteStream[1] << 8) | myByteStream[0]) << (BitStream::BufferSize - 16 - myBitCounter); - myBitCounter += 16; - myByteStream += 2; - } - return myBitCounter >= length; -} - -inline unsigned int BitStream::peek(unsigned char length) { - ensure(length); - return (length > 0) ? (myBuffer >> (BufferSize - length)) : 0; -} - -inline void BitStream::remove(unsigned char length) { - if (ensure(length)) { - myBuffer <<= length; - myBitCounter -= length; - } -} - -inline unsigned int BitStream::get(unsigned char length) { - unsigned int bits; - if (length > 16) { - bits = peek(length - 16) << 16; - remove(length - 16); - bits += peek(16); - remove(16); - } else { - bits = peek(length); - remove(length); - } - return bits; -} - -inline unsigned int BitStream::bytesLeft() const { - return myByteStreamEnd - myByteStream; -} - -#endif /* __BITSTREAM_H__ */ diff --git a/fbreader/src/formats/chm/CHMFile.cpp b/fbreader/src/formats/chm/CHMFile.cpp deleted file mode 100644 index 8c62bca..0000000 --- a/fbreader/src/formats/chm/CHMFile.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLFile.h> -#include <ZLStringUtil.h> -#include <ZLUnicodeUtil.h> -#include <ZLInputStream.h> - -#include "CHMFile.h" -#include "CHMReferenceCollection.h" - -#include "LZXDecompressor.h" - -static std::string readString(ZLInputStream &stream, std::size_t length) { - std::string string(length, ' '); - stream.read(const_cast<char*>(string.data()), length); - return string; -} - -static unsigned short readUnsignedWord(ZLInputStream &stream) { - unsigned char buffer[2]; - stream.read((char*)buffer, 2); - unsigned short result = buffer[1]; - result = result << 8; - result += buffer[0]; - return result; -} - -static unsigned long readUnsignedDWord(ZLInputStream &stream) { - unsigned long lowPart = readUnsignedWord(stream); - unsigned long highPart = readUnsignedWord(stream); - return (highPart << 16) + lowPart; -} - -static unsigned long long readUnsignedQWord(ZLInputStream &stream) { - unsigned long long lowPart = readUnsignedDWord(stream); - unsigned long long highPart = readUnsignedDWord(stream); - return (highPart << 32) + lowPart; -} - -static unsigned long long readEncodedInteger(ZLInputStream &stream) { - unsigned long long result = 0; - char part; - do { - result = result << 7; - stream.read(&part, 1); - result += part & 0x7F; - } while (part & -0x80); - return result; -} - -CHMInputStream::CHMInputStream(shared_ptr<ZLInputStream> base, const CHMFileInfo::SectionInfo §ionInfo, std::size_t offset, std::size_t size) : myBase(base), mySectionInfo(sectionInfo), mySize(size) { - myBaseStartIndex = offset / 0x8000; - myBaseStartIndex -= myBaseStartIndex % sectionInfo.ResetInterval; - myBytesToSkip = offset - myBaseStartIndex * 0x8000; - myOutData = new unsigned char[0x8000]; -} - -CHMInputStream::~CHMInputStream() { - close(); - delete[] myOutData; -} - -bool CHMInputStream::open() { - myOffset = 0; - myDoSkip = true; - myBaseIndex = myBaseStartIndex; - if (myDecompressor.isNull()) { - myDecompressor = new LZXDecompressor(mySectionInfo.WindowSizeIndex); - } else { - myDecompressor->reset(); - } - myOutDataOffset = 0; - myOutDataLength = 0; - return true; -} - -std::size_t CHMInputStream::read(char *buffer, std::size_t maxSize) { - if (myDoSkip) { - do_read(0, myBytesToSkip); - myDoSkip = false; - } - std::size_t realSize = do_read(buffer, std::min(maxSize, mySize - myOffset)); - myOffset += realSize; - return realSize; -} - -std::size_t CHMInputStream::do_read(char *buffer, std::size_t maxSize) { - std::size_t realSize = 0; - do { - if (myOutDataLength == 0) { - if (myBaseIndex >= mySectionInfo.ResetTable.size()) { - break; - } - const bool isTail = myBaseIndex + 1 == mySectionInfo.ResetTable.size(); - const std::size_t start = mySectionInfo.ResetTable[myBaseIndex]; - const std::size_t end = isTail ? mySectionInfo.CompressedSize : mySectionInfo.ResetTable[myBaseIndex + 1]; - myOutDataLength = isTail ? mySectionInfo.UncompressedSize % 0x8000 : 0x8000; - myOutDataOffset = 0; - - myInData.erase(); - myInData.append(end - start, '\0'); - myBase->seek(mySectionInfo.Offset + start, true); - myBase->read((char*)myInData.data(), myInData.length()); - if (myBaseIndex % mySectionInfo.ResetInterval == 0) { - myDecompressor->reset(); - } - ++myBaseIndex; - - if (!myDecompressor->decompress(myInData, myOutData, myOutDataLength)) { - break; - } - } - const std::size_t partSize = std::min(myOutDataLength, maxSize); - if (buffer != 0) { - std::memcpy(buffer + realSize, myOutData + myOutDataOffset, partSize); - } - maxSize -= partSize; - realSize += partSize; - myOutDataLength -= partSize; - myOutDataOffset += partSize; - } while (maxSize != 0); - return realSize; -} - -void CHMInputStream::close() { - myDecompressor = 0; -} - -void CHMInputStream::seek(int offset, bool absoluteOffset) { - if (absoluteOffset) { - offset -= myOffset; - } - if (offset > 0) { - read(0, offset); - } else if (offset < 0) { - open(); - read(0, std::max(offset + (int)myOffset, 0)); - } -} - -std::size_t CHMInputStream::offset() const { - return myOffset; -} - -std::size_t CHMInputStream::sizeOfOpened() { - return mySize; -} - -shared_ptr<ZLInputStream> CHMFileInfo::entryStream(shared_ptr<ZLInputStream> base, const std::string &name) const { - RecordMap::const_iterator it = myRecords.find(ZLUnicodeUtil::toLower(name)); - if (it == myRecords.end()) { - return 0; - } - const RecordInfo &recordInfo = it->second; - if (recordInfo.Length == 0) { - return 0; - } - if (recordInfo.Section == 0) { - // TODO: implement - return 0; - } - if (recordInfo.Section > mySectionInfos.size()) { - return 0; - } - const SectionInfo §ionInfo = mySectionInfos[recordInfo.Section - 1]; - if (recordInfo.Offset + recordInfo.Length > sectionInfo.UncompressedSize) { - return 0; - } - - return new CHMInputStream(base, sectionInfo, recordInfo.Offset, recordInfo.Length); -} - -CHMFileInfo::CHMFileInfo(const ZLFile &file) : myFilePath(file.path()) { -} - -bool CHMFileInfo::moveToEntry(ZLInputStream &stream, const std::string &entryName) { - RecordMap::const_iterator it = myRecords.find(entryName); - if (it == myRecords.end()) { - return false; - } - RecordInfo recordInfo = it->second; - if (recordInfo.Section > mySectionInfos.size()) { - return false; - } - if (recordInfo.Section != 0) { - // TODO: ??? - return false; - } - - stream.seek(mySection0Offset + recordInfo.Offset, true); - return true; -} - -bool CHMFileInfo::init(ZLInputStream &stream) { - { - // header start - if (readString(stream, 4) != "ITSF") { - return false; - } - - unsigned long version = readUnsignedDWord(stream); - - // DWORD total length - // DWORD unknown - // DWORD timestamp - // DWORD language id - // 0x10 bytes 1st GUID - // 0x10 bytes 2nd GUID - // QWORD section 0 offset - // QWORD section 0 length - stream.seek(4 * 4 + 2 * 0x10 + 2 * 8, false); - - unsigned long long sectionOffset1 = readUnsignedQWord(stream); - unsigned long long sectionLength1 = readUnsignedQWord(stream); - mySection0Offset = sectionOffset1 + sectionLength1; - // header end - - // additional header data start - if (version > 2) { - mySection0Offset = readUnsignedQWord(stream); - } - // additional header data end - - stream.seek(sectionOffset1, true); - // header section 1 start - // directory header start - if (readString(stream, 4) != "ITSP") { - return false; - } - - // DWORD version - // DWORD length - // DWORD 0x000A - // DWORD chunk size - // DWORD density - // DWORD depth - // DWORD root chunk number - // DWORD first chunk number - // DWORD last chunk number - // DWORD -1 - stream.seek(10 * 4, false); - unsigned long dirChunkNumber = readUnsignedDWord(stream); - // ... - stream.seek(36, false); - // header section 1 end - - std::size_t nextOffset = stream.offset(); - for (unsigned long i = 0; i < dirChunkNumber; ++i) { - nextOffset += 4096; - std::string header = readString(stream, 4); - if (header == "PMGL") { - unsigned long quickRefAreaSize = readUnsignedDWord(stream) % 4096; - stream.seek(12, false); - std::size_t startOffset = stream.offset(); - std::size_t oldOffset = startOffset; - while (startOffset < nextOffset - quickRefAreaSize) { - int nameLength = readEncodedInteger(stream); - std::string name = readString(stream, nameLength); - int contentSection = readEncodedInteger(stream); - int offset = readEncodedInteger(stream); - int length = readEncodedInteger(stream); - if (name.substr(0, 2) != "::") { - name = ZLUnicodeUtil::toLower(name); - } - myRecords.insert( - std::make_pair( - name, - CHMFileInfo::RecordInfo(contentSection, offset, length) - ) - ); - startOffset = stream.offset(); - if (oldOffset == startOffset) { - break; - } - oldOffset = startOffset; - } - } else if (header == "PMGI") { - unsigned long quickRefAreaSize = readUnsignedDWord(stream); - std::size_t startOffset = stream.offset(); - std::size_t oldOffset = startOffset; - while (startOffset < nextOffset - quickRefAreaSize) { - int nameLength = readEncodedInteger(stream); - std::string name = readString(stream, nameLength); - // chunk number - readEncodedInteger(stream); - startOffset = stream.offset(); - if (oldOffset == startOffset) { - break; - } - oldOffset = startOffset; - } - } - stream.seek(nextOffset, true); - if (stream.offset() != nextOffset) { - break; - } - } - } - - { - if (!moveToEntry(stream, "::DataSpace/NameList")) { - return false; - } - stream.seek(2, false); - const int sectionNumber = readUnsignedWord(stream); - for (int i = 0; i < sectionNumber; ++i) { - const int length = readUnsignedWord(stream); - std::string sectionName; - sectionName.reserve(length); - for (int j = 0; j < length; ++j) { - sectionName += (char)readUnsignedWord(stream); - } - stream.seek(2, false); - mySectionNames.push_back(sectionName); - } - } - - { - for (unsigned int i = 1; i < mySectionNames.size(); ++i) { - RecordMap::const_iterator it = - myRecords.find("::DataSpace/Storage/" + mySectionNames[i] + "/Content"); - if (it == myRecords.end()) { - return false; - } - RecordInfo recordInfo = it->second; - if (recordInfo.Section != 0) { - return false; - } - mySectionInfos.push_back(SectionInfo()); - SectionInfo &info = mySectionInfos.back(); - info.Offset = mySection0Offset + recordInfo.Offset; - info.Length = recordInfo.Length; - - if (!moveToEntry(stream, "::DataSpace/Storage/" + mySectionNames[i] + "/ControlData")) { - return false; - } - stream.seek(4, false); - std::string lzxc = readString(stream, 4); - if (lzxc != "LZXC") { - return false; - } - const int version = readUnsignedDWord(stream); - if ((version <= 0) || (version > 2)) { - return false; - } - info.ResetInterval = readUnsignedDWord(stream); - if (version == 1) { - info.ResetInterval /= 0x8000; - } - info.WindowSizeIndex = (version == 1) ? 0 : 15; - { - int ws = readUnsignedDWord(stream); - if (ws > 0) { - while ((ws & 1) == 0) { - ws >>= 1; - info.WindowSizeIndex++; - } - } - } - - if (!moveToEntry(stream, "::DataSpace/Storage/" + mySectionNames[i] + "/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable")) { - return false; - } - stream.seek(4, false); - const std::size_t entriesNumber = readUnsignedDWord(stream); - if (entriesNumber == 0) { - return false; - } - if (entriesNumber > 2048) { - // file size is greater than 60 Mb - return false; - } - info.ResetTable.reserve(entriesNumber); - stream.seek(8, false); - info.UncompressedSize = readUnsignedQWord(stream); - if ((info.UncompressedSize - 1) / 0x8000 != entriesNumber - 1) { - return false; - } - info.CompressedSize = readUnsignedQWord(stream); - stream.seek(8, false); - std::size_t previous = 0; - for (std::size_t j = 0; j < entriesNumber; ++j) { - std::size_t value = readUnsignedQWord(stream); - if ((j > 0) == (value <= previous)) { - return false; - } - info.ResetTable.push_back(value); - previous = value; - } - } - } - - return true; -} - -static std::string readNTString(ZLInputStream &stream) { - std::string s; - char c; - while (stream.read(&c, 1) == 1) { - if (c == '\0') { - break; - } else { - s += c; - } - } - return CHMReferenceCollection::fullReference("/", s); -} - -bool CHMFileInfo::FileNames::empty() const { - return Start.empty() && TOC.empty() && Home.empty() && Index.empty(); -} - -CHMFileInfo::FileNames CHMFileInfo::sectionNames(shared_ptr<ZLInputStream> base) const { - FileNames names; - shared_ptr<ZLInputStream> stringsStream = entryStream(base, "/#STRINGS"); - if (!stringsStream.isNull() && stringsStream->open()) { - std::vector<std::string> fileNames; - int tocIndex = -1; - int indexIndex = -1; - for (int i = 0; i < 12; ++i) { - std::string argument = readNTString(*stringsStream); - if (argument.empty() || (argument[argument.length() - 1] == '/')) { - continue; - } - if (myRecords.find(argument) == myRecords.end()) { - continue; - } - if ((tocIndex == -1) && ZLStringUtil::stringEndsWith(argument, ".hhc")) { - tocIndex = fileNames.size(); - names.TOC = argument; - } else if ((indexIndex == -1) && ZLStringUtil::stringEndsWith(argument, ".hhk")) { - indexIndex = fileNames.size(); - names.Index = argument; - } - fileNames.push_back(argument); - } - std::size_t startIndex = std::max(3, std::max(tocIndex, indexIndex) + 1); - if (startIndex < 11) { - if (startIndex < fileNames.size()) { - names.Start = fileNames[startIndex]; - } - if (startIndex + 1 < fileNames.size()) { - names.Home = fileNames[startIndex + 1]; - } - } - stringsStream->close(); - } - if (names.TOC.empty()) { - for (RecordMap::const_iterator it = myRecords.begin(); it != myRecords.end(); ++it) { - if (ZLStringUtil::stringEndsWith(it->first, ".hhc")) { - names.TOC = it->first; - break; - } - } - } - if (names.empty()) { - for (RecordMap::const_iterator it = myRecords.begin(); it != myRecords.end(); ++it) { - if ((ZLStringUtil::stringEndsWith(it->first, ".htm")) || - (ZLStringUtil::stringEndsWith(it->first, ".html"))) { - names.Start = it->first; - break; - } - } - } - - return names; -} - -const std::string CHMFileInfo::filePath() const { - return myFilePath; -} diff --git a/fbreader/src/formats/chm/CHMFile.h b/fbreader/src/formats/chm/CHMFile.h deleted file mode 100644 index d98bd84..0000000 --- a/fbreader/src/formats/chm/CHMFile.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __CHMFILE_H__ -#define __CHMFILE_H__ - -#include <string> -#include <map> -#include <vector> - -#include <shared_ptr.h> -#include <ZLInputStream.h> - -class ZLFile; - -class LZXDecompressor; - -class CHMFileInfo { - -public: - struct FileNames { - std::string TOC; - std::string Index; - std::string Start; - std::string Home; - - bool empty() const; - }; - -public: - CHMFileInfo(const ZLFile &file); - bool init(ZLInputStream &stream); - // We assume that base exists and is already open - shared_ptr<ZLInputStream> entryStream(shared_ptr<ZLInputStream> base, const std::string &name) const; - // We assume that base exists and is already open - FileNames sectionNames(shared_ptr<ZLInputStream> base) const; - const std::string filePath() const; - -private: - bool moveToEntry(ZLInputStream &stream, const std::string &entryName); - -private: - unsigned long long mySection0Offset; - - struct RecordInfo { - RecordInfo(int section, int offset, int length) : Section(section), Offset(offset), Length(length) {} - std::size_t Section; - std::size_t Offset; - std::size_t Length; - }; - - typedef std::map<std::string,RecordInfo> RecordMap; - RecordMap myRecords; - std::vector<std::string> mySectionNames; - - struct SectionInfo { - std::size_t WindowSizeIndex; - std::size_t ResetInterval; - std::size_t Offset; - std::size_t Length; - std::size_t CompressedSize; - std::size_t UncompressedSize; - std::vector<std::size_t> ResetTable; - }; - std::vector<SectionInfo> mySectionInfos; - - const std::string myFilePath; - -private: - CHMFileInfo(const CHMFileInfo&); - const CHMFileInfo &operator = (const CHMFileInfo&); - -friend class CHMInputStream; -}; - -class CHMInputStream : public ZLInputStream { - -public: - CHMInputStream(shared_ptr<ZLInputStream> base, const CHMFileInfo::SectionInfo §ionInfo, std::size_t offset, std::size_t size); - ~CHMInputStream(); - - bool open(); - std::size_t read(char *buffer, std::size_t maxSize); - void close(); - - void seek(int offset, bool absoluteOffset); - std::size_t offset() const; - std::size_t sizeOfOpened(); - -private: - std::size_t do_read(char *buffer, std::size_t maxSize); - -private: - shared_ptr<ZLInputStream> myBase; - const CHMFileInfo::SectionInfo mySectionInfo; - std::size_t myBaseStartIndex; - std::size_t myBaseIndex; - std::size_t myBytesToSkip; - const std::size_t mySize; - - std::size_t myOffset; - bool myDoSkip; - - shared_ptr<LZXDecompressor> myDecompressor; - std::string myInData; - - unsigned char *myOutData; - std::size_t myOutDataOffset; - std::size_t myOutDataLength; -}; - -#endif /* __CHMFILE_H__ */ diff --git a/fbreader/src/formats/chm/CHMFileImage.cpp b/fbreader/src/formats/chm/CHMFileImage.cpp deleted file mode 100644 index a2b58f0..0000000 --- a/fbreader/src/formats/chm/CHMFileImage.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLFile.h> - -#include "CHMFileImage.h" - -CHMFileImage::CHMFileImage(shared_ptr<CHMFileInfo> info, const std::string &entry) : ZLStreamImage(ZLMimeType::IMAGE_AUTO, 0, 0), myInfo(info), myEntry(entry) { -} - -shared_ptr<ZLInputStream> CHMFileImage::inputStream() const { - shared_ptr<ZLInputStream> baseStream = ZLFile(myInfo->filePath()).inputStream(); - if (baseStream.isNull() || !baseStream->open()) { - return 0; - } - return myInfo->entryStream(baseStream, myEntry); -} diff --git a/fbreader/src/formats/chm/CHMFileImage.h b/fbreader/src/formats/chm/CHMFileImage.h deleted file mode 100644 index bacb6aa..0000000 --- a/fbreader/src/formats/chm/CHMFileImage.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __CHMFILEIMAGE_H__ -#define __CHMFILEIMAGE_H__ - -#include <ZLStreamImage.h> - -#include "CHMFile.h" - -class CHMFileImage : public ZLStreamImage { - -public: - CHMFileImage(shared_ptr<CHMFileInfo> info, const std::string &entry); - -private: - shared_ptr<ZLInputStream> inputStream() const; - -private: - shared_ptr<CHMFileInfo> myInfo; - std::string myEntry; -}; - -#endif /* __CHMFILEIMAGE_H__ */ diff --git a/fbreader/src/formats/chm/CHMPlugin.cpp b/fbreader/src/formats/chm/CHMPlugin.cpp deleted file mode 100644 index 9ea88e4..0000000 --- a/fbreader/src/formats/chm/CHMPlugin.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLUnicodeUtil.h> -#include <ZLStringUtil.h> -#include <ZLFile.h> -#include <ZLInputStream.h> - -#include "CHMPlugin.h" -#include "CHMFile.h" -#include "CHMFileImage.h" -#include "CHMReferenceCollection.h" -#include "HHCReader.h" -#include "HHCReferenceCollector.h" -#include "../txt/PlainTextFormat.h" -#include "HtmlSectionReader.h" -#include "../util/MergedStream.h" -#include "../html/HtmlReaderStream.h" - -#include "../../bookmodel/BookModel.h" -#include "../../library/Book.h" - -bool CHMPlugin::acceptsFile(const ZLFile &file) const { - return file.extension() == "chm"; -} - -class CHMTextStream : public MergedStream { - -public: - CHMTextStream(CHMFileInfo &chmFile, shared_ptr<ZLInputStream> base); - -private: - void resetToStart(); - shared_ptr<ZLInputStream> nextStream(); - -private: - CHMFileInfo &myCHMFile; - shared_ptr<ZLInputStream> myBase; - std::vector<std::string> myEntryNames; - std::size_t myIndex; -}; - -CHMTextStream::CHMTextStream(CHMFileInfo &chmFile, shared_ptr<ZLInputStream> base) : myCHMFile(chmFile), myBase(base) { -} - -void CHMTextStream::resetToStart() { - myIndex = 0; - - if (!myEntryNames.empty()) { - return; - } - - CHMFileInfo::FileNames names = myCHMFile.sectionNames(myBase); - if (names.empty()) { - return; - } - - CHMReferenceCollection referenceCollection; - - referenceCollection.addReference(names.Start, false); - referenceCollection.addReference(names.Home, false); - - shared_ptr<ZLInputStream> tocStream = myCHMFile.entryStream(myBase, names.TOC); - if (!tocStream.isNull() && tocStream->open()) { - referenceCollection.setPrefix(names.TOC); - HHCReferenceCollector(referenceCollection).readDocument(*tocStream); - } - - while (referenceCollection.containsNonProcessedReferences()) { - myEntryNames.push_back(referenceCollection.nextReference()); - } -} - -shared_ptr<ZLInputStream> CHMTextStream::nextStream() { - while (myIndex < myEntryNames.size()) { - shared_ptr<ZLInputStream> stream = myCHMFile.entryStream(myBase, myEntryNames[myIndex++]); - if (!stream.isNull()) { - return new HtmlReaderStream(stream, 50000); - } - } - return 0; -} - -bool CHMPlugin::readMetaInfo(Book &book) const { - const ZLFile &file = book.file(); - shared_ptr<ZLInputStream> stream = file.inputStream(); - if (stream.isNull() || !stream->open()) { - return false; - } - - CHMFileInfo chmFile(file); - if (!chmFile.init(*stream)) { - return false; - } - - CHMFileInfo::FileNames names = chmFile.sectionNames(stream); - if (names.empty()) { - return false; - } - - /* - shared_ptr<ZLInputStream> entryStream = chmFile.entryStream(stream, names.Start); - if (entryStream.isNull()) { - entryStream = chmFile.entryStream(stream, names.Home); - } - if (entryStream.isNull()) { - entryStream = chmFile.entryStream(stream, names.TOC); - } - / * - if (entryStream.isNull()) { - chmFile.entryStream(stream, names.Index); - } - * / - if (entryStream.isNull()) { - return false; - } - */ - - CHMTextStream textStream(chmFile, stream); - detectEncodingAndLanguage(book, textStream); - if (book.encoding().empty()) { - return false; - } - - return true; -} - -bool CHMPlugin::readLanguageAndEncoding(Book &book) const { - (void)book; - return true; -} - -class CHMHyperlinkMatcher : public BookModel::HyperlinkMatcher { - -public: - BookModel::Label match(const std::map<std::string,BookModel::Label> &lMap, const std::string &id) const; -}; - -BookModel::Label CHMHyperlinkMatcher::match(const std::map<std::string,BookModel::Label> &lMap, const std::string &id) const { - std::map<std::string,BookModel::Label>::const_iterator it = lMap.find(id); - if (it != lMap.end()) { - return it->second; - } - std::size_t index = id.find('#'); - if (index != std::string::npos) { - it = lMap.find(id.substr(0, index)); - } - return (it != lMap.end()) ? it->second : BookModel::Label(0, -1); -} - -bool CHMPlugin::readModel(BookModel &model) const { - model.setHyperlinkMatcher(new CHMHyperlinkMatcher()); - - const Book &book = *model.book(); - const ZLFile &file = book.file(); - - shared_ptr<ZLInputStream> stream = file.inputStream(); - if (stream.isNull() || !stream->open()) { - return false; - } - - shared_ptr<CHMFileInfo> info = new CHMFileInfo(file); - if (!info->init(*stream)) { - return false; - } - - CHMFileInfo::FileNames names = info->sectionNames(stream); - if (names.empty()) { - return false; - } - - CHMReferenceCollection referenceCollection; - - referenceCollection.addReference(names.Start, false); - referenceCollection.addReference(names.Home, false); - - const std::string &encoding = book.encoding(); - - shared_ptr<ZLInputStream> tocStream = info->entryStream(stream, names.TOC); - HHCReader hhcReader(referenceCollection, model, encoding); - if (!tocStream.isNull() && tocStream->open()) { - referenceCollection.setPrefix(names.TOC); - hhcReader.readDocument(*tocStream); - } - - /* - if (!tocStream.isNull() && tocStream->open()) { - std::string buf; - buf.append(tocStream->sizeOfOpened(), '\0'); - tocStream->read((char*)buf.data(), buf.length()); - std::cerr << "[ " << names.TOC << " ]\n" << buf << "\n"; - } - */ - - int contentCounter = 0; - PlainTextFormat format(file); - HtmlSectionReader reader(model, format, encoding, info, referenceCollection); - while (referenceCollection.containsNonProcessedReferences()) { - const std::string fileName = referenceCollection.nextReference(); - if (ZLStringUtil::stringEndsWith(fileName, ".jpg") || - ZLStringUtil::stringEndsWith(fileName, ".gif")) { - std::string lowerCasedFileName = ZLUnicodeUtil::toLower(fileName); - BookReader bookReader(model); - bookReader.setMainTextModel(); - bookReader.addHyperlinkLabel(lowerCasedFileName); - bookReader.pushKind(REGULAR); - bookReader.beginParagraph(); - bookReader.addImageReference(lowerCasedFileName); - bookReader.addImage(fileName, new CHMFileImage(info, fileName)); - bookReader.endParagraph(); - bookReader.insertEndOfTextParagraph(); - } else { - shared_ptr<ZLInputStream> entryStream = info->entryStream(stream, fileName); - if (!entryStream.isNull() && entryStream->open()) { - /* - std::string buf; - buf.append(entryStream->sizeOfOpened(), '\0'); - entryStream->read((char*)buf.data(), buf.length()); - std::cerr << "[ " << fileName << " ]\n" << buf << "\n"; - entryStream->open(); - */ - reader.setSectionName(fileName); - reader.readDocument(*entryStream); - ++contentCounter; - } - } - } - if (contentCounter == 0) { - return false; - } - - hhcReader.setReferences(); - - - return true; -} diff --git a/fbreader/src/formats/chm/CHMPlugin.h b/fbreader/src/formats/chm/CHMPlugin.h deleted file mode 100644 index 0d38e62..0000000 --- a/fbreader/src/formats/chm/CHMPlugin.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __CHMPLUGIN_H__ -#define __CHMPLUGIN_H__ - -#include "../FormatPlugin.h" - -class CHMPlugin : public FormatPlugin { - -public: - CHMPlugin(); - ~CHMPlugin(); - bool providesMetaInfo() const; - bool acceptsFile(const ZLFile &file) const; - bool readMetaInfo(Book &book) const; - bool readLanguageAndEncoding(Book &book) const; - bool readModel(BookModel &model) const; -}; - -inline CHMPlugin::CHMPlugin() {} -inline CHMPlugin::~CHMPlugin() {} -inline bool CHMPlugin::providesMetaInfo() const { return false; } - -#endif /* __CHMPLUGIN_H__ */ diff --git a/fbreader/src/formats/chm/CHMReferenceCollection.cpp b/fbreader/src/formats/chm/CHMReferenceCollection.cpp deleted file mode 100644 index f29dd28..0000000 --- a/fbreader/src/formats/chm/CHMReferenceCollection.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLUnicodeUtil.h> - -#include "CHMReferenceCollection.h" -#include "../util/MiscUtil.h" - -std::string CHMReferenceCollection::fullReference(const std::string &prefix, std::string reference) { - reference = MiscUtil::decodeHtmlURL(reference); - if ((reference.length() > 0) && (reference[0] == '/')) { - return reference; - } - const int index = reference.rfind("::"); - if (index != -1) { - return reference.substr(index + 2); - } - - int counter = 0; - while (reference.substr(counter * 3, 3) == "../") { - ++counter; - } - - int slashIndex = prefix.length() - 1; - for (int i = 0; (i < counter) && (slashIndex > 0); ++i) { - slashIndex = prefix.rfind('/', slashIndex - 1); - } - return prefix.substr(0, slashIndex + 1) + reference.substr(counter * 3); -} - -CHMReferenceCollection::CHMReferenceCollection() : myPrefix("/") { -} - -const std::string &CHMReferenceCollection::addReference(const std::string &reference, bool doConvert) { - if (reference.empty()) { - return reference; - } - std::string fullRef = doConvert ? fullReference(myPrefix, reference) : MiscUtil::decodeHtmlURL(reference); - - const int index = fullRef.find('#'); - if (index == -1) { - fullRef = ZLUnicodeUtil::toLower(fullRef); - } else { - fullRef = ZLUnicodeUtil::toLower(fullRef.substr(0, index)); - } - std::set<std::string>::const_iterator it = myReferences.find(fullRef); - if (it != myReferences.end()) { - return *it; - } - - myReferences.insert(fullRef); - myReferenceQueue.push(fullRef); - return myReferenceQueue.back(); -} - -bool CHMReferenceCollection::containsNonProcessedReferences() const { - return !myReferenceQueue.empty(); -} - -const std::string CHMReferenceCollection::nextReference() { - if (myReferenceQueue.empty()) { - return ""; - } - const std::string front = myReferenceQueue.front(); - myReferenceQueue.pop(); - return front; -} - -void CHMReferenceCollection::setPrefix(const std::string &fileName) { - myPrefix = MiscUtil::decodeHtmlURL(fileName.substr(0, fileName.rfind('/') + 1)); -} - -const std::string &CHMReferenceCollection::prefix() const { - return myPrefix; -} diff --git a/fbreader/src/formats/chm/CHMReferenceCollection.h b/fbreader/src/formats/chm/CHMReferenceCollection.h deleted file mode 100644 index 6a53c45..0000000 --- a/fbreader/src/formats/chm/CHMReferenceCollection.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __CHMREFERENCECOLLECTION_H__ -#define __CHMREFERENCECOLLECTION_H__ - -#include <string> -#include <set> -#include <queue> - -class CHMReferenceCollection { - -public: - static std::string fullReference(const std::string &prefix, std::string reference); - -public: - CHMReferenceCollection(); - const std::string &addReference(const std::string &reference, bool doConvert); - bool containsNonProcessedReferences() const; - const std::string nextReference(); - void setPrefix(const std::string &fileName); - const std::string &prefix() const; - -private: - std::string myPrefix; - std::set<std::string> myReferences; - std::queue<std::string> myReferenceQueue; - -private: - CHMReferenceCollection(const CHMReferenceCollection&); - const CHMReferenceCollection &operator = (const CHMReferenceCollection&); -}; - -#endif /* __CHMREFERENCECOLLECTION_H__ */ diff --git a/fbreader/src/formats/chm/E8Decoder.cpp b/fbreader/src/formats/chm/E8Decoder.cpp deleted file mode 100644 index 53b9335..0000000 --- a/fbreader/src/formats/chm/E8Decoder.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 "LZXDecompressor.h" - -void LZXDecompressor::E8Decoder::reset(unsigned int fileSize) { - myFileSize = fileSize; - myFramesCounter = 0; - myPosition = 0; -} - -void LZXDecompressor::E8Decoder::decode(unsigned char *buffer, const std::size_t size) { - if (myFramesCounter >= 32768) { - return; - } - ++myFramesCounter; - if (myFileSize == 0) { - return; - } - - myPosition += size; - - if (size <= 10) { - return; - } - - const unsigned char *end = buffer + size - 10; - - for (unsigned char *ptr = buffer; ptr < end; ) { - if (*ptr == 0xE8) { - int absoluteOffset = - ptr[1] + (ptr[2] << 8) + (ptr[3] << 16) + (ptr[4] << 24); - int relativeOffset = - (absoluteOffset >= 0) ? - absoluteOffset - (ptr - buffer) : absoluteOffset + myFileSize; - ptr[1] = (unsigned char)relativeOffset; - ptr[2] = (unsigned char)(relativeOffset >> 8); - ptr[3] = (unsigned char)(relativeOffset >> 16); - ptr[4] = (unsigned char)(relativeOffset >> 24); - ptr += 5; - } else { - ++ptr; - } - } -} diff --git a/fbreader/src/formats/chm/HHCReader.cpp b/fbreader/src/formats/chm/HHCReader.cpp deleted file mode 100644 index 4fd3105..0000000 --- a/fbreader/src/formats/chm/HHCReader.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLUnicodeUtil.h> - -#include "HHCReader.h" -#include "CHMReferenceCollection.h" - -HHCReader::HHCReader(CHMReferenceCollection &collection, BookModel &model, const std::string &encoding) : HtmlReader(encoding), myReferenceCollection(collection), myBookReader(model) { -} - -HHCReader::~HHCReader() { -} - -void HHCReader::startDocumentHandler() { - myBookReader.setMainTextModel(); -} - -void HHCReader::endDocumentHandler() { - std::string tmp0; - myText.swap(tmp0); - std::string tmp1; - myReference.swap(tmp1); -} - -static const std::string UL = "UL"; -static const std::string LI = "LI"; -static const std::string OBJECT = "OBJECT"; -static const std::string PARAM = "PARAM"; -static const std::string NAME = "NAME"; -static const std::string VALUE = "VALUE"; -static const std::string NAME_VALUE = "Name"; -static const std::string LOCAL_VALUE = "Local"; - -static bool isFirstChild = false; - -bool HHCReader::tagHandler(const HtmlTag &tag) { - if (tag.Start) { - if (tag.Name == UL) { - isFirstChild = true; - } else if (tag.Name == LI) { - } else if (tag.Name == OBJECT) { - myText.erase(); - myReference.erase(); - } else if (tag.Name == PARAM) { - std::string name; - std::string value; - for (std::vector<HtmlAttribute>::const_iterator it = tag.Attributes.begin(); it != tag.Attributes.end(); ++it) { - if (it->Name == NAME) { - name = it->Value; - } else if (it->Name == VALUE) { - value = it->Value; - } - } - if (name == NAME_VALUE) { - myText = value; - } else if (name == LOCAL_VALUE) { - myReference = myReferenceCollection.addReference(value, true); - } - } - } else { - if (tag.Name == UL) { - myBookReader.endContentsParagraph(); - } else if (tag.Name == OBJECT) { - if (!myText.empty() || !myReference.empty()) { - if (!isFirstChild) { - myBookReader.endContentsParagraph(); - } else { - isFirstChild = false; - } - myBookReader.beginContentsParagraph(); - if (myText.empty()) { - myText = "..."; - } - myBookReader.addContentsData(myText.empty() ? "..." : myText); - myReferenceVector.push_back(ZLUnicodeUtil::toLower(myReference)); - } - } - } - return true; -} - -bool HHCReader::characterDataHandler(const char*, std::size_t, bool) { - return true; -} - -void HHCReader::setReferences() { - for (std::size_t i = 0; i < myReferenceVector.size(); ++i) { - myBookReader.setReference(i, myBookReader.model().label(myReferenceVector[i]).ParagraphNumber); - } -} diff --git a/fbreader/src/formats/chm/HHCReader.h b/fbreader/src/formats/chm/HHCReader.h deleted file mode 100644 index c0e4cef..0000000 --- a/fbreader/src/formats/chm/HHCReader.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __HHCREADER_H__ -#define __HHCREADER_H__ - -#include <vector> - -#include "../html/HtmlReader.h" -#include "../../bookmodel/BookModel.h" -#include "../../bookmodel/BookReader.h" - -class CHMReferenceCollection; - -class HHCReader : public HtmlReader { - -public: - HHCReader(CHMReferenceCollection &collection, BookModel &model, const std::string &encoding); - ~HHCReader(); - - void setReferences(); - -private: - void startDocumentHandler(); - void endDocumentHandler(); - - bool tagHandler(const HtmlTag &tag); - bool characterDataHandler(const char*, std::size_t, bool); - -private: - CHMReferenceCollection &myReferenceCollection; - - std::string myText; - std::string myReference; - - BookReader myBookReader; - - std::vector<std::string> myReferenceVector; -}; - -#endif /* __HHCREADER_H__ */ diff --git a/fbreader/src/formats/chm/HHCReferenceCollector.cpp b/fbreader/src/formats/chm/HHCReferenceCollector.cpp deleted file mode 100644 index 6abcef2..0000000 --- a/fbreader/src/formats/chm/HHCReferenceCollector.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008-2012 Geometer Plus <[email protected]> - * - * 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 <ZLUnicodeUtil.h> - -#include "HHCReferenceCollector.h" -#include "CHMReferenceCollection.h" - -HHCReferenceCollector::HHCReferenceCollector(CHMReferenceCollection &collection) : HtmlReader("US-ASCII"), myReferenceCollection(collection) { -} - -void HHCReferenceCollector::startDocumentHandler() { -} - -void HHCReferenceCollector::endDocumentHandler() { -} - -static const std::string PARAM = "PARAM"; -static const std::string NAME = "NAME"; -static const std::string VALUE = "VALUE"; -static const std::string NAME_VALUE = "Name"; -static const std::string LOCAL_VALUE = "Local"; - -bool HHCReferenceCollector::tagHandler(const HtmlTag &tag) { - if (tag.Start) { - if (tag.Name == PARAM) { - std::string name; - std::string value; - for (std::vector<HtmlAttribute>::const_iterator it = tag.Attributes.begin(); it != tag.Attributes.end(); ++it) { - if (it->Name == NAME) { - name = it->Value; - } else if (it->Name == VALUE) { - value = it->Value; - } - } - if (name == LOCAL_VALUE) { - myReferenceCollection.addReference(value, true); - } - } - } - return true; -} - -bool HHCReferenceCollector::characterDataHandler(const char*, std::size_t, bool) { - return true; -} diff --git a/fbreader/src/formats/chm/HHCReferenceCollector.h b/fbreader/src/formats/chm/HHCReferenceCollector.h deleted file mode 100644 index 20e58d1..0000000 --- a/fbreader/src/formats/chm/HHCReferenceCollector.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2008-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __HHCREFERENCECOLLECTOR_H__ -#define __HHCREFERENCECOLLECTOR_H__ - -#include <vector> - -#include "../html/HtmlReader.h" - -class CHMReferenceCollection; - -class HHCReferenceCollector : public HtmlReader { - -public: - HHCReferenceCollector(CHMReferenceCollection &collection); - -private: - void startDocumentHandler(); - void endDocumentHandler(); - - bool tagHandler(const HtmlTag &tag); - bool characterDataHandler(const char*, std::size_t, bool); - -private: - CHMReferenceCollection &myReferenceCollection; -}; - -#endif /* __HHCREFERENCECOLLECTOR_H__ */ diff --git a/fbreader/src/formats/chm/HtmlSectionReader.cpp b/fbreader/src/formats/chm/HtmlSectionReader.cpp deleted file mode 100644 index 9973e14..0000000 --- a/fbreader/src/formats/chm/HtmlSectionReader.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <ZLUnicodeUtil.h> - -#include "HtmlSectionReader.h" -#include "CHMReferenceCollection.h" -#include "CHMFileImage.h" -#include "../util/MiscUtil.h" -#include "../html/HtmlTagActions.h" - -class HtmlSectionHrefTagAction : public HtmlHrefTagAction { - -public: - HtmlSectionHrefTagAction(HtmlSectionReader &reader); - void run(const HtmlReader::HtmlTag &tag); -}; - -class HtmlSectionImageTagAction : public HtmlTagAction { - -public: - HtmlSectionImageTagAction(HtmlSectionReader &reader); - void run(const HtmlReader::HtmlTag &tag); -}; - -shared_ptr<HtmlTagAction> HtmlSectionReader::createAction(const std::string &tag) { - if (tag == "IMG") { - return new HtmlSectionImageTagAction(*this); - } else if (tag == "A") { - return new HtmlSectionHrefTagAction(*this); - } - return HtmlBookReader::createAction(tag); -} - -HtmlSectionReader::HtmlSectionReader(BookModel &model, const PlainTextFormat &format, const std::string &encoding, shared_ptr<CHMFileInfo> info, CHMReferenceCollection &collection) : HtmlBookReader("", model, format, encoding), myInfo(info), myReferenceCollection(collection) { - setBuildTableOfContent(false); -} - -void HtmlSectionReader::setSectionName(const std::string §ionName) { - myCurrentSectionName = ZLUnicodeUtil::toLower(sectionName); - myReferenceCollection.setPrefix(myCurrentSectionName); -} - -void HtmlSectionReader::startDocumentHandler() { - HtmlBookReader::startDocumentHandler(); - myBookReader.addHyperlinkLabel(ZLUnicodeUtil::toLower(myCurrentSectionName)); -} - -void HtmlSectionReader::endDocumentHandler() { - HtmlBookReader::endDocumentHandler(); - myBookReader.insertEndOfTextParagraph(); -} - -HtmlSectionHrefTagAction::HtmlSectionHrefTagAction(HtmlSectionReader &reader) : HtmlHrefTagAction(reader) { -} - -void HtmlSectionHrefTagAction::run(const HtmlReader::HtmlTag &tag) { - if (tag.Start) { - HtmlSectionReader &reader = (HtmlSectionReader&)myReader; - for (unsigned int i = 0; i < tag.Attributes.size(); ++i) { - if (tag.Attributes[i].Name == "NAME") { - bookReader().addHyperlinkLabel(ZLUnicodeUtil::toLower(reader.myCurrentSectionName + '#' + tag.Attributes[i].Value)); - } else if ((hyperlinkType() == REGULAR) && (tag.Attributes[i].Name == "HREF")) { - const std::string &value = tag.Attributes[i].Value; - if (!value.empty()) { - FBTextKind referenceType = MiscUtil::referenceType(value); - if (referenceType != INTERNAL_HYPERLINK) { - bookReader().addHyperlinkControl(referenceType, value); - setHyperlinkType(referenceType); - } else { - const int index = value.find('#'); - std::string sectionName = (index == -1) ? value : value.substr(0, index); - sectionName = ZLUnicodeUtil::toLower(MiscUtil::decodeHtmlURL(sectionName)); - if (sectionName.empty()) { - sectionName = reader.myCurrentSectionName; - } else { - sectionName = reader.myReferenceCollection.addReference(sectionName, true); - } - bookReader().addHyperlinkControl( - INTERNAL_HYPERLINK, ZLUnicodeUtil::toLower((index == -1) ? sectionName : (sectionName + value.substr(index))) - ); - setHyperlinkType(INTERNAL_HYPERLINK); - } - } - } - } - } else if (hyperlinkType() != REGULAR) { - bookReader().addControl(hyperlinkType(), false); - setHyperlinkType(REGULAR); - } -} - -HtmlSectionImageTagAction::HtmlSectionImageTagAction(HtmlSectionReader &reader) : HtmlTagAction(reader) { -} - -void HtmlSectionImageTagAction::run(const HtmlReader::HtmlTag &tag) { - if (tag.Start) { - //bookReader().endParagraph(); - HtmlSectionReader &reader = (HtmlSectionReader&)myReader; - for (unsigned int i = 0; i < tag.Attributes.size(); ++i) { - if (tag.Attributes[i].Name == "SRC") { - std::string fileName = MiscUtil::decodeHtmlURL(tag.Attributes[i].Value); - fileName = CHMReferenceCollection::fullReference(reader.myReferenceCollection.prefix(), fileName); - fileName = ZLUnicodeUtil::toLower(fileName); - bookReader().addImageReference(fileName); - bookReader().addImage(fileName, new CHMFileImage(reader.myInfo, fileName)); - break; - } - } - //bookReader().beginParagraph(); - } -} diff --git a/fbreader/src/formats/chm/HtmlSectionReader.h b/fbreader/src/formats/chm/HtmlSectionReader.h deleted file mode 100644 index 424c178..0000000 --- a/fbreader/src/formats/chm/HtmlSectionReader.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __HTMLSECTIONREADER_H__ -#define __HTMLSECTIONREADER_H__ - -#include "../html/HtmlBookReader.h" -#include "CHMFile.h" - -class CHMReferenceCollection; - -class HtmlSectionReader : public HtmlBookReader { - -public: - HtmlSectionReader(BookModel &model, const PlainTextFormat &format, const std::string &encoding, shared_ptr<CHMFileInfo> info, CHMReferenceCollection &collection); - void setSectionName(const std::string §ionName); - -private: - void startDocumentHandler(); - void endDocumentHandler(); - -private: - shared_ptr<HtmlTagAction> createAction(const std::string &tag); - -private: - shared_ptr<CHMFileInfo> myInfo; - CHMReferenceCollection &myReferenceCollection; - std::string myCurrentSectionName; - -friend class HtmlSectionHrefTagAction; -friend class HtmlSectionImageTagAction; -}; - -#endif /* __HTMLSECTIONREADER_H__ */ diff --git a/fbreader/src/formats/chm/HuffmanDecoder.cpp b/fbreader/src/formats/chm/HuffmanDecoder.cpp deleted file mode 100644 index db8718f..0000000 --- a/fbreader/src/formats/chm/HuffmanDecoder.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 <algorithm> - -#include "HuffmanDecoder.h" - -HuffmanDecoder::HuffmanDecoder() : myMaxBitsNumber(0) { -} - -void HuffmanDecoder::reset() { - CodeLengths.clear(); -} - -bool HuffmanDecoder::buildTable() { - myMaxBitsNumber = 0; - for (unsigned short symbol = 0; symbol < CodeLengths.size(); symbol++) { - myMaxBitsNumber = std::max(CodeLengths[symbol], myMaxBitsNumber); - } - if (myMaxBitsNumber > 16) { - return false; - } - - unsigned int tableSize = 1 << myMaxBitsNumber; - mySymbols.clear(); - mySymbols.reserve(tableSize); - - for (unsigned char i = 1; i <= myMaxBitsNumber; ++i) { - for (unsigned short symbol = 0; symbol < CodeLengths.size(); symbol++) { - if (CodeLengths[symbol] == i) { - mySymbols.insert(mySymbols.end(), 1 << (myMaxBitsNumber - i), symbol); - if (mySymbols.size() > tableSize) { - return false; - } - } - } - } - - if (mySymbols.size() < tableSize) { - mySymbols.insert(mySymbols.end(), tableSize - mySymbols.size(), 0); - } - - return true; -} diff --git a/fbreader/src/formats/chm/HuffmanDecoder.h b/fbreader/src/formats/chm/HuffmanDecoder.h deleted file mode 100644 index bd9f700..0000000 --- a/fbreader/src/formats/chm/HuffmanDecoder.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __HUFFMANDECODER_H__ -#define __HUFFMANDECODER_H__ - -#include <vector> - -#include "BitStream.h" - -class HuffmanDecoder { - -public: - HuffmanDecoder(); - - bool buildTable(); - void reset(); - - unsigned int getSymbol(BitStream &stream) const; - -private: - unsigned char myMaxBitsNumber; - std::vector<unsigned short> mySymbols; - std::vector<unsigned char> CodeLengths; - HuffmanDecoder(const HuffmanDecoder&); - const HuffmanDecoder &operator = (const HuffmanDecoder&); - -friend class LZXDecompressor; -}; - -inline unsigned int HuffmanDecoder::getSymbol(BitStream &stream) const { - unsigned int symbol = mySymbols[stream.peek(myMaxBitsNumber)]; - stream.remove(CodeLengths[symbol]); - return symbol; -} - -#endif /* __HUFFMANDECODER_H__ */ diff --git a/fbreader/src/formats/chm/LZXDecompressor.cpp b/fbreader/src/formats/chm/LZXDecompressor.cpp deleted file mode 100644 index 38b4311..0000000 --- a/fbreader/src/formats/chm/LZXDecompressor.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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 "LZXDecompressor.h" - -static unsigned int slotNumber(int windowSizeIndex) { - if (windowSizeIndex == 20) { - return 42; - } else if (windowSizeIndex == 21) { - return 50; - } else { - return 2 * windowSizeIndex; - } -} - -LZXDecompressor::LZXDecompressor(int windowSizeIndex) : myWindow(1 << windowSizeIndex, 0), mySlotNumber(slotNumber(windowSizeIndex)) { - reset(); -} - -void LZXDecompressor::reset() { - myCurrentBlockType = UNKNOWNN; - myReadHeader = true; - - myState.WindowIterator = myWindow.begin(); - myState.R0 = 1; - myState.R1 = 1; - myState.R2 = 1; - - myMainTree.reset(); - myLengthTree.reset(); - - myBlockBytesLeft = 0; - - myE8Decoder.reset(0); -} - -static bool fill(std::vector<unsigned char> &data, std::vector<unsigned char>::iterator &it, int num, unsigned char value) { - if (data.end() - it < num) { - return false; - } - std::vector<unsigned char>::iterator end = it + num; - while (it != end) { - *it++ = value; - } - return true; -} - -bool LZXDecompressor::readLengths(HuffmanDecoder &decoder, std::size_t from, std::size_t size) { - HuffmanDecoder preTree; - preTree.CodeLengths.reserve(20); - for (int i = 0; i < 20; i++) { - preTree.CodeLengths.push_back(myBitStream.get(4)); - } - if (!preTree.buildTable()) { - return false; - } - - std::vector<unsigned char> &lengths = decoder.CodeLengths; - if (lengths.size() < from + size) { - lengths.insert(lengths.end(), from + size - lengths.size(), 0); - } - std::vector<unsigned char>::iterator start = lengths.begin() + from; - std::vector<unsigned char>::iterator end = start + size; - for (std::vector<unsigned char>::iterator it = start; it != end; ) { - int z = preTree.getSymbol(myBitStream); - if (z == 17) { - if (!fill(lengths, it, myBitStream.get(4) + 4, 0)) { - return false; - } - } else if (z == 18) { - if (!fill(lengths, it, myBitStream.get(5) + 20, 0)) { - return false; - } - } else if (z == 19) { - unsigned int num = myBitStream.get(1) + 4; - z = *it - preTree.getSymbol(myBitStream); - if (!fill(lengths, it, num, (z < 0) ? z + 17 : z)) { - return false; - } - } else { - z = *it - z; - *it++ = (z < 0) ? z + 17 : z; - } - } - - return true; -} - -static const unsigned int basePosition[51] = { - 0, 1, 2, 3, 4, 6, 8, 12, - 16, 24, 32, 48, 64, 96, 128, 192, - 256, 384, 512, 768, 1024, 1536, 2048, 3072, - 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, - 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, - 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936, - 1835008, 1966080, 2097152 -}; - -bool LZXDecompressor::decodeBytes(DecodingState &state, std::size_t bytesToDecode) { - if (myCurrentBlockType == UNCOMPRESSED) { - if (!myBitStream.getBytesDirect(&*state.WindowIterator, bytesToDecode)) { - return false; - } - state.WindowIterator += bytesToDecode; - return true; - } - - while (bytesToDecode > 0) { - int symbol = myMainTree.getSymbol(myBitStream); - if (symbol < 256) { - *state.WindowIterator++ = symbol; - --bytesToDecode; - continue; - } - - std::size_t length = symbol % 8; - if (length == 7) { - length += myLengthTree.getSymbol(myBitStream); - } - length += 2; - if (length > bytesToDecode) { - return false; - } - - std::size_t offset = (symbol - 256) / 8; - switch (offset) { - case 0: - offset = state.R0; - break; - case 1: - offset = state.R1; - state.R1 = state.R0; - state.R0 = offset; - break; - case 2: - offset = state.R2; - state.R2 = state.R0; - state.R0 = offset; - break; - default: - if ((myCurrentBlockType == VERBATIM) && (offset == 3)) { - offset = 1; - } else { - if (offset > 50) { - return false; - } - const int positionFooterBits = std::max(0, std::min((int)offset / 2 - 1, 17)); - offset = basePosition[offset] - 2; - if ((myCurrentBlockType == VERBATIM) || (positionFooterBits == 1) || (positionFooterBits == 2)) { - offset += myBitStream.get(positionFooterBits); - } else if (positionFooterBits == 3) { - offset += myAlignedOffsetTree.getSymbol(myBitStream); - } else if (positionFooterBits > 3) { - offset += 8 * myBitStream.get(positionFooterBits - 3); - offset += myAlignedOffsetTree.getSymbol(myBitStream); - } else { - offset = 1; - } - } - state.R2 = state.R1; - state.R1 = state.R0; - state.R0 = offset; - break; - } - - if ((state.WindowIterator - myWindow.begin()) + myWindow.size() < offset) { - return false; - } - if (myWindow.size() >= offset + (myWindow.end() - state.WindowIterator)) { - offset += myWindow.size(); - if (myWindow.size() >= offset + (myWindow.end() - state.WindowIterator)) { - return false; - } - } - std::vector<unsigned char>::iterator srcIt = state.WindowIterator + (myWindow.size() - offset); - for (std::size_t i = 0; i < length; ++i) { - if (srcIt == myWindow.end()) { - srcIt -= myWindow.size(); - } - *state.WindowIterator++ = *srcIt++; - } - bytesToDecode -= length; - } - return true; -} - -bool LZXDecompressor::decompress(const std::string &data, unsigned char *outBuffer, const std::size_t outSize) { - myBitStream.setData(data); - - if (myReadHeader) { - if (myBitStream.get(1) == 1) { - myE8Decoder.reset(myBitStream.get(32)); - } - myReadHeader = false; - } - - DecodingState state = myState; - - for (std::size_t bytesToWrite = outSize; bytesToWrite > 0; ) { - if (myBlockBytesLeft == 0) { - if (myCurrentBlockType == UNCOMPRESSED) { - if (myBlockSize & 1) { - myBitStream.remove(8); - } - myBitStream.reset(); - } - - myCurrentBlockType = (BlockType)myBitStream.get(3); - myBlockSize = myBitStream.get(24); - myBlockBytesLeft = myBlockSize; - - switch (myCurrentBlockType) { - case UNCOMPRESSED: - myBitStream.reset(); - state.R0 = myBitStream.get4BytesDirect(); - state.R1 = myBitStream.get4BytesDirect(); - state.R2 = myBitStream.get4BytesDirect(); - break; - - case ALIGNED: - myAlignedOffsetTree.CodeLengths.clear(); - for (int i = 0; i < 8; i++) { - myAlignedOffsetTree.CodeLengths.push_back(myBitStream.get(3)); - } - if (!myAlignedOffsetTree.buildTable()) { - return false; - } - // no break; it's not a mistake - - case VERBATIM: - if (!readLengths(myMainTree, 0, 256) || - !readLengths(myMainTree, 256, 8 * mySlotNumber) || - !readLengths(myLengthTree, 0, 249) || - !myMainTree.buildTable() || - !myLengthTree.buildTable()) { - return false; - } - break; - - default: - return false; - } - } - - while ((myBlockBytesLeft > 0) && (bytesToWrite > 0)) { - std::size_t bytesToDecode = std::min(myBlockBytesLeft, bytesToWrite); - if (state.WindowIterator + bytesToDecode > myWindow.end()) { - return false; - } - - if (!decodeBytes(state, bytesToDecode)) { - return false; - } - - bytesToWrite -= bytesToDecode; - myBlockBytesLeft -= bytesToDecode; - } - } - - std::vector<unsigned char>::iterator jt = - (state.WindowIterator != myWindow.begin()) ? state.WindowIterator : myWindow.end(); - std::memcpy(outBuffer, &*(jt - outSize), outSize); - - myState = state; - - myE8Decoder.decode(outBuffer, outSize); - - return true; -} diff --git a/fbreader/src/formats/chm/LZXDecompressor.h b/fbreader/src/formats/chm/LZXDecompressor.h deleted file mode 100644 index dac9e1f..0000000 --- a/fbreader/src/formats/chm/LZXDecompressor.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2004-2012 Geometer Plus <[email protected]> - * - * 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. - */ - -#ifndef __LZXDECOMPRESSOR_H__ -#define __LZXDECOMPRESSOR_H__ - -#include <string> -#include <vector> - -#include "BitStream.h" -#include "HuffmanDecoder.h" - -class LZXDecompressor { - -public: - LZXDecompressor(int windowSizeIndex); - void reset(); - - bool decompress(const std::string &data, unsigned char *outBuffer, const std::size_t outSize); - -private: - struct DecodingState { - std::vector<unsigned char>::iterator WindowIterator; - unsigned int R0; - unsigned int R1; - unsigned int R2; - }; - - bool readLengths(HuffmanDecoder &decoder, std::size_t from, std::size_t size); - bool decodeBytes(DecodingState &state, std::size_t bytesToDecode); - -private: - enum BlockType { - UNKNOWNN = 0, - VERBATIM = 1, - ALIGNED = 2, - UNCOMPRESSED = 3 - }; - - BlockType myCurrentBlockType; - bool myReadHeader; - - std::vector<unsigned char> myWindow; - - DecodingState myState; - - std::size_t myBlockSize; - std::size_t myBlockBytesLeft; - - const unsigned int mySlotNumber; - HuffmanDecoder myMainTree; - HuffmanDecoder myLengthTree; - HuffmanDecoder myAlignedOffsetTree; - - BitStream myBitStream; - - class E8Decoder { - - public: - void reset(unsigned int fileSize); - void decode(unsigned char *buffer, const std::size_t size); - - private: - unsigned int myFramesCounter; - unsigned int myFileSize; - unsigned int myPosition; - }; - - E8Decoder myE8Decoder; -}; - -#endif /* __LZXDECOMPRESSOR_H__ */ |