21 # include <vcl_msvc_warnings.h> 28 #include <vxl_config.h> 30 static vxl_sint_16 get_short(
vil_stream* file,
int location = -1);
31 static vxl_uint_16 get_ushort(
vil_stream* file,
int location = -1);
32 static char get_char(
vil_stream* file,
int location = -1);
33 static vxl_sint_32 get_long(
vil_stream* file,
int location = -1);
34 static void send_char(
vil_stream* data,
char s);
35 static void send_short(
vil_stream* data, vxl_sint_16 s);
36 static void send_ushort(
vil_stream* data, vxl_uint_16 s);
37 static void send_long(
vil_stream* data, vxl_sint_32 s);
38 static void expandrow(
unsigned char *optr,
unsigned char *iptr,
int z);
45 if (is->
file_size() < 84L)
return nullptr;
48 vxl_sint_16 magic_ = get_short(is);
49 int storage_ = get_char(is);
50 int bytes_per_component = get_char(is);
51 int dimension_ = get_ushort(is);
60 if (is->
read(imagename, 80L) != 80)
return nullptr;
62 colormap_ = get_long(is);
64 if (magic_ != 474)
return nullptr;
65 if (storage_ != 0 && storage_ != 1)
return nullptr;
66 if (colormap_ == 3)
return nullptr;
67 if (dimension_ == 3 && colormap_ != 0)
return nullptr;
68 if (dimension_ > 3 || dimension_ < 1)
return nullptr;
69 if (bytes_per_component < 1 || bytes_per_component > 2)
return nullptr;
75 unsigned int ni,
unsigned int nj,
unsigned int nplanes,
89 starttab_(nullptr), lengthtab_(nullptr), is_(is)
108 unsigned int ni,
unsigned int nj,
unsigned int nplanes,
110 : starttab_(nullptr), lengthtab_(nullptr), is_(is), magic_(474), ni_(ni), nj_(nj),
111 nplanes_(nplanes), format_(format), pixmin_(0),
113 storage_(0), dimension_(nplanes_==1 ? 2 : 3), colormap_(0)
119 std::strcpy(
imagename_,
"written by vil_iris_generic_image");
122 std::cerr << __FILE__
": Cannot write iris image, can only do grayscale or RGB(A)\n";
125 else std::cerr << __FILE__
": Cannot write iris image, which needs 8 or 16 bits per component\n";
142 std::cerr << __FILE__
": This is not an Iris RGB file: magic number is incorrect: " 150 std::cerr << __FILE__
": This is not an Iris RGB file: storage must be RLE or VERBATIM\n";
154 int bytes_per_component = get_char(
is_);
178 std::cerr << __FILE__
": This is not an ordinary Iris RGB image but a colormap file which I cannot handle\n";
184 std::cerr << __FILE__
": Cannot handle Iris RGB file with colormap other than NORMAL\n";
198 std::cerr << __FILE__
": vil_iris_generic_image::write_header()\n" 200 <<
"magic_ = " <<
magic_ << std::endl
201 <<
"storage_ = " <<
storage_ << std::endl
202 <<
"format_ = " <<
format_ << std::endl
204 <<
"ni_ = " <<
ni_ << std::endl
205 <<
"nj_ = " <<
nj_ << std::endl
206 <<
"nplanes_ = " <<
nplanes_ << std::endl
207 <<
"pixmin_ = " <<
pixmin_ << std::endl
208 <<
"pixmax_ = " <<
pixmax_ << std::endl
209 <<
"colormap_ = " <<
colormap_ << std::endl
216 send_short(
is_, static_cast<vxl_sint_16>(
magic_));
220 send_ushort(
is_, static_cast<vxl_uint_16>(
ni_));
221 send_ushort(
is_, static_cast<vxl_uint_16>(
nj_));
222 send_ushort(
is_, static_cast<vxl_uint_16>(
nplanes_));
232 return is_->
write(dummy, 404L) == 404L;
236 static inline void swap(
void* p,
int length)
240 if (length ==
sizeof(vxl_uint_32) && *(vxl_uint_32*)p != 0) {
241 std::cerr <<
"Swapping " << *(vxl_uint_32*)p;
242 if (length ==
sizeof(
float))
243 std::cerr <<
" (or " << *(
float*)p <<
')';
246 for (
int j=0;2*j<length;++j) {
char c = t[j]; t[j] = t[length-j-1]; t[length-j-1] = c; }
248 if (length ==
sizeof(vxl_uint_32) && *(vxl_uint_32*)p != 0) {
249 std::cerr <<
" to " << *(vxl_uint_32*)p;
250 if (length ==
sizeof(
float))
251 std::cerr <<
" (or " << *(
float*)p <<
')';
258 unsigned int y0,
unsigned int ys)
const 273 unsigned int y0,
unsigned int ys)
const 276 unsigned int row_len = xs * pix_size;
279 auto* ib = reinterpret_cast<vxl_byte*>(buf->data());
280 auto* ob = reinterpret_cast<vxl_uint_16*>(buf->data());
284 for (
unsigned int channel=0; channel<
nplanes_; ++channel)
287 for (
unsigned int row =
nj_-y0-ys; row <
nj_-y0; ++row,cbi+=row_len)
293 if (VXL_LITTLE_ENDIAN && pix_size > 1)
294 for (
unsigned int i=0;i<xs*ys*
nplanes_;++i)
308 unsigned int y0,
unsigned int ys)
const 311 unsigned int row_len = xs * pix_size;
314 auto* ib = reinterpret_cast<vxl_byte*>(buf->data());
315 auto* ob = reinterpret_cast<vxl_uint_16*>(buf->data());
317 auto* exrow =
new unsigned char[
ni_];
320 for (
unsigned int channel=0; channel<
nplanes_; ++channel)
323 for (
unsigned int rowno=
nj_-y0-ys; rowno<
nj_-y0; ++rowno,cbi+=row_len)
330 auto* rlerow =
new unsigned char[rlelength];
332 is_->
read((
void*)rlerow, rlelength);
335 expandrow(exrow,rlerow,0);
339 std::memcpy(cbi,exrow+x0,xs);
361 std::cerr <<
"vil_iris_image::put_view() : buf=" 362 << buf.
ni()<<
'x'<<buf.
nj()<<
'x'<< buf.
nplanes()<<
'p' 363 <<
" at ("<<x0<<
','<<y0<<
")\n";
369 std::size_t rowsize = pix_size*buf.
ni();
370 std::ptrdiff_t rowskip = pix_size*buff.jstep();
371 std::size_t planeskip = pix_size*buff.planestep();
373 if (VXL_LITTLE_ENDIAN && pix_size > 1)
376 auto* tempbuf =
new vxl_byte[rowsize];
378 for (
unsigned int channel = 0; channel<
nplanes_; ++channel) {
379 ob += rowskip*buff.
nj();
381 for (
unsigned int y =
nj_-y0-buf.
nj(); y <
nj_-y0; ++y) {
386 std::memcpy(tempbuf,ob,rowsize);
387 for (
unsigned int i=0;i<buf.
ni();++i)
388 swap(tempbuf+i*pix_size,pix_size);
391 std::cerr <<
"WARNING: " << __FILE__ <<
":\n" 392 <<
" could not write "<<rowsize<<
" bytes to stream;\n" 393 <<
" channel="<<channel<<
", y="<<y<<
'\n';
396 std::cerr <<
"written "<<rowsize<<
" bytes to stream; channel="<<channel<<
", y="<<y<<
'\n';
406 for (
unsigned int channel = 0; channel<
nplanes_; ++channel) {
407 ob += rowskip*buff.
nj();
409 for (
unsigned int y =
nj_-y0-buf.
nj(); y <
nj_-y0; ++y) {
414 std::cerr <<
"WARNING: " << __FILE__ <<
":\n" 415 <<
" could not write "<<rowsize<<
" bytes to stream;\n" 416 <<
" channel="<<channel<<
", y="<<y<<
'\n';
419 std::cerr <<
"written "<<rowsize<<
" bytes to stream; channel="<<channel<<
", y="<<y<<
'\n';
435 for (
unsigned int i=0; i<tablen; ++i) {
439 unsigned int lengthtab_offset = 512 + tablen*4;
441 for (
unsigned int i=0; i<tablen; ++i) {
449 vxl_sint_16 get_short(
vil_stream* file,
int location)
451 if (location >= 0) file->
seek(location);
454 file->
read(buff, 2L);
457 auto bits = static_cast<vxl_uint_16>(( buff[0] << 8 ) + buff[1]);
459 if ( ( bits & 0x8000 ) != 0 )
460 return static_cast<vxl_sint_16>(-( ~bits + 1 ));
462 return static_cast<vxl_sint_16>( bits );
468 if (location >= 0) file->
seek(location);
471 file->
read((
void*)buff, 1L);
475 vxl_uint_16 get_ushort(
vil_stream* file,
int location)
477 if (location >= 0) file->
seek(location);
479 unsigned char buff[2];
480 file->
read((
void*)buff, 2L);
481 return static_cast<vxl_uint_16>((buff[0]<<8)+(buff[1]<<0));
484 vxl_sint_32 get_long(
vil_stream* file,
int location)
486 if (location >= 0) file->
seek(location);
489 if (file->
read((
void*)buff, 4L) != 4L)
return 0;
492 vxl_uint_32 bits = ( vxl_uint_32(buff[0]) << 24 ) |
493 ( vxl_uint_32(buff[1]) << 16 ) |
494 ( vxl_uint_32(buff[2]) << 8 ) |
497 if ( ( bits & 0x80000000L ) != 0 )
498 return -vxl_sint_32( ~bits + 1 );
500 return vxl_sint_32( bits );
509 void send_short(
vil_stream* data, vxl_sint_16 s)
513 bits = static_cast<vxl_uint_16>(-s);
514 bits = static_cast<vxl_uint_16>(~bits + 1);
517 bits = static_cast<vxl_uint_16>(s);
521 buff[0] = static_cast<vxl_byte>((bits >> 8) & 0xff);
522 buff[1] = static_cast<vxl_byte>( bits & 0xff);
523 data->
write(buff, 2L);
526 void send_ushort(
vil_stream* data, vxl_uint_16 s)
528 unsigned char buff[2];
529 buff[0] = static_cast<unsigned char>((s >> 8) & 0xff);
530 buff[1] = static_cast<unsigned char>( s & 0xff);
531 data->
write(buff, 2L);
534 void send_long(
vil_stream* data, vxl_sint_32 s)
548 buff[0] = static_cast<unsigned char>( (bits >> 24) & 0xff );
549 buff[1] = static_cast<unsigned char>( (bits >> 16) & 0xff );
550 buff[2] = static_cast<unsigned char>( (bits >> 8) & 0xff );
551 buff[3] = static_cast<unsigned char>( bits & 0xff );
552 data->
write(buff, 4L);
555 void expandrow(
unsigned char *optr,
unsigned char *iptr,
int z)
557 unsigned char pixel, count;
563 if ( !(count = static_cast<unsigned char>(pixel & 0x7f)) )
567 while (count--) { *optr = *iptr++; ++optr; }
572 while (count--) { *optr = pixel; ++optr; }
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
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.
bool read_offset_tables()
bool get_property(char const *tag, void *prop=nullptr) const override
Extra property information.
virtual vil_streampos tell() const =0
Return file pointer.
void swap(double &a, double &b)
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.
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.
vil_image_view_base_sptr get_section_verbatim(unsigned int x0, unsigned int ni, unsigned int y0, unsigned int nj) const
unsigned ni() const
Width.
Stream interface for VIL image loaders.
unsigned nj() const
Height.
~vil_iris_generic_image() override
Generic image implementation for iris (SGI) RGB files.
virtual enum vil_pixel_format pixel_format() const =0
Return a description of the concrete data pixel type.
vil_streampos start_of_data_
Indicates that some reference was made to pixels beyond the bounds of an image.
bool put_view(vil_image_view_base const &buf, unsigned int x0, unsigned int y0) override
unsigned long * starttab_
enum vil_pixel_format format_
vil_image_view_base_sptr get_section_rle(unsigned int x0, unsigned int ni, unsigned int y0, unsigned int nj) const
char const * file_format() const override
Return a string describing the file format.
void ref()
up/down the reference count.
char const * vil_iris_format_tag
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.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
unsigned nplanes() const
Number of planes.
virtual vil_streampos file_size() const =0
Amount of data in the stream.
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
vil_iris_generic_image(vil_stream *is, char const *imagename="")
unsigned long * lengthtab_