vil_sgi.cxx
Go to the documentation of this file.
1 // This is core/vil/file_formats/vil_sgi.cxx
2 
3 #include <iostream>
4 
5 #include <vil/vil_image_view.h>
6 #include <vil/vil_exception.h>
7 #include "vil_sgi.h"
8 
9 #define where (std::cerr << __FILE__ " : " << __LINE__ << " : ")
10 #define SGI_HDR_SIZE 512
11 
12 //--------------------------------------------------------------------------------
13 
15 {
16  // Attempt to read header
18  vs->seek(0L);
19  hdr.read(vs);
20 
21  if ( hdr.signature_valid() )
22  return new vil_sgi_image(vs);
23  else
24  return nullptr;
25 }
26 
28  unsigned nx,
29  unsigned ny,
30  unsigned nplanes,
31  vil_pixel_format format)
32 {
33  return new vil_sgi_image(vs, nx, ny, nplanes, format);
34 }
35 
36 char const* vil_sgi_format_tag = "sgi";
37 
38 char const* vil_sgi_file_format::tag() const
39 {
40  return vil_sgi_format_tag;
41 }
42 
43 /////////////////////////////////////////////////////////////////////////////
44 
45 char const* vil_sgi_image::file_format() const
46 {
47  return vil_sgi_format_tag;
48 }
49 
51  : is_(is)
52 {
53  is_->ref();
54  if (!read_header())
55  vil_exception_error(vil_exception_image_io("vil_sgi_image::read_header", "SGI", ""));
56 }
57 
58 bool vil_sgi_image::get_property(char const * /*tag*/, void * /*value*/) const
59 {
60  return true;
61 }
62 
63 vil_sgi_image::vil_sgi_image(vil_stream* vs, unsigned nx, unsigned ny,
64  unsigned nplanes, vil_pixel_format format):
65  is_(vs)
66 {
67  if (format != VIL_PIXEL_FORMAT_BYTE)
68  {
70  //std::cerr << "Sorry -- pixel format " << format << " not yet supported\n";
71  return;
72  }
73  if(nplanes != 1 && nplanes != 3 && nplanes != 4)
74  {
75  vil_exception_warning(vil_exception_unsupported_operation("vil_sgi_image::vil_sgi_image: invalid number of planes"));
76  return;
77  }
78 
79  assert(format == VIL_PIXEL_FORMAT_BYTE);
80  assert(nplanes == 1 || nplanes == 3 || nplanes == 4);
81 
82  is_->ref();
83 
84  hdr.dimension = (nplanes == 1) ? 2 : 3; // dimension is 2 for one channel image, 3 otherwise
85  hdr.xsize = nx;
86  hdr.ysize = ny;
87  hdr.zsize = nplanes;
88 
89  write_header();
90 }
91 
93 {
94  is_->unref();
95 }
96 
97 unsigned vil_sgi_image::nplanes() const
98 {
99  return hdr.zsize;
100 }
101 
102 unsigned vil_sgi_image::ni() const
103 {
104  return hdr.xsize;
105 }
106 
107 unsigned vil_sgi_image::nj() const
108 {
109  return hdr.ysize;
110 }
111 
113 {
114  // seek to beginning and read file header.
115  is_->seek(0L);
116  hdr.read(is_);
117  if ( ! hdr.signature_valid() )
118  {
119  where << "File is not a valid SGI file\n";
120  return false;
121  }
122 #ifdef DEBUG
123  hdr.print(std::cerr); // blather
124 #endif
125 
126  // SGI allows an arbitrary number of bits per pixel, but assume one byte per channel and 1, 3, or 4 channels.
127  if ( hdr.bpc*hdr.zsize != 1 && hdr.bpc*hdr.zsize != 3 && hdr.bpc*hdr.zsize != 4 )
128  {
129  where << "SGI file has a non-supported pixel size of " << hdr.bpc*hdr.zsize*8 << " bits\n";
130  return false;
131  }
132 
133  // RLE should be added in - FIXME
134  if ( hdr.storage == 1 )
135  {
136  where << "The RLE storage format is not yet supported for SGI images\n";
137  return false;
138  }
139 
140  // There are four colormap modes. Only mode 0 ("normal") is in widespread use. Mode 1 and 2 are obsolete, mode 3 is for SGI hardware.
141  if ( hdr.colormap != 0 )
142  {
143  where << "Only colormap mode 0 is supported for SGI images\n";
144  return false;
145  }
146 
147  return true;
148 }
149 
151 {
152 #ifdef DEBUG
153  std::cerr << "Writing SGI header\n"
154  << ni() << 'x' << nj() << '@'
155  << nplanes() << 'x' <<
157 #endif
158 
159 #ifdef DEBUG
160  hdr.print(std::cerr); // blather
161 #endif
162  is_->seek(0L);
163  hdr.write(is_);
164 
165  return true;
166 }
167 
168 //------------------------------------------------------------
170  unsigned x0, unsigned nx, unsigned y0, unsigned ny) const
171 {
172  if (x0+nx > ni() || y0+ny > nj())
173  {
174  vil_exception_warning(vil_exception_out_of_bounds("vil_sgi_image::get_copy_view"));
175  return nullptr;
176  }
177 
178  // Number of bytes per pixel is equal to the number of channels
180 
181  for(int i = 0; i < ny; i++)
182  {
183  is_->seek(SGI_HDR_SIZE+ni()*nplanes()*(nj()-1-y0-i)+x0*nplanes());
184  is_->read(reinterpret_cast<vxl_byte *>(chunk->data()) + i*nx*nplanes(), nx*nplanes());
185  }
186 
187  return new vil_image_view<vxl_byte>(chunk, reinterpret_cast<vxl_byte *>(chunk->data()), nx, ny, nplanes(), nplanes(), nx*nplanes(), 1);
188 }
189 
191  unsigned x0, unsigned y0)
192 {
193  if (!view_fits(view, x0, y0))
194  {
195  vil_exception_warning(vil_exception_out_of_bounds("vil_sgi_image::put_view"));
196  return false;
197  }
198 
199  if(view.pixel_format() != VIL_PIXEL_FORMAT_BYTE)
200  {
202  return false;
203  }
204  const auto & view2 = static_cast<const vil_image_view<vxl_byte> &>(view);
205 
206  for(int i = 0; i < view2.nj(); i++)
207  {
208  is_->seek(SGI_HDR_SIZE+ni()*nplanes()*(nj()-1-y0-i)+x0*nplanes());
209  is_->write(&view2(0, i, view2.nplanes()-1), view2.ni()*view2.nplanes());
210  }
211 
212  return true;
213 }
vil_sgi_image(vil_stream *is, unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format)
Definition: vil_sgi.cxx:63
An abstract base class of smart pointers to actual image data in memory.
vil_pixel_format
Describes the type of the concrete data.
virtual bool view_fits(const vil_image_view_base &im, unsigned i0, unsigned j0)
Check that a view will fit into the data at the given offset.
enum vil_pixel_format pixel_format() const override
Pixel Format.
Definition: vil_sgi.h:43
#define SGI_HDR_SIZE
Definition: vil_sgi.cxx:10
void write(vil_stream *) const
void print(std::ostream &) const
Indicates that some operation is not supported.
Definition: vil_exception.h:99
virtual vil_streampos write(void const *buf, vil_streampos n)=0
Write n bytes from buf. Returns number of bytes written.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
bool put_view(const vil_image_view_base &im, unsigned i0, unsigned j0) override
Put the data in this view back into the image source.
Definition: vil_sgi.cxx:190
bool get_property(char const *tag, void *prop=nullptr) const override
Extra property information.
Definition: vil_sgi.cxx:58
Indicates that an image load or save operation failed.
virtual void seek(vil_streampos position)=0
Goto file pointer.
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
Exceptions thrown by vil, and a mechanism for turning them off.
char const * tag() const override
Return a character string which uniquely identifies this format.
Definition: vil_sgi.cxx:38
unsigned vil_pixel_format_sizeof_components(enum vil_pixel_format f)
Return the number of bytes used by each component of pixel format f.
bool write_header()
Definition: vil_sgi.cxx:150
vil_stream * is_
Definition: vil_sgi.h:56
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
~vil_sgi_image() override
Definition: vil_sgi.cxx:92
bool read_header()
Definition: vil_sgi.cxx:112
virtual enum vil_pixel_format pixel_format() const =0
Return a description of the concrete data pixel type.
Indicates that some reference was made to pixels beyond the bounds of an image.
Definition: vil_exception.h:81
vil_image_resource_sptr make_input_image(vil_stream *vs) override
Attempt to make a generic_image which will read from vil_stream vs.
Definition: vil_sgi.cxx:14
char const * file_format() const override
Return a string describing the file format.
Definition: vil_sgi.cxx:45
Generic image implementation for SGI files.
Definition: vil_sgi.h:30
Indicates that a function call failed because the pixel types were incompatible.
Definition: vil_exception.h:47
void ref()
up/down the reference count.
Definition: vil_stream.h:45
vil_image_view_base_sptr get_copy_view() const
Create a read/write view of a copy of all the data.
A base class reference-counting view of some image data.
Ref. counted block of data on the heap.
void unref()
Definition: vil_stream.cxx:31
unsigned ni() const override
Dimensions: Planes x ni x nj.
Definition: vil_sgi.cxx:102
unsigned nplanes() const override
Dimensions: planes x width x height x components.
Definition: vil_sgi.cxx:97
unsigned nj() const override
Dimensions: Planes x ni x nj.
Definition: vil_sgi.cxx:107
void read(vil_stream *)
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
Definition: vil_exception.h:37
void vil_exception_error(T exception)
Throw an exception indicating a definite problem.
Definition: vil_exception.h:23
vil_image_resource_sptr make_output_image(vil_stream *vs, unsigned nx, unsigned ny, unsigned nplanes, vil_pixel_format format) override
Make a "generic_image" on which put_section may be applied.
Definition: vil_sgi.cxx:27
#define where
Definition: vil_sgi.cxx:9
vil_sgi_file_header hdr
Definition: vil_sgi.h:63
char const * vil_sgi_format_tag
Definition: vil_sgi.cxx:36