summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/plucker.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/plucker.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-reader/plucker.cpp579
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
8CPlucker::CPlucker() : expandedtextbuffer(NULL), compressedtextbuffer(NULL) { /*printf("constructing:%x\n",fin);*/ }
9
10
11int 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
54int 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
88int 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
263void CPlucker::getch(int& ch, CStyle& sty)
264{
265 ch = getch();
266 sty = mystyle;
267}
268
269unsigned 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
288void 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
314bool 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
347bool 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
413void 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
448void 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
501void CPlucker::home()
502{
503 currentpos = 0;
504 expand(1);
505}
506
507CList<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
529void 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}