USGS

Isis 3.0 Object Programmers' Reference

Home

Buffer.cpp
Go to the documentation of this file.
1 
24 #include "PixelType.h"
25 #include "Buffer.h"
26 #include "IException.h"
27 #include "Message.h"
28 
29 #include <iostream>
30 
31 using namespace std;
32 
33 namespace Isis {
34 
41  Buffer::Buffer() : p_sample(0), p_nsamps(0), p_line(0), p_nlines(0),
42  p_band(0), p_nbands(0), p_npixels(0), p_buf(0),
43  p_pixelType(None), p_rawbuf(0) { }
44 
56  Buffer::Buffer(const int nsamps, const int nlines,
57  const int nbands, const Isis::PixelType type) :
58  p_nsamps(nsamps), p_nlines(nlines),
59  p_nbands(nbands), p_pixelType(type) {
60 
61  p_sample = p_line = p_band = 0;
62 
63  if(p_nsamps <= 0) {
64  string message = "Invalid value for sample dimensions (nsamps)";
66  }
67  if(p_nlines <= 0) {
68  string message = "Invalid value for line dimensions (nlines)";
70  }
71  if(p_nbands <= 0) {
72  string message = "Invalid value for band dimensions (nbands)";
74  }
75 
77 
78  Allocate();
79  }
80 
83  try {
84  if(p_buf) {
85  delete [] p_buf;
86  }
87  if(p_rawbuf) {
88  delete [](char *) p_rawbuf;
89  }
90  }
91  catch(...) {
92 
93  }
94  }
95 
102  Buffer &Buffer::operator=(const double &d) {
103  for(int i = 0 ; i < p_npixels ; i++) {
104  p_buf[i] = d;
105  }
106  return (*this);
107  }
108 
118  void Buffer::SetBasePosition(const int start_sample,
119  const int start_line,
120  const int start_band) {
121  SetBaseSample(start_sample);
122  SetBaseLine(start_line);
123  SetBaseBand(start_band);
124  }
125 
126 
139  int Buffer::Sample(const int index) const {
140  return (index % p_nsamps) + p_sample;
141  }
142 
156  int Buffer::Line(const int index) const {
157  int sub_index = index % (p_nsamps * p_nlines);
158  return sub_index / p_nsamps + p_line;
159  }
160 
172  int Buffer::Band(const int index) const {
173  return index / (p_nsamps * p_nlines) + p_band;
174  }
175 
186  void Buffer::Position(const int index, int &i_samp, int &i_line,
187  int &i_band) const {
188  i_samp = Sample(index);
189  i_line = Line(index);
190  i_band = Band(index);
191  }
192 
205  int Buffer::Index(const int i_samp, const int i_line, const int i_band)
206  const {
207  if((i_samp < p_sample) || (i_samp > (p_sample + p_nsamps - 1))) {
208  QString message = Message::ArraySubscriptNotInRange(i_samp);
210  }
211 
212  if((i_line < p_line) || (i_line > (p_line + p_nlines - 1))) {
213  QString message = Message::ArraySubscriptNotInRange(i_line);
215  }
216 
217  if((i_band < p_band) || (i_band > (p_band + p_nbands - 1))) {
218  QString message = Message::ArraySubscriptNotInRange(i_band);
220  }
221 
222  // Got a valid reference location so compute the index and return
223  int index = (i_band - p_band) * (p_nlines * p_nsamps) +
224  (i_line - p_line) * (p_nsamps) +
225  (i_samp - p_sample);
226  return (index);
227  }
228 
238  double Buffer::at(const int index) const {
239  if(index < 0) {
240  QString message = Message::ArraySubscriptNotInRange(index);
242  }
243  else if(index >= p_npixels) {
244  QString message = Message::ArraySubscriptNotInRange(index);
246  }
247 
248  return p_buf[index];
249  }
250 
259  void Buffer::Copy(const Buffer &in, bool includeRawBuf) {
260  if(p_npixels != in.size()) {
261  string message = "Input and output buffers are not the same size";
263  }
264 
265  if(includeRawBuf && p_pixelType != in.PixelType()) {
266  string message = "Input and output buffers are not the same pixel type";
268  }
269 
270  size_t n = sizeof(double);
271  n = n * (size_t) p_npixels;
272  memcpy(p_buf, in.p_buf, n);
273 
274  if (includeRawBuf) {
276  n = n * (size_t) p_npixels;
277  memcpy(p_rawbuf, in.p_rawbuf, n);
278  }
279  }
280 
288  bool Buffer::CopyOverlapFrom(const Buffer &in) {
289  bool isSubareaOfIn = (p_npixels <= in.size());
290  isSubareaOfIn &= (p_sample >= in.p_sample);
291  isSubareaOfIn &= (p_line >= in.p_line);
292  isSubareaOfIn &= (p_band >= in.p_band);
293 
294  int endSample = p_sample + p_nsamps - 1;
295  int otherEndSample = in.p_sample + in.p_nsamps - 1;
296 
297  int endLine = p_line + p_nlines - 1;
298  int otherEndLine = in.p_line + in.p_nlines - 1;
299 
300  int endBand = p_band + p_nbands - 1;
301  int otherEndBand = in.p_band + in.p_nbands - 1;
302 
303  isSubareaOfIn &= (endSample <= otherEndSample);
304  isSubareaOfIn &= (endLine <= otherEndLine);
305  isSubareaOfIn &= (endBand <= otherEndBand);
306 
307  if (isSubareaOfIn) {
308  for (int i = 0; i < size(); i++) {
309  (*this)[i] = in[in.Index(Sample(i), Line(i), Band(i))];
310  }
311  }
312 
313  return isSubareaOfIn;
314  }
315 
322  Buffer::Buffer(const Buffer &rhs) :
323  p_nsamps(rhs.p_nsamps), p_nlines(rhs.p_nlines),
324  p_nbands(rhs.p_nbands), p_pixelType(rhs.p_pixelType) {
325 
326  p_sample = rhs.p_sample;
327  p_line = rhs.p_line;
328  p_band = rhs.p_band;
329 
330  p_npixels = rhs.p_npixels;
331 
332  Allocate();
333  Copy(rhs);
334  }
335 
342  p_buf = NULL;
343  p_rawbuf = NULL;
344  try {
345  p_buf = new double [p_npixels];
346  size_t n = Isis::SizeOf(p_pixelType);
347  n = n * (size_t) p_npixels;
348  p_rawbuf = new char[n];
349  }
350  catch(...) {
351  try {
352  if(p_buf) {
353  delete [] p_buf;
354  p_buf = NULL;
355  }
356  if(p_rawbuf) {
357  delete [](char *)p_rawbuf;
358  p_rawbuf = NULL;
359  }
360  }
361  catch(...) {
362  p_buf = NULL;
363  p_rawbuf = NULL;
364  }
365  QString message = Message::MemoryAllocationFailed();
366  throw IException(IException::Unknown, message, _FILEINFO_);
367  }
368  }
369 }