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