author | llornkcor <llornkcor> | 2002-09-14 12:19:03 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2002-09-14 12:19:03 (UTC) |
commit | d01f8da912a2bed9de1943d174ec10dba505bf38 (patch) (unidiff) | |
tree | 2e09e6dff15e9cc29e730219b2cb0b2773fb4370 /noncore/apps/opie-reader/plucker.cpp | |
parent | e82423eb0aa113cf8accd92a698cf236d9b069a6 (diff) | |
download | opie-d01f8da912a2bed9de1943d174ec10dba505bf38.zip opie-d01f8da912a2bed9de1943d174ec10dba505bf38.tar.gz opie-d01f8da912a2bed9de1943d174ec10dba505bf38.tar.bz2 |
add this too
Diffstat (limited to 'noncore/apps/opie-reader/plucker.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/plucker.cpp | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/plucker.cpp b/noncore/apps/opie-reader/plucker.cpp new file mode 100644 index 0000000..ddda4bc --- a/dev/null +++ b/noncore/apps/opie-reader/plucker.cpp | |||
@@ -0,0 +1,579 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include <qmessagebox.h> | ||
4 | #include "plucker.h" | ||
5 | |||
6 | #include "Aportis.h" | ||
7 | |||
8 | CPlucker::CPlucker() : expandedtextbuffer(NULL), compressedtextbuffer(NULL) { /*printf("constructing:%x\n",fin);*/ } | ||
9 | |||
10 | |||
11 | int CPlucker::openfile(const char *src) | ||
12 | { | ||
13 | if (!Cpdb::openfile(src)) | ||
14 | { | ||
15 | return -1; | ||
16 | } | ||
17 | |||
18 | //printf("Okay %u\n", 4); | ||
19 | |||
20 | if (memcmp(&head.type, "DataPlkr", 8) != 0) return -1; | ||
21 | |||
22 | // qDebug("Cool - this IS plucker"); | ||
23 | |||
24 | textlength = 0; | ||
25 | for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++) | ||
26 | { | ||
27 | CPlucker_dataRecord thisHdr; | ||
28 | gotorecordnumber(recptr); | ||
29 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
30 | if (thisHdr.type < 2) textlength += htons(thisHdr.size); | ||
31 | } | ||
32 | |||
33 | gotorecordnumber(0); | ||
34 | fread(&hdr0, 1, sizeof(hdr0), fin); | ||
35 | //printf("Okay %u\n", 5); | ||
36 | buffersize = 32*1024; | ||
37 | compressedtextbuffer = new UInt8[buffersize]; | ||
38 | expandedtextbuffer = new UInt8[buffersize]; | ||
39 | |||
40 | // qDebug("Total number of records:%u", ntohs(head.recordList.numRecords)); | ||
41 | |||
42 | unsigned int nrecs = ntohs(hdr0.nRecords); | ||
43 | // qDebug("Version %u, no. res %u", ntohs(hdr0.version), nrecs); | ||
44 | for (unsigned int i = 0; i < 4*nrecs; i++) | ||
45 | { | ||
46 | UInt8 id; | ||
47 | fread(&id, 1, sizeof(id), fin); | ||
48 | // qDebug("%x", id); | ||
49 | } | ||
50 | home(); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | int CPlucker::bgetch() | ||
55 | { | ||
56 | int ch = EOF; | ||
57 | if (bufferpos >= buffercontent) | ||
58 | { | ||
59 | if (bufferrec >= ntohs(head.recordList.numRecords) - 1) return EOF; | ||
60 | // qDebug("Passing through %u", currentpos); | ||
61 | if (!expand(bufferrec+1)) return EOF; | ||
62 | mystyle.unset(); | ||
63 | } | ||
64 | |||
65 | if (bufferpos == m_nextPara) | ||
66 | { | ||
67 | UInt16 attr = m_ParaAttrs[m_nextParaIndex]; | ||
68 | m_nextParaIndex++; | ||
69 | if (m_nextParaIndex == m_nParas) | ||
70 | { | ||
71 | m_nextPara = -1; | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | m_nextPara += m_ParaOffsets[m_nextParaIndex]; | ||
76 | } | ||
77 | // qDebug("New paragraph"); | ||
78 | ch = 10; | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | currentpos++; | ||
83 | ch = expandedtextbuffer[bufferpos++]; | ||
84 | } | ||
85 | return ch; | ||
86 | } | ||
87 | |||
88 | int CPlucker::getch() | ||
89 | { | ||
90 | int ch = bgetch(); | ||
91 | while (ch == 0) | ||
92 | { | ||
93 | ch = bgetch(); | ||
94 | // qDebug("Function:%x", ch); | ||
95 | switch (ch) | ||
96 | { | ||
97 | case 0x38: | ||
98 | ch = 10; | ||
99 | break; | ||
100 | case 0x0a: | ||
101 | case 0x0c: | ||
102 | { | ||
103 | unsigned long ln = 0; | ||
104 | int skip = ch & 7; | ||
105 | for (int i = 0; i < 2; i++) | ||
106 | { | ||
107 | int ch = bgetch(); | ||
108 | ln = (ln << 8) + ch; | ||
109 | // qDebug("ch:%d, ln:%u", ch, ln); | ||
110 | } | ||
111 | if (skip == 2) | ||
112 | { | ||
113 | ln <<= 16; | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | for (int i = 0; i < 2; i++) | ||
118 | { | ||
119 | int ch = bgetch(); | ||
120 | ln = (ln << 8) + ch; | ||
121 | // qDebug("ch:%d, ln:%u", ch, ln); | ||
122 | } | ||
123 | } | ||
124 | // qDebug("ln:%u", ln); | ||
125 | mystyle.setLink(true); | ||
126 | mystyle.setData(ln); | ||
127 | mystyle.setColour(255, 0, 0); | ||
128 | ch = bgetch(); | ||
129 | } | ||
130 | break; | ||
131 | case 0x08: | ||
132 | ch = bgetch(); | ||
133 | mystyle.setColour(0, 0, 0); | ||
134 | mystyle.setLink(false); | ||
135 | mystyle.setData(0); | ||
136 | break; | ||
137 | case 0x40: | ||
138 | mystyle.setItalic(); | ||
139 | ch = bgetch(); | ||
140 | break; | ||
141 | case 0x48: | ||
142 | mystyle.unsetItalic(); | ||
143 | ch = bgetch(); | ||
144 | break; | ||
145 | case 0x11: | ||
146 | { | ||
147 | ch = bgetch(); | ||
148 | qDebug("Font:%d",ch); | ||
149 | switch (ch) | ||
150 | { | ||
151 | case 0: | ||
152 | mystyle.unsetBold(); | ||
153 | mystyle.setFontSize(0); | ||
154 | break; | ||
155 | case 1: | ||
156 | mystyle.setBold(); | ||
157 | mystyle.setFontSize(1); | ||
158 | break; | ||
159 | case 2: | ||
160 | mystyle.setBold(); | ||
161 | mystyle.setFontSize(1); | ||
162 | break; | ||
163 | case 3: | ||
164 | // mystyle.setBold(); | ||
165 | mystyle.setFontSize(1); | ||
166 | break; | ||
167 | case 4: | ||
168 | // mystyle.setBold(); | ||
169 | mystyle.setFontSize(1); | ||
170 | break; | ||
171 | case 5: | ||
172 | mystyle.setBold(); | ||
173 | mystyle.setFontSize(0); | ||
174 | break; | ||
175 | case 6: | ||
176 | mystyle.setBold(); | ||
177 | mystyle.setFontSize(0); | ||
178 | break; | ||
179 | case 7: | ||
180 | mystyle.setBold(); | ||
181 | mystyle.setFontSize(0); | ||
182 | break; | ||
183 | case 8: // should be fixed width | ||
184 | mystyle.unsetBold(); | ||
185 | mystyle.setFontSize(0); | ||
186 | break; | ||
187 | default: | ||
188 | mystyle.unsetBold(); | ||
189 | mystyle.setFontSize(0); | ||
190 | break; | ||
191 | } | ||
192 | ch = bgetch(); | ||
193 | } | ||
194 | break; | ||
195 | case 0x29: | ||
196 | ch = bgetch(); | ||
197 | switch (ch) | ||
198 | { | ||
199 | case 0: | ||
200 | mystyle.setLeftJustify(); | ||
201 | // qDebug("left"); | ||
202 | break; | ||
203 | case 1: | ||
204 | mystyle.setRightJustify(); | ||
205 | // qDebug("right"); | ||
206 | break; | ||
207 | case 2: | ||
208 | mystyle.setCentreJustify(); | ||
209 | // qDebug("centre"); | ||
210 | break; | ||
211 | case 3: | ||
212 | mystyle.setFullJustify(); | ||
213 | // qDebug("full"); | ||
214 | break; | ||
215 | |||
216 | } | ||
217 | ch = bgetch(); | ||
218 | break; | ||
219 | case 0x53: | ||
220 | { | ||
221 | int r = bgetch(); | ||
222 | int g = bgetch(); | ||
223 | int b = bgetch(); | ||
224 | mystyle.setColour(r,g,b); | ||
225 | ch = bgetch(); | ||
226 | } | ||
227 | break; | ||
228 | case 0x1a: | ||
229 | /* | ||
230 | { | ||
231 | UInt16 ir = bgetch(); | ||
232 | ir = (ir << 8) + bgetch(); | ||
233 | expandimg(ir); | ||
234 | } | ||
235 | ch = bgetch(); | ||
236 | break; | ||
237 | */ | ||
238 | case 0x33: | ||
239 | case 0x22: | ||
240 | case 0x5c: | ||
241 | case 0x60: | ||
242 | case 0x68: | ||
243 | case 0x70: | ||
244 | case 0x78: | ||
245 | case 0x83: | ||
246 | case 0x85: | ||
247 | default: | ||
248 | qDebug("Function:%x NOT IMPLEMENTED", ch); | ||
249 | { | ||
250 | int skip = ch & 7; | ||
251 | for (int i = 0; i < skip; i++) | ||
252 | { | ||
253 | ch = bgetch(); | ||
254 | qDebug("Arg %d, %d", i, ch); | ||
255 | } | ||
256 | ch = bgetch(); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | return ch; | ||
261 | } | ||
262 | |||
263 | void CPlucker::getch(int& ch, CStyle& sty) | ||
264 | { | ||
265 | ch = getch(); | ||
266 | sty = mystyle; | ||
267 | } | ||
268 | |||
269 | unsigned int CPlucker::locate() | ||
270 | { | ||
271 | return currentpos; | ||
272 | /* | ||
273 | UInt16 thisrec = 1; | ||
274 | unsigned long locpos = 0; | ||
275 | gotorecordnumber(thisrec); | ||
276 | CPlucker_dataRecord thisHdr; | ||
277 | while (thisrec < bufferrec) | ||
278 | { | ||
279 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
280 | if (thisHdr.type < 2) locpos += htons(thisHdr.size); | ||
281 | thisrec++; | ||
282 | gotorecordnumber(thisrec); | ||
283 | } | ||
284 | return locpos+bufferpos; | ||
285 | */ | ||
286 | } | ||
287 | |||
288 | void CPlucker::locate(unsigned int n) | ||
289 | { | ||
290 | UInt16 thisrec = 0; | ||
291 | unsigned long locpos = 0; | ||
292 | unsigned long bs = 0; | ||
293 | CPlucker_dataRecord thisHdr; | ||
294 | do | ||
295 | { | ||
296 | thisrec++; | ||
297 | locpos += bs; | ||
298 | gotorecordnumber(thisrec); | ||
299 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
300 | if (thisHdr.type < 2) | ||
301 | { | ||
302 | bs = htons(thisHdr.size); | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | bs = 0; | ||
307 | } | ||
308 | } while (locpos + bs < n); | ||
309 | currentpos = locpos; | ||
310 | expand(thisrec); | ||
311 | while (currentpos < n && bufferpos < buffercontent) bgetch(); | ||
312 | } | ||
313 | |||
314 | bool CPlucker::hyperlink(unsigned int n) | ||
315 | { | ||
316 | UInt16 tuid = (n >> 16); | ||
317 | n &= 0xffff; | ||
318 | UInt16 thisrec = 1; | ||
319 | currentpos = 0; | ||
320 | gotorecordnumber(thisrec); | ||
321 | CPlucker_dataRecord thisHdr; | ||
322 | while (1) | ||
323 | { | ||
324 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
325 | if (tuid <= htons(thisHdr.uid)) break; | ||
326 | if (thisHdr.type < 2) currentpos += htons(thisHdr.size); | ||
327 | // qDebug("hyper-cp:%u", currentpos); | ||
328 | thisrec++; | ||
329 | gotorecordnumber(thisrec); | ||
330 | } | ||
331 | if (thisHdr.type > 1) | ||
332 | { | ||
333 | QMessageBox::information(NULL, | ||
334 | QString("OpieReader"), | ||
335 | QString("External links\nnot yet supported") | ||
336 | ); | ||
337 | return false; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | expand(thisrec); | ||
342 | while (bufferpos < n && bufferpos < buffercontent) getch(); | ||
343 | } | ||
344 | return true; | ||
345 | } | ||
346 | |||
347 | bool CPlucker::expand(int thisrec) | ||
348 | { | ||
349 | mystyle.unset(); | ||
350 | size_t reclen = recordlength(thisrec); | ||
351 | gotorecordnumber(thisrec); | ||
352 | CPlucker_dataRecord thisHdr; | ||
353 | while (1) | ||
354 | { | ||
355 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
356 | // qDebug("This (%d) type is %d, uid is %u", thisrec, thisHdr.type, ntohs(thisHdr.uid)); | ||
357 | if (thisHdr.type < 2) break; | ||
358 | qDebug("Skipping paragraph of type %d", thisHdr.type); | ||
359 | if (++thisrec >= ntohs(head.recordList.numRecords) - 1) return false; | ||
360 | reclen = recordlength(thisrec); | ||
361 | gotorecordnumber(thisrec); | ||
362 | } | ||
363 | m_nParas = ntohs(thisHdr.nParagraphs); | ||
364 | // qDebug("It has %u paragraphs and is %u bytes", htons(thisHdr.nParagraphs), htons(thisHdr.size)); | ||
365 | uid = ntohs(thisHdr.uid); | ||
366 | for (int i = 0; i < m_nParas; i++) | ||
367 | { | ||
368 | UInt16 ubytes, attrs; | ||
369 | fread(&ubytes, 1, sizeof(ubytes), fin); | ||
370 | fread(&attrs, 1, sizeof(attrs), fin); | ||
371 | m_ParaOffsets[i] = ntohs(ubytes); | ||
372 | m_ParaAttrs[i] = ntohs(attrs); | ||
373 | // qDebug("Bytes %u, Attr %x", ntohs(ubytes), attrs); | ||
374 | } | ||
375 | if (m_nParas > 0) | ||
376 | { | ||
377 | m_nextPara = m_ParaOffsets[0]; | ||
378 | // qDebug("First offset = %u", m_nextPara); | ||
379 | m_nextParaIndex = 0; | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | m_nextPara = -1; | ||
384 | } | ||
385 | |||
386 | reclen -= sizeof(thisHdr)+4*m_nParas; | ||
387 | |||
388 | buffercontent = htons(thisHdr.size); | ||
389 | |||
390 | if (thisHdr.type == 0) | ||
391 | { | ||
392 | fread(expandedtextbuffer, reclen, sizeof(char), fin); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | fread(compressedtextbuffer, reclen, sizeof(char), fin); | ||
397 | switch (ntohs(hdr0.version)) | ||
398 | { | ||
399 | case 2: | ||
400 | UnZip(reclen, expandedtextbuffer, buffercontent); | ||
401 | break; | ||
402 | case 1: | ||
403 | UnDoc(reclen, expandedtextbuffer, buffercontent); | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | bufferpos = 0; | ||
408 | bufferrec = thisrec; | ||
409 | // qDebug("BC:%u, HS:%u", buffercontent, ntohs(thisHdr.size)); | ||
410 | return true; | ||
411 | } | ||
412 | |||
413 | void CPlucker::UnZip(size_t reclen, UInt8* tgtbuffer, UInt16 bsize) | ||
414 | { | ||
415 | z_stream zstream; | ||
416 | memset(&zstream,sizeof(zstream),0); | ||
417 | zstream.next_in = compressedtextbuffer; | ||
418 | zstream.next_out = tgtbuffer; | ||
419 | zstream.avail_out = bsize; | ||
420 | zstream.avail_in = reclen; | ||
421 | |||
422 | int keylen = 0; | ||
423 | |||
424 | zstream.zalloc = Z_NULL; | ||
425 | zstream.zfree = Z_NULL; | ||
426 | zstream.opaque = Z_NULL; | ||
427 | |||
428 | // printf("Initialising\n"); | ||
429 | |||
430 | inflateInit(&zstream); | ||
431 | int err = 0; | ||
432 | do { | ||
433 | if ( zstream.avail_in == 0 && 0 < keylen ) { | ||
434 | zstream.next_in = compressedtextbuffer + keylen; | ||
435 | zstream.avail_in = reclen - keylen; | ||
436 | keylen = 0; | ||
437 | } | ||
438 | zstream.next_out = tgtbuffer; | ||
439 | zstream.avail_out = bsize; | ||
440 | |||
441 | err = inflate( &zstream, Z_SYNC_FLUSH ); | ||
442 | |||
443 | } while ( err == Z_OK ); | ||
444 | |||
445 | inflateEnd(&zstream); | ||
446 | } | ||
447 | |||
448 | void CPlucker::UnDoc(size_t reclen, UInt8* tgtbuffer, UInt16 bsize) | ||
449 | { | ||
450 | // UInt16 headerSize; | ||
451 | UInt16 docSize; | ||
452 | UInt16 i; | ||
453 | UInt16 j; | ||
454 | UInt16 k; | ||
455 | |||
456 | UInt8 *inBuf = compressedtextbuffer; | ||
457 | UInt8 *outBuf = tgtbuffer; | ||
458 | |||
459 | // headerSize = sizeof( Header ) + record->paragraphs * sizeof( Paragraph ); | ||
460 | docSize = reclen; | ||
461 | |||
462 | j = 0; | ||
463 | k = 0; | ||
464 | while ( j < docSize ) { | ||
465 | i = 0; | ||
466 | while ( i < bsize && j < docSize ) { | ||
467 | UInt16 c; | ||
468 | |||
469 | c = (UInt16) inBuf[ j++ ]; | ||
470 | if ( 0 < c && c < 9 ) { | ||
471 | while ( 0 < c-- ) | ||
472 | outBuf[ i++ ] = inBuf[ j++ ]; | ||
473 | } | ||
474 | else if ( c < 0x80 ) | ||
475 | outBuf[ i++ ] = c; | ||
476 | else if ( 0xc0 <= c ) { | ||
477 | outBuf[ i++ ] = ' '; | ||
478 | outBuf[ i++ ] = c ^ 0x80; | ||
479 | } | ||
480 | else { | ||
481 | Int16 m; | ||
482 | Int16 n; | ||
483 | |||
484 | c <<= 8; | ||
485 | c += inBuf[ j++ ]; | ||
486 | |||
487 | m = ( c & 0x3fff ) >> COUNT_BITS; | ||
488 | n = c & ( ( 1 << COUNT_BITS ) - 1 ); | ||
489 | n += 2; | ||
490 | |||
491 | do { | ||
492 | outBuf[ i ] = outBuf[ i - m ]; | ||
493 | i++; | ||
494 | } while ( 0 < n-- ); | ||
495 | } | ||
496 | } | ||
497 | k += bsize; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | void CPlucker::home() | ||
502 | { | ||
503 | currentpos = 0; | ||
504 | expand(1); | ||
505 | } | ||
506 | |||
507 | CList<Bkmk>* CPlucker::getbkmklist() | ||
508 | { | ||
509 | /* | ||
510 | CPlucker_dataRecord thisHdr; | ||
511 | |||
512 | for (int i = 1; i < ntohs(head.recordList.numRecords); i++) | ||
513 | { | ||
514 | gotorecordnumber(i); | ||
515 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
516 | if (thisHdr.type == 8) | ||
517 | { | ||
518 | UInt16 n; | ||
519 | fread(&n, 1, sizeof(n), fin); | ||
520 | n = ntohs(n); | ||
521 | qDebug("Found %u bookmarks", n); | ||
522 | } | ||
523 | qDebug("Found:%d, %u", i , thisHdr.type); | ||
524 | } | ||
525 | */ | ||
526 | return NULL; | ||
527 | } | ||
528 | |||
529 | void CPlucker::expandimg(UInt16 tgt) | ||
530 | { | ||
531 | qDebug("Image:%u", tgt); | ||
532 | CPlucker_dataRecord thisHdr; | ||
533 | size_t reclen; | ||
534 | UInt16 thisrec = 0; | ||
535 | do | ||
536 | { | ||
537 | thisrec++; | ||
538 | reclen = recordlength(thisrec); | ||
539 | gotorecordnumber(thisrec); | ||
540 | qDebug("thisrec:%u.%u", ftell(fin),thisrec); | ||
541 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
542 | } | ||
543 | while (ntohs(thisHdr.uid) != tgt); | ||
544 | |||
545 | reclen -= sizeof(thisHdr); | ||
546 | |||
547 | UInt16 imgsize = htons(thisHdr.size); | ||
548 | UInt8* imgbuffer = new UInt8[imgsize]; | ||
549 | |||
550 | qDebug("type:%u", thisHdr.type); | ||
551 | |||
552 | if (thisHdr.type == 2) | ||
553 | { | ||
554 | qDebug("Not compressed:%u.%u", ftell(fin),reclen); | ||
555 | fread(imgbuffer, reclen, sizeof(char), fin); | ||
556 | qDebug("Not compressed:%u.%u", ftell(fin),reclen); | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | qDebug("Compressed"); | ||
561 | fread(compressedtextbuffer, reclen, sizeof(char), fin); | ||
562 | switch (ntohs(hdr0.version)) | ||
563 | { | ||
564 | case 2: | ||
565 | UnZip(reclen, imgbuffer, imgsize); | ||
566 | break; | ||
567 | case 1: | ||
568 | UnDoc(reclen, imgbuffer, imgsize); | ||
569 | break; | ||
570 | } | ||
571 | } | ||
572 | FILE* imgfile = fopen("/home/tim/newreader/imagefile.tbmp", "w"); | ||
573 | if (imgfile != NULL) | ||
574 | { | ||
575 | fwrite(imgbuffer, 1, imgsize, imgfile); | ||
576 | fclose(imgfile); | ||
577 | } | ||
578 | delete [] imgbuffer; | ||
579 | } | ||