13 # include <vcl_msvc_warnings.h> 17 #include <vxl_config.h> 26 #if 0 // see comment below 32 static inline bool iseol(
int c)
34 return c == 10 || c == 13;
37 static inline bool isws(
int c)
39 return c ==
' ' || c ==
'\t' || c == 10 || c == 13;
46 if (vs->
read(buf, 3L) != 3L)
48 bool ok = ((buf[0] ==
'P') &&
50 (buf[1] >=
'1' && buf[2] <=
'6'));
132 else assert(!
"nplanes must be 1 or 3");
151 static void SkipSpaces(
vil_stream* vs,
char& temp)
153 while (isws(temp) || temp ==
'#')
157 if (1L > vs->
read(&temp,1L))
return;
159 if (1L > vs->
read(&temp,1L))
return;
164 static int ReadInteger(
vil_stream* vs,
char& temp)
167 while ((temp >=
'0') && (temp <=
'9'))
169 n *= 10; n += (temp -
'0');
170 if (1L > vs->
read(&temp,1L))
return n;
175 #if VXL_LITTLE_ENDIAN 178 static void ConvertMSBToHost(
void* buf,
int num_words )
180 auto* ptr = static_cast<unsigned char*>(buf);
181 for (
int i=0; i < num_words; ++i )
183 unsigned char t = *ptr;
191 static void ConvertHostToMSB(
void* buf,
int num_words )
193 auto* ptr = static_cast<unsigned char*>(buf);
194 for (
int i=0; i < num_words; ++i )
196 unsigned char t = *ptr;
203 #endif // VXL_LITTLE_ENDIAN 215 if (3L >
vs_->
read(buf, 3L))
return false;
216 if (buf[0] !=
'P')
return false;
217 if (!isws(buf[2]))
return false;
219 if (magic_ < 1 || magic_ > 6)
return false;
225 SkipSpaces(
vs_,temp);
228 ni_ = ReadInteger(
vs_,temp);
231 SkipSpaces(
vs_,temp);
234 nj_ = ReadInteger(
vs_,temp);
242 SkipSpaces(
vs_,temp);
257 else if (
maxval_ == 0) assert(!
"problem reading maxval from PNM file");
262 else assert(!
"vil_pnm_image: maxval is too big");
293 std::sprintf(buf,
"P%d\n#vil pnm image, #c=%u, bpc=%u\n%u %u\n",
298 std::sprintf(buf,
"%lu\n",
maxval_);
307 char c; vs.
read(&c,1L);
309 if (c < '0' || c >
'9')
return false;
310 a = ReadInteger(&vs,c);
315 unsigned x0,
unsigned ni,
unsigned y0,
unsigned nj)
const 318 unsigned char* ib =
nullptr;
319 unsigned short* jb =
nullptr;
320 unsigned int* kb =
nullptr;
327 bb = reinterpret_cast<bool *>(buf->data());
332 ib = reinterpret_cast<vxl_byte*>(buf->data());
337 jb = reinterpret_cast<vxl_uint_16*>(buf->data());
342 kb = reinterpret_cast<vxl_uint_32*>(buf->data());
348 unsigned bytes_per_pixel =
nplanes() * bytes_per_sample;
350 unsigned byte_width =
ni_ * bytes_per_pixel;
351 unsigned byte_out_width =
ni * bytes_per_pixel;
353 for (
unsigned y = 0; y <
nj; ++y)
356 vs_->
read((
unsigned char *)buf->data() + y * byte_out_width, byte_out_width);
357 byte_start += byte_width;
359 if ( bytes_per_sample > 2 )
361 std::cerr <<
"ERROR: pnm: reading rawbits format with > 16bit samples\n";
364 #if VXL_LITTLE_ENDIAN 365 else if ( bytes_per_sample==2 )
366 ConvertMSBToHost( reinterpret_cast<unsigned char *>(buf->data()),
ni*
nj*
nplanes() );
368 #if 0 // see comment below 379 #if 0 // never return vil_image_view<vil_rgb<T> > : default image representation is planar 394 unsigned byte_width = (
ni_+7)/8;
396 for (
unsigned y = 0; y <
nj; ++y)
400 unsigned char a;
vs_->
read(&a, 1L);
401 for (
unsigned x = 0; x <
ni+x0; ++x)
404 bb[y *
ni + x-x0] = (a & 0x80) != 0;
410 assert (buf->size() ==
ni*
nj*
sizeof(bool));
418 for (
unsigned t = 0; t < y0*
ni_*
nplanes(); ++t) {
int a; (*vs_) >> a; }
419 for (
unsigned y = 0; y <
nj; ++y)
422 for (
unsigned t = 0; t < x0*
nplanes(); ++t) {
int a; (*vs_) >> a; }
423 for (
unsigned x = 0; x <
ni; ++x)
427 for (
unsigned p = 0; p <
nplanes(); ++p) {
int a; (*vs_) >> a; *(bb++)=(a!=0); }
429 for (
unsigned p = 0; p <
nplanes(); ++p) {
int a; (*vs_) >> a; *(ib++)=vxl_byte(a); }
431 for (
unsigned p = 0; p <
nplanes(); ++p) {
int a; (*vs_) >> a; *(jb++)=vxl_uint_16(a); }
433 for (
unsigned p = 0; p <
nplanes(); ++p) {
int a; (*vs_) >> a; *(kb++)=vxl_uint_32(a); }
436 for (
unsigned t = 0; t < (
ni_-x0-
ni)*
nplanes(); ++t) {
int a; (*vs_) >> a; }
438 #if 0 // see comment below 452 #if 0 // never return vil_image_view<vil_rgb<T> > : default image representation is planar 471 char buf[128]; std::sprintf(buf,
" %d\n", a); vs.
write(buf,std::strlen(buf));
475 unsigned x0,
unsigned y0)
493 std::cerr <<
"ERROR: " << __FILE__ <<
":\n Can't fit view into pnm component size\n";
512 std::cerr <<
"ERROR: " << __FILE__ <<
":\n Do not support putting " 513 << view.
is_a() <<
" views into pnm image_resource objects\n";
520 unsigned bytes_per_pixel = bytes_per_sample;
522 unsigned byte_width =
ni_ * bytes_per_pixel;
523 unsigned byte_out_width = view.
ni() * bytes_per_pixel;
525 if ( bytes_per_sample==1 )
528 for (
unsigned y = 0; y < view.
nj(); ++y)
532 byte_start += byte_width;
535 else if ( bytes_per_sample==2 && VXL_BIG_ENDIAN )
538 for (
unsigned y = 0; y < view.
nj(); ++y)
542 byte_start += byte_width;
545 else if ( bytes_per_sample==2 )
550 std::vector<vxl_byte> tempbuf(byte_out_width);
552 for (
unsigned y = 0; y < view.
nj(); ++y)
556 #if VXL_LITTLE_ENDIAN 557 ConvertHostToMSB(&tempbuf[0], view.
ni());
559 vs_->
write(&tempbuf[0], byte_out_width);
560 byte_start += byte_width;
564 std::cerr <<
"ERROR: pgm: writing rawbits format with > 16bit samples\n";
571 unsigned bytes_per_pixel =
nplanes() * bytes_per_sample;
573 unsigned byte_width =
ni_ * bytes_per_pixel;
575 if ( bytes_per_sample==1 )
581 std::vector<vxl_byte> scanline( byte_width );
583 for (
unsigned y = 0; y < view.
nj(); ++y)
586 for (
unsigned x = 0, c = 0; x < view.
ni(); ++x)
588 scanline[c] = (*ob)(x,y,p);
589 vs_->
write(&scanline[0], byte_width);
590 byte_start += byte_width;
593 else if ( bytes_per_sample==2 )
596 for (
unsigned y = y0; y < view.
nj(); ++y)
599 for (
unsigned x = x0; x < view.
ni(); ++x)
601 vxl_uint_16 tempbuf[3];
603 tempbuf[p] = (*pb)(x,y,p);
604 #if VXL_LITTLE_ENDIAN 607 vs_->
write(tempbuf, bytes_per_pixel);
609 byte_start += byte_width;
613 std::cerr <<
"ERROR: pgm: writing rawbits format with > 16bit samples\n";
619 int byte_width = (
ni_+7)/8;
622 for (
unsigned y = 0; y < view.
nj(); ++y)
631 a &= ((1<<s)-1)<<(8-s);
633 for (
unsigned x = 0; x < view.
ni(); ++x)
635 if ((*bb)(x,y)) a |= 1<<(7-s);
636 if (s >= 7) {
vs_->
write(&a, 1L); ++byte_start; s = 0; a = 0; }
641 if (x0+view.
ni() <
ni_)
644 unsigned char c;
vs_->
read(&c, 1L);
655 if (x0 > 0 || y0 > 0 || view.
ni() <
ni_ || view.
nj() <
nj_)
658 for (
unsigned y = 0; y < view.
nj(); ++y)
659 for (
unsigned x = 0; x < view.
ni(); ++x)
665 else (*
vs_) << (*qb)(x,y,p);
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
unsigned bits_per_component_
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.
char const * vil_pnm_format_tag
virtual std::string is_a() const =0
Return class name.
virtual vil_streampos tell() const =0
Return file pointer.
bool get_property(char const *tag, void *prop=nullptr) const override
Extra property information.
Pixel type for 24 bit images.
virtual vil_streampos write(void const *buf, vil_streampos n)=0
Write n bytes from buf. Returns number of bytes written.
vil_streampos start_of_data_
virtual void seek(vil_streampos position)=0
Goto file pointer.
char const * file_format() const override
Return a string describing the file format.
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.
bool read_header()
This method accepts any valid PNM file (first 3 bytes "P1\n" to "P6\n").
#define vil_property_quantisation_depth
The quantisation depth of pixel components.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned nplanes() const override
Dimensions: Planes x ni x nj.
unsigned ni() const
Width.
Stream interface for VIL image loaders.
unsigned ni() const override
Dimensions: Planes x ni x nj.
std::istream & operator>>(std::istream &is, vnl_bignum &x)
unsigned nj() const
Height.
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.
Generic image implementation for PNM files.
void ref()
up/down the reference count.
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.
There is no class or function called vil_property.
unsigned long int maxval_
Ref. counted block of data on the heap.
vil_pnm_image(vil_stream *is, unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format)
vil_pixel_format format_
Describe the format of each pixel.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
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.
std::ostream & operator<<(std::ostream &s, const vnl_amoeba_SimplexCorner &simplex)
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
Representation of a generic image source or destination.
unsigned nj() const override
Dimensions: Planes x ni x nj.
This is the appropriate pixel type for 24-bit colour images.
~vil_pnm_image() override