1 /* This file is part of the KDE project 2 Copyright (C) 2012 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com> 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 along with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef MOBIHEADERGENERATOR_H 21 #define MOBIHEADERGENERATOR_H 22 23 #include <QObject> 24 #include <QHash> 25 #include <QChar> 26 27 // I follow the file structure that mobi packet creator create. 28 struct palmDBHeader { 29 palmDBHeader(); 30 31 /// database name. This name is 0 terminated in the field and will be used as the file name on a computer. 32 /// For eBooks this usually contains the title and may have the author depending on the length available. 33 QByteArray title; 34 35 /** bit field. 36 0x0002 Read-Only 37 0x0004 Dirty AppInfoArea 38 0x0008 Backup this database (i.e. no conduit exists) 39 0x0010 (16 decimal) Okay to install newer over existing copy, if present on PalmPilot 40 0x0020 (32 decimal) Force the PalmPilot to reset after this database is installed 41 0x0040 (64 decimal) Don't allow copy of file to be beamed to other Pilot. 42 */ 43 qint16 attributes; 44 45 qint16 version; /// file version 46 qint32 creationDate; /// No. of seconds since start of January 1, 1904. 47 qint32 modificationDate; /// No. of seconds since start of January 1, 1904. 48 qint32 lastBackupDate; /// No. of seconds since start of January 1, 1904. 49 qint32 modificationNumber; 50 qint32 appInfoId; /// offset to start of Application Info (if present) or null 51 qint32 sortInfoId; /// offset to start of Sort Info (if present) or null 52 QByteArray type; 53 QByteArray creator; 54 qint32 uniqueIdSeed; /// used internally to identify record 55 qint32 nextRecordIdList; /// Only used when in-memory on Palm OS. Always set to zero in stored files. 56 qint16 numberOfRecords; /// number of records in the file - N 57 58 // This will repeate of record numbers. 59 qint32 recordOffset; /// the offset of record n from the start of the PDB of this record 60 int recordUniqueId; /// The unique ID for this record. Often just a sequential count from 0 61 // Format: QHash<recordOffset, recorUniqueId> 62 QHash<int, int> recordsInfo; 63 // 64 65 // There should two bytes zero 66 67 int headerLength; // This is not in header just to have header length for myself 68 //qint32 grapToData; /// traditionally 2 zero bytes to Info or raw data 69 }; 70 71 /// PalmDocHeadr length = 16 72 struct palmDocHeader 73 { 74 palmDocHeader(); 75 76 qint16 compression; /// 1 == no compression, 2 = PalmDOC compression, 17480 = HUFF/CDIC compression 77 qint16 unused; /// Always zero 78 qint32 textLength; 79 qint16 pdbrecordCount; 80 qint16 maxRecordSize;/// Maximum size of each record containing text, always 4096 81 82 /// 0 == no encryption, 1 = Old Mobipocket 83 /// Encryption, 2 = Mobipocket Encryption 84 qint16 encryptionType; 85 86 qint16 unknown;/// Usually zero 87 qint32 headerLength; // This is not in header just to have header length for myself 88 }; 89 90 /// mobi header length 232 91 struct mobiHeader 92 { 93 mobiHeader(); 94 95 QByteArray identifier; /// the characters M O B I 96 int mobiHeaderLength;// = 232; 97 qint32 mobiType;// = 2; 98 /** The kind of Mobipocket file this is 99 2 Mobipocket Book 100 3 PalmDoc Book 101 4 Audio 102 232 mobipocket? generated by kindlegen1.2 103 248 KF8: generated by kindlegen2 104 257 News 105 258 News_Feed 106 259 News_Magazine 107 513 PICS 108 514 WORD 109 515 XLS 110 516 PPT 111 517 TEXT 112 518 HTML 113 */ 114 qint32 textEncoding; /// 1252 = CP1252 (WinLatin1); 65001 = UTF-8 115 qint32 uniqueId; /// Some kind of unique ID number 116 117 // FIXME: Really i do not know what should i set for this parameter. 118 qint32 fileVersion; /// Version of the Mobipocket format used in this file. 119 120 qint32 ortographicIndex;/// Section number of orthographic meta index. 0xFFFFFFFF if index is not available. 121 qint32 inflectionIndex;/// Section number of inflection meta index. 0xFFFFFFFF if index is not available. 122 qint32 indexNames;/// 0xFFFFFFFF if index is not available. 123 qint32 indexkeys;/// 0xFFFFFFFF if index is not available. 124 qint32 extraIndex0;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 125 qint32 extraIndex1;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 126 qint32 extraIndex2;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 127 qint32 extraIndex3;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 128 qint32 extraIndex4;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 129 qint32 extraIndex5;/// Section number of extra 0 meta index. 0xFFFFFFFF if index is not available. 130 131 qint32 firstNonBookIndex; /// First record number (starting with 0) that's not the book's text 132 133 qint32 fullNameOffset; /// Offset in record 0 (not from start of file) of the full name of the book 134 qint32 fullNameLength; /// Length in bytes of the full name of the book 135 136 /// Book locale code. Low byte is main language 09= English, 137 /// next byte is dialect, 08 = British, 04 = US. 138 /// Thus US English is 1033, UK English is 2057. 139 qint32 local; 140 qint32 inputLanguage;/// Input language for a dictionary 141 qint32 outputLanguage;/// Output language for a dictionary 142 qint32 minversion;/// Minimum mobipocket version support needed to read this file. 143 144 /// First record number (starting with 0) that contains an image. 145 /// Image records should be sequential. 146 qint32 firstImageIndex; 147 qint32 huffmanRecordOffset;/// The record number of the first huffman compression record. 148 qint32 huffmanRecordCount;/// The number of huffman compression records. 149 qint32 huffmanTableOffset;// = 0; 150 qint32 huffmanTableLength;// = 0; 151 152 qint32 EXTH_Flags;/// bitfield. if bit 6 (0x40) is set, then there's an EXTH record 153 154 // Here there is 32 byte 155 qint64 unknown1;// = 0; 156 qint64 unknown1_1;// = 0; 157 qint64 unknown1_2;// = 0; 158 qint64 unknown1_3;// = 0; 159 160 qint32 drmOffset;/// Offset to DRM key info in DRMed files. 0xFFFFFFFF if no DRM 161 qint32 drmCount;/// Number of entries in DRM info. 0xFFFFFFFF if no DRM 162 qint32 drmSize;/// Number of bytes in DRM info. 163 qint32 drmFlags;/// Some flags concerning the DRM info. 164 165 // Here there is 12 byte unknown 166 qint64 unknown2;// = 0; 167 qint32 unknown2_1;// = 0; 168 169 qint16 firstContentRecordNumber;/// Number of first text record. Normally 1. 170 qint16 lastContentRecordNumber; /// Last content record number 171 172 qint32 unknown3;/// Use 0x00000001. 173 174 qint32 FCIS_recordNumber; 175 qint32 unknown4;/// Use 0x00000001. 176 177 qint32 FLIS_recordNumber; 178 qint32 unknown5;/// Use 0x00000001. 179 180 qint64 unknown6;/// Use 0x0000000000000000. 181 qint32 unknown7;/// Use 0xFFFFFFFF. 182 qint32 unknown8;/// Use 0x00000000. 183 qint32 unknown9;/// Use 0xFFFFFFFF. 184 qint32 unknown10;/// Use 0xFFFFFFFF. 185 qint32 extraRecordDataFlags;// = 0; 186 187 /// (If not 0xFFFFFFFF)The record number of the 188 /// first INDX record created from an ncx file. 189 qint32 INDX_recordOffset; 190 }; 191 struct exthHeader { 192 exthHeader(); 193 194 QByteArray identifier; /// the characters E X T H. 195 196 /// the length of the EXTH header, including 197 /// the previous 4 bytes - but not including the final padding. 198 int headerLength; 199 200 /// The number of records in the EXTH header. the rest of the EXTH header 201 /// consists of repeated EXTH records to the end of the EXTH length. 202 qint32 exthRecordCount; 203 204 // EXTH record start 205 qint32 recordType; /// Exth Record type. Just a number identifying what's stored in the record 206 207 /// length of EXTH record = L , including the 8 bytes in 208 /// the type and length fields 209 210 int pad; 211 QHash<qint32, QByteArray> exthRecord; 212 }; 213 214 class MobiHeaderGenerator 215 { 216 public: 217 MobiHeaderGenerator(); 218 ~MobiHeaderGenerator(); 219 220 void generateMobiHeaders(QHash<QString, QString> metaData 221 ,int compressedTextSize, int uncompressedTextSize, 222 QList<int> imagesSize, QList<qint32> textRecordsOffset); 223 224 public: 225 palmDBHeader *m_dbHeader; 226 palmDocHeader *m_docHeader; 227 mobiHeader *m_mobiHeader; 228 exthHeader *m_exthHeader; 229 230 QByteArray m_title; 231 232 private: 233 void generatePalmDataBase(); 234 void generatePalmDocHeader(); 235 void generateMobiHeader(); 236 void generateEXTH(); 237 int calculateRecordsCount(); 238 239 private: 240 241 QByteArray m_author; 242 int m_rawTextSize; 243 int m_uncompressedTextSize; 244 QList<int> m_imgListSize; 245 QList<qint32> m_textRecordsOffset; 246 }; 247 248 #endif // MOBIHEADERGENERATOR_H 249