Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: Implementation of the CPCIDSK_BLUT class. 4 : * 5 : ****************************************************************************** 6 : * Copyright (c) 2015 7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada. 8 : * 9 : * SPDX-License-Identifier: MIT 10 : ****************************************************************************/ 11 : 12 : #include "pcidsk_exception.h" 13 : #include "segment/cpcidskblut.h" 14 : #include <cassert> 15 : #include <cstring> 16 : #include <sstream> 17 : #include <cmath> 18 : #include <stdlib.h> 19 : 20 : using namespace PCIDSK; 21 : 22 : /************************************************************************/ 23 : /* CPCIDSK_BLUT() */ 24 : /************************************************************************/ 25 0 : CPCIDSK_BLUT::CPCIDSK_BLUT( PCIDSKFile *fileIn, int segmentIn, 26 0 : const char *segment_pointer ) 27 0 : : CPCIDSKSegment( fileIn, segmentIn, segment_pointer ) 28 : 29 : { 30 0 : } 31 : 32 : /************************************************************************/ 33 : /* ~CPCIDSK_BLUT() */ 34 : /************************************************************************/ 35 0 : CPCIDSK_BLUT::~CPCIDSK_BLUT() 36 : 37 : { 38 0 : } 39 : 40 : /************************************************************************/ 41 : /* ReadBLUT() */ 42 : /************************************************************************/ 43 0 : void CPCIDSK_BLUT::ReadBLUT( std::vector<BLUTEntry>& vBLUT ) 44 : 45 : { 46 0 : PCIDSKBuffer seg_data; 47 : 48 0 : seg_data.SetSize( (int) GetContentSize() ); 49 : 50 0 : ReadFromFile( seg_data.buffer, 0, seg_data.buffer_size ); 51 : 52 0 : std::istringstream ss(seg_data.buffer); 53 : 54 0 : vBLUT.clear(); 55 : 56 : // the first token is interpolation type (not used) 57 : std::size_t nInterp; 58 0 : if(!(ss >> nInterp)) 59 0 : throw PCIDSKException("Invalid BLUT segment."); 60 : 61 : // the second token is the number of entries 62 : std::size_t nCount; 63 0 : if(!(ss >> nCount) || nCount > 1024 * 1024 /* arbitrary limit */) 64 0 : throw PCIDSKException("Invalid BLUT segment."); 65 : 66 0 : for(std::size_t n=0; n<nCount; ++n) 67 : { 68 0 : BLUTEntry oEntry; 69 : 70 0 : if(!(ss >> oEntry.first)) 71 0 : throw PCIDSKException("Invalid BLUT segment."); 72 : 73 0 : if(!(ss >> oEntry.second)) 74 0 : throw PCIDSKException("Invalid BLUT segment."); 75 : 76 0 : vBLUT.push_back(oEntry); 77 : 78 : } 79 0 : } 80 : 81 : /************************************************************************/ 82 : /* WriteBLUT() */ 83 : /************************************************************************/ 84 0 : void CPCIDSK_BLUT::WriteBLUT( const std::vector<BLUTEntry>& vBLUT ) 85 : 86 : { 87 0 : std::stringstream oSS; 88 : 89 0 : oSS << INTERP_LINEAR << " " << vBLUT.size(); 90 0 : oSS.precision(15); 91 : 92 0 : for(std::vector<BLUTEntry>::const_iterator it = vBLUT.begin(); 93 0 : it != vBLUT.end(); 94 0 : ++it) 95 : { 96 0 : if(it->first == std::floor(it->first)) 97 0 : oSS << " " << (int) it->first; 98 : else 99 0 : oSS << " " << it->first; 100 : 101 0 : if(it->second == std::floor(it->second)) 102 0 : oSS << " " << (int) it->second; 103 : else 104 0 : oSS << " " << it->second; 105 : } 106 : 107 0 : std::string sData = oSS.str(); 108 0 : WriteToFile( sData.c_str(), 0, sData.size() ); 109 0 : }