Changeset 16814 for trunk/FACT++/src/fitsCompressor.cc
- Timestamp:
- 06/12/13 15:56:12 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/fitsCompressor.cc
r16810 r16814 19 19 20 20 using namespace std; 21 22 typedef struct TileHeader 23 { 24 char id[4]; 25 uint32_t numRows; 26 uint64_t size; 27 TileHeader(uint32_t nRows=0, 28 uint64_t s=0) : id({'T', 'I', 'L', 'E'}), 29 numRows(nRows), 30 size(s) 31 { }; 32 } __attribute__((__packed__)) TileHeader; 33 34 typedef struct BlockHeader 35 { 36 uint64_t size; 37 char ordering; 38 unsigned char numProcs; 39 BlockHeader(uint64_t s=0, 40 char o=FACT_ROW_MAJOR, 41 unsigned char n=1) : size(s), 42 ordering(o), 43 numProcs(n) 44 {} 45 } __attribute__((__packed__)) BlockHeader; 21 46 22 47 class CompressedFitsFile … … 249 274 char t, 250 275 int numOf, 251 uint32_t comp) : _name(n), 252 _num(numOf), 253 _typeSize(0), 254 _offset(0), 255 _type(t), 256 _description(""), 257 _compression(comp) 276 BlockHeader& head, 277 vector<uint16_t>& seq) : _name(n), 278 _num(numOf), 279 _typeSize(0), 280 _offset(0), 281 _type(t), 282 _description(""), 283 _header(head), 284 _compSequence(seq) 258 285 { 259 286 switch (t) … … 297 324 char type() const { return _type;}; 298 325 string getDescription() const { return _description;} 299 uint32_t getCompression() const { return _compression;} 326 BlockHeader& getBlockHeader() { return _header;} 327 const vector<uint16_t>& getCompressionSequence() const { return _compSequence;} 328 const char& getColumnOrdering() const { return _header.ordering;} 329 300 330 301 331 string getCompressionString() const 302 332 { 303 switch (_compression) 333 return "FACT"; 334 /* 335 ostringstream str; 336 for (uint32_t i=0;i<_compSequence.size();i++) 337 switch (_compSequence[i]) 304 338 { 305 case UNCOMPRESSED: return "RAW"; 306 case SMOOTHMAN: return "SMOO"; 339 case FACT_RAW: if (str.str().size() == 0) str << "RAW"; break; 340 case FACT_SMOOTHING: str << "SMOOTHING "; break; 341 case FACT_HUFFMAN16: str << "HUFFMAN16 "; break; 307 342 }; 308 return "UNKNOWN";343 return str.str();*/ 309 344 } 310 345 … … 317 352 char _type; ///< the type of the column, as specified by the fits documentation 318 353 string _description; ///< a description for the column. It will be placed in the header 319 uint32_t _compression; ///< the compression of the column. Only looked for if used by the compressed writer 354 BlockHeader _header; 355 vector<uint16_t> _compSequence; 320 356 }; 321 357 … … 435 471 uint32_t compressHUFFMAN(char* dest, const char* src, uint32_t numRows, uint32_t sizeOfElems, uint32_t numRowElems); 436 472 uint32_t compressSMOOTHMAN(char* dest, char* src, uint32_t numRows, uint32_t sizeOfElems, uint32_t numRowElems); 473 uint32_t applySMOOTHING(char* dest, char* src, uint32_t numRows, uint32_t sizeOfElems, uint32_t numRowElems); 437 474 438 475 int32_t _checkOffset; ///< offset to the data pointer to calculate the checksum … … 452 489 const uint32_t CompressedFitsFile::_THREAD_READ_ = 4; 453 490 const uint32_t CompressedFitsFile::_THREAD_EXIT_ = 5; 454 455 #define COMPRESSED_FLAG 0x1456 #define UNCOMPRESSED_FLAG 0x0457 458 typedef struct TileHeader459 {460 char id[4];461 uint32_t numRows;462 uint64_t size;463 TileHeader(uint32_t nRows=0,464 uint64_t s=0) : id({'T', 'I', 'L', 'E'}),465 numRows(nRows),466 size(s)467 { };468 } __attribute__((__packed__)) TileHeader;469 470 typedef struct BlockHeader471 {472 uint64_t size;473 char ordering;474 unsigned char numProcs;475 uint16_t procs[];476 } __attribute__((__packed__)) BlockHeader;477 491 478 492 template<> … … 1140 1154 for (uint32_t i=0;i<_columns.size();i++) 1141 1155 { 1142 switch (_columns[i].getCompression()) 1143 { 1144 case UNCOMPRESSED: 1145 case SMOOTHMAN: 1156 switch (_columns[i].getColumnOrdering())//getCompression()) 1157 { 1158 case FACT_ROW_MAJOR: 1146 1159 for (uint32_t k=0;k<thisRoundNumRows;k++) 1147 1160 {//regular, "semi-transposed" copy … … 1150 1163 } 1151 1164 break; 1152 default : 1165 1166 case FACT_COL_MAJOR : 1153 1167 for (int j=0;j<_columns[i].numElems();j++) 1154 1168 for (uint32_t k=0;k<thisRoundNumRows;k++) … … 1158 1172 } 1159 1173 break; 1174 default: 1175 cout << "Error: unknown column ordering: " << _columns[i].getColumnOrdering() << endl; 1160 1176 1161 1177 }; … … 1247 1263 } 1248 1264 1265 uint32_t CompressedFitsWriter::applySMOOTHING(char* , char* src, uint32_t numRows, uint32_t sizeOfElems, uint32_t numRowElems) 1266 { 1267 uint32_t colWidth = numRowElems; 1268 for (int j=colWidth*numRows-1;j>1;j--) 1269 reinterpret_cast<int16_t*>(src)[j] = reinterpret_cast<int16_t*>(src)[j] - (reinterpret_cast<int16_t*>(src)[j-1]+reinterpret_cast<int16_t*>(src)[j-2])/2; 1270 1271 return numRows*sizeOfElems*numRowElems; 1272 } 1249 1273 /**************************************************************** 1250 1274 * COMPRESS BUFFER … … 1262 1286 _catalog[currentCatalogRow][i].second = compressedOffset; 1263 1287 1264 uint32_t compression = _columns[i].getCompression();1265 1266 1288 if (_columns[i].numElems() == 0) continue; 1289 1290 BlockHeader& head = _columns[i].getBlockHeader(); 1291 const vector<uint16_t>& sequence = _columns[i].getCompressionSequence(); 1267 1292 //set the default byte telling if uncompressed the compressed Flag 1268 1293 uint64_t previousOffset = compressedOffset; 1269 _compressedBuffer[threadIndex][compressedOffset++] = COMPRESSED_FLAG; 1270 switch (compression) 1271 { 1272 case UNCOMPRESSED: 1273 compressedOffset += compressUNCOMPRESSED(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1274 break; 1275 case SMOOTHMAN: 1276 compressedOffset += compressSMOOTHMAN(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1277 break; 1278 1279 default: 1280 ; 1281 }; 1294 //skip header data 1295 compressedOffset += sizeof(BlockHeader) + sizeof(uint16_t)*sequence.size(); 1296 1297 for (uint32_t j=0;j<sequence.size(); j++) 1298 { 1299 switch (sequence[j]) 1300 { 1301 case FACT_RAW: 1302 if (head.numProcs == 1) 1303 compressedOffset += compressUNCOMPRESSED(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1304 break; 1305 case FACT_SMOOTHING: 1306 applySMOOTHING(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1307 break; 1308 case FACT_HUFFMAN16: 1309 if (head.ordering == FACT_COL_MAJOR) 1310 compressedOffset += compressHUFFMAN(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1311 else 1312 compressedOffset += compressHUFFMAN(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), _columns[i].numElems(), _columns[i].sizeOfElems(), thisRoundNumRows); 1313 break; 1314 default: 1315 cout << "ERROR: Unkown compression sequence entry: " << sequence[i] << endl; 1316 break; 1317 } 1318 } 1319 1282 1320 //check if compressed size is larger than uncompressed 1283 if ( compression != UNCOMPRESSED&&1284 compressedOffset - previousOffset > _columns[i].sizeOfElems()*_columns[i].numElems()*thisRoundNumRows+ 1)1321 if (sequence[0] != FACT_RAW && 1322 compressedOffset - previousOffset > _columns[i].sizeOfElems()*_columns[i].numElems()*thisRoundNumRows+sizeof(BlockHeader)+sizeof(uint16_t)*sequence.size()) 1285 1323 {//if so set flag and redo it uncompressed 1286 co mpressedOffset = previousOffset;1287 _compressedBuffer[threadIndex][compressedOffset++] = UNCOMPRESSED_FLAG;1324 cout << "REDOING UNCOMPRESSED" << endl; 1325 compressedOffset = previousOffset + sizeof(BlockHeader) + 1; 1288 1326 compressedOffset += compressUNCOMPRESSED(&(_compressedBuffer[threadIndex][compressedOffset]), &(_transposedBuffer[threadIndex][offset]), thisRoundNumRows, _columns[i].sizeOfElems(), _columns[i].numElems()); 1289 } 1327 BlockHeader he; 1328 he.size = compressedOffset - previousOffset; 1329 he.numProcs = 1; 1330 he.ordering = FACT_ROW_MAJOR; 1331 memcpy(&(_compressedBuffer[threadIndex][previousOffset]), (char*)(&he), sizeof(BlockHeader)); 1332 _compressedBuffer[threadIndex][previousOffset+sizeof(BlockHeader)] = FACT_RAW; 1333 offset += thisRoundNumRows*_columns[i].sizeOfElems()*_columns[i].numElems(); 1334 _catalog[currentCatalogRow][i].first = compressedOffset - _catalog[currentCatalogRow][i].second; 1335 continue; 1336 } 1337 head.size = compressedOffset - previousOffset; 1338 memcpy(&(_compressedBuffer[threadIndex][previousOffset]), (char*)(&head), sizeof(BlockHeader)); 1339 memcpy(&(_compressedBuffer[threadIndex][previousOffset+sizeof(BlockHeader)]), sequence.data(), sizeof(uint16_t)*sequence.size()); 1340 1290 1341 offset += thisRoundNumRows*_columns[i].sizeOfElems()*_columns[i].numElems(); 1291 1342 _catalog[currentCatalogRow][i].first = compressedOffset - _catalog[currentCatalogRow][i].second; 1292 1343 } 1344 1293 1345 TileHeader tHead(thisRoundNumRows, compressedOffset); 1294 // tHead.numRows = thisRoundNumRows;1295 // tHead.size = compressedOffset;1296 1346 memcpy(_compressedBuffer[threadIndex], &tHead, sizeof(TileHeader)); 1297 1347 return compressedOffset; … … 1338 1388 pthread_mutex_unlock(&(myself->_mutex)); 1339 1389 uint32_t threadToWaitForBeforeWriting = (myID == 0) ? myself->_numThreads-1 : myID-1; 1390 1340 1391 while (myself->_threadStatus[myID] != _THREAD_EXIT_) 1341 1392 { … … 1603 1654 } 1604 1655 1656 //get header structures 1657 BlockHeader rawHeader; 1658 BlockHeader smoothmanHeader(0, FACT_ROW_MAJOR, 3); 1659 vector<uint16_t> rawProcessings(1); 1660 rawProcessings[0] = FACT_RAW; 1661 vector<uint16_t> smoothmanProcessings(3); 1662 smoothmanProcessings[0] = FACT_SMOOTHING; 1663 smoothmanProcessings[1] = FACT_HUFFMAN16; 1664 smoothmanProcessings[2] = FACT_RAW; 1665 1605 1666 //first lets see if we do have an explicit request 1606 1667 bool explicitRequest = false; … … 1612 1673 if (displayText) cout << compressions[j].second << endl; 1613 1674 if (compressions[j].second == "UNCOMPRESSED") 1614 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, CompressedFitsFile::UNCOMPRESSED));1675 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, rawHeader, rawProcessings)); 1615 1676 if (compressions[j].second == "SMOOTHMAN") 1616 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, CompressedFitsFile::SMOOTHMAN));1677 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, smoothmanHeader, smoothmanProcessings)); 1617 1678 break; 1618 1679 } … … 1624 1685 { 1625 1686 if (displayText) cout << "UNCOMPRESSED" << endl; 1626 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, CompressedFitsFile::UNCOMPRESSED));1687 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, rawHeader, rawProcessings)); 1627 1688 } 1628 1689 else 1629 1690 { 1630 1691 if (displayText) cout << "SMOOTHMAN" << endl; 1631 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, CompressedFitsFile::SMOOTHMAN));1692 outFile.addColumn(CompressedFitsFile::ColumnEntry(colName, sortedColumns[i].type, sortedColumns[i].num, smoothmanHeader, smoothmanProcessings)); 1632 1693 } 1633 1694 }
Note:
See TracChangeset
for help on using the changeset viewer.