00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "define.h"
00013 #include "libpst.h"
00014
00015 #include <sys/types.h>
00016 #include <string.h>
00017 #include <stdio.h>
00018
00019 #include "lzfu.h"
00020
00021 #define LZFU_COMPRESSED 0x75465a4c
00022 #define LZFU_UNCOMPRESSED 0x414c454d
00023
00024
00025 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \
00026 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \
00027 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \
00028 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \
00029 "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \
00030 "\\tx"
00031
00032 #define LZFU_INITLENGTH 207
00033
00034
00035 typedef struct _lzfuheader {
00036 uint32_t cbSize;
00037 uint32_t cbRawSize;
00038 uint32_t dwMagic;
00039 uint32_t dwCRC;
00040 } lzfuheader;
00041
00042
00043 char* lzfu_decompress(char* rtfcomp, uint32_t compsize, size_t *size) {
00044 unsigned char dict[4096];
00045 unsigned int dict_length = 0;
00046 lzfuheader lzfuhdr;
00047 unsigned char flags;
00048 unsigned char flag_mask;
00049 uint32_t i;
00050 char *out_buf;
00051 uint32_t out_ptr = 0;
00052 uint32_t out_size;
00053 uint32_t in_ptr;
00054 uint32_t in_size;
00055
00056 memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH);
00057 memset(dict + LZFU_INITLENGTH, 0, sizeof(dict) - LZFU_INITLENGTH);
00058 dict_length = LZFU_INITLENGTH;
00059
00060 memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr));
00061 LE32_CPU(lzfuhdr.cbSize);
00062 LE32_CPU(lzfuhdr.cbRawSize);
00063 LE32_CPU(lzfuhdr.dwMagic);
00064 LE32_CPU(lzfuhdr.dwCRC);
00065
00066
00067
00068
00069
00070 out_size = lzfuhdr.cbRawSize;
00071 out_buf = (char*)xmalloc(out_size);
00072 in_ptr = sizeof(lzfuhdr);
00073
00074
00075 in_size = (lzfuhdr.cbSize + 4 < compsize) ? lzfuhdr.cbSize + 4 : compsize;
00076 while (in_ptr < in_size) {
00077 flags = (unsigned char)(rtfcomp[in_ptr++]);
00078 flag_mask = 1;
00079 while (flag_mask) {
00080 if (flag_mask & flags) {
00081
00082 if (in_ptr+1 < in_size) {
00083
00084 unsigned short int blkhdr, offset, length;
00085 memcpy(&blkhdr, rtfcomp+in_ptr, 2);
00086 LE16_CPU(blkhdr);
00087 in_ptr += 2;
00088
00089 blkhdr = (((blkhdr&0xFF00)>>8)+
00090 ((blkhdr&0x00FF)<<8));
00091
00092 offset = (blkhdr&0xFFF0)>>4;
00093
00094 length = (blkhdr&0x000F)+2;
00095
00096 for (i=0; i < length; i++) {
00097 unsigned char c1;
00098 c1 = dict[(offset+i)%4096];
00099 dict[dict_length] = c1;
00100 dict_length = (dict_length+1) % 4096;
00101 if (out_ptr < out_size) out_buf[out_ptr++] = (char)c1;
00102
00103
00104 dict[dict_length] = 0;
00105 }
00106 }
00107 } else {
00108
00109 if (in_ptr < in_size) {
00110
00111 char c1 = rtfcomp[in_ptr++];
00112 dict[dict_length] = c1;
00113 dict_length = (dict_length+1)%4096;
00114 if (out_ptr < out_size) out_buf[out_ptr++] = (char)c1;
00115
00116
00117 dict[dict_length] = 0;
00118 }
00119 }
00120 flag_mask <<= 1;
00121 }
00122 }
00123 *size = out_ptr;
00124 return out_buf;
00125 }