summaryrefslogtreecommitdiffstats
path: root/fbreader/src/formats/chm
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2024-06-07 23:30:05 +0900
committerMichele Calgaro <[email protected]>2024-06-07 23:30:05 +0900
commit17b259df9cb6b28779d4881b2b6c805ee2e48eea (patch)
tree5ed61937459cb7081089111b0242c01ec178f1f3 /fbreader/src/formats/chm
parent1cba8bce178eb2d6719c6f7f21e2c9352c5513a6 (diff)
downloadtde-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')
-rw-r--r--fbreader/src/formats/chm/BitStream.cpp44
-rw-r--r--fbreader/src/formats/chm/BitStream.h111
-rw-r--r--fbreader/src/formats/chm/CHMFile.cpp490
-rw-r--r--fbreader/src/formats/chm/CHMFile.h128
-rw-r--r--fbreader/src/formats/chm/CHMFileImage.cpp33
-rw-r--r--fbreader/src/formats/chm/CHMFileImage.h40
-rw-r--r--fbreader/src/formats/chm/CHMPlugin.cpp252
-rw-r--r--fbreader/src/formats/chm/CHMPlugin.h41
-rw-r--r--fbreader/src/formats/chm/CHMReferenceCollection.cpp91
-rw-r--r--fbreader/src/formats/chm/CHMReferenceCollection.h50
-rw-r--r--fbreader/src/formats/chm/E8Decoder.cpp61
-rw-r--r--fbreader/src/formats/chm/HHCReader.cpp107
-rw-r--r--fbreader/src/formats/chm/HHCReader.h57
-rw-r--r--fbreader/src/formats/chm/HHCReferenceCollector.cpp62
-rw-r--r--fbreader/src/formats/chm/HHCReferenceCollector.h45
-rw-r--r--fbreader/src/formats/chm/HtmlSectionReader.cpp128
-rw-r--r--fbreader/src/formats/chm/HtmlSectionReader.h50
-rw-r--r--fbreader/src/formats/chm/HuffmanDecoder.cpp60
-rw-r--r--fbreader/src/formats/chm/HuffmanDecoder.h53
-rw-r--r--fbreader/src/formats/chm/LZXDecompressor.cpp287
-rw-r--r--fbreader/src/formats/chm/LZXDecompressor.h88
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 &sectionInfo, 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 &sectionInfo = 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 &sectionInfo, 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 &sectionName) {
- 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 &sectionName);
-
-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__ */