Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

VecCompressor.cc

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // VecCompressor.cc 00004 // Copyright (C) 2001 Pascal Vincent 00005 // Copyright (C) 2002 Pascal Vincent, Julien Keable, Xavier Saint-Mleux 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 00036 /* ******************************************************* 00037 * $Id: VecCompressor.cc,v 1.2 2004/02/20 21:11:46 chrish42 Exp $ 00038 ******************************************************* */ 00039 00040 #include "VecCompressor.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 // ******************* 00046 // ** VecCompressor ** 00047 00048 signed char* VecCompressor::compressVec(const Vec& v, signed char* data) 00049 { 00050 real* vdata = v.data(); 00051 signed char* ptr = data; 00052 00053 // mode can be '0' for zeroes, 'F' for floats, 'I' for small integers (signed chars) 00054 // If mode is '0' abs(count) indicates the number of zeroes, 00055 // a positive sign indicates switch to 'F' mode 00056 // a negative sign indicates switch to 'I' mode 00057 // a 0 count means insert 127 zeros and stay in zero mode 00058 // If mode is 'F' abs(count) indicates the number of floats that follow 00059 // a positive sign indicates switch to 'I' mode 00060 // a negative sign indicates switch to '0' mode 00061 // a 0 count means insert 127 floats and stay in float mode 00062 // If mode is 'I' abs(count) indicates the number of small integers that follow 00063 // a positive sign indicates switch to 'F' mode 00064 // a negative sign indicates switch to '0' mode 00065 // a 0 count means insert 127 small integers and stay in 'I' mode 00066 00067 int l = v.length(); 00068 00069 int i=0; 00070 real val = vdata[i]; 00071 00072 signed char mode = 'F'; 00073 if(val==0.) 00074 mode = '0'; 00075 else if(issmallint(val)) 00076 mode = 'I'; 00077 // else 'F' 00078 00079 int count = 0; 00080 int istart = 0; 00081 float fval = 0.; 00082 signed char* pfval = (signed char*)&fval; 00083 00084 *ptr++ = mode; 00085 00086 while(i<l) 00087 { 00088 switch(mode) 00089 { 00090 case '0': 00091 istart = i; 00092 while(i<l && is0(vdata[i])) 00093 i++; 00094 count = i - istart; 00095 while(count>127) 00096 { 00097 *ptr++ = 0; 00098 count -= 127; 00099 } 00100 if(i>=l || issmallint(vdata[i])) 00101 { 00102 *ptr++ = (signed char)(-count); 00103 mode = 'I'; 00104 } 00105 else 00106 { 00107 *ptr++ = (signed char)count; 00108 mode = 'F'; 00109 } 00110 break; 00111 00112 case 'I': 00113 istart = i; 00114 while(i<l && isI(vdata[i])) 00115 i++; 00116 count = i - istart; 00117 while(count>127) 00118 { 00119 *ptr++ = 0; 00120 int n = 127; 00121 while(n--) 00122 *ptr++ = (signed char)vdata[istart++]; 00123 count -= 127; 00124 } 00125 if(i>=l || is0(vdata[i])) 00126 { 00127 *ptr++ = (signed char)(-count); 00128 mode = '0'; 00129 } 00130 else // next value is a floating point 00131 { 00132 *ptr++ = (signed char)count; 00133 mode = 'F'; 00134 } 00135 while(count--) 00136 *ptr++ = (signed char)vdata[istart++]; 00137 break; 00138 00139 case 'F': 00140 istart = i; 00141 val = vdata[i]; 00142 while(i<l && isF(vdata[i])) 00143 i++; 00144 count = i - istart; 00145 while(count>127) 00146 { 00147 *ptr++ = 0; 00148 int n = 127; 00149 while(n--) 00150 { 00151 fval = (float)vdata[istart++]; 00152 *ptr++ = pfval[0]; 00153 *ptr++ = pfval[1]; 00154 *ptr++ = pfval[2]; 00155 *ptr++ = pfval[3]; 00156 } 00157 count -= 127; 00158 } 00159 if(i>=l || is0(vdata[i])) 00160 { 00161 *ptr++ = (signed char)(-count); 00162 mode = '0'; 00163 } 00164 else 00165 { 00166 *ptr++ = (signed char)count; 00167 mode = 'I'; 00168 } 00169 while(count--) 00170 { 00171 fval = (float)vdata[istart++]; 00172 *ptr++ = pfval[0]; 00173 *ptr++ = pfval[1]; 00174 *ptr++ = pfval[2]; 00175 *ptr++ = pfval[3]; 00176 } 00177 } 00178 } 00179 return ptr; 00180 } 00181 00182 void VecCompressor::uncompressVec(signed char* data, const Vec& v) 00183 { 00184 // mode can be '0' for zeroes, 'F' for floats, 'I' for small integers (signed chars) 00185 // If mode is '0' abs(count) indicates the number of zeroes, 00186 // a positive sign indicates switch to 'F' mode 00187 // a negative sign indicates switch to 'I' mode 00188 // a 0 count means insert 127 zeros and stay in zero mode 00189 // If mode is 'F' abs(count) indicates the number of floats that follow 00190 // a positive sign indicates switch to 'I' mode 00191 // a negative sign indicates switch to '0' mode 00192 // a 0 count means insert 127 floats and stay in float mode 00193 // If mode is 'I' abs(count) indicates the number of small integers that follow 00194 // a positive sign indicates switch to 'F' mode 00195 // a negative sign indicates switch to '0' mode 00196 // a 0 count means insert 127 small integers and stay in 'I' mode 00197 00198 real* vptr = v.data(); 00199 real* vptrend = vptr+v.length(); 00200 signed char* ptr = data; 00201 signed char mode = *ptr++; 00202 float fval = 0.; 00203 signed char* pfval = (signed char*)&fval; 00204 signed char count; 00205 while(vptr!=vptrend) 00206 { 00207 count = *ptr++; 00208 switch(mode) 00209 { 00210 case '0': 00211 if(count<0) 00212 { 00213 mode = 'I'; 00214 count = -count; 00215 } 00216 else if(count>0) 00217 mode = 'F'; 00218 else 00219 count = 127; 00220 00221 while(count--) 00222 *vptr++ = 0.; 00223 break; 00224 00225 case 'I': 00226 if(count<0) 00227 { 00228 mode = '0'; 00229 count = -count; 00230 } 00231 else if(count>0) 00232 mode = 'F'; 00233 else 00234 count = 127; 00235 00236 while(count--) 00237 *vptr++ = real(*ptr++); 00238 break; 00239 00240 case 'F': 00241 if(count<0) 00242 { 00243 mode = '0'; 00244 count = -count; 00245 } 00246 else if(count>0) 00247 mode = 'I'; 00248 else 00249 count = 127; 00250 00251 while(count--) 00252 { 00253 pfval[0] = *ptr++; 00254 pfval[1] = *ptr++; 00255 pfval[2] = *ptr++; 00256 pfval[3] = *ptr++; 00257 *vptr++ = real(fval); 00258 } 00259 break; 00260 00261 default: 00262 PLERROR("Problem in VecCompressor::uncompressVec this should not happen!!! (wrong data format?)"); 00263 } 00264 } 00265 } 00266 00267 void VecCompressor::writeCompressedVec(ostream& out, const Vec& v) 00268 { 00269 real* vdata = v.data(); 00270 00271 // mode can be '0' for zeroes, 'F' for floats, 'I' for small integers (signed chars) 00272 // If mode is '0' abs(count) indicates the number of zeroes, 00273 // a positive sign indicates switch to 'F' mode 00274 // a negative sign indicates switch to 'I' mode 00275 // a 0 count means insert 127 zeros and stay in zero mode 00276 // If mode is 'F' abs(count) indicates the number of floats that follow 00277 // a positive sign indicates switch to 'I' mode 00278 // a negative sign indicates switch to '0' mode 00279 // a 0 count means insert 127 floats and stay in float mode 00280 // If mode is 'I' abs(count) indicates the number of small integers that follow 00281 // a positive sign indicates switch to 'F' mode 00282 // a negative sign indicates switch to '0' mode 00283 // a 0 count means insert 127 small integers and stay in 'I' mode 00284 00285 int l = v.length(); 00286 00287 int i=0; 00288 real val = vdata[i]; 00289 00290 signed char mode = 'F'; 00291 if(val==0.) 00292 mode = '0'; 00293 else if(issmallint(val)) 00294 mode = 'I'; 00295 // else 'F' 00296 00297 int count = 0; 00298 int istart = 0; 00299 float fval = 0.; 00300 00301 write_sbyte(out,mode); 00302 00303 while(i<l) 00304 { 00305 switch(mode) 00306 { 00307 case '0': 00308 istart = i; 00309 while(i<l && is0(vdata[i])) 00310 i++; 00311 count = i - istart; 00312 while(count>127) 00313 { 00314 write_sbyte(out,0); 00315 count -= 127; 00316 } 00317 if(i>=l || issmallint(vdata[i])) 00318 { 00319 write_sbyte(out,-count); 00320 mode = 'I'; 00321 } 00322 else 00323 { 00324 write_sbyte(out,count); 00325 mode = 'F'; 00326 } 00327 break; 00328 00329 case 'I': 00330 istart = i; 00331 while(i<l && isI(vdata[i])) 00332 i++; 00333 count = i - istart; 00334 while(count>127) 00335 { 00336 write_sbyte(out,0); 00337 int n = 127; 00338 while(n--) 00339 write_sbyte(out,(signed char)vdata[istart++]); 00340 count -= 127; 00341 } 00342 if(i>=l || is0(vdata[i])) 00343 { 00344 write_sbyte(out,-count); 00345 mode = '0'; 00346 } 00347 else // next value is a floating point 00348 { 00349 write_sbyte(out,count); 00350 mode = 'F'; 00351 } 00352 while(count--) 00353 write_sbyte(out,(signed char)vdata[istart++]); 00354 break; 00355 00356 case 'F': 00357 istart = i; 00358 while(i<l && isF(vdata[i])) 00359 i++; 00360 count = i - istart; 00361 while(count>127) 00362 { 00363 write_sbyte(out,0); 00364 int n = 127; 00365 while(n--) 00366 { 00367 fval = (float)vdata[istart++]; 00368 out.write((char*)&fval,4); 00369 } 00370 count -= 127; 00371 } 00372 if(i>=l || is0(vdata[i])) 00373 { 00374 write_sbyte(out,-count); 00375 mode = '0'; 00376 } 00377 else 00378 { 00379 write_sbyte(out,count); 00380 mode = 'I'; 00381 } 00382 while(count--) 00383 { 00384 fval = (float)vdata[istart++]; 00385 out.write((char*)&fval,4); 00386 } 00387 } 00388 } 00389 } 00390 00391 void VecCompressor::readCompressedVec(istream& in, const Vec& v) 00392 { 00393 // mode can be '0' for zeroes, 'F' for floats, 'I' for small integers (signed chars) 00394 // If mode is '0' abs(count) indicates the number of zeroes, 00395 // a positive sign indicates switch to 'F' mode 00396 // a negative sign indicates switch to 'I' mode 00397 // a 0 count means insert 127 zeros and stay in zero mode 00398 // If mode is 'F' abs(count) indicates the number of floats that follow 00399 // a positive sign indicates switch to 'I' mode 00400 // a negative sign indicates switch to '0' mode 00401 // a 0 count means insert 127 floats and stay in float mode 00402 // If mode is 'I' abs(count) indicates the number of small integers that follow 00403 // a positive sign indicates switch to 'F' mode 00404 // a negative sign indicates switch to '0' mode 00405 // a 0 count means insert 127 small integers and stay in 'I' mode 00406 00407 real* vptr = v.data(); 00408 real* vptrend = vptr+v.length(); 00409 signed char mode = read_sbyte(in); 00410 float fval = 0.; 00411 signed char count; 00412 00413 while(vptr!=vptrend) 00414 { 00415 count = read_sbyte(in); 00416 // cerr << int(count) << ' '; 00417 switch(mode) 00418 { 00419 case '0': 00420 if(count<0) 00421 { 00422 mode = 'I'; 00423 count = -count; 00424 } 00425 else if(count>0) 00426 mode = 'F'; 00427 else 00428 count = 127; 00429 00430 while(count--) 00431 *vptr++ = 0.; 00432 break; 00433 00434 case 'I': 00435 if(count<0) 00436 { 00437 mode = '0'; 00438 count = -count; 00439 } 00440 else if(count>0) 00441 mode = 'F'; 00442 else 00443 count = 127; 00444 00445 while(count--) 00446 *vptr++ = real(read_sbyte(in)); 00447 break; 00448 00449 case 'F': 00450 if(count<0) 00451 { 00452 mode = '0'; 00453 count = -count; 00454 } 00455 else if(count>0) 00456 mode = 'I'; 00457 else 00458 count = 127; 00459 00460 while(count--) 00461 { 00462 in.read((char*)&fval,4); 00463 *vptr++ = real(fval); 00464 } 00465 break; 00466 00467 default: 00468 PLERROR("Problem in VecCompressor::readCompressedVec this should not happen!!! (wrong data format?)"); 00469 } 00470 } 00471 // cerr << endl; 00472 } 00473 00474 00475 00476 } // end of namespcae PLearn

Generated on Tue Aug 17 16:10:15 2004 for PLearn by doxygen 1.3.7