Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: Implementation of the CPCIDSK_BPCT 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/cpcidskbpct.h" 14 : #include <cassert> 15 : #include <cstring> 16 : #include <sstream> 17 : #include <cmath> 18 : #include <stdlib.h> 19 : #include "core/pcidsk_utils.h" 20 : 21 : using namespace PCIDSK; 22 : 23 : /************************************************************************/ 24 : /* CPCIDSK_BPCT() */ 25 : /************************************************************************/ 26 0 : CPCIDSK_BPCT::CPCIDSK_BPCT( PCIDSKFile *fileIn, int segmentIn, 27 0 : const char *segment_pointer ) 28 0 : : CPCIDSKSegment( fileIn, segmentIn, segment_pointer ) 29 : 30 : { 31 0 : } 32 : 33 : /************************************************************************/ 34 : /* ~CPCIDSK_BPCT() */ 35 : /************************************************************************/ 36 0 : CPCIDSK_BPCT::~CPCIDSK_BPCT() 37 : 38 : { 39 0 : } 40 : 41 : /************************************************************************/ 42 : /* ReadBPCT() */ 43 : /************************************************************************/ 44 0 : void CPCIDSK_BPCT::ReadBPCT( std::vector<BPCTEntry>& vBPCT ) 45 : 46 : { 47 0 : PCIDSKBuffer seg_data; 48 : 49 0 : seg_data.SetSize( (int) GetContentSize() ); 50 : 51 0 : ReadFromFile( seg_data.buffer, 0, seg_data.buffer_size ); 52 : 53 0 : std::istringstream ss(seg_data.buffer); 54 : 55 0 : vBPCT.clear(); 56 : 57 : // the first token is interpolation type (not used) 58 : std::size_t nInterp; 59 0 : if(!(ss >> nInterp)) 60 0 : throw PCIDSKException("Invalid BPCT segment."); 61 : 62 : // the second token is the number of entries 63 : std::size_t nCount; 64 0 : if(!(ss >> nCount)|| nCount > 1024 * 1024 /* arbitrary limit */) 65 0 : throw PCIDSKException("Invalid BPCT segment."); 66 : 67 : 68 0 : for(std::size_t n=0; n<nCount; ++n) 69 : { 70 0 : BPCTEntry oEntry; 71 : 72 0 : if(!(ss >> oEntry.boundary)) 73 0 : throw PCIDSKException("Invalid BPCT segment."); 74 : 75 : int nTemp; 76 0 : if(!(ss >> nTemp) || nTemp < 0 || nTemp > 255) 77 0 : throw PCIDSKException("Invalid BPCT segment."); 78 0 : oEntry.red = (unsigned char) nTemp; 79 : 80 0 : if(!(ss >> nTemp) || nTemp < 0 || nTemp > 255) 81 0 : throw PCIDSKException("Invalid BPCT segment."); 82 0 : oEntry.green = (unsigned char) nTemp; 83 : 84 0 : if(!(ss >> nTemp) || nTemp < 0 || nTemp > 255) 85 0 : throw PCIDSKException("Invalid BPCT segment."); 86 0 : oEntry.blue = (unsigned char) nTemp; 87 : 88 0 : vBPCT.push_back(oEntry); 89 : 90 : } 91 0 : } 92 : 93 : /************************************************************************/ 94 : /* WriteBPCT() */ 95 : /************************************************************************/ 96 0 : void CPCIDSK_BPCT::WriteBPCT( const std::vector<BPCTEntry>& vBPCT ) 97 : 98 : { 99 0 : std::stringstream oSS; 100 : 101 0 : oSS << INTERP_LINEAR << " " << vBPCT.size(); 102 0 : oSS.precision(15); 103 : 104 0 : for(std::vector<BPCTEntry>::const_iterator it = vBPCT.begin(); 105 0 : it != vBPCT.end(); 106 0 : ++it) 107 : { 108 0 : if(it->boundary == std::floor(it->boundary)) 109 0 : oSS << " " << (int) it->boundary; 110 : else 111 0 : oSS << " " << it->boundary; 112 0 : oSS << " " << (unsigned int) it->red; 113 0 : oSS << " " << (unsigned int) it->green; 114 0 : oSS << " " << (unsigned int) it->blue; 115 : } 116 : 117 0 : std::string sData = oSS.str(); 118 0 : WriteToFile( sData.c_str(), 0, sData.size() ); 119 0 : }