YARP
Yet Another Robot Platform
ImageFile.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <yarp/sig/ImageFile.h>
11 #include <yarp/os/LogComponent.h>
12 #include <yarp/os/LogStream.h>
13 
14 #include <cstdio>
15 #include <cstring>
16 #include <cstdlib>
17 
18 #if YARP_HAS_JPEG_C
19 #include "jpeglib.h"
20 #endif
21 
22 #if defined (YARP_HAS_PNG)
23 #include <png.h>
24 #endif
25 
26 using namespace std;
27 using namespace yarp::os;
28 using namespace yarp::sig;
29 
30 namespace {
31 YARP_LOG_COMPONENT(IMAGEFILE, "yarp.sig.ImageFile")
32 }
33 
34 
36 // private read methods for PNG Files
38 static bool ImageReadRGB_PNG(ImageOf<PixelRgb>& img, const char* filename)
39 {
40 #if defined (YARP_HAS_PNG)
41  FILE* fp = fopen(filename, "rb");
42 
43  png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
44  if (!png)
45  {
46  yCError(IMAGEFILE) << "PNG internal error";
47  return false;
48  }
49 
50  png_infop info = png_create_info_struct(png);
51  if (!info)
52  {
53  yCError(IMAGEFILE) << "PNG internal error";
54  return false;
55  }
56 
57  if (setjmp(png_jmpbuf(png)))
58  {
59  yCError(IMAGEFILE) << "PNG internal error";
60  return false;
61  }
62 
63  png_init_io(png, fp);
64 
65  png_read_info(png, info);
66 
67  int width = png_get_image_width(png, info);
68  int height = png_get_image_height(png, info);
69  png_byte color_type = png_get_color_type(png, info);
70  png_byte bit_depth = png_get_bit_depth(png, info);
71 
72  // Read any color_type into 8bit depth, RGBA format.
73  // See http://www.libpng.org/pub/png/libpng-manual.txt
74 
75  if (bit_depth == 16)
76  png_set_strip_16(png);
77 
78  if (color_type == PNG_COLOR_TYPE_PALETTE)
79  png_set_palette_to_rgb(png);
80 
81  // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
82  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
83  png_set_expand_gray_1_2_4_to_8(png);
84 
85  if (png_get_valid(png, info, PNG_INFO_tRNS))
86  png_set_tRNS_to_alpha(png);
87 
88  // These color_type don't have an alpha channel then fill it with 0xff.
89  if (color_type == PNG_COLOR_TYPE_RGB ||
90  color_type == PNG_COLOR_TYPE_GRAY ||
91  color_type == PNG_COLOR_TYPE_PALETTE)
92  png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
93 
94  if (color_type == PNG_COLOR_TYPE_GRAY ||
95  color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96  png_set_gray_to_rgb(png);
97 
98  png_read_update_info(png, info);
99 
100  png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
101  for (int y = 0; y < height; y++)
102  {
103  row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
104  }
105 
106  png_read_image(png, row_pointers);
107  fclose(fp);
108 
109  img.resize(width,height);
110  for (int y = 0; y < height; y++)
111  {
112  png_bytep row = row_pointers[y];
113  for (int x = 0; x < width; x++)
114  {
115  png_bytep px = &(row[x * 4]);
116  unsigned char* address = img.getPixelAddress(x,y);
117  address[0] = px[0];
118  address[1] = px[1];
119  address[2] = px[2];
120  }
121  }
122 
123  png_destroy_read_struct(&png, &info, NULL);
124  for (int y = 0; y < height; y++)
125  {
126  free(row_pointers[y]);
127  }
128  free(row_pointers);
129  return true;
130 #else
131  yCError(IMAGEFILE) << "PNG library not available/not found";
132  return false;
133 #endif
134 }
135 
136 static bool ImageReadFloat_PNG(ImageOf<PixelFloat>& dest, const std::string& filename)
137 {
138 #if defined (YARP_HAS_PNG)
139  yCError(IMAGEFILE) << "Not yet implemented";
140  return false;
141 #else
142  yCError(IMAGEFILE) << "PNG library not available/not found";
143  return false;
144 #endif
145 }
146 
147 static bool ImageReadBGR_PNG(ImageOf<PixelBgr>& img, const char* filename)
148 {
149 #if defined (YARP_HAS_PNG)
150  yCError(IMAGEFILE) << "Not yet implemented";
151  return false;
152 #else
153  yCError(IMAGEFILE) << "PNG library not available/not found";
154  return false;
155 #endif
156 }
157 
158 static bool ImageReadMono_PNG(ImageOf<PixelMono>& img, const char* filename)
159 {
160 #if defined (YARP_HAS_PNG)
161  yCError(IMAGEFILE) << "Not yet implemented";
162  return false;
163 #else
164  yCError(IMAGEFILE) << "PNG library not available/not found";
165  return false;
166 #endif
167 }
168 
170 // private read methods for PGM/PPM Files
172 
173 static bool ReadHeader_PxM(FILE *fp, int *height, int *width, int *color)
174 {
175  char ch;
176  int maxval;
177 
178  *color = 0;
179 
181  if (fscanf(fp, "P%c\n", &ch) != 1 || (ch!='6'&&ch!='5'))
182  {
183  yCWarning(IMAGEFILE, "file is not in pgm/ppm raw format; cannot read");
184  return false;
185  }
186 
187  if (ch=='6') *color = 1;
188 
189  // skip comments
190  ch = fgetc(fp);
191  while (ch == '#')
192  {
193  do
194  {
195  ch = fgetc(fp);
196  }
197  while (ch != '\n');
198  ch = fgetc(fp);
199  }
200  ungetc(ch, fp);
201 
203  int n=fscanf(fp, "%d%d%d", width, height, &maxval);
204  if (n!=3)
205  return false;
206 
207  fgetc(fp);
208  if (maxval != 255)
209  {
210  //die("image is not true-color (24 bit); read failed");
211  yCWarning(IMAGEFILE, "image is not true-color (24 bit); read failed");
212  return false;
213  }
214 
215  return true;
216 }
217 
218 
219 static bool ImageReadRGB_PxM(ImageOf<PixelRgb> &img, const char *filename)
220 {
221  int width, height, color, num;
222  FILE *fp=nullptr;
223  fp = fopen(filename, "rb");
224 
225  if(fp==nullptr)
226  {
227  yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
228  return false;
229  }
230 
231  if (!ReadHeader_PxM(fp, &height, &width, &color))
232  {
233  fclose (fp);
234  yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
235  return false;
236  }
237 
238  if (!color)
239  {
240  ImageOf<PixelMono> tmp;
241  tmp.resize(width,height);
242 
243  const int w = tmp.width() * tmp.getPixelSize();
244  const int h = tmp.height();
245  const int pad = tmp.getRowSize();
246  unsigned char *dst = tmp.getRawImage ();
247 
248  num = 0;
249  for (int i = 0; i < h; i++)
250  {
251  num += (int)fread((void *) dst, 1, (size_t) w, fp);
252  dst += pad;
253  }
254  fclose(fp);
255  img.copy(tmp);
256  return true;
257  }
258 
259  img.resize(width,height);
260 
261  const int w = img.width() * img.getPixelSize();
262  const int h = img.height();
263  const int pad = img.getRowSize();
264  unsigned char *dst = img.getRawImage ();
265 
266  num = 0;
267  for (int i = 0; i < h; i++)
268  {
269  num += (int)fread((void *) dst, 1, (size_t) w, fp);
270  dst += pad;
271  }
272 
273  fclose(fp);
274 
275  return true;
276 }
277 
278 static bool ImageReadFloat_PxM(ImageOf<PixelFloat>& dest, const std::string& filename)
279 {
280  FILE *fp = fopen(filename.c_str(), "rb");
281  if (fp == nullptr) {
282  return false;
283  }
284 
285  size_t br = 0;
286  size_t size_ = sizeof(float);
287  size_t count_ = 0;
288 
289  size_t dims[2];
290  if (fread(dims, sizeof(dims), 1, fp) > 0)
291  {
292  count_ = (size_t)(dims[0] * dims[1]);
293  dest.resize(dims[0], dims[1]);
294  br = fread(&dest(0, 0), size_, count_, fp);
295  }
296 
297  fclose(fp);
298  return (br > 0);
299 }
300 
301 static bool ImageReadBGR_PxM(ImageOf<PixelBgr> &img, const char *filename)
302 {
303  int width, height, color, num;
304  FILE *fp=nullptr;
305  fp = fopen(filename, "rb");
306 
307  if(fp==nullptr)
308  {
309  yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
310  return false;
311  }
312 
313  if (!ReadHeader_PxM(fp, &height, &width, &color))
314  {
315  fclose (fp);
316  yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
317  return false;
318  }
319 
320  if (!color)
321  {
322  fclose(fp);
323  yCError(IMAGEFILE, "File is grayscale, conversion not yet supported\n");
324  return false;
325  }
326 
327  ImageOf<PixelRgb> tmpImg;
328  tmpImg.resize(width, height);
329 
330  const int w = tmpImg.width() * img.getPixelSize();
331  const int h = tmpImg.height();
332  const int pad = tmpImg.getRowSize();
333  unsigned char *dst = tmpImg.getRawImage ();
334 
335  num = 0;
336  for (int i = 0; i < h; i++)
337  {
338  num += (int)fread((void *) dst, 1, (size_t) w, fp);
339  dst += pad;
340  }
341 
342  fclose(fp);
343 
344  return img.copy(tmpImg);
345 }
346 
347 
348 static bool ImageReadMono_PxM(ImageOf<PixelMono> &img, const char *filename)
349 {
350  int width, height, color, num;
351  FILE *fp=nullptr;
352  fp = fopen(filename, "rb");
353 
354  if(fp==nullptr)
355  {
356  yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
357  return false;
358  }
359 
360  if (!ReadHeader_PxM(fp, &height, &width, &color))
361  {
362  fclose (fp);
363  yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
364  return false;
365  }
366 
367  if (color)
368  {
369  fclose(fp);
370  yCError(IMAGEFILE, "File is color, conversion not yet supported\n");
371  return false;
372  }
373 
374  img.resize(width,height);
375 
376  const int w = img.width() * img.getPixelSize();
377  const int h = img.height();
378  const int pad = img.getRowSize();
379  unsigned char *dst = img.getRawImage ();
380 
381  num = 0;
382  for (int i = 0; i < h; i++)
383  {
384  num += (int)fread((void *) dst, 1, (size_t) w, fp);
385  dst += pad;
386  }
387 
388  fclose(fp);
389 
390  return true;
391 }
392 
394 // private write methods
396 
397 #if defined (YARP_HAS_PNG)
398 static bool SavePNG(char *src, const char *filename, size_t h, size_t w, size_t rowSize, png_byte color_type, png_byte bit_depth)
399 {
400  // create file
401  if (src == nullptr)
402  {
403  yCError(IMAGEFILE, "[write_png_file] Cannot write to file a nullptr image");
404  return false;
405  }
406 
407  if (filename == nullptr)
408  {
409  yCError(IMAGEFILE, "[write_png_file] Filename is nullptr");
410  return false;
411  }
412 
413  FILE *fp = fopen(filename, "wb");
414  if (!fp)
415  {
416  yCError(IMAGEFILE, "[write_png_file] File %s could not be opened for writing", filename);
417  return false;
418  }
419 
420  // initialize stuff
421  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
422  if (!png_ptr)
423  {
424  yCError(IMAGEFILE, "[write_png_file] png_create_write_struct failed");
425  fclose(fp);
426  return false;
427  }
428 
429  png_infop info_ptr = png_create_info_struct(png_ptr);
430  if (!info_ptr)
431  {
432  yCError(IMAGEFILE, "[write_png_file] png_create_info_struct failed");
433  fclose(fp);
434  return false;
435  }
436 
437  png_bytep * row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * h);
438  for (size_t y = 0; y < h; y++)
439  {
440  row_pointers[y] = (png_bytep)(src)+y*w;
441  }
442 
443  if (setjmp(png_jmpbuf(png_ptr)))
444  {
445  yCError(IMAGEFILE, "[write_png_file] Error during init_io");
446  free(row_pointers);
447  fclose(fp);
448  return false;
449  }
450  png_init_io(png_ptr, fp);
451 
452 
453  // write header
454  if (setjmp(png_jmpbuf(png_ptr)))
455  {
456  yCError(IMAGEFILE, "[write_png_file] Error during writing header");
457  free(row_pointers);
458  return false;
459  }
460  png_set_IHDR(png_ptr, info_ptr, w, h,
461  bit_depth, color_type, PNG_INTERLACE_NONE,
462  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
463 
464  png_write_info(png_ptr, info_ptr);
465 
466 
467  // write bytes
468  if (setjmp(png_jmpbuf(png_ptr)))
469  {
470  yCError(IMAGEFILE, "[write_png_file] Error during writing bytes");
471  free(row_pointers);
472  fclose(fp);
473  return false;
474  }
475  png_write_image(png_ptr, row_pointers);
476 
477 
478  // end write
479  if (setjmp(png_jmpbuf(png_ptr)))
480  {
481  yCError(IMAGEFILE, "[write_png_file] Error during end of write");
482  free(row_pointers);
483  fclose(fp);
484  return false;
485  }
486  png_write_end(png_ptr, NULL);
487 
488  // cleanup heap allocation
489  free(row_pointers);
490 
491  fclose(fp);
492  return true;
493 }
494 #endif
495 
496 static bool SaveJPG(char *src, const char *filename, int h, int w, int rowSize)
497 {
498 #if YARP_HAS_JPEG_C
499  int quality = 100;
500  struct jpeg_compress_struct cinfo;
501  struct jpeg_error_mgr jerr;
502  FILE * outfile;
503  JSAMPROW row_pointer[1];
504  int row_stride;
505 
506  cinfo.err = jpeg_std_error(&jerr);
507  jpeg_create_compress(&cinfo);
508 
509  if ((outfile = fopen(filename, "wb")) == nullptr)
510  {
511  yCError(IMAGEFILE, "can't write file: %s\n", filename);
512  return false;
513  }
514  jpeg_stdio_dest(&cinfo, outfile);
515 
516  cinfo.image_width = w;
517  cinfo.image_height = h;
518  cinfo.input_components = 3;
519  cinfo.in_color_space = JCS_RGB;
520  jpeg_set_defaults(&cinfo);
521  jpeg_set_quality(&cinfo, quality, TRUE);
522 
523  jpeg_start_compress(&cinfo, TRUE);
524 
525  row_stride = w * 3;
526 
527  while (cinfo.next_scanline < cinfo.image_height)
528  {
529  row_pointer[0] = (JSAMPROW)&src[cinfo.next_scanline * row_stride];
530  (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
531  }
532 
533  jpeg_finish_compress(&cinfo);
534  fclose(outfile);
535  jpeg_destroy_compress(&cinfo);
536  return true;
537 #else
538  yCError(IMAGEFILE) << "libjpeg not installed";
539  return false;
540 #endif
541 }
542 
543 static bool SavePGM(char *src, const char *filename, int h, int w, int rowSize)
544 {
545  FILE *fp = fopen(filename, "wb");
546  if (!fp)
547  {
548  yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
549  return false;
550  }
551  else
552  {
553  const int inc = rowSize;
554 
555  fprintf(fp, "P5\n%d %d\n%d\n", w, h, 255);
556  for (int i = 0; i < h; i++)
557  {
558  fwrite((void *)src, 1, (size_t)w, fp);
559  src += inc;
560  }
561 
562  fclose(fp);
563  }
564 
565  return true;
566 }
567 
568 
569 static bool SavePPM(char *src, const char *filename, int h, int w, int rowSize)
570 {
571  FILE *fp = fopen(filename, "wb");
572  if (!fp)
573  {
574  yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
575  return false;
576  }
577  else
578  {
579  const int inc = rowSize;//YARPSimpleOperation::ComputePadding (w*3, YarpImageAlign) + w * 3;
580 
581  fprintf(fp, "P6\n%d %d\n%d\n", w, h, 255);
582  for (int i = 0; i < h; i++)
583  {
584  fwrite((void *)src, 1, (size_t)(w * 3), fp);
585  src += inc;
586  }
587 
589  fclose(fp);
590  }
591 
592  return true;
593 }
594 
595 static bool ImageWriteJPG(ImageOf<PixelRgb>& img, const char *filename)
596 {
597  return SaveJPG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
598 }
599 
600 static bool ImageWritePNG(ImageOf<PixelRgb>& img, const char *filename)
601 {
602 #if defined (YARP_HAS_PNG)
603  return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_RGB, 24);
604 #else
605  yCError(IMAGEFILE) << "YARP was not built with png support";
606  return false;
607 #endif
608 }
609 
610 static bool ImageWritePNG(ImageOf<PixelMono>& img, const char *filename)
611 {
612 #if defined (YARP_HAS_PNG)
613  return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_GRAY, 8);
614 #else
615  yCError(IMAGEFILE) << "YARP was not built with png support";
616  return false;
617 #endif
618 }
619 
620 static bool ImageWriteRGB(ImageOf<PixelRgb>& img, const char *filename)
621 {
622  return SavePPM((char*)img.getRawImage(),filename,img.height(),img.width(),img.getRowSize());
623 }
624 
625 static bool ImageWriteMono(ImageOf<PixelMono>& img, const char *filename)
626 {
627  return SavePGM((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
628 }
629 
630 static bool ImageWriteFloat(ImageOf<PixelFloat>& img, const char *filename)
631 {
632  FILE *fp = fopen(filename, "wb");
633  if (fp == nullptr)
634  {
635  return false;
636  }
637 
638  size_t dims[2] = { img.width(), img.height() };
639 
640  size_t bw = 0;
641  size_t size_ = sizeof(float);
642  auto count_ = (size_t)(dims[0] * dims[1]);
643 
644  if (fwrite(dims, sizeof(dims), 1, fp) > 0) {
645  bw = fwrite(&img(0, 0), size_, count_, fp);
646  }
647 
648  fclose(fp);
649  return (bw > 0);
650 }
651 
653 // public read methods
655 
656 bool file::read(ImageOf<PixelRgb> & dest, const std::string& src, image_fileformat format)
657 {
658  const char* file_ext = strrchr(src.c_str(), '.');
659  if (strcmp(file_ext, ".pgm")==0 ||
660  strcmp(file_ext, ".ppm")==0 ||
661  format == FORMAT_PGM ||
662  format == FORMAT_PPM)
663  {
664  return ImageReadRGB_PxM(dest,src.c_str());
665  }
666  else if(strcmp(file_ext, ".png")==0 ||
667  format == FORMAT_PNG)
668  {
669  return ImageReadRGB_PNG(dest, src.c_str());
670  }
671  else if(strcmp(file_ext, ".jpg") == 0 ||
672  strcmp(file_ext, ".jpeg") == 0 ||
673  format == FORMAT_JPG)
674  {
675  yCError(IMAGEFILE) << "jpeg not yet implemented";
676  return false;
677  }
678  yCError(IMAGEFILE) << "unsupported file format";
679  return false;
680 }
681 
682 
683 bool file::read(ImageOf<PixelBgr> & dest, const std::string& src, image_fileformat format)
684 {
685  const char* file_ext = strrchr(src.c_str(), '.');
686  if (strcmp(file_ext, ".pgm") == 0 ||
687  strcmp(file_ext, ".ppm") == 0 ||
688  format == FORMAT_PGM ||
689  format == FORMAT_PPM)
690  {
691  return ImageReadBGR_PxM(dest, src.c_str());
692  }
693  else if (strcmp(file_ext, ".png") == 0 ||
694  format == FORMAT_PNG)
695  {
696  return ImageReadBGR_PNG(dest, src.c_str());
697  }
698  else if (strcmp(file_ext, ".jpg") == 0 ||
699  strcmp(file_ext, ".jpeg") == 0 ||
700  format == FORMAT_JPG)
701  {
702  yCError(IMAGEFILE) << "jpeg not yet implemented";
703  return false;
704  }
705  yCError(IMAGEFILE) << "unsupported file format";
706  return false;
707 }
708 
709 
710 bool file::read(ImageOf<PixelRgba> & dest, const std::string& src, image_fileformat format)
711 {
712  const char* file_ext = strrchr(src.c_str(), '.');
713  if (strcmp(file_ext, ".pgm") == 0 ||
714  strcmp(file_ext, ".ppm") == 0 ||
715  format == FORMAT_PGM ||
716  format == FORMAT_PPM)
717  {
718  ImageOf<PixelRgb> img2;
719  bool ok = ImageReadRGB_PxM(img2, src.c_str());
720  if (ok)
721  {
722  dest.copy(img2);
723  }
724  return ok;
725  }
726  else if (strcmp(file_ext, ".png") == 0 ||
727  format == FORMAT_PNG)
728  {
729  ImageOf<PixelRgb> img2;
730  bool ok = ImageReadRGB_PNG(img2, src.c_str());
731  if (ok)
732  {
733  dest.copy(img2);
734  }
735  return ok;
736  }
737  else if (strcmp(file_ext, ".jpg") == 0 ||
738  strcmp(file_ext, ".jpeg") == 0 ||
739  format == FORMAT_JPG)
740  {
741  yCError(IMAGEFILE) << "jpeg not yet implemented";
742  return false;
743  }
744  yCError(IMAGEFILE) << "unsupported file format";
745  return false;
746 }
747 
748 bool file::read(ImageOf<PixelMono> & dest, const std::string& src, image_fileformat format)
749 {
750  const char* file_ext = strrchr(src.c_str(), '.');
751  if (strcmp(file_ext, ".pgm") == 0 ||
752  strcmp(file_ext, ".ppm") == 0 ||
753  format == FORMAT_PGM ||
754  format == FORMAT_PPM)
755  {
756  return ImageReadMono_PxM(dest, src.c_str());
757  }
758  else if (strcmp(file_ext, ".png") == 0 ||
759  format == FORMAT_PNG)
760  {
761  return ImageReadMono_PNG(dest, src.c_str());
762  }
763  else if (strcmp(file_ext, ".jpg") == 0 ||
764  strcmp(file_ext, ".jpeg") == 0 ||
765  format == FORMAT_JPG)
766  {
767  yCError(IMAGEFILE) << "jpeg not yet implemented";
768  return false;
769  }
770  yCError(IMAGEFILE) << "unsupported file format";
771  return false;
772 }
773 
774 bool file::read(ImageOf<PixelFloat>& dest, const std::string& src, image_fileformat format)
775 {
776  const char* file_ext = strrchr(src.c_str(), '.');
777  if (strcmp(file_ext, ".pgm") == 0 ||
778  strcmp(file_ext, ".ppm") == 0 ||
779  format == FORMAT_PGM ||
780  format == FORMAT_PPM)
781  {
782  return ImageReadFloat_PxM(dest, src);
783  }
784  else if (strcmp(file_ext, ".png") == 0 ||
785  format == FORMAT_PNG)
786  {
787  return ImageReadFloat_PNG(dest, src);
788  }
789  else if (strcmp(file_ext, ".jpg") == 0 ||
790  strcmp(file_ext, ".jpeg") == 0 ||
791  format == FORMAT_JPG)
792  {
793  yCError(IMAGEFILE) << "jpeg not yet implemented";
794  return false;
795  }
796  yCError(IMAGEFILE) << "unsupported file format";
797  return false;
798 }
799 
803 
804 bool file::write(const ImageOf<PixelRgb> & src, const std::string& dest, image_fileformat format)
805 {
806  if (format == FORMAT_PPM)
807  {
808  return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
809  }
810  else if (format == FORMAT_JPG)
811  {
812  return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
813  }
814  else if (format == FORMAT_PNG)
815  {
816  return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
817  }
818  else
819  {
820  yCError(IMAGEFILE) << "Invalid format, operation not supported";
821  return false;
822  }
823 }
824 
825 bool file::write(const ImageOf<PixelBgr> & src, const std::string& dest, image_fileformat format)
826 {
827  ImageOf<PixelRgb> imgRGB;
828  imgRGB.copy(src);
829  if (format == FORMAT_PPM)
830  {
831  return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
832  }
833  else if (format == FORMAT_JPG)
834  {
835  return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
836  }
837  else if (format == FORMAT_PNG)
838  {
839  return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
840  }
841  else
842  {
843  yCError(IMAGEFILE) << "Invalid format, operation not supported";
844  return false;
845  }
846 }
847 
848 
849 bool file::write(const ImageOf<PixelRgba> & src, const std::string& dest, image_fileformat format)
850 {
851  ImageOf<PixelRgb> imgRGB;
852  imgRGB.copy(src);
853  if (format == FORMAT_PPM)
854  {
855  return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
856  }
857  else if (format == FORMAT_JPG)
858  {
859  return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
860  }
861  else if (format == FORMAT_PNG)
862  {
863  return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
864  }
865  else
866  {
867  yCError(IMAGEFILE) << "Invalid format, operation not supported";
868  return false;
869  }
870 }
871 
872 
873 bool file::write(const ImageOf<PixelMono> & src, const std::string& dest, image_fileformat format)
874 {
875  if (format == FORMAT_PGM)
876  {
877  return ImageWriteMono(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
878  }
879  else if (format == FORMAT_PNG)
880  {
881  return ImageWritePNG(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
882  }
883  else
884  {
885  yCError(IMAGEFILE) << "Invalid format, operation not supported";
886  return false;
887  }
888 }
889 
890 bool file::write(const ImageOf<PixelFloat>& src, const std::string& dest, image_fileformat format)
891 {
892  if (format == FORMAT_NUMERIC)
893  {
894  return ImageWriteFloat(const_cast<ImageOf<PixelFloat> &>(src), dest.c_str());
895  }
896  else
897  {
898  yCError(IMAGEFILE) << "Invalid format, operation not supported";
899  return false;
900  }
901 }
902 
903 bool file::write(const Image& src, const std::string& dest, image_fileformat format)
904 {
905  int code=src.getPixelCode();
906  if (code == VOCAB_PIXEL_MONO)
907  {
908  return write(static_cast<const ImageOf<PixelMono>&>(src), dest, format);
909  }
910  else if (code == VOCAB_PIXEL_MONO_FLOAT)
911  {
912  return write(static_cast<const ImageOf<PixelFloat>&>(src), dest, format);
913  }
914  else if (code == VOCAB_PIXEL_BGR)
915  {
916  return write(static_cast<const ImageOf<PixelBgr>&>(src), dest, format);
917  }
918  else if (code == VOCAB_PIXEL_RGB)
919  {
920  return write(static_cast<const ImageOf<PixelRgb>&>(src), dest, format);
921  }
922  else if (code == VOCAB_PIXEL_RGBA)
923  {
924  return write(static_cast<const ImageOf<PixelRgba>&>(src), dest, format);
925  }
926  else
927  {
928  ImageOf<PixelRgb> img;
929  img.copy(src);
930  return write(img,dest);
931  }
932 }
933 
934 
static bool ImageWriteFloat(ImageOf< PixelFloat > &img, const char *filename)
Definition: ImageFile.cpp:630
static bool ImageReadBGR_PxM(ImageOf< PixelBgr > &img, const char *filename)
Definition: ImageFile.cpp:301
static bool ImageReadRGB_PNG(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:38
static bool ImageWriteJPG(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:595
static bool ImageWriteRGB(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:620
static bool ImageReadMono_PxM(ImageOf< PixelMono > &img, const char *filename)
Definition: ImageFile.cpp:348
static bool ImageReadBGR_PNG(ImageOf< PixelBgr > &img, const char *filename)
Definition: ImageFile.cpp:147
static bool ImageReadMono_PNG(ImageOf< PixelMono > &img, const char *filename)
Definition: ImageFile.cpp:158
static bool ImageWriteMono(ImageOf< PixelMono > &img, const char *filename)
Definition: ImageFile.cpp:625
static bool SaveJPG(char *src, const char *filename, int h, int w, int rowSize)
Definition: ImageFile.cpp:496
static bool ReadHeader_PxM(FILE *fp, int *height, int *width, int *color)
Definition: ImageFile.cpp:173
static bool ImageReadFloat_PxM(ImageOf< PixelFloat > &dest, const std::string &filename)
Definition: ImageFile.cpp:278
static bool SavePGM(char *src, const char *filename, int h, int w, int rowSize)
Definition: ImageFile.cpp:543
static bool ImageReadRGB_PxM(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:219
static bool SavePPM(char *src, const char *filename, int h, int w, int rowSize)
Definition: ImageFile.cpp:569
static bool ImageReadFloat_PNG(ImageOf< PixelFloat > &dest, const std::string &filename)
Definition: ImageFile.cpp:136
static bool ImageWritePNG(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:600
size_t getPixelSize() const override
Gets pixel size in memory in bytes.
Definition: Image.h:657
Base class for storing images.
Definition: Image.h:85
unsigned char * getPixelAddress(size_t x, size_t y) const
Get address of a pixel in memory.
Definition: Image.h:227
size_t width() const
Gets width of image in pixels.
Definition: Image.h:153
size_t getRowSize() const
Size of the underlying image buffer rows.
Definition: Image.h:179
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:535
bool copy(const Image &alt)
Copy operator.
Definition: Image.cpp:847
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition: Image.cpp:467
size_t height() const
Gets height of image in pixels.
Definition: Image.h:159
virtual int getPixelCode() const
Gets pixel type identifier.
Definition: Image.cpp:455
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCWarning(component,...)
Definition: LogComponent.h:146
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
@ VOCAB_PIXEL_RGBA
Definition: Image.h:51
@ VOCAB_PIXEL_BGR
Definition: Image.h:55
@ VOCAB_PIXEL_MONO_FLOAT
Definition: Image.h:59
@ VOCAB_PIXEL_MONO
Definition: Image.h:48
@ VOCAB_PIXEL_RGB
Definition: Image.h:50
An interface to the operating system, including Port based communication.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:656
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:804
Signal processing.
Definition: Image.h:25