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 }