Mercurial > libpst
comparison src/lzfu.c @ 36:6fe121a971c9 stable-0-5-7
valgrind fixes
author | carl |
---|---|
date | Thu, 09 Aug 2007 15:46:34 -0700 |
parents | c508ee15dfca |
children | ddfb25318812 |
comparison
equal
deleted
inserted
replaced
35:b2f247463b83 | 36:6fe121a971c9 |
---|---|
1 /* | 1 /* |
2 This program is free software; you can redistribute it and/or modify | 2 This program is free software; you can redistribute it and/or modify |
3 it under the terms of the GNU General Public License as published by | 3 it under the terms of the GNU General Public License as published by |
4 the Free Software Foundation; either version 2 of the License, or | 4 the Free Software Foundation; either version 2 of the License, or |
5 (at your option) any later version. | 5 (at your option) any later version. |
6 | 6 |
7 You should have received a copy of the GNU General Public License | 7 You should have received a copy of the GNU General Public License |
8 along with this program; if not, write to the Free Software Foundation, | 8 along with this program; if not, write to the Free Software Foundation, |
9 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 9 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
10 */ | 10 */ |
11 | 11 |
12 #include "define.h" | 12 #include "define.h" |
13 #include "libpst.h" | 13 #include "libpst.h" |
14 #include <sys/types.h> | 14 #include <sys/types.h> |
23 #define uint32_t unsigned int | 23 #define uint32_t unsigned int |
24 #endif | 24 #endif |
25 | 25 |
26 #include "lzfu.h" | 26 #include "lzfu.h" |
27 | 27 |
28 #define LZFU_COMPRESSED 0x75465a4c | 28 #define LZFU_COMPRESSED 0x75465a4c |
29 #define LZFU_UNCOMPRESSED 0x414c454d | 29 #define LZFU_UNCOMPRESSED 0x414c454d |
30 | 30 |
31 // initital dictionary | 31 // initital dictionary |
32 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \ | 32 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \ |
33 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ | 33 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ |
34 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ | 34 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ |
35 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ | 35 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ |
36 "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \ | 36 "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \ |
37 "\\tx" | 37 "\\tx" |
38 // initial length of dictionary | 38 // initial length of dictionary |
39 #define LZFU_INITLENGTH 207 | 39 #define LZFU_INITLENGTH 207 |
40 | 40 |
41 // header for compressed rtf | 41 // header for compressed rtf |
42 typedef struct _lzfuheader { | 42 typedef struct _lzfuheader { |
43 uint32_t cbSize; | 43 uint32_t cbSize; |
44 uint32_t cbRawSize; | 44 uint32_t cbRawSize; |
45 uint32_t dwMagic; | 45 uint32_t dwMagic; |
46 uint32_t dwCRC; | 46 uint32_t dwCRC; |
47 } lzfuheader; | 47 } lzfuheader; |
48 | 48 |
49 | 49 |
50 /** | 50 /** |
51 We always need to add 0x10 to the buffer offset because we need to skip past the header info | 51 We always need to add 0x10 to the buffer offset because we need to skip past the header info |
52 */ | 52 */ |
53 | 53 |
54 unsigned char* lzfu_decompress (unsigned char* rtfcomp) { | 54 unsigned char* lzfu_decompress (unsigned char* rtfcomp, size_t *size) { |
55 // the dictionary buffer | 55 // the dictionary buffer |
56 unsigned char dict[4096]; | 56 unsigned char dict[4096]; |
57 // the dictionary pointer | 57 // the dictionary pointer |
58 unsigned int dict_length=0; | 58 unsigned int dict_length=0; |
59 // the header of the lzfu block | 59 // the header of the lzfu block |
60 lzfuheader lzfuhdr; | 60 lzfuheader lzfuhdr; |
61 // container for the data blocks | 61 // container for the data blocks |
62 unsigned char flags; | 62 unsigned char flags; |
63 // temp value for determining the bits in the flag | 63 // temp value for determining the bits in the flag |
64 unsigned char flag_mask; | 64 unsigned char flag_mask; |
65 unsigned int i, in_size; | 65 unsigned int i, in_size; |
66 unsigned char *out_buf; | 66 unsigned char *out_buf; |
67 unsigned int out_ptr = 0; | 67 unsigned int out_ptr = 0; |
68 | 68 |
69 memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH); | 69 memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH); |
70 dict_length = LZFU_INITLENGTH; | 70 dict_length = LZFU_INITLENGTH; |
71 memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr)); | 71 memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr)); |
72 LE32_CPU(lzfuhdr.cbSize); LE32_CPU(lzfuhdr.cbRawSize); | 72 LE32_CPU(lzfuhdr.cbSize); LE32_CPU(lzfuhdr.cbRawSize); |
73 LE32_CPU(lzfuhdr.dwMagic); LE32_CPU(lzfuhdr.dwCRC); | 73 LE32_CPU(lzfuhdr.dwMagic); LE32_CPU(lzfuhdr.dwCRC); |
74 /* printf("total size: %d\n", lzfuhdr.cbSize+4); | 74 /* printf("total size: %d\n", lzfuhdr.cbSize+4); |
75 printf("raw size : %d\n", lzfuhdr.cbRawSize); | 75 printf("raw size : %d\n", lzfuhdr.cbRawSize); |
76 printf("compressed: %s\n", (lzfuhdr.dwMagic == LZFU_COMPRESSED ? "yes" : "no")); | 76 printf("compressed: %s\n", (lzfuhdr.dwMagic == LZFU_COMPRESSED ? "yes" : "no")); |
77 printf("CRC : %#x\n", lzfuhdr.dwCRC); | 77 printf("CRC : %#x\n", lzfuhdr.dwCRC); |
78 printf("\n");*/ | 78 printf("\n");*/ |
79 out_buf = (unsigned char*)xmalloc(lzfuhdr.cbRawSize+20); //plus 4 cause we have 2x'}' and a \0 | 79 out_buf = (unsigned char*)xmalloc(lzfuhdr.cbRawSize+20); //plus 4 cause we have 2x'}' and a \0 |
80 in_size = 0; | 80 in_size = 0; |
81 // we add plus one here cause when referencing an array, the index is always one less | 81 // we add plus one here cause when referencing an array, the index is always one less |
82 // (ie, when accessing 2 element array, highest index is [1]) | 82 // (ie, when accessing 2 element array, highest index is [1]) |
83 while (in_size+0x11 < lzfuhdr.cbSize) { | 83 while (in_size+0x11 < lzfuhdr.cbSize) { |
84 memcpy(&flags, &(rtfcomp[in_size+0x10]), 1); | 84 memcpy(&flags, &(rtfcomp[in_size+0x10]), 1); |
85 in_size += 1; | 85 in_size += 1; |
86 | 86 |
87 flag_mask = 1; | 87 flag_mask = 1; |
88 while (flag_mask != 0 && in_size+0x11 < lzfuhdr.cbSize) { | 88 while (flag_mask != 0 && in_size+0x11 < lzfuhdr.cbSize) { |
89 if (flag_mask & flags) { | 89 if (flag_mask & flags) { |
90 // read 2 bytes from input | 90 // read 2 bytes from input |
91 unsigned short int blkhdr, offset, length; | 91 unsigned short int blkhdr, offset, length; |
92 memcpy(&blkhdr, &(rtfcomp[in_size+0x10]), 2); | 92 memcpy(&blkhdr, &(rtfcomp[in_size+0x10]), 2); |
93 LE16_CPU(blkhdr); | 93 LE16_CPU(blkhdr); |
94 in_size += 2; | 94 in_size += 2; |
95 /* swap the upper and lower bytes of blkhdr */ | 95 /* swap the upper and lower bytes of blkhdr */ |
96 blkhdr = (((blkhdr&0xFF00)>>8)+ | 96 blkhdr = (((blkhdr&0xFF00)>>8)+ |
97 ((blkhdr&0x00FF)<<8)); | 97 ((blkhdr&0x00FF)<<8)); |
98 /* the offset is the first 24 bits of the 32 bit value */ | 98 /* the offset is the first 24 bits of the 32 bit value */ |
99 offset = (blkhdr&0xFFF0)>>4; | 99 offset = (blkhdr&0xFFF0)>>4; |
100 /* the length of the dict entry are the last 8 bits */ | 100 /* the length of the dict entry are the last 8 bits */ |
101 length = (blkhdr&0x000F)+2; | 101 length = (blkhdr&0x000F)+2; |
102 // add the value we are about to print to the dictionary | 102 // add the value we are about to print to the dictionary |
103 for (i=0; i < length; i++) { | 103 for (i=0; i < length; i++) { |
104 unsigned char c1; | 104 unsigned char c1; |
105 c1 = dict[(offset+i)%4096]; | 105 c1 = dict[(offset+i)%4096]; |
106 dict[dict_length]=c1; | 106 dict[dict_length]=c1; |
107 dict_length = (dict_length+1) % 4096; | 107 dict_length = (dict_length+1) % 4096; |
108 out_buf[out_ptr++] = c1; | 108 out_buf[out_ptr++] = c1; |
109 } | |
110 } else { | |
111 // uncompressed chunk (single byte) | |
112 char c1 = rtfcomp[in_size+0x10]; | |
113 in_size ++; | |
114 dict[dict_length] = c1; | |
115 dict_length = (dict_length+1)%4096; | |
116 out_buf[out_ptr++] = c1; | |
117 } | |
118 flag_mask <<= 1; | |
119 } | |
109 } | 120 } |
110 } else { | 121 // the compressed version doesn't appear to drop the closing braces onto the doc. |
111 // uncompressed chunk (single byte) | 122 // we should do that |
112 char c1 = rtfcomp[in_size+0x10]; | 123 out_buf[out_ptr++] = '}'; |
113 in_size ++; | 124 out_buf[out_ptr++] = '}'; |
114 dict[dict_length] = c1; | 125 out_buf[out_ptr++] = '\0'; |
115 dict_length = (dict_length+1)%4096; | 126 *size = out_ptr; |
116 out_buf[out_ptr++] = c1; | 127 return out_buf; |
117 } | |
118 flag_mask <<= 1; | |
119 } | |
120 } | |
121 // the compressed version doesn't appear to drop the closing braces onto the doc. | |
122 // we should do that | |
123 out_buf[out_ptr++] = '}'; | |
124 out_buf[out_ptr++] = '}'; | |
125 out_buf[out_ptr++] = '\0'; | |
126 return out_buf; | |
127 } | 128 } |