vil_pnm.cxx
Go to the documentation of this file.
1 // This is core/vil/file_formats/vil_pnm.cxx
2 //:
3 // \file
4 
5 #include <cstdio>
6 #include <vector>
7 #include <iostream>
8 #include <cstring>
9 #include "vil_pnm.h"
10 
11 #include <cassert>
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15 
16 
17 #include <vxl_config.h> // for VXL_BIG_ENDIAN and vxl_byte
18 
19 #include <vil/vil_property.h>
20 #include <vil/vil_stream.h>
21 #include <vil/vil_image_resource.h>
22 #include <vil/vil_image_view.h>
23 #include <vil/vil_memory_chunk.h>
24 #include <vil/vil_exception.h>
25 
26 #if 0 // see comment below
27 # include <vil/vil_rgb.h>
28 #endif
29 
30 char const* vil_pnm_format_tag = "pnm";
31 
32 static inline bool iseol(int c)
33 {
34  return c == 10 || c == 13;
35 }
36 
37 static inline bool isws(int c)
38 {
39  return c == ' ' || c == '\t' || c == 10 || c == 13;
40 }
41 
43 {
44  // Attempt to read header
45  unsigned char buf[3];
46  if (vs->read(buf, 3L) != 3L)
47  return nullptr;
48  bool ok = ((buf[0] == 'P') &&
49  isws(buf[2]) &&
50  (buf[1] >= '1' && buf[2] <= '6'));
51  if (!ok)
52  return nullptr;
53 
54  return new vil_pnm_image(vs);
55 }
56 
58  unsigned ni,
59  unsigned nj,
60  unsigned nplanes,
61  vil_pixel_format format)
62 {
63  return new vil_pnm_image(vs, ni, nj, nplanes, format);
64 }
65 
66 char const* vil_pnm_file_format::tag() const
67 {
68  return vil_pnm_format_tag;
69 }
70 
71 /////////////////////////////////////////////////////////////////////////////
72 
74  vs_(vs)
75 {
76  vs_->ref();
77  read_header();
78 }
79 
80 bool vil_pnm_image::get_property(char const * tag, void * value) const
81 {
82  if (std::strcmp(vil_property_quantisation_depth, tag)==0)
83  {
84  if (value)
85  *static_cast<unsigned int*>(value) = bits_per_component_;
86  return true;
87  }
88 
89  return false;
90 }
91 
92 char const* vil_pnm_image::file_format() const
93 {
94  return vil_pnm_format_tag;
95 }
96 
97 vil_pnm_image::vil_pnm_image(vil_stream* vs, unsigned ni, unsigned nj,
98  unsigned nplanes, vil_pixel_format format):
99  vs_(vs)
100 {
101  vs_->ref();
102  ni_ = ni;
103  nj_ = nj;
104 
107  if (nplanes == 1 &&
108  (format==VIL_PIXEL_FORMAT_RGB_BYTE ||
109  format==VIL_PIXEL_FORMAT_RGB_SBYTE ||
110  format==VIL_PIXEL_FORMAT_RGB_INT_16 ||
111  format==VIL_PIXEL_FORMAT_RGB_INT_16 ||
112  format==VIL_PIXEL_FORMAT_RGB_INT_32 ||
113  format==VIL_PIXEL_FORMAT_RGB_INT_32 ||
114  format==VIL_PIXEL_FORMAT_RGB_FLOAT ||
116  ))
117  ncomponents_ = 3;
118  if (format==VIL_PIXEL_FORMAT_BOOL)
120  else
122 
123  if (ncomponents_ == 3)
124  magic_ = 6;
125  else if (ncomponents_ == 1)
126  {
127  if (bits_per_component_ == 1)
128  magic_ = 4;
129  else
130  magic_ = 5;
131  }
132  else assert(!"nplanes must be 1 or 3");
133 
134  // pnm allows 16 bit samples in rawbits format, stored MSB, but not 32 bit.
135  if (bits_per_component_ > 16) magic_ -= 3;
136 
137  if (bits_per_component_ < 31)
138  maxval_ = (1L<<bits_per_component_)-1;
139  else
140  maxval_ = 0x7FFFFFFF; // not 0xFFFFFFFF as the pnm format does not allow values > MAX_INT
141 
142  write_header();
143 }
144 
146 {
147  vs_->unref();
148 }
149 
150 // Skip over spaces and comments; temp is the current vs character
151 static void SkipSpaces(vil_stream* vs, char& temp)
152 {
153  while (isws(temp) || temp == '#')
154  {
155  if (temp == '#') // skip this line:
156  while (!iseol(temp))
157  if (1L > vs->read(&temp,1L)) return; // at end-of-file?
158  // skip this `whitespace' byte by reading the next byte:
159  if (1L > vs->read(&temp,1L)) return;
160  }
161 }
162 
163 // Get a nonnegative integer from the vs stream; temp is the current vs byte
164 static int ReadInteger(vil_stream* vs, char& temp)
165 {
166  int n = 0;
167  while ((temp >= '0') && (temp <= '9'))
168  {
169  n *= 10; n += (temp - '0');
170  if (1L > vs->read(&temp,1L)) return n; // at end-of-file?
171  }
172  return n;
173 }
174 
175 #if VXL_LITTLE_ENDIAN
176 
177 // Convert the buffer of 16 bit words from MSB to host order
178 static void ConvertMSBToHost( void* buf, int num_words )
179 {
180  auto* ptr = static_cast<unsigned char*>(buf);
181  for ( int i=0; i < num_words; ++i )
182  {
183  unsigned char t = *ptr;
184  *ptr = *(ptr+1);
185  *(ptr+1) = t;
186  ptr += 2;
187  }
188 }
189 
190 // Convert the buffer of 16 bit words from host order to MSB
191 static void ConvertHostToMSB( void* buf, int num_words )
192 {
193  auto* ptr = static_cast<unsigned char*>(buf);
194  for ( int i=0; i < num_words; ++i )
195  {
196  unsigned char t = *ptr;
197  *ptr = *(ptr+1);
198  *(ptr+1) = t;
199  ptr += 2;
200  }
201 }
202 
203 #endif // VXL_LITTLE_ENDIAN
204 
205 
206 //: This method accepts any valid PNM file (first 3 bytes "P1\n" to "P6\n")
208 {
209  char temp;
210 
211  // Go to start of file
212  vs_->seek(0L);
213 
214  char buf[3];
215  if (3L > vs_->read(buf, 3L)) return false; // at end-of-file?
216  if (buf[0] != 'P') return false;
217  if (!isws(buf[2])) return false;
218  magic_ = buf[1] - '0';
219  if (magic_ < 1 || magic_ > 6) return false;
220 
221  // read 1 byte
222  vs_->read(&temp, 1L);
223 
224  // Skip over spaces and comments
225  SkipSpaces(vs_,temp);
226 
227  // Read in Width
228  ni_ = ReadInteger(vs_,temp);
229 
230  // Skip over spaces and comments
231  SkipSpaces(vs_,temp);
232 
233  // Read in Height
234  nj_ = ReadInteger(vs_,temp);
235 
236  // a pbm (bitmap) image does not have a maxval field
237  if (magic_ == 1 || magic_ == 4)
238  maxval_ = 1;
239  else
240  {
241  // Skip over spaces and comments
242  SkipSpaces(vs_,temp);
243 
244  // Read in Maxval
245  maxval_ = ReadInteger(vs_,temp);
246  }
247 
248  start_of_data_ = vs_->tell() - 1L;
249 
250  // Final end-of-line or other white space (1 byte) before the data section begins
251  if (isws(temp))
252  ++start_of_data_;
253 
254  ncomponents_ = ((magic_ == 3 || magic_ == 6) ? 3 : 1);
255 
256  if (magic_ == 1 || magic_ == 4) bits_per_component_ = 1;
257  else if (maxval_ == 0) assert(!"problem reading maxval from PNM file");
258  else if (maxval_ <= 0xFF) bits_per_component_ = 8;
259  else if (maxval_ <= 0xFFFF) bits_per_component_ = 16;
260  else if (maxval_ <= 0xFFFFFF) bits_per_component_ = 24;
261  else if (maxval_ <= 0x7FFFFFFF) bits_per_component_ = 32;
262  else assert(!"vil_pnm_image: maxval is too big");
263 
264  switch (magic_)
265  {
266  case 1: // pbm format
267  case 4:
269  break;
270  case 2: // pgm format
271  case 5:
272  case 3: // ppm format
273  case 6:
274  if (bits_per_component_ <= 8)
276  else if (bits_per_component_ <= 16)
278  else
280  break;
281  default: // this should never happen
282  break;
283  }
284 
285  return true;
286 }
287 
289 {
290  vs_->seek(0L);
291 
292  char buf[1024];
293  std::sprintf(buf, "P%d\n#vil pnm image, #c=%u, bpc=%u\n%u %u\n",
295  vs_->write(buf, std::strlen(buf));
296  if (magic_ != 1 && magic_ != 4)
297  {
298  std::sprintf(buf, "%lu\n", maxval_);
299  vs_->write(buf, std::strlen(buf));
300  }
301  start_of_data_ = vs_->tell();
302  return true;
303 }
304 
305 static bool operator>>(vil_stream& vs, int& a)
306 {
307  char c; vs.read(&c,1L);
308  SkipSpaces(&vs,c);
309  if (c < '0' || c > '9') return false; // non-digit found
310  a = ReadInteger(&vs,c);
311  return true;
312 }
313 
315  unsigned x0, unsigned ni, unsigned y0, unsigned nj) const
316 {
317  bool* bb = nullptr;
318  unsigned char* ib = nullptr;
319  unsigned short* jb = nullptr;
320  unsigned int* kb = nullptr;
321 
323 
324  if (bits_per_component_ == 1)
325  {
326  buf = new vil_memory_chunk(ni * nj* nplanes() * sizeof(bool),VIL_PIXEL_FORMAT_BOOL);
327  bb = reinterpret_cast<bool *>(buf->data());
328  }
329  else if (bits_per_component_ <= 8)
330  {
331  buf = new vil_memory_chunk(ni * nj* nplanes() * 1,VIL_PIXEL_FORMAT_BYTE);
332  ib = reinterpret_cast<vxl_byte*>(buf->data());
333  }
334  else if (bits_per_component_ <= 16)
335  {
337  jb = reinterpret_cast<vxl_uint_16*>(buf->data());
338  }
339  else
340  {
342  kb = reinterpret_cast<vxl_uint_32*>(buf->data());
343  }
344 
345  if (magic_ > 4) // pgm or ppm raw image
346  {
347  unsigned bytes_per_sample = (bits_per_component_+7)/8;
348  unsigned bytes_per_pixel = nplanes() * bytes_per_sample;
349  vil_streampos byte_start = start_of_data_ + (y0 * ni_ + x0) * bytes_per_pixel;
350  unsigned byte_width = ni_ * bytes_per_pixel;
351  unsigned byte_out_width = ni * bytes_per_pixel;
352 
353  for (unsigned y = 0; y < nj; ++y)
354  {
355  vs_->seek(byte_start);
356  vs_->read((unsigned char *)buf->data() + y * byte_out_width, byte_out_width);
357  byte_start += byte_width;
358  }
359  if ( bytes_per_sample > 2 )
360  {
361  std::cerr << "ERROR: pnm: reading rawbits format with > 16bit samples\n";
362  return nullptr;
363  }
364 #if VXL_LITTLE_ENDIAN
365  else if ( bytes_per_sample==2 )
366  ConvertMSBToHost( reinterpret_cast<unsigned char *>(buf->data()), ni*nj*nplanes() );
367 #endif
368 #if 0 // see comment below
369  if (ncomponents_ == 1) {
370 #endif
371  if (bits_per_component_ <= 1)
372  return new vil_image_view<bool>(buf, bb, ni, nj, nplanes(), nplanes(), ni*nplanes(), 1);
373  if (bits_per_component_ <= 8)
374  return new vil_image_view<vxl_byte>(buf, ib, ni, nj, nplanes(), nplanes(), ni*nplanes(), 1);
375  else if (bits_per_component_ <= 16)
376  return new vil_image_view<vxl_uint_16>(buf, jb, ni, nj, nplanes(), nplanes(), ni*nplanes(), 1);
377  else
378  return new vil_image_view<vxl_uint_32>(buf, kb, ni, nj, nplanes(), nplanes(), ni*nplanes(), 1);
379 #if 0 // never return vil_image_view<vil_rgb<T> > : default image representation is planar
380  }
381  else if (ncomponents_ == 3) {
382  if (bits_per_component_ <= 8)
383  return new vil_image_view<vil_rgb<vxl_byte> >(buf, (vil_rgb<vxl_byte>*)ib, ni, nj, 1, 1, ni, 1);
384  else if (bits_per_component_ <= 16)
385  return new vil_image_view<vil_rgb<vxl_uint_16> >(buf, (vil_rgb<vxl_uint_16>*)jb, ni, nj, 1, 1, ni, 1);
386  else
387  return new vil_image_view<vil_rgb<vxl_uint_32> >(buf, (vil_rgb<vxl_uint_32>*)kb, ni, nj, 1, 1, ni, 1);
388  }
389  else return 0;
390 #endif // 0
391  }
392  else if (magic_ == 4) // pbm (bitmap) raw image
393  {
394  unsigned byte_width = (ni_+7)/8;
395 
396  for (unsigned y = 0; y < nj; ++y)
397  {
398  vil_streampos byte_start = start_of_data_ + (y0+y) * byte_width + x0/8;
399  vs_->seek(byte_start);
400  unsigned char a; vs_->read(&a, 1L);
401  for (unsigned x = 0; x < ni+x0; ++x)
402  {
403  if ( x >= x0 )
404  bb[y * ni + x-x0] = (a & 0x80) != 0;
405  a <<= 1;
406  if (x%8 == 7)
407  vs_->read(&a, 1L);
408  }
409  }
410  assert (buf->size() == ni*nj*sizeof(bool));
411  return new vil_image_view<bool>(buf, bb, ni, nj, 1, 1, ni, ni*nj);
412  }
413  else // ascii (non-raw) image data
414  {
416  // 0. Skip to the starting line
417  //
418  for (unsigned t = 0; t < y0*ni_*nplanes(); ++t) { int a; (*vs_) >> a; }
419  for (unsigned y = 0; y < nj; ++y)
420  {
421  // 1. Skip to column x0
422  for (unsigned t = 0; t < x0*nplanes(); ++t) { int a; (*vs_) >> a; }
423  for (unsigned x = 0; x < ni; ++x)
424  {
425  // 3. Read the data
426  if (bits_per_component_ <= 1)
427  for (unsigned p = 0; p < nplanes(); ++p) { int a; (*vs_) >> a; *(bb++)=(a!=0); }
428  else if (bits_per_component_ <= 8)
429  for (unsigned p = 0; p < nplanes(); ++p) { int a; (*vs_) >> a; *(ib++)=vxl_byte(a); }
430  else if (bits_per_component_ <= 16)
431  for (unsigned p = 0; p < nplanes(); ++p) { int a; (*vs_) >> a; *(jb++)=vxl_uint_16(a); }
432  else
433  for (unsigned p = 0; p < nplanes(); ++p) { int a; (*vs_) >> a; *(kb++)=vxl_uint_32(a); }
434  }
435  // 5. Skip to the next line
436  for (unsigned t = 0; t < (ni_-x0-ni)*nplanes(); ++t) { int a; (*vs_) >> a; }
437  }
438 #if 0 // see comment below
439  if (ncomponents_ == 1)
440  {
441 #endif
442  if (bits_per_component_ <= 1)
443  return new vil_image_view<bool>(buf, reinterpret_cast<bool*>(buf->data()), ni, nj, nplanes(), nplanes(), ni*nplanes(), 1);
444  if (bits_per_component_ <= 8)
445  return new vil_image_view<vxl_byte>(buf,reinterpret_cast<vxl_byte*>(buf->data()),ni,nj,nplanes(),nplanes(),ni*nplanes(),1);
446  else if (bits_per_component_ <= 16)
447  return new
448  vil_image_view<vxl_uint_16>(buf,reinterpret_cast<vxl_uint_16*>(buf->data()),ni,nj,nplanes(),nplanes(),ni*nplanes(),1);
449  else
450  return new
451  vil_image_view<vxl_uint_32>(buf,reinterpret_cast<vxl_uint_32*>(buf->data()),ni,nj,nplanes(),nplanes(),ni*nplanes(),1);
452 #if 0 // never return vil_image_view<vil_rgb<T> > : default image representation is planar
453  }
454  else if (ncomponents_ == 3)
455  {
456  if (bits_per_component_ <= 8)
457  return new vil_image_view<vil_rgb<vxl_byte> >(buf, reinterpret_cast<vil_rgb<vxl_byte>*>(buf->data()), ni,nj,1, 1,ni,1);
458  else if (bits_per_component_ <= 16)
459  return new vil_image_view<vil_rgb<vxl_uint_16> >(buf,reinterpret_cast<vil_rgb<vxl_uint_16>*>(buf->data()),ni,nj,1,1,ni,1);
460  else
461  return new vil_image_view<vil_rgb<vxl_uint_32> >(buf,reinterpret_cast<vil_rgb<vxl_uint_32>*>(buf->data()),ni,nj,1,1,ni,1);
462  }
463  else return 0;
464 #endif // 0
465  }
466 }
467 
468 
469 static void operator<<(vil_stream& vs, int a)
470 {
471  char buf[128]; std::sprintf(buf, " %d\n", a); vs.write(buf,std::strlen(buf));
472 }
473 
475  unsigned x0, unsigned y0)
476 {
477  if (!view_fits(view, x0, y0))
478  {
479  vil_exception_warning(vil_exception_out_of_bounds("vil_pnm_image::put_view"));
480  return false;
481  }
482 
492  {
493  std::cerr << "ERROR: " << __FILE__ << ":\n Can't fit view into pnm component size\n";
494  return false;
495  }
496 
497  const vil_image_view<bool>* bb=nullptr;
498  const vil_image_view<vxl_byte>* ob = nullptr;
499  const vil_image_view<vxl_uint_16>* pb = nullptr;
500  const vil_image_view<vxl_uint_32>* qb = nullptr;
501 
502  if (view.pixel_format() == VIL_PIXEL_FORMAT_BOOL)
503  bb = &static_cast<const vil_image_view<bool>& >(view);
504  else if (view.pixel_format() == VIL_PIXEL_FORMAT_BYTE)
505  ob = &static_cast<const vil_image_view<vxl_byte>& >(view);
506  else if (view.pixel_format() == VIL_PIXEL_FORMAT_UINT_16)
507  pb = &static_cast<const vil_image_view<vxl_uint_16>& >(view);
508  else if (view.pixel_format() == VIL_PIXEL_FORMAT_UINT_32)
509  qb = &static_cast<const vil_image_view<vxl_uint_32>& >(view);
510  else
511  {
512  std::cerr << "ERROR: " << __FILE__ << ":\n Do not support putting "
513  << view.is_a() << " views into pnm image_resource objects\n";
514  return false;
515  }
516 
517  if (magic_ == 5) // pgm raw image ==> nplanes() == 1
518  {
519  unsigned bytes_per_sample = (bits_per_component_+7)/8;
520  unsigned bytes_per_pixel = bytes_per_sample;
521  vil_streampos byte_start = start_of_data_ + (y0 * ni_ + x0) * bytes_per_pixel;
522  unsigned byte_width = ni_ * bytes_per_pixel;
523  unsigned byte_out_width = view.ni() * bytes_per_pixel;
524 
525  if ( bytes_per_sample==1 )
526  {
527  assert(ob!=nullptr);
528  for (unsigned y = 0; y < view.nj(); ++y)
529  {
530  vs_->seek(byte_start);
531  vs_->write(ob->top_left_ptr() + y * ob->jstep(), byte_out_width);
532  byte_start += byte_width;
533  }
534  }
535  else if ( bytes_per_sample==2 && VXL_BIG_ENDIAN )
536  {
537  assert(pb!=nullptr);
538  for (unsigned y = 0; y < view.nj(); ++y)
539  {
540  vs_->seek(byte_start);
541  vs_->write(pb->top_left_ptr() + y * pb->jstep(), byte_out_width);
542  byte_start += byte_width;
543  }
544  }
545  else if ( bytes_per_sample==2 )
546  {
547  // Little endian host; must convert words to have MSB first.
548  //
549  // Convert line by line to avoid duplicating a potentially large image.
550  std::vector<vxl_byte> tempbuf(byte_out_width);
551  assert(pb!=nullptr);
552  for (unsigned y = 0; y < view.nj(); ++y)
553  {
554  vs_->seek(byte_start);
555  std::memcpy(&tempbuf[0], pb->top_left_ptr() + y * pb->jstep(), byte_out_width);
556 #if VXL_LITTLE_ENDIAN
557  ConvertHostToMSB(&tempbuf[0], view.ni());
558 #endif
559  vs_->write(&tempbuf[0], byte_out_width);
560  byte_start += byte_width;
561  }
562  }
563  else { // This should never occur...
564  std::cerr << "ERROR: pgm: writing rawbits format with > 16bit samples\n";
565  return false;
566  }
567  }
568  else if (magic_ == 6) // ppm raw image; cannot be written as efficiently as pgm
569  {
570  unsigned bytes_per_sample = (bits_per_component_+7)/8;
571  unsigned bytes_per_pixel = nplanes() * bytes_per_sample;
572  vil_streampos byte_start = start_of_data_ + (y0 * ni_ + x0) * bytes_per_pixel;
573  unsigned byte_width = ni_ * bytes_per_pixel;
574 
575  if ( bytes_per_sample==1 )
576  {
577  assert(ob!=nullptr);
578 
579  // capes_at_robots - Modified to write a scan-line at once. Writing single bytes
580  // to disk was extremely slow.
581  std::vector<vxl_byte> scanline( byte_width );
582 
583  for (unsigned y = 0; y < view.nj(); ++y)
584  {
585  vs_->seek(byte_start);
586  for (unsigned x = 0, c = 0; x < view.ni(); ++x)
587  for (unsigned p = 0; p < ncomponents_; ++p, ++c)
588  scanline[c] = (*ob)(x,y,p);
589  vs_->write(&scanline[0], byte_width);
590  byte_start += byte_width;
591  }
592  }
593  else if ( bytes_per_sample==2 )
594  {
595  assert(pb!=nullptr);
596  for (unsigned y = y0; y < view.nj(); ++y)
597  {
598  vs_->seek(byte_start);
599  for (unsigned x = x0; x < view.ni(); ++x)
600  {
601  vxl_uint_16 tempbuf[3];
602  for (unsigned p = 0; p < ncomponents_; ++p)
603  tempbuf[p] = (*pb)(x,y,p);
604 #if VXL_LITTLE_ENDIAN
605  ConvertHostToMSB(tempbuf, ncomponents_);
606 #endif
607  vs_->write(tempbuf, bytes_per_pixel);
608  }
609  byte_start += byte_width;
610  }
611  }
612  else { // This should never occur...
613  std::cerr << "ERROR: pgm: writing rawbits format with > 16bit samples\n";
614  return false;
615  }
616  }
617  else if (magic_ == 4) // pbm (bitmap) raw image
618  {
619  int byte_width = (ni_+7)/8;
620 
621  assert(bb!=nullptr);
622  for (unsigned y = 0; y < view.nj(); ++y)
623  {
624  vil_streampos byte_start = start_of_data_ + (y0+y) * byte_width + x0/8;
625  int s = x0&7; // = x0%8;
626  unsigned char a = 0;
627  if (s)
628  {
629  vs_->read(&a, 1L);
630  vs_->seek(byte_start);
631  a &= ((1<<s)-1)<<(8-s); // clear the last 8-s bits of a
632  }
633  for (unsigned x = 0; x < view.ni(); ++x)
634  {
635  if ((*bb)(x,y)) a |= 1<<(7-s); // single bit; high bit = first
636  if (s >= 7) { vs_->write(&a, 1L); ++byte_start; s = 0; a = 0; }
637  else ++s;
638  }
639  if (s)
640  {
641  if (x0+view.ni() < ni_)
642  {
643  vs_->seek(byte_start);
644  unsigned char c; vs_->read(&c, 1L);
645  vs_->seek(byte_start);
646  c &= ((1<<(8-s))-1); // clear the first s bits of c
647  a |= c;
648  }
649  vs_->write(&a, 1L);
650  }
651  }
652  }
653  else // ascii (non-raw) image data
654  {
655  if (x0 > 0 || y0 > 0 || view.ni() < ni_ || view.nj() < nj_)
656  return false; // can only write the full image in this mode
658  for (unsigned y = 0; y < view.nj(); ++y)
659  for (unsigned x = 0; x < view.ni(); ++x)
660  for (unsigned p = 0; p < ncomponents_; ++p)
661  {
662  if (bits_per_component_ <= 1) (*vs_) << (*bb)(x,y,p);
663  else if (bits_per_component_ <= 8) (*vs_) << (*ob)(x,y,p);
664  else if (bits_per_component_ <= 16) (*vs_) << (*pb)(x,y,p);
665  else (*vs_) << (*qb)(x,y,p);
666  }
667  }
668 
669  return true;
670 }
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
vil_pixel_format
Describes the type of the concrete data.
vil_pixel_format vil_pixel_format_component_format(enum vil_pixel_format f)
Return the number of components in pixel format f.
unsigned bits_per_component_
Definition: vil_pnm.h:68
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
Definition: vil_pnm.cxx:30
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.
Definition: vil_pnm.cxx:80
unsigned ni_
Definition: vil_pnm.h:62
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_
Definition: vil_pnm.h:66
bool write_header()
Definition: vil_pnm.cxx:288
virtual void seek(vil_streampos position)=0
Goto file pointer.
unsigned nj_
Definition: vil_pnm.h:63
char const * file_format() const override
Return a string describing the file format.
Definition: vil_pnm.cxx:92
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.
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 read_header()
This method accepts any valid PNM file (first 3 bytes "P1\n" to "P6\n").
Definition: vil_pnm.cxx:207
#define vil_property_quantisation_depth
The quantisation depth of pixel components.
Definition: vil_property.h:67
vil_image_resource_sptr make_output_image(vil_stream *vs, unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format) override
Make a "generic_image" on which put_section may be applied.
Definition: vil_pnm.cxx:57
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
int magic_
Definition: vil_pnm.h:61
unsigned nplanes() const override
Dimensions: Planes x ni x nj.
Definition: vil_pnm.h:87
unsigned ncomponents_
Definition: vil_pnm.h:67
unsigned ni() const
Width.
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
unsigned ni() const override
Dimensions: Planes x ni x nj.
Definition: vil_pnm.h:88
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.
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_pnm.cxx:42
Generic image implementation for PNM files.
Definition: vil_pnm.h:58
char const * tag() const override
Return a character string which uniquely identifies this format.
Definition: vil_pnm.cxx:66
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.
There is no class or function called vil_property.
unsigned long int maxval_
Definition: vil_pnm.h:64
Ref. counted block of data on the heap.
vil_pnm_image(vil_stream *is, unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format)
Definition: vil_pnm.cxx:97
vil_pixel_format format_
Describe the format of each pixel.
Definition: vil_pnm.h:71
void unref()
Definition: vil_stream.cxx:31
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.
Definition: vil_pnm.cxx:474
std::ostream & operator<<(std::ostream &s, const vnl_amoeba_SimplexCorner &simplex)
vxl_int_32 vil_streampos
Definition: vil_stream.h:16
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
Definition: vil_exception.h:37
Representation of a generic image source or destination.
vil_stream * vs_
Definition: vil_pnm.h:60
unsigned nj() const override
Dimensions: Planes x ni x nj.
Definition: vil_pnm.h:89
char const * tag() const override
Return a character string which uniquely identifies this format.
Definition: vil_png.cxx:75
This is the appropriate pixel type for 24-bit colour images.
Definition: vil_fwd.h:14
~vil_pnm_image() override
Definition: vil_pnm.cxx:145