KTNEF Library
lzfu.cpp
Go to the documentation of this file.
00001 /* 00002 lzfu.cpp 00003 00004 Copyright (C) 2003 Michael Goffioul <kdeprint@swing.be> 00005 00006 This file is part of KTNEF, the KDE TNEF support library/program. 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 Boston, MA 02110-1301, USA. 00022 */ 00031 #include "lzfu.h" 00032 00033 #include <QtCore/QIODevice> 00034 00035 #include <sys/types.h> 00036 #include <string.h> 00037 #include <stdio.h> 00038 00039 //#define DO_DEBUG 00040 00041 //@cond IGNORE 00042 #define LZFU_COMPRESSED 0x75465a4c 00043 #define LZFU_UNCOMPRESSED 0x414c454d 00044 00045 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \ 00046 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ 00047 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ 00048 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ 00049 "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \ 00050 "\\tx" 00051 #define LZFU_INITLENGTH 207 00052 //@endcond 00053 00054 //@cond PRIVATE 00055 typedef struct _lzfuheader 00056 { 00057 quint32 cbSize; 00058 quint32 cbRawSize; 00059 quint32 dwMagic; 00060 quint32 dwCRC; 00061 } lzfuheader; 00062 //@endcond 00063 00064 //@cond IGNORE 00065 #define FLAG(f,n) (f>>n)&0x1 00066 00067 /*typedef struct _blockheader { 00068 unsigned int offset:12; 00069 unsigned int length:4; 00070 } blockheader;*/ 00071 00072 #define OFFSET(b) (b>>4)&0xFFF 00073 #define LENGTH(b) ((b&0xF)+2) 00074 //@endcond 00075 00076 int lzfu_decompress( QIODevice *input, QIODevice *output ) 00077 { 00078 unsigned char window[4096]; 00079 unsigned int wlength = 0, cursor = 0, ocursor = 0; 00080 lzfuheader lzfuhdr; 00081 //blockheader blkhdr; 00082 quint16 blkhdr; 00083 char bFlags; 00084 int nFlags; 00085 00086 memcpy( window, LZFU_INITDICT, LZFU_INITLENGTH ); 00087 wlength = LZFU_INITLENGTH; 00088 if ( input->read( (char *)&lzfuhdr, sizeof(lzfuhdr) ) != sizeof(lzfuhdr) ) { 00089 fprintf( stderr, "unexpected eof, cannot read LZFU header\n" ); 00090 return -1; 00091 } 00092 cursor += sizeof( lzfuhdr ); 00093 #ifdef DO_DEBUG 00094 fprintf( stdout, "total size : %d\n", lzfuhdr.cbSize+4 ); 00095 fprintf( stdout, "raw size : %d\n", lzfuhdr.cbRawSize ); 00096 fprintf( stdout, "compressed : %s\n", ( lzfuhdr.dwMagic == LZFU_COMPRESSED ? "yes" : "no" ) ); 00097 fprintf( stdout, "CRC : %x\n", lzfuhdr.dwCRC ); 00098 fprintf( stdout, "\n" ); 00099 #endif 00100 00101 while ( cursor < lzfuhdr.cbSize+4 && ocursor < lzfuhdr.cbRawSize && !input->atEnd() ) { 00102 if ( input->read( &bFlags, 1 ) != 1 ) { 00103 fprintf( stderr, "unexpected eof, cannot read chunk flag\n" ); 00104 return -1; 00105 } 00106 nFlags = 8; 00107 cursor++; 00108 #ifdef DO_DEBUG 00109 fprintf( stdout, "Flags : " ); 00110 for ( int i=nFlags-1; i>=0; i-- ) { 00111 fprintf( stdout, "%d", FLAG( bFlags, i ) ); 00112 } 00113 fprintf( stdout, "\n" ); 00114 #endif 00115 for ( int i=0; i<nFlags && ocursor<lzfuhdr.cbRawSize && cursor<lzfuhdr.cbSize+4; i++ ) { 00116 if ( FLAG( bFlags, i ) ) { 00117 // compressed chunck 00118 char c1, c2; 00119 if ( input->read( &c1, 1 ) != 1 || input->read( &c2, 1 ) != 1 ) { 00120 fprintf( stderr, "unexpected eof, cannot read block header\n" ); 00121 return -1; 00122 } 00123 blkhdr = c1; 00124 blkhdr <<= 8; 00125 blkhdr |= ( 0xFF & c2 ); 00126 unsigned int offset = OFFSET( blkhdr ), length = LENGTH( blkhdr ); 00127 cursor += 2; 00128 #ifdef DO_DEBUG 00129 fprintf( stdout, "block : offset=%.4d [%d], length=%.2d (0x%04X)\n", 00130 OFFSET( blkhdr ), wlength, LENGTH( blkhdr ), blkhdr ); 00131 #endif 00132 //if ( offset >= wlength ) { 00133 // break; 00134 //} 00135 #ifdef DO_DEBUG 00136 fprintf( stdout, "block : " ); 00137 #endif 00138 for ( unsigned int i=0; i<length; i++ ) { 00139 c1 = window[( offset + i ) % 4096]; 00140 //if ( wlength < 4096 ) { 00141 window[wlength] = c1; 00142 wlength = ( wlength + 1 ) % 4096; 00143 //} 00144 #ifdef DO_DEBUG 00145 if ( c1 == '\n' ) { 00146 fprintf( stdout, "\nblock : " ); 00147 } else { 00148 fprintf( stdout, "%c", c1 ); 00149 } 00150 #endif 00151 output->putChar( c1 ); 00152 ocursor++; 00153 } 00154 #ifdef DO_DEBUG 00155 fprintf( stdout, "\n" ); 00156 #endif 00157 } else { 00158 // uncompressed chunk (char) 00159 char c; 00160 if ( !input->getChar( &c ) ) { 00161 if ( !input->atEnd() ) { 00162 fprintf( stderr, "unexpected eof, cannot read character\n" ); 00163 return -1; 00164 } 00165 break; 00166 } 00167 #ifdef DO_DEBUG 00168 fprintf( stdout, "char : %c\n", c ); 00169 #endif 00170 cursor++; 00171 //if ( wlength < 4096 ) { 00172 window[wlength] = c; 00173 wlength = ( wlength+1 ) % 4096; 00174 //} 00175 output->putChar( c ); 00176 ocursor++; 00177 } 00178 } 00179 00180 } 00181 00182 return 0; 00183 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:50:02 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:50:02 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.