OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimBilSplitter.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: David Burken (dburken@imagelinks.com)
6 //
7 // Description:
8 //
9 // Contains class definition for ossimBilSplitter.
10 //
11 // Utility class for splitting an image that is band interleaved by line into
12 // separate files.
13 //*******************************************************************
14 // $Id: ossimBilSplitter.cpp 9966 2006-11-29 02:01:07Z gpotts $
15 
16 #include <iomanip>
17 #include <iostream>
18 using namespace std;
19 
23 
24 ossimBilSplitter::ossimBilSplitter(const char* file_to_split,
25  ossim_uint32 header_size_in_bytes,
26  ossim_uint32 bytes_per_pixel,
27  ossim_uint32 samples_per_line,
28  ossim_uint32 number_of_channels)
29  :
30  theSourceFileStr(),
31  theHeaderSizeInBytes(header_size_in_bytes),
32  theBytesPerLine(bytes_per_pixel * samples_per_line),
33  theLinesToWrite(0),
34  theNumberOfChannels(number_of_channels),
35  theErrorStatus(OSSIM_OK)
36 {
37  static const char MODULE[] = "ossimBilSplitter::ossimBilSplitter";
38 
39  //***
40  // Open up the source bil file and check for a good descriptor.
41  //***
42  theSourceFileStr.open(file_to_split, ios::in | ios::binary);
43  if (!theSourceFileStr)
44  {
46  ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":\nCould not open file: " << file_to_split
47  << "\n";
48 
49  return;
50  }
51 
52  //***
53  // Get the file size to make sure that the ( size - header ) / byte per line
54  // come out even; if not, consider this an error.
55  //***
56  ossimFilename f(file_to_split);
58 
60  {
62  ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":"
63  << "\nFile size error..."
64  << "\nbytes_per_pixel * samples_per_line * "
65  << "number_of_channels should"
66  << "\ndivide evenly into total file size in bytes."
67  << "\nHeader size in bytes: " << header_size_in_bytes
68  << "\nBytes per pixel: " << bytes_per_pixel
69  << "\nSamples per line: " << samples_per_line
70  << "\nBytes per line: " << theBytesPerLine
71  << "\nNumber of channels: " << theNumberOfChannels
72  << "\nFile size in bytes: " << size
73  << "\nthe file size in bytes. Returning with error."
74  << "\n";
75  return;
76  }
77 
80 
81  ossimNotify(ossimNotifyLevel_INFO) << "\nFile to split: " << file_to_split
82  << "\nHeader size in bytes: " << header_size_in_bytes
83  << "\nBytes per pixel: " << bytes_per_pixel
84  << "\nSamples per line: " << samples_per_line
85  << "\nBytes per line: " << theBytesPerLine
86  << "\nNumber of channels: " << theNumberOfChannels
87  << "\nLines to write per channel: " << theLinesToWrite
88  << "\n";
89 }
90 
92 {
93  theSourceFileStr.close();
94 }
95 
96 bool ossimBilSplitter::output_multi_files(const char* output_dir)
97 {
98  static const char MODULE[] = "ossimBilSplitter::output_multi_files";
99 
100  if (theErrorStatus)
101  {
102  ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " :"
103  << "\nError status has been set. Cannot split file." << "\n";
104  return false;
105  }
106 
107  // Open up all the FILE pointers needed.
108  ossimFilename outDir = output_dir;
109  ossimString base("channel_");
110  ossimString ext(".ras");
112 
113  ossim_uint32 i = 0;
114  for(i = 0; i < theNumberOfChannels; i++)
115  {
116  ossimString file_basename = base + ossimString::toString(int(i+1)) + ext;
117  ossimFilename tmpFile = outDir.dirCat(file_basename);
118 
119  os[i].open(tmpFile.c_str(), ios::out | ios::binary);
120 
121  if (!os)
122  {
123  ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":\n"
124  << "Cannot open: " << tmpFile.c_str()
125  << "\nReturning from application." << "\n";
126  return false;
127  }
128  }
129 
130  char* lineBuffer = new char[theBytesPerLine];
131 
132  // Move the source pointer past the header.
133  theSourceFileStr.seekg(theHeaderSizeInBytes, ios::beg);
134 
135  // Write the lines out to the individual files.
136  ossimNotify(ossimNotifyLevel_INFO) << "\nOutputting to separate files to: " << output_dir << "\n";
137 
138  for (i=0; i<theLinesToWrite; ++i)
139  {
140  for(ossim_uint32 j=0; j < theNumberOfChannels; ++j)
141  {
142  // Read a line.
143  theSourceFileStr.read(lineBuffer, theBytesPerLine);
144 
145  // Write the line to the channel file.
146  os[j].write(lineBuffer, theBytesPerLine);
147 
148  } // End of loop through the channels.
149 
150  //***
151  // Output some status info.
152  //***
153  ossim_float64 totalLines = theLinesToWrite;
154  ossim_float64 linesWritten = i + 1;
155  ossimNotify(ossimNotifyLevel_INFO) << setiosflags(ios::fixed)
156  << setprecision(0) << setw(3)
157  << linesWritten / totalLines * 100.0 << " % \r"
158  << flush;
159 
160  } // End of loop through lines.
161 
162  ossimNotify(ossimNotifyLevel_INFO) << "100 %\nFinished...\n";
163 
164  // Cleanup.
165  for(i = 0; i < theNumberOfChannels; i++) os[i].close();
166  delete [] os;
167  delete [] lineBuffer;
168 
169  return true;
170 }
ifstream theSourceFileStr
ossim_int64 fileSize() const
static ossimString toString(bool aValue)
Numeric to string methods.
double ossim_float64
yy_size_t size
ossim_uint32 theBytesPerLine
ossimBilSplitter(const char *file_to_split, ossim_uint32 header_size_in_bytes, ossim_uint32 bytes_per_pixel, ossim_uint32 samples_per_line, ossim_uint32 number_of_channels)
unsigned int ossim_uint32
ossim_uint32 theLinesToWrite
ossim_uint32 theHeaderSizeInBytes
bool output_multi_files(const char *output_dir)
ossimFilename dirCat(const ossimFilename &file) const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
ossimStatus theErrorStatus
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossim_uint32 theNumberOfChannels