/src/libe-book/src/lib/BBeBParser.cpp
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* |
3 | | * This file is part of the libe-book project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | */ |
9 | | |
10 | | #include <algorithm> |
11 | | |
12 | | #include <librevenge-stream/librevenge-stream.h> |
13 | | |
14 | | #include "libebook_utils.h" |
15 | | #include "EBOOKCharsetConverter.h" |
16 | | #include "EBOOKMemoryStream.h" |
17 | | #include "EBOOKStreamView.h" |
18 | | #include "EBOOKUTF8Stream.h" |
19 | | #include "EBOOKZlibStream.h" |
20 | | #include "BBeBMetadataParser.h" |
21 | | #include "BBeBParser.h" |
22 | | |
23 | | using std::string; |
24 | | |
25 | | namespace libebook |
26 | | { |
27 | | |
28 | | namespace |
29 | | { |
30 | | |
31 | | enum Tag |
32 | | { |
33 | | TAG_OBJECT_START = 0xf500, |
34 | | TAG_OBJECT_END = 0xf501, |
35 | | TAG_OBJECT_INFO_LINK = 0xf502, |
36 | | TAG_LINK = 0xf503, |
37 | | TAG_STREAM_SIZE = 0xf504, |
38 | | TAG_STREAM_START = 0xf505, |
39 | | TAG_STREAM_END = 0xf506, |
40 | | TAG_F507 = 0xf507, |
41 | | TAG_F508 = 0xf508, |
42 | | TAG_F509 = 0xf509, |
43 | | TAG_F50A = 0xf50a, |
44 | | TAG_CONTAINED_OBJECTS_LIST = 0xf50b, |
45 | | TAG_F50D = 0xf50d, |
46 | | TAG_F50E = 0xf50e, |
47 | | TAG_FONT_SIZE = 0xf511, |
48 | | TAG_FONT_WIDTH = 0xf512, |
49 | | TAG_FONT_ESCAPEMENT = 0xf513, |
50 | | TAG_FONT_ORIENTATION = 0xf514, |
51 | | TAG_FONT_WEIGHT = 0xf515, |
52 | | TAG_FONT_FACENAME = 0xf516, |
53 | | TAG_TEXT_COLOR = 0xf517, |
54 | | TAG_TEXT_BG_COLOR = 0xf518, |
55 | | TAG_WORD_SPACE = 0xf519, |
56 | | TAG_LETTER_SPACE = 0xf51a, |
57 | | TAG_BASE_LINE_SKIP = 0xf51b, |
58 | | TAG_LINE_SPACE = 0xf51c, |
59 | | TAG_PAR_INDENT = 0xf51d, |
60 | | TAG_PAR_SKIP = 0xf51e, |
61 | | TAG_TOP_MARGIN = 0xf521, |
62 | | TAG_F522 = 0xf522, |
63 | | TAG_F523 = 0xf523, |
64 | | TAG_ODD_SIDE_MARGIN = 0xf524, |
65 | | TAG_PAGE_HEIGHT = 0xf525, |
66 | | TAG_PAGE_WIDTH = 0xf526, |
67 | | TAG_F527 = 0xf527, |
68 | | TAG_F528 = 0xf528, |
69 | | TAG_F529 = 0xf529, |
70 | | TAG_F52A = 0xf52a, |
71 | | TAG_F52B = 0xf52b, |
72 | | TAG_EVEN_SIDE_MARGIN = 0xf52c, |
73 | | TAG_F52D = 0xf52d, |
74 | | TAG_F52E = 0xf52e, |
75 | | TAG_BLOCK_WIDTH = 0xf531, |
76 | | TAG_BLOCK_HEIGHT = 0xf532, |
77 | | TAG_BLOCK_RULE = 0xf533, |
78 | | TAG_F534 = 0xf534, |
79 | | TAG_F535 = 0xf535, |
80 | | TAG_F536 = 0xf536, |
81 | | TAG_F537 = 0xf537, |
82 | | TAG_TOP_SKIP = 0xf538, |
83 | | TAG_F539 = 0xf539, |
84 | | TAG_F53A = 0xf53a, |
85 | | TAG_ALIGN = 0xf53c, |
86 | | TAG_F53D = 0xf53d, |
87 | | TAG_F53E = 0xf53e, |
88 | | TAG_MINI_PAGE_HEIGHT = 0xf541, |
89 | | TAG_MINI_PAGE_WIDTH = 0xf542, |
90 | | TAG_F544 = 0xf544, |
91 | | TAG_F545 = 0xf545, |
92 | | TAG_LOCATION_Y = 0xf546, |
93 | | TAG_LOCATION_X = 0xf547, |
94 | | TAG_F548 = 0xf548, |
95 | | TAG_PUT_SOUND = 0xf549, |
96 | | TAG_IMAGE_CROP_RECT = 0xf54a, |
97 | | TAG_IMAGE_SIZE = 0xf54b, |
98 | | TAG_IMAGE_STREAM = 0xf54c, |
99 | | TAG_F54D = 0xf54d, |
100 | | TAG_F54E = 0xf54e, |
101 | | TAG_CANVAS_WIDTH = 0xf551, |
102 | | TAG_CANVAS_HEIGHT = 0xf552, |
103 | | TAG_F553 = 0xf553, |
104 | | TAG_STREAM_FLAGS = 0xf554, |
105 | | TAG_F555 = 0xf555, |
106 | | TAG_F556 = 0xf556, |
107 | | TAG_F557 = 0xf557, |
108 | | TAG_F558 = 0xf558, |
109 | | TAG_FONT_FILE_NAME = 0xf559, |
110 | | TAG_F55A = 0xf55a, |
111 | | TAG_VIEW_POINT = 0xf55b, |
112 | | TAG_PAGE_LIST = 0xf55c, |
113 | | TAG_FONT_FACE_NAME = 0xf55d, |
114 | | TAG_F55E = 0xf55e, |
115 | | TAG_F561 = 0xf561, |
116 | | TAG_F562 = 0xf562, |
117 | | TAG_F563 = 0xf563, |
118 | | TAG_F564 = 0xf564, |
119 | | TAG_F565 = 0xf565, |
120 | | TAG_F566 = 0xf566, |
121 | | TAG_F567 = 0xf567, |
122 | | TAG_F568 = 0xf568, |
123 | | TAG_F569 = 0xf569, |
124 | | TAG_F56A = 0xf56a, |
125 | | TAG_F56B = 0xf56b, |
126 | | TAG_JUMP_TO = 0xf56c, |
127 | | TAG_F56D = 0xf56d, |
128 | | TAG_F56E = 0xf56e, |
129 | | TAG_F571 = 0xf571, |
130 | | TAG_F572 = 0xf572, |
131 | | TAG_RULED_LINE = 0xf573, |
132 | | TAG_RUBY_ALIGN = 0xf575, |
133 | | TAG_RUBY_OVERHANG = 0xf576, |
134 | | TAG_EMPTY_DOTS_POSITION = 0xf577, |
135 | | TAG_EMPTY_DOTS_CODE = 0xf578, |
136 | | TAG_EMPTY_LINE_POSITION = 0xf579, |
137 | | TAG_EMPTY_LINE_MODE = 0xf57a, |
138 | | TAG_CHILD_PAGE_TREE = 0xf57b, |
139 | | TAG_PARENT_PAGE_TREE = 0xf57c, |
140 | | TAG_BEGIN_ITALIC = 0xf581, |
141 | | TAG_END_ITALIC = 0xf582, |
142 | | TAG_BEGIN_P = 0xf5a1, |
143 | | TAG_END_P = 0xf5a2, |
144 | | TAG_KOMA_GAIJI = 0xf5a5, |
145 | | TAG_KOMA_EMP_DOT_CHAR = 0xf5a6, |
146 | | TAG_BEGIN_BUTTON = 0xf5a7, |
147 | | TAG_END_BUTTON = 0xf5a8, |
148 | | TAG_BEGIN_RUBY = 0xf5a9, |
149 | | TAG_END_RUBY = 0xf5aa, |
150 | | TAG_BEGIN_RUBY_BASE = 0xf5ab, |
151 | | TAG_END_RUBY_BASE = 0xf5ac, |
152 | | TAG_BEGIN_RUBY_TEXT = 0xf5ad, |
153 | | TAG_END_RUBY_TEXT = 0xf5ae, |
154 | | TAG_KOMA_YOKOMOJI = 0xf5b1, |
155 | | TAG_F5B2 = 0xf5b2, |
156 | | TAG_BEGIN_TATE = 0xf5b3, |
157 | | TAG_END_TATE = 0xf5b4, |
158 | | TAG_BEGIN_NEKASE = 0xf5b5, |
159 | | TAG_END_NEKASE = 0xf5b6, |
160 | | TAG_BEGIN_SUP = 0xf5b7, |
161 | | TAG_END_SUP = 0xf5b8, |
162 | | TAG_BEGIN_SUB = 0xf5b9, |
163 | | TAG_END_SUB = 0xf5ba, |
164 | | TAG_F5BB = 0xf5bb, |
165 | | TAG_F5BC = 0xf5bc, |
166 | | TAG_F5BD = 0xf5bd, |
167 | | TAG_F5BE = 0xf5be, |
168 | | TAG_BEGIN_EMP_LINE = 0xf5c1, |
169 | | TAG_END_EMP_LINE = 0xf5c2, |
170 | | TAG_BEGIN_DRAW_CHAR = 0xf5c3, |
171 | | TAG_END_DRAW_CHAR = 0xf5c4, |
172 | | TAG_F5C5 = 0xf5c5, |
173 | | TAG_F5C6 = 0xf5c6, |
174 | | TAG_F5C7 = 0xf5c7, |
175 | | TAG_KOMA_AUTO_SPACING = 0xf5c8, |
176 | | TAG_F5C9 = 0xf5c9, |
177 | | TAG_SPACE = 0xf5ca, |
178 | | TAG_F5CB = 0xf5cb, |
179 | | TAG_TEXT_SIZE = 0xf5cc, |
180 | | TAG_KOMA_PLOT = 0xf5d1, |
181 | | TAG_EOL = 0xf5d2, |
182 | | TAG_WAIT = 0xf5d4, |
183 | | TAG_SOUND_STOP = 0xf5d6, |
184 | | TAG_MOVE_OBJ = 0xf5d7, |
185 | | TAG_BOOK_FONT = 0xf5d8, |
186 | | TAG_KOMA_PLOT_TEXT = 0xf5d9, |
187 | | TAG_F5DA = 0xf5da, |
188 | | TAG_F5DB = 0xf5db, |
189 | | TAG_F5DC = 0xf5dc, |
190 | | TAG_CHAR_SPACE = 0xf5dd, |
191 | | TAG_LINE_WIDTH = 0xf5f1, |
192 | | TAG_LINE_COLOR = 0xf5f2, |
193 | | TAG_FILL_COLOR = 0xf5f3, |
194 | | TAG_LINE_MODE = 0xf5f4, |
195 | | TAG_MOVE_TO = 0xf5f5, |
196 | | TAG_LINE_TO = 0xf5f6, |
197 | | TAG_DRAW_BOX = 0xf5f7, |
198 | | TAG_DRAW_ELLIPSE = 0xf5f8, |
199 | | TAG_F5F9 = 0xf5f9 |
200 | | }; |
201 | | |
202 | | // NOTE: This is just guessing. I have no idea if the stream flags are |
203 | | // actually binary flags, or just a set of possible values. |
204 | | enum StreamType |
205 | | { |
206 | | STREAM_TYPE_BBEB_TAGS = 0, |
207 | | STREAM_TYPE_JPEG = BBEB_IMAGE_TYPE_JPEG, |
208 | | STREAM_TYPE_PNG = BBEB_IMAGE_TYPE_PNG, |
209 | | STREAM_TYPE_BMP = BBEB_IMAGE_TYPE_BMP, |
210 | | STREAM_TYPE_GIF = BBEB_IMAGE_TYPE_GIF, |
211 | | STREAM_TYPE_BBEB_TOC = 0x51, |
212 | | STREAM_TYPE_BBEB_TAGS_COMPRESSED = 0x100 |
213 | | }; |
214 | | |
215 | | class ParserException |
216 | | { |
217 | | }; |
218 | | |
219 | | const std::string readString(librevenge::RVNGInputStream *const input) |
220 | 75.7k | { |
221 | 75.7k | const unsigned size = readU16(input); |
222 | | |
223 | 75.7k | EBOOKStreamView textStrm(input, input->tell(), input->tell() + int(size)); |
224 | 75.7k | EBOOKCharsetConverter utf16("UTF-16LE"); |
225 | 75.7k | EBOOKUTF8Stream utf8Strm(&textStrm, &utf16); |
226 | | |
227 | 75.7k | std::string text; |
228 | 3.80M | while (!utf8Strm.isEnd()) |
229 | 3.72M | text.push_back((char) readU8(&utf8Strm)); |
230 | | |
231 | 75.7k | return text; |
232 | 75.7k | } |
233 | | |
234 | | } |
235 | | |
236 | | struct BBeBHeader |
237 | | { |
238 | | BBeBHeader(); |
239 | | |
240 | | unsigned version; |
241 | | uint16_t key; |
242 | | unsigned rootOID; |
243 | | uint64_t numberOfObjects; |
244 | | uint64_t objectIndexOffset; |
245 | | unsigned xmlCompSize; |
246 | | BBeBImageType thumbnailType; |
247 | | unsigned thumbnailSize; |
248 | | unsigned dpi; |
249 | | unsigned width; |
250 | | unsigned tocOID; |
251 | | }; |
252 | | |
253 | | BBeBHeader::BBeBHeader() |
254 | 6.21k | : version(0) |
255 | 6.21k | , key(0) |
256 | 6.21k | , rootOID(0) |
257 | 6.21k | , numberOfObjects(0) |
258 | 6.21k | , objectIndexOffset(0) |
259 | 6.21k | , xmlCompSize(0) |
260 | 6.21k | , thumbnailType(BBEB_IMAGE_TYPE_UNKNOWN) |
261 | 6.21k | , thumbnailSize(0) |
262 | 6.21k | , dpi(0) |
263 | 6.21k | , width(0) |
264 | 6.21k | , tocOID(0) |
265 | 6.21k | { |
266 | 6.21k | } |
267 | | |
268 | | BBeBParser::BBeBParser(librevenge::RVNGInputStream *const input, librevenge::RVNGTextInterface *const document) |
269 | 6.21k | : m_collector(document) |
270 | 6.21k | , m_input(input) |
271 | 6.21k | , m_header(new BBeBHeader()) |
272 | 6.21k | , m_objectIndex() |
273 | 6.21k | , m_pageTree(0) |
274 | 6.21k | , m_toc() |
275 | 6.21k | , m_objectNesting(0) |
276 | 6.21k | { |
277 | 6.21k | } |
278 | | |
279 | | BBeBParser::~BBeBParser() |
280 | 6.21k | { |
281 | 6.21k | } |
282 | | |
283 | | bool BBeBParser::parse() |
284 | 6.21k | { |
285 | 6.21k | readHeader(); |
286 | 6.21k | readMetadata(); |
287 | 6.21k | readThumbnail(); |
288 | 6.21k | readObjectIndex(); |
289 | | |
290 | 6.21k | if (0 != m_header->tocOID) |
291 | 591 | readObject(m_header->tocOID, OBJECT_TYPE_TOC); |
292 | | |
293 | 6.21k | m_collector.startDocument(); |
294 | 6.21k | readObject(m_header->rootOID, OBJECT_TYPE_BOOK_ATR); |
295 | 6.21k | m_collector.endDocument(); |
296 | | |
297 | 6.21k | return false; |
298 | 6.21k | } |
299 | | |
300 | | bool BBeBParser::isSupported(librevenge::RVNGInputStream *const input) |
301 | 0 | { |
302 | 0 | const unsigned char signature[] = { 'L', '\0', 'R', '\0', 'F', '\0' }; |
303 | 0 | unsigned long readBytes = 0; |
304 | 0 | const unsigned char *s = input->read(sizeof(signature), readBytes); |
305 | 0 | return (sizeof(signature) == readBytes) && std::equal(signature, signature + sizeof(signature), s); |
306 | 0 | } |
307 | | |
308 | | void BBeBParser::readHeader() |
309 | 6.21k | { |
310 | 6.21k | skip(m_input, 8); |
311 | 6.21k | m_header->version = readU16(m_input); |
312 | 6.21k | m_header->key = readU16(m_input); |
313 | 6.21k | m_header->rootOID = readU32(m_input); |
314 | 6.21k | m_header->numberOfObjects = readU64(m_input); |
315 | 6.21k | m_header->objectIndexOffset = readU64(m_input); |
316 | 6.21k | skip(m_input, 6); |
317 | 6.21k | m_header->dpi = readU16(m_input); |
318 | 6.21k | if (0 == m_header->dpi) |
319 | 1.01k | { |
320 | 1.01k | EBOOK_DEBUG_MSG(("DPI is 0, likely a broken file\n")); |
321 | 1.01k | m_header->dpi = 1660; |
322 | 1.01k | } |
323 | 6.21k | skip(m_input, 2); |
324 | 6.21k | m_header->width = readU16(m_input); |
325 | 6.21k | skip(m_input, 24); |
326 | 6.21k | m_header->tocOID = readU32(m_input); |
327 | 6.21k | skip(m_input, 4); |
328 | 6.21k | m_header->xmlCompSize = readU16(m_input); |
329 | | |
330 | 6.21k | if (800 <= m_header->version) |
331 | 4.33k | { |
332 | 4.33k | const unsigned thumbnailType = readU16(m_input); |
333 | 4.33k | switch (thumbnailType) |
334 | 4.33k | { |
335 | 2.71k | case BBEB_IMAGE_TYPE_JPEG : |
336 | 2.72k | case BBEB_IMAGE_TYPE_PNG : |
337 | 2.72k | case BBEB_IMAGE_TYPE_BMP : |
338 | 2.72k | case BBEB_IMAGE_TYPE_GIF : |
339 | 2.72k | m_header->thumbnailType = static_cast<BBeBImageType>(thumbnailType); |
340 | 2.72k | break; |
341 | 1.59k | default : |
342 | 1.59k | EBOOK_DEBUG_MSG(("unknown thumbnail type %x\n", thumbnailType)); |
343 | 1.59k | break; |
344 | 4.33k | } |
345 | 4.32k | m_header->thumbnailSize = readU32(m_input); |
346 | 4.32k | } |
347 | 6.21k | } |
348 | | |
349 | | void BBeBParser::readMetadata() |
350 | 6.13k | { |
351 | 6.13k | skip(m_input, 4); // uncompressed size? |
352 | 6.13k | unsigned const char *const data = readNBytes(m_input, m_header->xmlCompSize); |
353 | 6.13k | EBOOKMemoryStream memoryStrm(data, m_header->xmlCompSize); |
354 | 6.13k | EBOOKZlibStream zlibStrm(&memoryStrm); |
355 | | |
356 | 6.13k | BBeBMetadataParser parser(&zlibStrm); |
357 | 6.13k | parser.parse(); |
358 | | |
359 | 6.13k | m_collector.collectMetadata(parser.getMetadata()); |
360 | 6.13k | } |
361 | | |
362 | | void BBeBParser::readThumbnail() |
363 | 5.49k | { |
364 | | // TODO: implement me |
365 | 5.49k | } |
366 | | |
367 | | void BBeBParser::readObjectIndex() |
368 | 5.49k | { |
369 | 5.49k | m_input->seek((long) m_header->objectIndexOffset, librevenge::RVNG_SEEK_SET); |
370 | 256k | for (uint64_t i = m_header->numberOfObjects; 0 != i; --i) |
371 | 250k | { |
372 | 250k | unsigned id = readU32(m_input); |
373 | 250k | BBeBIndexEntry entry; |
374 | 250k | entry.offset = readU32(m_input); |
375 | 250k | entry.size = readU32(m_input); |
376 | 250k | entry.read = false; |
377 | 250k | entry.reading = false; |
378 | 250k | m_objectIndex.insert(ObjectIndex_t::value_type(id, entry)); |
379 | 250k | skip(m_input, 4); |
380 | 250k | } |
381 | 5.49k | } |
382 | | |
383 | | namespace |
384 | | { |
385 | | |
386 | | const unsigned BBEB_MAX_OBJECT_NESTING = 1 << 10; |
387 | | |
388 | | struct NestingGuard |
389 | | { |
390 | 84.6k | explicit NestingGuard(unsigned &nesting) : m_nesting(nesting) |
391 | 84.6k | { |
392 | 84.6k | ++m_nesting; |
393 | 84.6k | } |
394 | | ~NestingGuard() |
395 | 84.6k | { |
396 | 84.6k | --m_nesting; |
397 | 84.6k | } |
398 | | unsigned &m_nesting; |
399 | | private: |
400 | | NestingGuard(const NestingGuard &); |
401 | | NestingGuard &operator=(const NestingGuard &); |
402 | | }; |
403 | | |
404 | | } |
405 | | |
406 | | void BBeBParser::readObject(const unsigned id, const unsigned type) |
407 | 84.6k | { |
408 | 84.6k | if (m_objectNesting >= BBEB_MAX_OBJECT_NESTING) |
409 | 0 | throw ParserException(); |
410 | 84.6k | const NestingGuard guard(m_objectNesting); |
411 | | |
412 | 84.6k | auto it = m_objectIndex.find(id); |
413 | 84.6k | if (it == m_objectIndex.end()) |
414 | 701 | { |
415 | 701 | EBOOK_DEBUG_MSG(("object with ID %x not found\n", id)); |
416 | 701 | throw ParserException(); |
417 | 701 | } |
418 | | |
419 | 83.9k | BBeBIndexEntry &entry = it->second; |
420 | 83.9k | if (entry.reading) |
421 | 24 | { |
422 | 24 | EBOOK_DEBUG_MSG(("object %x is already being read\n", id)); |
423 | 24 | throw ParserException(); |
424 | 24 | } |
425 | 83.9k | if (entry.read) |
426 | 65.6k | { |
427 | 65.6k | EBOOK_DEBUG_MSG(("object %x has already been read\n", id)); |
428 | 65.6k | } |
429 | | |
430 | 83.9k | m_input->seek((long) entry.offset, librevenge::RVNG_SEEK_SET); |
431 | | |
432 | 83.9k | const unsigned startTag = readU16(m_input); |
433 | 83.9k | if (TAG_OBJECT_START != startTag) |
434 | 39 | { |
435 | 39 | EBOOK_DEBUG_MSG(("reading object %x, but there is no object at the position\n", id)); |
436 | 39 | throw ParserException(); |
437 | 39 | } |
438 | | |
439 | 83.8k | const unsigned objectID = readU32(m_input); |
440 | 83.8k | if (id != objectID) |
441 | 54 | { |
442 | 54 | EBOOK_DEBUG_MSG(("expected object with ID %x, but found %x\n", id, objectID)); |
443 | 54 | throw ParserException(); |
444 | 54 | } |
445 | | |
446 | 83.8k | const unsigned objectType = readU16(m_input); |
447 | 83.8k | if ((OBJECT_TYPE_PAGE_TREE > objectType) || (OBJECT_TYPE_TOC < objectType)) |
448 | 19 | { |
449 | 19 | EBOOK_DEBUG_MSG(("object is of unknown type %x\n", objectType)); |
450 | 19 | throw ParserException(); |
451 | 19 | } |
452 | 83.8k | if ((OBJECT_TYPE_UNSPECIFIED != type) && (type != objectType)) |
453 | 20 | { |
454 | 20 | EBOOK_DEBUG_MSG(("expected object of type %x, but found %x\n", type, objectType)); |
455 | 20 | throw ParserException(); |
456 | 20 | } |
457 | | |
458 | 83.7k | const unsigned char *const data = readNBytes(m_input, entry.size - 10); |
459 | 83.7k | EBOOKMemoryStream strm(data, entry.size - 10); |
460 | | |
461 | 83.7k | const unsigned endTag = readU16(m_input); |
462 | 83.7k | if (TAG_OBJECT_END != endTag) |
463 | 15 | { |
464 | 15 | EBOOK_DEBUG_MSG(("no end tag found at the end of the object\n")); |
465 | 15 | throw ParserException(); |
466 | 15 | } |
467 | | |
468 | 83.7k | entry.reading = true; |
469 | | |
470 | 83.7k | switch (objectType) |
471 | 83.7k | { |
472 | 3.08k | case OBJECT_TYPE_PAGE_TREE : |
473 | 3.08k | m_pageTree = id; |
474 | 3.08k | readPageTreeObject(&strm); |
475 | 3.08k | m_pageTree = 0; |
476 | 3.08k | break; |
477 | 16.2k | case OBJECT_TYPE_PAGE : |
478 | 16.2k | readPageObject(&strm); |
479 | 16.2k | break; |
480 | 141 | case OBJECT_TYPE_HEADER : |
481 | 141 | readHeaderObject(&strm); |
482 | 141 | break; |
483 | 135 | case OBJECT_TYPE_FOOTER : |
484 | 135 | readFooterObject(&strm); |
485 | 135 | break; |
486 | 5.32k | case OBJECT_TYPE_PAGE_ATR : |
487 | 5.32k | readPageAtrObject(&strm, id); |
488 | 5.32k | break; |
489 | 23.1k | case OBJECT_TYPE_BLOCK : |
490 | 23.1k | readBlockObject(&strm, id); |
491 | 23.1k | break; |
492 | 3.81k | case OBJECT_TYPE_BLOCK_ATR : |
493 | 3.81k | readBlockAtrObject(&strm, id); |
494 | 3.81k | break; |
495 | 6 | case OBJECT_TYPE_MINI_PAGE : |
496 | 6 | readMiniPageObject(&strm); |
497 | 6 | break; |
498 | 2 | case OBJECT_TYPE_BLOCK_LIST : |
499 | 2 | readBlockListObject(&strm); |
500 | 2 | break; |
501 | 13.5k | case OBJECT_TYPE_TEXT : |
502 | 13.5k | readTextObject(&strm); |
503 | 13.5k | break; |
504 | 2.33k | case OBJECT_TYPE_TEXT_ATR : |
505 | 2.33k | readTextAtrObject(&strm, id); |
506 | 2.33k | break; |
507 | 3.74k | case OBJECT_TYPE_IMAGE : |
508 | 3.74k | readImageObject(&strm, id); |
509 | 3.74k | break; |
510 | 182 | case OBJECT_TYPE_CANVAS : |
511 | 182 | readCanvasObject(&strm); |
512 | 182 | break; |
513 | 1.53k | case OBJECT_TYPE_PARAGRAPH_ATR : |
514 | 1.53k | readParagraphAtrObject(&strm, id); |
515 | 1.53k | break; |
516 | 1.98k | case OBJECT_TYPE_IMAGE_STREAM : |
517 | 1.98k | readImageStreamObject(&strm, id); |
518 | 1.98k | break; |
519 | 2 | case OBJECT_TYPE_SoftBookORT : |
520 | 2 | readImportObject(&strm); |
521 | 2 | break; |
522 | 6 | case OBJECT_TYPE_BUTTON : |
523 | 6 | readButtonObject(&strm); |
524 | 6 | break; |
525 | 0 | case OBJECT_TYPE_WINDOW : |
526 | 0 | readWindowObject(&strm); |
527 | 0 | break; |
528 | 8 | case OBJECT_TYPE_POP_UP_WIN : |
529 | 8 | readPopUpWinObject(&strm); |
530 | 8 | break; |
531 | 24 | case OBJECT_TYPE_SOUND : |
532 | 24 | readSoundObject(&strm); |
533 | 24 | break; |
534 | 3 | case OBJECT_TYPE_PLANE_STREAM : |
535 | 3 | readPlaneStreamObject(&strm); |
536 | 3 | break; |
537 | 54 | case OBJECT_TYPE_FONT : |
538 | 54 | readFontObject(&strm); |
539 | 54 | break; |
540 | 6 | case OBJECT_TYPE_OBJECT_INFO : |
541 | 6 | readObjectInfoObject(&strm); |
542 | 6 | break; |
543 | 4.10k | case OBJECT_TYPE_BOOK_ATR : |
544 | 4.10k | readBookAtrObject(&strm); |
545 | 4.10k | break; |
546 | 0 | case OBJECT_TYPE_SSoftBookLE_TEXT : |
547 | 0 | readSimpleTextObject(&strm); |
548 | 0 | break; |
549 | 4.06k | case OBJECT_TYPE_TOC : |
550 | 4.06k | readTOCObject(&strm); |
551 | 4.06k | break; |
552 | 212 | default : |
553 | 212 | EBOOK_DEBUG_MSG(("unhandled object type %x\n", type)); |
554 | 212 | break; |
555 | 83.7k | } |
556 | | |
557 | 74.4k | entry.reading = false; |
558 | 74.4k | entry.read = true; |
559 | 74.4k | } |
560 | | |
561 | | void BBeBParser::readPageTreeObject(librevenge::RVNGInputStream *const object) |
562 | 3.08k | { |
563 | 3.08k | bool readAnyPage = false; |
564 | 3.08k | if (TAG_PAGE_LIST == readU16(object)) |
565 | 3.05k | { |
566 | 3.05k | unsigned count = readU16(object); |
567 | 3.05k | if (count > getRemainingLength(object) / 4) |
568 | 513 | count = getRemainingLength(object) / 4; |
569 | 3.05k | readAnyPage = 0 != count; |
570 | 6.73k | for (unsigned i = 0; i != count; ++i) |
571 | 3.67k | readObject(readU32(object), OBJECT_TYPE_PAGE); |
572 | 3.05k | } |
573 | | |
574 | 3.08k | if (!readAnyPage) |
575 | 24 | { |
576 | 24 | EBOOK_DEBUG_MSG(("page tree has no pages\n")); |
577 | 24 | throw ParserException(); |
578 | 24 | } |
579 | 3.08k | } |
580 | | |
581 | | void BBeBParser::readPageObject(librevenge::RVNGInputStream *const object) |
582 | 16.2k | { |
583 | 16.2k | unsigned pageAtrID = 0; |
584 | 16.2k | BBeBAttributes attributes; |
585 | 16.2k | unsigned streamFlags = 0; |
586 | 16.2k | unsigned streamSize = 0; |
587 | 16.2k | std::unique_ptr<EBOOKMemoryStream> strm; |
588 | | |
589 | 1.19M | while (!object->isEnd()) |
590 | 1.18M | { |
591 | 1.18M | const unsigned tag = readU16(object); |
592 | 1.18M | switch (tag) |
593 | 1.18M | { |
594 | 3.95k | case TAG_LINK : |
595 | 3.95k | pageAtrID = readU32(object); |
596 | | // It is possible that pages can share attributes. So avoid |
597 | | // reading the same Page Atr object twice. |
598 | 3.95k | if (!isObjectRead(pageAtrID)) |
599 | 320 | readObject(pageAtrID, OBJECT_TYPE_PAGE_ATR); |
600 | 3.95k | break; |
601 | 7.54k | case TAG_PARENT_PAGE_TREE : |
602 | 7.54k | if (readU32(object) != m_pageTree) |
603 | 44 | { |
604 | 44 | EBOOK_DEBUG_MSG(("page is not belonging to the current page tree\n")); |
605 | 44 | throw ParserException(); |
606 | 44 | } |
607 | 7.50k | break; |
608 | 9.19k | case TAG_STREAM_FLAGS : |
609 | 9.19k | streamFlags = readU16(object); |
610 | 9.19k | if (streamFlags != 0) |
611 | 10 | { |
612 | 10 | EBOOK_DEBUG_MSG(("page stream with weird flags, giving up\n")); |
613 | 10 | throw ParserException(); |
614 | 10 | } |
615 | 9.18k | break; |
616 | 21.3k | case TAG_STREAM_SIZE : |
617 | 21.3k | streamSize = readU32(object); |
618 | 21.3k | if (streamSize > getRemainingLength(object)) |
619 | 2.86k | streamSize = getRemainingLength(object); |
620 | 21.3k | break; |
621 | 18.4k | case TAG_STREAM_START : |
622 | 18.4k | { |
623 | 18.4k | const unsigned char *streamData = readNBytes(object, streamSize); |
624 | 18.4k | strm.reset(new EBOOKMemoryStream(streamData, streamSize)); |
625 | 18.4k | if (TAG_STREAM_END != readU16(object)) |
626 | 29 | { |
627 | 29 | EBOOK_DEBUG_MSG(("Stream does not end by Stream End tag\n")); |
628 | 29 | throw ParserException(); |
629 | 29 | } |
630 | 18.3k | break; |
631 | 18.4k | } |
632 | 1.12M | default : |
633 | 1.12M | if (!readAttribute(tag, object, attributes)) |
634 | 1.09M | skipUnhandledTag(tag, object, "Page"); |
635 | 1.12M | break; |
636 | 1.18M | } |
637 | 1.18M | } |
638 | | |
639 | 16.0k | if (!strm) |
640 | 20 | { |
641 | 20 | EBOOK_DEBUG_MSG(("No stream data in PageObject\n")); |
642 | 20 | throw ParserException(); |
643 | 20 | } |
644 | | |
645 | 16.0k | m_collector.openPage(pageAtrID, attributes); |
646 | | |
647 | 316k | while (!strm->isEnd()) |
648 | 300k | { |
649 | 300k | const unsigned tag = readU16(strm.get()); |
650 | 300k | if (TAG_LINK == tag) |
651 | 51.6k | readObject(readU32(strm.get())); // this might be a block or a canvas |
652 | 248k | else |
653 | 248k | skipUnhandledTag(tag, strm.get(), "Page Stream"); |
654 | 300k | } |
655 | | |
656 | 16.0k | m_collector.closePage(); |
657 | 16.0k | } |
658 | | |
659 | | void BBeBParser::readFooterObject(librevenge::RVNGInputStream *const object) |
660 | 135 | { |
661 | | // TODO: implement me |
662 | 135 | (void) object; |
663 | 135 | EBOOK_DEBUG_MSG(("object type Footer is not supported yet\n")); |
664 | 135 | } |
665 | | |
666 | | void BBeBParser::readHeaderObject(librevenge::RVNGInputStream *const object) |
667 | 141 | { |
668 | | // TODO: implement me |
669 | 141 | (void) object; |
670 | 141 | EBOOK_DEBUG_MSG(("object type Header is not supported yet\n")); |
671 | 141 | } |
672 | | |
673 | | void BBeBParser::readPageAtrObject(librevenge::RVNGInputStream *const object, const unsigned id) |
674 | 5.32k | { |
675 | 5.32k | BBeBAttributes attributes; |
676 | | |
677 | 1.00M | while (!object->isEnd()) |
678 | 1.00M | { |
679 | 1.00M | const unsigned tag = readU16(object); |
680 | 1.00M | if (!readAttribute(tag, object, attributes)) |
681 | 952k | skipUnhandledTag(tag, object, "Page Atr"); |
682 | 1.00M | } |
683 | | |
684 | 5.32k | m_collector.collectPageAttributes(id, attributes); |
685 | 5.32k | } |
686 | | |
687 | | void BBeBParser::readBlockObject(librevenge::RVNGInputStream *const object, const unsigned id) |
688 | 23.1k | { |
689 | 23.1k | unsigned blockAtrID = 0; |
690 | 23.1k | BBeBAttributes attributes; |
691 | 23.1k | unsigned streamFlags = 0; |
692 | 23.1k | unsigned streamSize = 0; |
693 | 23.1k | std::unique_ptr<EBOOKMemoryStream> strm; |
694 | | |
695 | 447k | while (!object->isEnd()) |
696 | 424k | { |
697 | 424k | const unsigned tag = readU16(object); |
698 | 424k | switch (tag) |
699 | 424k | { |
700 | 16.9k | case TAG_LINK : |
701 | 16.9k | blockAtrID = readU32(object); |
702 | 16.9k | if (!isObjectRead(blockAtrID)) |
703 | 572 | readObject(blockAtrID, OBJECT_TYPE_BLOCK_ATR); |
704 | 16.9k | break; |
705 | 20.7k | case TAG_STREAM_FLAGS : |
706 | 20.7k | streamFlags = readU16(object); |
707 | 20.7k | break; |
708 | 27.4k | case TAG_STREAM_SIZE : |
709 | 27.4k | streamSize = readU32(object); |
710 | 27.4k | if (streamSize > getRemainingLength(object)) |
711 | 2.11k | streamSize = getRemainingLength(object); |
712 | 27.4k | break; |
713 | 25.1k | case TAG_STREAM_START : |
714 | 25.1k | { |
715 | 25.1k | const unsigned char *const streamData = readNBytes(object, streamSize); |
716 | 25.1k | if (0 == streamFlags) |
717 | 23.7k | strm.reset(new EBOOKMemoryStream(streamData, streamSize)); |
718 | 25.1k | if (TAG_STREAM_END != readU16(object)) |
719 | 7 | { |
720 | 7 | EBOOK_DEBUG_MSG(("Stream does not end by Stream End tag\n")); |
721 | 7 | throw ParserException(); |
722 | 7 | } |
723 | 25.1k | break; |
724 | 25.1k | } |
725 | 334k | default : |
726 | 334k | if (!readAttribute(tag, object, attributes)) |
727 | 320k | skipUnhandledTag(tag, object, "Block"); |
728 | 334k | break; |
729 | 424k | } |
730 | 424k | } |
731 | | |
732 | 23.0k | if ((0 == streamFlags) && !strm) |
733 | 6 | { |
734 | 6 | EBOOK_DEBUG_MSG(("No stream data in BlockObject\n")); |
735 | 6 | throw ParserException(); |
736 | 6 | } |
737 | | |
738 | 23.0k | if (std::binary_search(m_toc.begin(), m_toc.end(), id)) |
739 | 299 | attributes.heading = true; |
740 | | |
741 | 23.0k | m_collector.openBlock(blockAtrID, attributes); |
742 | | |
743 | 23.0k | if (bool(strm)) |
744 | 23.0k | { |
745 | 127k | while (!strm->isEnd()) |
746 | 104k | { |
747 | 104k | const unsigned tag = readU16(strm.get()); |
748 | 104k | if (TAG_LINK == tag) |
749 | 19.7k | readObject(readU32(strm.get())); |
750 | 85.1k | else |
751 | 85.1k | skipUnhandledTag(tag, strm.get(), "Block Stream"); |
752 | 104k | } |
753 | 23.0k | } |
754 | 17 | else |
755 | 17 | { |
756 | 17 | EBOOK_DEBUG_MSG(("block stream with weird flags, giving up\n")); |
757 | 17 | throw ParserException(); |
758 | 17 | } |
759 | | |
760 | 23.0k | m_collector.closeBlock(); |
761 | 23.0k | } |
762 | | |
763 | | void BBeBParser::readBlockAtrObject(librevenge::RVNGInputStream *const object, const unsigned id) |
764 | 3.81k | { |
765 | 3.81k | BBeBAttributes attributes; |
766 | | |
767 | 2.38M | while (!object->isEnd()) |
768 | 2.38M | { |
769 | 2.38M | const unsigned tag = readU16(object); |
770 | 2.38M | if (!readAttribute(tag, object, attributes)) |
771 | 2.24M | skipUnhandledTag(tag, object, "Block Atr"); |
772 | 2.38M | } |
773 | | |
774 | 3.81k | m_collector.collectBlockAttributes(id, attributes); |
775 | 3.81k | } |
776 | | |
777 | | void BBeBParser::readMiniPageObject(librevenge::RVNGInputStream *const object) |
778 | 6 | { |
779 | | // TODO: implement me |
780 | 6 | (void) object; |
781 | 6 | EBOOK_DEBUG_MSG(("object type Mini Page is not supported yet\n")); |
782 | 6 | } |
783 | | |
784 | | void BBeBParser::readBlockListObject(librevenge::RVNGInputStream *const object) |
785 | 2 | { |
786 | | // TODO: implement me |
787 | 2 | (void) object; |
788 | 2 | EBOOK_DEBUG_MSG(("object type Block List is not supported yet\n")); |
789 | 2 | } |
790 | | |
791 | | void BBeBParser::readTextObject(librevenge::RVNGInputStream *const object) |
792 | 13.5k | { |
793 | 13.5k | unsigned textAtrID = 0; |
794 | 13.5k | BBeBAttributes attributes; |
795 | 13.5k | unsigned streamFlags = 0; |
796 | 13.5k | unsigned streamSize = 0; |
797 | 13.5k | std::unique_ptr<librevenge::RVNGInputStream> textStrm; |
798 | 13.5k | unsigned textLength = 0; |
799 | | |
800 | 661k | while (!object->isEnd()) |
801 | 647k | { |
802 | 647k | const unsigned tag = readU16(object); |
803 | 647k | switch (tag) |
804 | 647k | { |
805 | 6.72k | case TAG_LINK : |
806 | 6.72k | textAtrID = readU32(object); |
807 | 6.72k | if (!isObjectRead(textAtrID)) |
808 | 385 | readObject(textAtrID, OBJECT_TYPE_TEXT_ATR); |
809 | 6.72k | break; |
810 | 11.5k | case TAG_STREAM_FLAGS : |
811 | 11.5k | streamFlags = readU16(object); |
812 | 11.5k | break; |
813 | 14.6k | case TAG_STREAM_SIZE : |
814 | 14.6k | streamSize = readU32(object); |
815 | 14.6k | break; |
816 | 12.9k | case TAG_STREAM_START : |
817 | 12.9k | { |
818 | 12.9k | if (streamSize > getRemainingLength(object)) |
819 | 31 | streamSize = getRemainingLength(object); |
820 | 12.9k | if (STREAM_TYPE_BBEB_TAGS_COMPRESSED == streamFlags) |
821 | 10.8k | { |
822 | 10.8k | textLength = readU32(object); |
823 | 10.8k | if (streamSize <= 4) |
824 | 2 | { |
825 | 2 | EBOOK_DEBUG_MSG(("Compressed stream is too short\n")); |
826 | 2 | throw ParserException(); |
827 | 2 | } |
828 | 10.8k | streamSize -= 4; |
829 | 10.8k | } |
830 | 2.11k | else |
831 | 2.11k | textLength = streamSize; |
832 | 12.9k | const unsigned char *const streamData = readNBytes(object, streamSize); |
833 | | |
834 | | // prepare text stream |
835 | 12.9k | if (STREAM_TYPE_BBEB_TAGS == streamFlags) |
836 | 2.10k | textStrm.reset(new EBOOKMemoryStream(streamData, streamSize)); |
837 | 10.8k | else if (STREAM_TYPE_BBEB_TAGS_COMPRESSED == streamFlags) |
838 | 10.8k | { |
839 | 10.8k | EBOOKMemoryStream strm(streamData, streamSize); |
840 | 10.8k | textStrm.reset(new EBOOKZlibStream(&strm)); |
841 | 10.8k | } |
842 | 18 | else |
843 | 18 | { |
844 | 18 | EBOOK_DEBUG_MSG(("Text stream of invalid type\n")); |
845 | 18 | throw ParserException(); |
846 | 18 | } |
847 | | |
848 | 12.9k | if (TAG_STREAM_END != readU16(object)) |
849 | 13 | { |
850 | 13 | EBOOK_DEBUG_MSG(("Stream does not end by Stream End tag\n")); |
851 | 13 | throw ParserException(); |
852 | 13 | } |
853 | 12.9k | } |
854 | 12.9k | break; |
855 | 602k | default : |
856 | 602k | if (!readAttribute(tag, object, attributes)) |
857 | 579k | skipUnhandledTag(tag, object, "Text"); |
858 | 602k | break; |
859 | 647k | } |
860 | 647k | } |
861 | | |
862 | 13.4k | if (0 != textLength) |
863 | 10.6k | { |
864 | 10.6k | m_collector.openTextBlock(textAtrID, attributes); |
865 | | |
866 | | // process text, if any |
867 | 10.6k | BBeBAttributes textAttributes; |
868 | 10.6k | bool inParagraph = false; |
869 | | |
870 | 936k | while (!textStrm->isEnd()) |
871 | 927k | { |
872 | 927k | const unsigned tag = readU16(textStrm.get()); |
873 | | |
874 | 927k | switch (tag) |
875 | 927k | { |
876 | 24.4k | case TAG_BEGIN_P : |
877 | 24.4k | { |
878 | | // NOTE: I am not quite sure the argument is an object ID. |
879 | | // But it makes sense. |
880 | 24.4k | const unsigned paragraphAtrID = readU32(textStrm.get()); |
881 | 24.4k | if ((0 != paragraphAtrID) && !isObjectRead(paragraphAtrID)) |
882 | 93 | readObject(paragraphAtrID, OBJECT_TYPE_PARAGRAPH_ATR); |
883 | 24.4k | m_collector.openParagraph(paragraphAtrID, attributes); |
884 | 24.4k | inParagraph = true; |
885 | 24.4k | } |
886 | 24.4k | break; |
887 | 3.46k | case TAG_END_P : |
888 | 3.46k | if (inParagraph) |
889 | 1.57k | { |
890 | 1.57k | m_collector.closeParagraph(); |
891 | 1.57k | } |
892 | 1.89k | else |
893 | 1.89k | { |
894 | 1.89k | EBOOK_DEBUG_MSG(("End P tag encountered, but there is no paragraph opened\n")); |
895 | 1.89k | } |
896 | 3.46k | inParagraph = false; |
897 | 3.46k | break; |
898 | 59.8k | case TAG_TEXT_SIZE : |
899 | 59.8k | { |
900 | 59.8k | const std::string &text = readString(textStrm.get()); |
901 | 59.8k | m_collector.collectText(text, textAttributes); |
902 | 59.8k | } |
903 | 59.8k | break; |
904 | 5.36k | case TAG_EOL : |
905 | 5.36k | if (inParagraph) |
906 | 2.56k | m_collector.insertLineBreak(); |
907 | 5.36k | break; |
908 | 3.23k | case TAG_KOMA_PLOT : |
909 | 3.23k | { |
910 | 3.23k | skip(textStrm.get(), 4); |
911 | 3.23k | const unsigned imageID = readU32(textStrm.get()); |
912 | 3.23k | skip(textStrm.get(), 4); |
913 | 3.23k | if (!isObjectRead(imageID)) |
914 | 124 | readObject(imageID, OBJECT_TYPE_IMAGE); |
915 | 3.23k | m_collector.insertImage(imageID); |
916 | 3.23k | } |
917 | 3.23k | break; |
918 | 830k | default : |
919 | 830k | if (!readAttribute(tag, textStrm.get(), textAttributes)) |
920 | 799k | skipUnhandledTag(tag, textStrm.get(), "Text Stream"); |
921 | 927k | } |
922 | 927k | } |
923 | | |
924 | 9.45k | if (inParagraph) |
925 | 2.98k | { |
926 | 2.98k | EBOOK_DEBUG_MSG(("No End P tag encountered\n")); |
927 | 2.98k | m_collector.closeParagraph(); |
928 | 2.98k | } |
929 | | |
930 | 9.45k | m_collector.closeTextBlock(); |
931 | 9.45k | } |
932 | 13.4k | } |
933 | | |
934 | | void BBeBParser::readTextAtrObject(librevenge::RVNGInputStream *const object, const unsigned id) |
935 | 2.33k | { |
936 | 2.33k | BBeBAttributes attributes; |
937 | | |
938 | 119k | while (!object->isEnd()) |
939 | 116k | { |
940 | 116k | const unsigned tag = readU16(object); |
941 | 116k | if (!readAttribute(tag, object, attributes)) |
942 | 100k | skipUnhandledTag(tag, object, "Text Atr"); |
943 | 116k | } |
944 | | |
945 | 2.33k | m_collector.collectTextAttributes(id, attributes); |
946 | 2.33k | } |
947 | | |
948 | | void BBeBParser::readImageObject(librevenge::RVNGInputStream *const object, const unsigned id) |
949 | 3.74k | { |
950 | 3.74k | unsigned width = 0; |
951 | 3.74k | unsigned height = 0; |
952 | | |
953 | 207k | while (!object->isEnd()) |
954 | 203k | { |
955 | 203k | const unsigned tag = readU16(object); |
956 | | |
957 | 203k | switch (tag) |
958 | 203k | { |
959 | 1.27k | case TAG_IMAGE_CROP_RECT : |
960 | 1.27k | skip(object, 8); |
961 | 1.27k | break; |
962 | 2.30k | case TAG_IMAGE_SIZE : |
963 | 2.30k | { |
964 | 2.30k | width = readU16(object); |
965 | 2.30k | height = readU16(object); |
966 | 2.30k | break; |
967 | 0 | } |
968 | 2.57k | case TAG_IMAGE_STREAM : |
969 | 2.57k | { |
970 | 2.57k | const unsigned image = readU32(object); |
971 | 2.57k | if (!isObjectRead(image)) |
972 | 127 | readObject(image, OBJECT_TYPE_IMAGE_STREAM); |
973 | 2.57k | m_collector.collectImage(id, image, width, height); |
974 | 2.57k | break; |
975 | 0 | } |
976 | 197k | default : |
977 | 197k | skipUnhandledTag(tag, object, "Image"); |
978 | 197k | break; |
979 | 203k | } |
980 | 203k | } |
981 | 3.74k | } |
982 | | |
983 | | void BBeBParser::readCanvasObject(librevenge::RVNGInputStream *const object) |
984 | 182 | { |
985 | | // TODO: implement me |
986 | 182 | (void) object; |
987 | 182 | EBOOK_DEBUG_MSG(("object type Canvas is not supported yet\n")); |
988 | 182 | } |
989 | | |
990 | | void BBeBParser::readParagraphAtrObject(librevenge::RVNGInputStream *const object, const unsigned id) |
991 | 1.53k | { |
992 | 1.53k | BBeBAttributes attributes; |
993 | | |
994 | 179k | while (!object->isEnd()) |
995 | 178k | { |
996 | 178k | const unsigned tag = readU16(object); |
997 | 178k | if (!readAttribute(tag, object, attributes)) |
998 | 162k | skipUnhandledTag(tag, object, "Paragraph Atr"); |
999 | 178k | } |
1000 | | |
1001 | 1.53k | m_collector.collectParagraphAttributes(id, attributes); |
1002 | 1.53k | } |
1003 | | |
1004 | | void BBeBParser::readImageStreamObject(librevenge::RVNGInputStream *const object, const unsigned id) |
1005 | 1.98k | { |
1006 | 1.98k | unsigned streamType = 0; |
1007 | 1.98k | unsigned streamSize = 0; |
1008 | 1.98k | RVNGInputStreamPtr_t image; |
1009 | | |
1010 | 482k | while (!object->isEnd()) |
1011 | 480k | { |
1012 | 480k | const unsigned tag = readU16(object); |
1013 | | |
1014 | 480k | switch (tag) |
1015 | 480k | { |
1016 | 2.36k | case TAG_STREAM_FLAGS : |
1017 | 2.36k | streamType = readU16(object); |
1018 | 2.36k | break; |
1019 | 3.37k | case TAG_STREAM_SIZE : |
1020 | 3.37k | streamSize = readU16(object); |
1021 | 3.37k | if (streamSize > getRemainingLength(object)) |
1022 | 667 | streamSize = getRemainingLength(object); |
1023 | 3.37k | break; |
1024 | 2.55k | case TAG_STREAM_START : |
1025 | 2.55k | { |
1026 | 2.55k | const unsigned char *const streamData = readNBytes(object, streamSize); |
1027 | | |
1028 | 2.55k | switch (streamType) |
1029 | 2.55k | { |
1030 | 1.42k | case STREAM_TYPE_JPEG : |
1031 | 1.43k | case STREAM_TYPE_PNG : |
1032 | 1.99k | case STREAM_TYPE_BMP : |
1033 | 2.54k | case STREAM_TYPE_GIF : |
1034 | 2.54k | image.reset(new EBOOKMemoryStream(streamData, streamSize)); |
1035 | 2.54k | break; |
1036 | 5 | default : |
1037 | 5 | EBOOK_DEBUG_MSG(("unknown image type %x\n", streamType)); |
1038 | 5 | throw ParserException(); |
1039 | 2.55k | } |
1040 | | |
1041 | 2.54k | if (TAG_STREAM_END != readU16(object)) |
1042 | 16 | { |
1043 | 16 | EBOOK_DEBUG_MSG(("Stream does not end by Stream End tag\n")); |
1044 | 16 | throw ParserException(); |
1045 | 16 | } |
1046 | 2.53k | break; |
1047 | 2.54k | } |
1048 | 472k | default : |
1049 | 472k | skipUnhandledTag(tag, object, "Image Stream"); |
1050 | 480k | } |
1051 | 480k | } |
1052 | | |
1053 | 1.95k | if (!image) |
1054 | 9 | { |
1055 | 9 | EBOOK_DEBUG_MSG(("No stream data in ImageStreamObject\n")); |
1056 | 9 | throw ParserException(); |
1057 | 9 | } |
1058 | | |
1059 | 1.94k | m_collector.collectImageData(id, static_cast<BBeBImageType>(streamType), image); |
1060 | 1.94k | } |
1061 | | |
1062 | | void BBeBParser::readImportObject(librevenge::RVNGInputStream *const object) |
1063 | 2 | { |
1064 | | // TODO: implement me |
1065 | 2 | (void) object; |
1066 | 2 | EBOOK_DEBUG_MSG(("object type Import is not supported yet\n")); |
1067 | 2 | } |
1068 | | |
1069 | | void BBeBParser::readButtonObject(librevenge::RVNGInputStream *const object) |
1070 | 6 | { |
1071 | | // TODO: implement me |
1072 | 6 | (void) object; |
1073 | 6 | EBOOK_DEBUG_MSG(("object type Button is not supported yet\n")); |
1074 | 6 | } |
1075 | | |
1076 | | void BBeBParser::readWindowObject(librevenge::RVNGInputStream *const object) |
1077 | 0 | { |
1078 | | // TODO: implement me |
1079 | 0 | (void) object; |
1080 | 0 | EBOOK_DEBUG_MSG(("object type Window is not supported yet\n")); |
1081 | 0 | } |
1082 | | |
1083 | | void BBeBParser::readPopUpWinObject(librevenge::RVNGInputStream *const object) |
1084 | 8 | { |
1085 | | // TODO: implement me |
1086 | 8 | (void) object; |
1087 | 8 | EBOOK_DEBUG_MSG(("object type Pop Up Win is not supported yet\n")); |
1088 | 8 | } |
1089 | | |
1090 | | void BBeBParser::readSoundObject(librevenge::RVNGInputStream *const object) |
1091 | 24 | { |
1092 | | // TODO: implement me |
1093 | 24 | (void) object; |
1094 | 24 | EBOOK_DEBUG_MSG(("object type Sound is not supported yet\n")); |
1095 | 24 | } |
1096 | | |
1097 | | void BBeBParser::readPlaneStreamObject(librevenge::RVNGInputStream *const object) |
1098 | 3 | { |
1099 | | // TODO: implement me |
1100 | 3 | (void) object; |
1101 | 3 | EBOOK_DEBUG_MSG(("object type Plane Stream is not supported yet\n")); |
1102 | 3 | } |
1103 | | |
1104 | | void BBeBParser::readFontObject(librevenge::RVNGInputStream *const object) |
1105 | 54 | { |
1106 | | // TODO: implement me |
1107 | 54 | (void) object; |
1108 | 54 | EBOOK_DEBUG_MSG(("object type Font is not supported yet\n")); |
1109 | 54 | } |
1110 | | |
1111 | | void BBeBParser::readObjectInfoObject(librevenge::RVNGInputStream *const object) |
1112 | 6 | { |
1113 | | // TODO: implement me |
1114 | 6 | (void) object; |
1115 | 6 | EBOOK_DEBUG_MSG(("object type Object Info is not supported yet\n")); |
1116 | 6 | } |
1117 | | |
1118 | | void BBeBParser::readBookAtrObject(librevenge::RVNGInputStream *const object) |
1119 | 4.10k | { |
1120 | 4.10k | BBeBAttributes attributes; |
1121 | 4.10k | unsigned pageTree = 0; |
1122 | | |
1123 | 388k | while (!object->isEnd()) |
1124 | 384k | { |
1125 | 384k | const unsigned tag = readU16(object); |
1126 | 384k | switch (tag) |
1127 | 384k | { |
1128 | 3.52k | case TAG_CHILD_PAGE_TREE : |
1129 | 3.52k | pageTree = readU32(object); |
1130 | 3.52k | break; |
1131 | 380k | default : |
1132 | 380k | if (!readAttribute(tag, object, attributes)) |
1133 | 364k | skipUnhandledTag(tag, object, "Book Atr"); |
1134 | 384k | } |
1135 | 384k | } |
1136 | | |
1137 | 3.48k | m_collector.collectBookAttributes(attributes); |
1138 | | |
1139 | 3.48k | if (0 == pageTree) |
1140 | 339 | { |
1141 | 339 | EBOOK_DEBUG_MSG(("the book has no page tree")); |
1142 | 339 | throw ParserException(); |
1143 | 339 | } |
1144 | 3.14k | readObject(pageTree, OBJECT_TYPE_PAGE_TREE); |
1145 | 3.14k | } |
1146 | | |
1147 | | void BBeBParser::readSimpleTextObject(librevenge::RVNGInputStream *const object) |
1148 | 0 | { |
1149 | | // TODO: implement me |
1150 | 0 | (void) object; |
1151 | 0 | EBOOK_DEBUG_MSG(("object type Simple Text is not supported yet\n")); |
1152 | 0 | } |
1153 | | |
1154 | | void BBeBParser::readTOCObject(librevenge::RVNGInputStream *const object) |
1155 | 4.06k | { |
1156 | 4.06k | unsigned streamFlags = 0; |
1157 | 4.06k | unsigned streamSize = 0; |
1158 | 4.06k | std::unique_ptr<EBOOKMemoryStream> data; |
1159 | | |
1160 | 836k | while (!object->isEnd()) |
1161 | 833k | { |
1162 | 833k | const unsigned tag = readU16(object); |
1163 | 833k | switch (tag) |
1164 | 833k | { |
1165 | 6.11k | case TAG_STREAM_FLAGS : |
1166 | 6.11k | streamFlags = readU16(object); |
1167 | 6.11k | if (STREAM_TYPE_BBEB_TOC != streamFlags) |
1168 | 3.32k | { |
1169 | 3.32k | EBOOK_DEBUG_MSG(("unexpected ToC stream type %x\n", streamFlags)); |
1170 | 3.32k | } |
1171 | 6.11k | break; |
1172 | 7.31k | case TAG_STREAM_SIZE : |
1173 | 7.31k | streamSize = readU32(object); |
1174 | 7.31k | if (streamSize > getRemainingLength(object)) |
1175 | 1.69k | streamSize = getRemainingLength(object); |
1176 | 7.31k | break; |
1177 | 7.37k | case TAG_STREAM_START : |
1178 | 7.37k | if (STREAM_TYPE_BBEB_TOC == streamFlags) |
1179 | 2.99k | { |
1180 | 2.99k | const unsigned char *const streamData = readNBytes(object, streamSize); |
1181 | 2.99k | data.reset(new EBOOKMemoryStream(streamData, streamSize)); |
1182 | 2.99k | if (TAG_STREAM_END != readU16(object)) |
1183 | 8 | { |
1184 | 8 | EBOOK_DEBUG_MSG(("Stream does not end by Stream End tag\n")); |
1185 | 8 | throw ParserException(); |
1186 | 8 | } |
1187 | 2.99k | } |
1188 | 4.38k | else |
1189 | 4.38k | { |
1190 | 4.38k | skip(object, streamSize); |
1191 | 4.38k | } |
1192 | 7.36k | break; |
1193 | 812k | default : |
1194 | 812k | skipUnhandledTag(tag, object, "ToC"); |
1195 | 812k | break; |
1196 | 833k | } |
1197 | 833k | } |
1198 | | |
1199 | 3.82k | if (bool(data)) |
1200 | 2.65k | readToCStream(data.get()); |
1201 | 3.82k | } |
1202 | | |
1203 | | void BBeBParser::readToCStream(librevenge::RVNGInputStream *const input) |
1204 | 2.65k | { |
1205 | 2.65k | unsigned count = readU32(input); |
1206 | 2.65k | if (count > getRemainingLength(input) / 4) |
1207 | 267 | count = getRemainingLength(input) / 4; |
1208 | 2.65k | std::vector<unsigned> offsets; |
1209 | | |
1210 | 2.65k | offsets.reserve(count); |
1211 | 29.7k | for (unsigned i = 0; count != i; ++i) |
1212 | 27.1k | offsets.push_back(readU32(input)); |
1213 | | |
1214 | 2.65k | const long start = input->tell(); |
1215 | 2.65k | m_toc.reserve(count); |
1216 | 28.4k | for (std::vector<unsigned>::const_iterator it = offsets.begin(); offsets.end() != it; ++it) |
1217 | 25.8k | { |
1218 | 25.8k | seek(input, (unsigned long)(start + int(*it) + 4)); |
1219 | 25.8k | const unsigned oid = readU32(input); |
1220 | 25.8k | if (m_objectIndex.end() != m_objectIndex.find(oid)) |
1221 | 17.6k | { |
1222 | 17.6k | m_toc.push_back(oid); |
1223 | 17.6k | } |
1224 | 8.14k | else |
1225 | 8.14k | { |
1226 | 8.14k | EBOOK_DEBUG_MSG(("ToC refers to an unexistent block id %x\n", oid)); |
1227 | 8.14k | } |
1228 | 25.8k | } |
1229 | | |
1230 | 2.65k | std::sort(m_toc.begin(), m_toc.end()); |
1231 | 2.65k | } |
1232 | | |
1233 | | bool BBeBParser::readAttribute(const unsigned tag, librevenge::RVNGInputStream *const input, BBeBAttributes &attributes) |
1234 | 6.94M | { |
1235 | 6.94M | bool handled = true; |
1236 | | |
1237 | 6.94M | switch (tag) |
1238 | 6.94M | { |
1239 | 15.0k | case TAG_FONT_SIZE : |
1240 | 15.0k | attributes.fontSize = readU16(input); |
1241 | 15.0k | break; |
1242 | 12.3k | case TAG_FONT_WIDTH : |
1243 | 12.3k | attributes.fontWidth = readU16(input); |
1244 | 12.3k | break; |
1245 | 14.5k | case TAG_FONT_ESCAPEMENT : |
1246 | 14.5k | attributes.fontEscapement = readU16(input); |
1247 | 14.5k | break; |
1248 | 13.0k | case TAG_FONT_ORIENTATION : |
1249 | 13.0k | attributes.fontOrientation = readU16(input); |
1250 | 13.0k | break; |
1251 | 12.1k | case TAG_FONT_WEIGHT : |
1252 | 12.1k | attributes.fontWeight = readU16(input); |
1253 | 12.1k | break; |
1254 | 15.9k | case TAG_FONT_FACENAME : |
1255 | 15.9k | attributes.fontFacename = readString(input); |
1256 | 15.9k | break; |
1257 | 10.6k | case TAG_TEXT_COLOR : |
1258 | 10.6k | attributes.textColor = BBeBColor(readU32(input)); |
1259 | 10.6k | break; |
1260 | 13.9k | case TAG_TEXT_BG_COLOR : |
1261 | 13.9k | attributes.textBgColor = BBeBColor(readU32(input)); |
1262 | 13.9k | break; |
1263 | 15.6k | case TAG_WORD_SPACE : |
1264 | 15.6k | attributes.wordSpace = readU16(input); |
1265 | 15.6k | break; |
1266 | 10.5k | case TAG_LETTER_SPACE : |
1267 | 10.5k | attributes.letterSpace = readU16(input); |
1268 | 10.5k | break; |
1269 | 17.3k | case TAG_BASE_LINE_SKIP : |
1270 | 17.3k | attributes.baseLineSkip = readU16(input); |
1271 | 17.3k | break; |
1272 | 13.7k | case TAG_LINE_SPACE : |
1273 | 13.7k | attributes.lineSpace = readU16(input); |
1274 | 13.7k | break; |
1275 | 11.3k | case TAG_PAR_INDENT : |
1276 | 11.3k | attributes.parIndent = readU16(input); |
1277 | 11.3k | break; |
1278 | 10.6k | case TAG_PAR_SKIP : |
1279 | 10.6k | attributes.parSkip = readU16(input); |
1280 | 10.6k | break; |
1281 | 1.26k | case TAG_PAGE_HEIGHT : |
1282 | 19.4k | case TAG_BLOCK_HEIGHT : |
1283 | 21.9k | case TAG_MINI_PAGE_HEIGHT : |
1284 | 23.6k | case TAG_CANVAS_HEIGHT : |
1285 | 23.6k | attributes.height = readU16(input); |
1286 | 23.6k | break; |
1287 | 4.47k | case TAG_PAGE_WIDTH : |
1288 | 17.3k | case TAG_BLOCK_WIDTH : |
1289 | 18.2k | case TAG_MINI_PAGE_WIDTH : |
1290 | 19.6k | case TAG_CANVAS_WIDTH : |
1291 | 19.6k | attributes.width = readU16(input); |
1292 | 19.6k | break; |
1293 | 2.93k | case TAG_LOCATION_X : |
1294 | 2.93k | attributes.locationX = readU16(input); |
1295 | 2.93k | break; |
1296 | 3.22k | case TAG_LOCATION_Y : |
1297 | 3.22k | attributes.locationY = readU16(input); |
1298 | 3.22k | break; |
1299 | 2.68k | case TAG_BEGIN_ITALIC : |
1300 | 2.68k | attributes.italic = true; |
1301 | 2.68k | break; |
1302 | 4.23k | case TAG_END_ITALIC : |
1303 | 4.23k | attributes.italic = false; |
1304 | 4.23k | break; |
1305 | 1.59k | case TAG_BEGIN_SUP : |
1306 | 1.59k | attributes.sup = true; |
1307 | 1.59k | break; |
1308 | 2.14k | case TAG_END_SUP : |
1309 | 2.14k | attributes.sup = false; |
1310 | 2.14k | break; |
1311 | 2.53k | case TAG_BEGIN_SUB : |
1312 | 2.53k | attributes.sub = true; |
1313 | 2.53k | break; |
1314 | 4.07k | case TAG_END_SUB : |
1315 | 4.07k | attributes.sub = false; |
1316 | 4.07k | break; |
1317 | 14.5k | case TAG_BEGIN_EMP_LINE : |
1318 | 14.5k | attributes.emptyLine = BBeBEmptyLine(); |
1319 | 14.5k | break; |
1320 | 7.77k | case TAG_END_EMP_LINE : |
1321 | 7.77k | attributes.emptyLine.reset(); |
1322 | 7.77k | break; |
1323 | 4.10k | case TAG_EMPTY_LINE_POSITION : |
1324 | 4.10k | { |
1325 | 4.10k | const unsigned position = readU16(input); |
1326 | 4.10k | if (attributes.emptyLine) |
1327 | 2.35k | { |
1328 | 2.35k | switch (position) |
1329 | 2.35k | { |
1330 | 491 | case 0x1 : |
1331 | 491 | get(attributes.emptyLine).m_position = BBEB_EMPTY_LINE_POSITION_BEFORE; |
1332 | 491 | break; |
1333 | 1.08k | case 0x2 : |
1334 | 1.08k | get(attributes.emptyLine).m_position = BBEB_EMPTY_LINE_POSITION_AFTER; |
1335 | 1.08k | break; |
1336 | 781 | default : |
1337 | 781 | EBOOK_DEBUG_MSG(("unkown Empty Line Position: %u\n", position)); |
1338 | 781 | break; |
1339 | 2.35k | } |
1340 | 2.35k | } |
1341 | 1.74k | else |
1342 | 1.74k | { |
1343 | 1.74k | EBOOK_DEBUG_MSG(("Empty Line Position without Begin Emp Line\n")); |
1344 | 1.74k | } |
1345 | 4.10k | break; |
1346 | 4.10k | } |
1347 | 8.26k | case TAG_EMPTY_LINE_MODE : |
1348 | 8.26k | { |
1349 | 8.26k | const unsigned mode = readU16(input); |
1350 | 8.26k | if (attributes.emptyLine) |
1351 | 4.42k | { |
1352 | 4.42k | switch (mode) |
1353 | 4.42k | { |
1354 | 342 | case 0x0 : |
1355 | 342 | get(attributes.emptyLine).m_mode = BBEB_EMPTY_LINE_MODE_NONE; |
1356 | 342 | break; |
1357 | 1.22k | case 0x10 : |
1358 | 1.22k | get(attributes.emptyLine).m_mode = BBEB_EMPTY_LINE_MODE_SOLID; |
1359 | 1.22k | break; |
1360 | 408 | case 0x20 : |
1361 | 408 | get(attributes.emptyLine).m_mode = BBEB_EMPTY_LINE_MODE_DASHED; |
1362 | 408 | break; |
1363 | 333 | case 0x30 : |
1364 | 333 | get(attributes.emptyLine).m_mode = BBEB_EMPTY_LINE_MODE_DOUBLE; |
1365 | 333 | break; |
1366 | 461 | case 0x40 : |
1367 | 461 | get(attributes.emptyLine).m_mode = BBEB_EMPTY_LINE_MODE_DOTTED; |
1368 | 461 | break; |
1369 | 1.65k | default : |
1370 | 1.65k | EBOOK_DEBUG_MSG(("unkown Empty Line Mode: %u\n", mode)); |
1371 | 1.65k | break; |
1372 | 4.42k | } |
1373 | 4.42k | } |
1374 | 3.84k | else |
1375 | 3.84k | { |
1376 | 3.84k | EBOOK_DEBUG_MSG(("Empty Line Mode without Begin Emp Line\n")); |
1377 | 3.84k | } |
1378 | 8.26k | break; |
1379 | 8.26k | } |
1380 | 11.3k | case TAG_ALIGN : |
1381 | 11.3k | { |
1382 | 11.3k | const unsigned align = readU16(input); |
1383 | 11.3k | switch (align) |
1384 | 11.3k | { |
1385 | 5.01k | case 0x1 : |
1386 | 5.01k | attributes.align = BBEB_ALIGN_START; |
1387 | 5.01k | break; |
1388 | 1.16k | case 0x4 : |
1389 | 1.16k | attributes.align = BBEB_ALIGN_CENTER; |
1390 | 1.16k | break; |
1391 | 1.54k | case 0x8 : |
1392 | 1.54k | attributes.align = BBEB_ALIGN_END; |
1393 | 1.54k | break; |
1394 | 3.66k | default : |
1395 | 3.66k | EBOOK_DEBUG_MSG(("unkown Align: %u\n", align)); |
1396 | 3.66k | break; |
1397 | 11.3k | } |
1398 | 11.3k | break; |
1399 | 11.3k | } |
1400 | 15.4k | case TAG_TOP_SKIP : |
1401 | 15.4k | attributes.topSkip = readU16(input); |
1402 | 15.4k | break; |
1403 | 4.15k | case TAG_TOP_MARGIN : |
1404 | 4.15k | attributes.topMargin = readU16(input); |
1405 | 4.15k | break; |
1406 | 3.53k | case TAG_ODD_SIDE_MARGIN : |
1407 | 3.53k | attributes.oddSideMargin = readU16(input); |
1408 | 3.53k | break; |
1409 | 4.40k | case TAG_EVEN_SIDE_MARGIN : |
1410 | 4.40k | attributes.evenSideMargin = readU16(input); |
1411 | 4.40k | break; |
1412 | 6.62M | default : |
1413 | 6.62M | handled = false; |
1414 | 6.62M | break; |
1415 | 6.94M | } |
1416 | | |
1417 | 6.94M | return handled; |
1418 | 6.94M | } |
1419 | | |
1420 | | void BBeBParser::skipUnhandledTag(const unsigned tag, librevenge::RVNGInputStream *const input, const char *const objectType) |
1421 | 8.43M | { |
1422 | 8.43M | switch (tag) |
1423 | 8.43M | { |
1424 | 76.1k | case TAG_OBJECT_END : |
1425 | 76.1k | EBOOK_DEBUG_MSG(("Object End tag should never appear\n")); |
1426 | 90.6k | case TAG_STREAM_START : |
1427 | 135k | case TAG_STREAM_END : |
1428 | 135k | case TAG_F54D : |
1429 | 135k | case TAG_F562 : |
1430 | 136k | case TAG_F563 : |
1431 | 137k | case TAG_F564 : |
1432 | 139k | case TAG_F565 : |
1433 | 142k | case TAG_F566 : |
1434 | 142k | case TAG_F567 : |
1435 | 143k | case TAG_F568 : |
1436 | 144k | case TAG_F569 : |
1437 | 145k | case TAG_F56A : |
1438 | 147k | case TAG_F56B : |
1439 | 147k | case TAG_F56E : |
1440 | 147k | case TAG_F571 : |
1441 | 148k | case TAG_F572 : |
1442 | 148k | case TAG_BEGIN_ITALIC : |
1443 | 149k | case TAG_END_ITALIC : |
1444 | 149k | case TAG_END_P : |
1445 | 149k | case TAG_KOMA_EMP_DOT_CHAR : |
1446 | 149k | case TAG_END_BUTTON : |
1447 | 149k | case TAG_BEGIN_RUBY : |
1448 | 151k | case TAG_END_RUBY : |
1449 | 151k | case TAG_BEGIN_RUBY_BASE : |
1450 | 151k | case TAG_END_RUBY_BASE : |
1451 | 152k | case TAG_BEGIN_RUBY_TEXT : |
1452 | 152k | case TAG_END_RUBY_TEXT : |
1453 | 152k | case TAG_KOMA_YOKOMOJI : |
1454 | 152k | case TAG_F5B2 : |
1455 | 152k | case TAG_BEGIN_TATE : |
1456 | 153k | case TAG_END_TATE : |
1457 | 153k | case TAG_BEGIN_NEKASE : |
1458 | 153k | case TAG_END_NEKASE : |
1459 | 153k | case TAG_BEGIN_SUP : |
1460 | 153k | case TAG_END_SUP : |
1461 | 153k | case TAG_BEGIN_SUB : |
1462 | 154k | case TAG_END_SUB : |
1463 | 154k | case TAG_F5BB : |
1464 | 154k | case TAG_F5BC : |
1465 | 154k | case TAG_F5BD : |
1466 | 155k | case TAG_F5BE : |
1467 | 159k | case TAG_BEGIN_EMP_LINE : |
1468 | 162k | case TAG_END_EMP_LINE : |
1469 | 162k | case TAG_END_DRAW_CHAR : |
1470 | 162k | case TAG_F5C7 : |
1471 | 162k | case TAG_F5C9 : |
1472 | 162k | case TAG_EOL : |
1473 | 162k | case TAG_SOUND_STOP : |
1474 | | // no arguments |
1475 | 162k | break; |
1476 | | |
1477 | 2.38k | case TAG_F50E : |
1478 | 3.82k | case TAG_FONT_SIZE : |
1479 | 5.97k | case TAG_FONT_WIDTH : |
1480 | 9.59k | case TAG_FONT_ESCAPEMENT : |
1481 | 11.3k | case TAG_FONT_ORIENTATION : |
1482 | 14.4k | case TAG_FONT_WEIGHT : |
1483 | 15.6k | case TAG_WORD_SPACE : |
1484 | 17.1k | case TAG_LETTER_SPACE : |
1485 | 18.8k | case TAG_BASE_LINE_SKIP : |
1486 | 20.4k | case TAG_LINE_SPACE : |
1487 | 21.4k | case TAG_PAR_INDENT : |
1488 | 22.5k | case TAG_PAR_SKIP : |
1489 | 24.3k | case TAG_TOP_MARGIN : |
1490 | 31.4k | case TAG_F522 : |
1491 | 34.6k | case TAG_F523 : |
1492 | 35.7k | case TAG_ODD_SIDE_MARGIN : |
1493 | 37.4k | case TAG_PAGE_HEIGHT : |
1494 | 39.4k | case TAG_PAGE_WIDTH : |
1495 | 41.3k | case TAG_F527 : |
1496 | 47.1k | case TAG_F528 : |
1497 | 53.2k | case TAG_F52A : |
1498 | 57.9k | case TAG_F52B : |
1499 | 59.0k | case TAG_EVEN_SIDE_MARGIN : |
1500 | 80.0k | case TAG_F52E : |
1501 | 82.2k | case TAG_BLOCK_WIDTH : |
1502 | 84.3k | case TAG_BLOCK_HEIGHT : |
1503 | 103k | case TAG_BLOCK_RULE : |
1504 | 125k | case TAG_F535 : |
1505 | 144k | case TAG_F536 : |
1506 | 145k | case TAG_TOP_SKIP : |
1507 | 163k | case TAG_F539 : |
1508 | 183k | case TAG_F53A : |
1509 | 184k | case TAG_ALIGN : |
1510 | 199k | case TAG_F53D : |
1511 | 211k | case TAG_F53E : |
1512 | 211k | case TAG_MINI_PAGE_HEIGHT : |
1513 | 214k | case TAG_MINI_PAGE_WIDTH : |
1514 | 215k | case TAG_LOCATION_Y : |
1515 | 216k | case TAG_LOCATION_X : |
1516 | 218k | case TAG_F548 : |
1517 | 219k | case TAG_CANVAS_WIDTH : |
1518 | 220k | case TAG_CANVAS_HEIGHT : |
1519 | 233k | case TAG_STREAM_FLAGS : |
1520 | 234k | case TAG_F557 : |
1521 | 235k | case TAG_F558 : |
1522 | 240k | case TAG_F55E : |
1523 | 243k | case TAG_F561 : |
1524 | 245k | case TAG_RUBY_ALIGN : |
1525 | 247k | case TAG_RUBY_OVERHANG : |
1526 | 249k | case TAG_EMPTY_DOTS_POSITION : |
1527 | 251k | case TAG_EMPTY_LINE_POSITION : |
1528 | 254k | case TAG_EMPTY_LINE_MODE : |
1529 | 255k | case TAG_BEGIN_DRAW_CHAR : |
1530 | 258k | case TAG_F5C5 : |
1531 | 259k | case TAG_F5C6 : |
1532 | 262k | case TAG_KOMA_AUTO_SPACING : |
1533 | 264k | case TAG_SPACE : |
1534 | 267k | case TAG_TEXT_SIZE : |
1535 | 268k | case TAG_WAIT : |
1536 | 274k | case TAG_F5DA : |
1537 | 276k | case TAG_F5DB : |
1538 | 280k | case TAG_F5DC : |
1539 | 291k | case TAG_CHAR_SPACE : |
1540 | 300k | case TAG_LINE_WIDTH : |
1541 | 303k | case TAG_LINE_MODE : |
1542 | 303k | skip(input, 2); |
1543 | 303k | break; |
1544 | | |
1545 | 6.40k | case TAG_OBJECT_INFO_LINK : |
1546 | 69.3k | case TAG_LINK : |
1547 | 84.4k | case TAG_STREAM_SIZE : |
1548 | 90.0k | case TAG_F507 : |
1549 | 93.1k | case TAG_F508 : |
1550 | 96.2k | case TAG_F509 : |
1551 | 98.5k | case TAG_F50A : |
1552 | 100k | case TAG_TEXT_COLOR : |
1553 | 102k | case TAG_TEXT_BG_COLOR : |
1554 | 103k | case TAG_F52D : |
1555 | 121k | case TAG_F534 : |
1556 | 138k | case TAG_F537 : |
1557 | 141k | case TAG_F544 : |
1558 | 143k | case TAG_F545 : |
1559 | 147k | case TAG_IMAGE_SIZE : |
1560 | 149k | case TAG_IMAGE_STREAM : |
1561 | 151k | case TAG_F553 : |
1562 | 156k | case TAG_VIEW_POINT : |
1563 | 162k | case TAG_CHILD_PAGE_TREE : |
1564 | 167k | case TAG_PARENT_PAGE_TREE : |
1565 | 167k | case TAG_BEGIN_P : |
1566 | 169k | case TAG_BEGIN_BUTTON : |
1567 | 171k | case TAG_BOOK_FONT : |
1568 | 181k | case TAG_LINE_COLOR : |
1569 | 184k | case TAG_FILL_COLOR : |
1570 | 208k | case TAG_MOVE_TO : |
1571 | 210k | case TAG_LINE_TO : |
1572 | 213k | case TAG_DRAW_BOX : |
1573 | 215k | case TAG_DRAW_ELLIPSE : |
1574 | 215k | skip(input, 4); |
1575 | 215k | break; |
1576 | | |
1577 | 103k | case TAG_OBJECT_START : |
1578 | 103k | EBOOK_DEBUG_MSG(("Object Start tag should never appear\n")); |
1579 | | // fall-through intended |
1580 | 123k | case TAG_F529 : |
1581 | 125k | case TAG_F5F9 : |
1582 | 125k | skip(input, 6); |
1583 | 125k | break; |
1584 | | |
1585 | 1.15k | case TAG_PUT_SOUND : |
1586 | 2.01k | case TAG_IMAGE_CROP_RECT : |
1587 | 5.32k | case TAG_JUMP_TO : |
1588 | 7.31k | case TAG_KOMA_PLOT_TEXT : |
1589 | 7.31k | skip(input, 8); |
1590 | 7.31k | break; |
1591 | | |
1592 | 5.83k | case TAG_RULED_LINE : |
1593 | 5.83k | skip(input, 10); |
1594 | 5.83k | break; |
1595 | | |
1596 | 836 | case TAG_F54E : |
1597 | 2.25k | case TAG_KOMA_PLOT : |
1598 | 2.25k | skip(input, 12); |
1599 | 2.25k | break; |
1600 | | |
1601 | 1.94k | case TAG_MOVE_OBJ : |
1602 | 1.94k | skip(input, 14); |
1603 | 1.94k | break; |
1604 | | |
1605 | 2.75k | case TAG_CONTAINED_OBJECTS_LIST : |
1606 | 13.1k | case TAG_PAGE_LIST : |
1607 | 13.1k | { |
1608 | 13.1k | unsigned count = readU16(input); |
1609 | 13.1k | skip(input, count * 4); |
1610 | 13.1k | } |
1611 | 13.1k | break; |
1612 | 3.95k | case TAG_F50D : |
1613 | 4.72k | case TAG_FONT_FACENAME : |
1614 | 5.47k | case TAG_F555 : |
1615 | 6.00k | case TAG_F556 : |
1616 | 6.74k | case TAG_FONT_FILE_NAME : |
1617 | 7.74k | case TAG_F55A : |
1618 | 9.23k | case TAG_FONT_FACE_NAME : |
1619 | 10.3k | case TAG_F56D : |
1620 | 12.2k | case TAG_EMPTY_DOTS_CODE : |
1621 | 13.2k | case TAG_KOMA_GAIJI : |
1622 | 14.1k | case TAG_F5CB : |
1623 | 14.1k | { |
1624 | | // try to find the next tag |
1625 | 14.1k | unsigned n = 1; |
1626 | 9.12M | while (!input->isEnd() && ((0xf5 != readU8(input)) || (2 <= n))) |
1627 | 9.10M | ++n; |
1628 | 14.1k | if (!input->isEnd()) |
1629 | 4.18k | input->seek(-2, librevenge::RVNG_SEEK_CUR); |
1630 | 14.1k | } |
1631 | 14.1k | break; |
1632 | 7.58M | default : |
1633 | 7.58M | EBOOK_DEBUG_MSG(("unknown tag %x\n", tag)); |
1634 | 7.58M | return; |
1635 | 8.43M | } |
1636 | | |
1637 | 851k | (void) objectType; |
1638 | 851k | EBOOK_DEBUG_MSG(("skipping unhandled tag %x at %s object\n", tag, objectType)); |
1639 | 851k | } |
1640 | | |
1641 | | bool BBeBParser::isObjectRead(const unsigned id) const |
1642 | 33.8k | { |
1643 | 33.8k | const ObjectIndex_t::const_iterator it = m_objectIndex.find(id); |
1644 | 33.8k | return (m_objectIndex.end() != it) && it->second.read; |
1645 | 33.8k | } |
1646 | | |
1647 | | } // namespace libebook |
1648 | | |
1649 | | /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ |