KTnef

lzfu.cpp
Go to the documentation of this file.
1 /*
2  lzfu.cpp
3 
4  SPDX-FileCopyrightText: 2003 Michael Goffioul <[email protected]>
5 
6  This file is part of KTNEF, the KDE TNEF support library/program.
7 
8  SPDX-License-Identifier: LGPL-2.0-or-later
9  */
18 #include "lzfu.h"
19 
20 #include <QIODevice>
21 
22 #include <sys/types.h>
23 #include <string.h>
24 #include <stdio.h>
25 
26 //#define DO_DEBUG
27 
28 //@cond IGNORE
29 #define LZFU_COMPRESSED 0x75465a4c
30 #define LZFU_UNCOMPRESSED 0x414c454d
31 
32 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \
33  "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \
34  "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \
35  "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \
36  "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \
37  "\\tx"
38 #define LZFU_INITLENGTH 207
39 //@endcond
40 
41 //@cond PRIVATE
42 typedef struct _lzfuheader {
43  quint32 cbSize;
44  quint32 cbRawSize;
45  quint32 dwMagic;
46  quint32 dwCRC;
47 } lzfuheader;
48 //@endcond
49 
50 //@cond IGNORE
51 #define FLAG(f,n) (f>>n)&0x1
52 
53 /*typedef struct _blockheader {
54  unsigned int offset:12;
55  unsigned int length:4;
56  } blockheader;*/
57 
58 #define OFFSET(b) (b>>4)&0xFFF
59 #define LENGTH(b) ((b&0xF)+2)
60 //@endcond
61 
63 {
64  unsigned char window[4096];
65  unsigned int wlength = 0, cursor = 0, ocursor = 0;
66  lzfuheader lzfuhdr;
67  //blockheader blkhdr;
68  quint16 blkhdr;
69  char bFlags;
70  int nFlags;
71 
72  memcpy(window, LZFU_INITDICT, LZFU_INITLENGTH);
73  wlength = LZFU_INITLENGTH;
74  if (input->read((char *)&lzfuhdr, sizeof(lzfuhdr)) != sizeof(lzfuhdr)) {
75  fprintf(stderr, "unexpected eof, cannot read LZFU header\n");
76  return -1;
77  }
78  cursor += sizeof(lzfuhdr);
79 #ifdef DO_DEBUG
80  fprintf(stdout, "total size : %d\n", lzfuhdr.cbSize + 4);
81  fprintf(stdout, "raw size : %d\n", lzfuhdr.cbRawSize);
82  fprintf(stdout, "compressed : %s\n", (lzfuhdr.dwMagic == LZFU_COMPRESSED ? "yes" : "no"));
83  fprintf(stdout, "CRC : %x\n", lzfuhdr.dwCRC);
84  fprintf(stdout, "\n");
85 #endif
86 
87  while (cursor < lzfuhdr.cbSize + 4 && ocursor < lzfuhdr.cbRawSize && !input->atEnd()) {
88  if (input->read(&bFlags, 1) != 1) {
89  fprintf(stderr, "unexpected eof, cannot read chunk flag\n");
90  return -1;
91  }
92  nFlags = 8;
93  cursor++;
94 #ifdef DO_DEBUG
95  fprintf(stdout, "Flags : ");
96  for (int i = nFlags - 1; i >= 0; i--) {
97  fprintf(stdout, "%d", FLAG(bFlags, i));
98  }
99  fprintf(stdout, "\n");
100 #endif
101  for (int i = 0; i < nFlags && ocursor < lzfuhdr.cbRawSize && cursor < lzfuhdr.cbSize + 4; i++) {
102  if (FLAG(bFlags, i)) {
103  // compressed chunck
104  char c1, c2;
105  if (input->read(&c1, 1) != 1 || input->read(&c2, 1) != 1) {
106  fprintf(stderr, "unexpected eof, cannot read block header\n");
107  return -1;
108  }
109  blkhdr = c1;
110  blkhdr <<= 8;
111  blkhdr |= (0xFF & c2);
112  unsigned int offset = OFFSET(blkhdr), length = LENGTH(blkhdr);
113  cursor += 2;
114 #ifdef DO_DEBUG
115  fprintf(stdout, "block : offset=%.4d [%d], length=%.2d (0x%04X)\n",
116  OFFSET(blkhdr), wlength, LENGTH(blkhdr), blkhdr);
117 #endif
118  //if ( offset >= wlength ) {
119  // break;
120  //}
121 #ifdef DO_DEBUG
122  fprintf(stdout, "block : ");
123 #endif
124  for (unsigned int i = 0; i < length; i++) {
125  c1 = window[(offset + i) % 4096];
126  //if ( wlength < 4096 ) {
127  window[wlength] = c1;
128  wlength = (wlength + 1) % 4096;
129  //}
130 #ifdef DO_DEBUG
131  if (c1 == '\n') {
132  fprintf(stdout, "\nblock : ");
133  } else {
134  fprintf(stdout, "%c", c1);
135  }
136 #endif
137  output->putChar(c1);
138  ocursor++;
139  }
140 #ifdef DO_DEBUG
141  fprintf(stdout, "\n");
142 #endif
143  } else {
144  // uncompressed chunk (char)
145  char c;
146  if (!input->getChar(&c)) {
147  if (!input->atEnd()) {
148  fprintf(stderr, "unexpected eof, cannot read character\n");
149  return -1;
150  }
151  break;
152  }
153 #ifdef DO_DEBUG
154  fprintf(stdout, "char : %c\n", c);
155 #endif
156  cursor++;
157  //if ( wlength < 4096 ) {
158  window[wlength] = c;
159  wlength = (wlength + 1) % 4096;
160  //}
161  output->putChar(c);
162  ocursor++;
163  }
164  }
165 
166  }
167 
168  return 0;
169 }
virtual bool atEnd() const const
bool getChar(char *c)
This file is part of the API for handling TNEF data and provides the LZFU decompression functionality...
int lzfu_decompress(QIODevice *input, QIODevice *output)
LZFU decompress data in compressed Rich Text Format (RTF).
Definition: lzfu.cpp:62
qint64 read(char *data, qint64 maxSize)
bool putChar(char c)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Oct 28 2020 23:21:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.