YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
ImageFile.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
9#include <yarp/os/LogStream.h>
10
11#include <cstdio>
12#include <cstring>
13#include <cstdlib>
14
15#if defined (YARP_HAS_JPEG)
16#include "jpeglib.h"
17#endif
18
19#if defined (YARP_HAS_PNG)
20#include <png.h>
21#endif
22
23#if defined (YARP_HAS_ZLIB)
24#include <zlib.h>
25#endif
26
27using namespace yarp::os;
28using namespace yarp::sig;
29
30namespace
31{
32 YARP_LOG_COMPONENT(IMAGEFILE, "yarp.sig.ImageFile")
33
34 bool ImageReadRGB_JPG(ImageOf<PixelRgb>& img, const char* filename);
35 bool ImageReadBGR_JPG(ImageOf<PixelBgr>& img, const char* filename);
36 bool ImageReadMono_JPG(ImageOf<PixelMono>& img, const char* filename);
37
38 bool ImageReadRGB_PNG(ImageOf<PixelRgb>& img, const char* filename);
39 bool ImageReadBGR_PNG(ImageOf<PixelBgr>& img, const char* filename);
40 bool ImageReadMono_PNG(ImageOf<PixelMono>& img, const char* filename);
41
42 bool ReadHeader_PxM(FILE* fp, int* height, int* width, int* color);
43 bool ImageReadMono_PxM(ImageOf<PixelMono>& img, const char* filename);
44 bool ImageReadRGB_PxM(ImageOf<PixelRgb>& img, const char* filename);
45 bool ImageReadBGR_PxM(ImageOf<PixelBgr>& img, const char* filename);
46
47 bool ImageReadFloat_PlainHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename);
48#if defined (YARP_HAS_ZLIB)
49 bool ImageReadFloat_CompressedHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename);
50#endif
51
52 bool SaveJPG(char* src, const char* filename, size_t h, size_t w, size_t rowSize);
53 bool SavePGM(char* src, const char* filename, size_t h, size_t w, size_t rowSize);
54 bool SavePPM(char* src, const char* filename, size_t h, size_t w, size_t rowSize);
55#if defined (YARP_HAS_PNG)
56 bool SavePNG(char* src, const char* filename, size_t h, size_t w, size_t rowSize, png_byte color_type, png_byte bit_depth);
57#endif
58 bool SaveFloatRaw(char* src, const char* filename, size_t h, size_t w, size_t rowSize);
59#if defined (YARP_HAS_ZLIB)
60 bool SaveFloatCompressed(char* src, const char* filename, size_t h, size_t w, size_t rowSize);
61#endif
62
63 bool ImageWriteJPG(ImageOf<PixelRgb>& img, const char* filename);
64 bool ImageWritePNG(ImageOf<PixelRgb>& img, const char* filename);
65 bool ImageWritePNG(ImageOf<PixelMono>& img, const char* filename);
66 bool ImageWriteRGB(ImageOf<PixelRgb>& img, const char* filename);
67 bool ImageWriteMono(ImageOf<PixelMono>& img, const char* filename);
68
69 bool ImageWriteFloat_PlainHeaderless(ImageOf<PixelFloat>& img, const char* filename);
70 bool ImageWriteFloat_CompressedHeaderless(ImageOf<PixelFloat>& img, const char* filename);
71
73// private read methods for JPG Files
75bool ImageReadRGB_JPG(ImageOf<PixelRgb>& img, const char* filename)
76{
77#if defined (YARP_HAS_JPEG)
78
79 struct jpeg_decompress_struct cinfo;
80 struct jpeg_error_mgr jerr;
82 cinfo.err = jpeg_std_error(&jerr);
83
84 FILE* fp = fopen(filename, "rb");
85 if (fp == NULL)
86 {
87 yCError(IMAGEFILE) << "Error: failed to open" << filename;
88 return false;
89 }
90
91 jpeg_stdio_src(&cinfo, fp);
92 jpeg_read_header(&cinfo, TRUE);
94
95 uint32_t j_width = cinfo.image_width;
96 uint32_t j_height = cinfo.image_height;
97 uint32_t j_ch = cinfo.num_components;
98
100 j_data = (uint8_t*)malloc(sizeof(uint8_t) * j_width * j_height * j_ch);
101
102 //read line by line
104 const uint32_t j_stride = j_width * j_ch;
105 for (size_t y = 0; y < j_height; y++)
106 {
107 jpeg_read_scanlines(&cinfo, &j_row, 1);
108 j_row += j_stride;
109 }
110
113 fclose(fp);
114
115 img.resize(j_width, j_height);
116 for (size_t y = 0; y < j_height; y++)
117 {
118 for (size_t x = 0; x < j_width; x++)
119 {
120 unsigned char* address = img.getPixelAddress(x, y);
121 address[0] = j_data[y * j_width * j_ch + x * j_ch + 0];
122 address[1] = j_data[y * j_width * j_ch + x * j_ch + 1];
123 address[2] = j_data[y * j_width * j_ch + x * j_ch + 2];
124 }
125 }
126
127 free(j_data);
128 j_data = nullptr;
129
130 return true;
131#else
132 yCError(IMAGEFILE) << "JPG library not available/not found";
133 return false;
134#endif
135}
136
137bool ImageReadBGR_JPG(ImageOf<PixelBgr>& img, const char* filename)
138{
139#if defined (YARP_HAS_JPEG)
140 yCError(IMAGEFILE) << "Not yet implemented";
141 return false;
142#else
143 yCError(IMAGEFILE) << "JPG library not available/not found";
144 return false;
145#endif
146}
147
148bool ImageReadMono_JPG(ImageOf<PixelMono>& img, const char* filename)
149{
150#if defined (YARP_HAS_JPEG)
151 yCError(IMAGEFILE) << "Not yet implemented";
152 return false;
153#else
154 yCError(IMAGEFILE) << "JPG library not available/not found";
155 return false;
156#endif
157}
158
160// private read methods for PNG Files
162bool ImageReadRGB_PNG(ImageOf<PixelRgb>& img, const char* filename)
163{
164#if defined (YARP_HAS_PNG)
165 FILE* fp = fopen(filename, "rb");
166
168 if (!png)
169 {
170 fclose(fp);
171 yCError(IMAGEFILE) << "PNG internal error";
172 return false;
173 }
174
176 if (!info)
177 {
178 fclose(fp);
179 yCError(IMAGEFILE) << "PNG internal error";
180 return false;
181 }
182
183 if (setjmp(png_jmpbuf(png)))
184 {
185 fclose(fp);
186 yCError(IMAGEFILE) << "PNG internal error";
187 return false;
188 }
189
191
193
194 int width = png_get_image_width(png, info);
195 int height = png_get_image_height(png, info);
198
199 // Read any color_type into 8bit depth, RGBA format.
200 // See http://www.libpng.org/pub/png/libpng-manual.txt
201
202 if (bit_depth == 16) {
204 }
205
208 }
209
210 // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
213 }
214
217 }
218
219 // These color_type don't have an alpha channel then fill it with 0xff.
222 }
223
226 }
227
229
230 png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
231 for (int y = 0; y < height; y++)
232 {
234 }
235
237 fclose(fp);
238
239 img.resize(width,height);
240 for (int y = 0; y < height; y++)
241 {
243 for (int x = 0; x < width; x++)
244 {
245 png_bytep px = &(row[x * 4]);
246 unsigned char* address = img.getPixelAddress(x,y);
247 address[0] = px[0];
248 address[1] = px[1];
249 address[2] = px[2];
250 }
251 }
252
254 for (int y = 0; y < height; y++)
255 {
256 free(row_pointers[y]);
257 }
259 return true;
260#else
261 yCError(IMAGEFILE) << "PNG library not available/not found";
262 return false;
263#endif
264}
265
266bool ImageReadBGR_PNG(ImageOf<PixelBgr>& img, const char* filename)
267{
268#if defined (YARP_HAS_PNG)
269 yCError(IMAGEFILE) << "Not yet implemented";
270 return false;
271#else
272 yCError(IMAGEFILE) << "PNG library not available/not found";
273 return false;
274#endif
275}
276
277bool ImageReadMono_PNG(ImageOf<PixelMono>& img, const char* filename)
278{
279#if defined (YARP_HAS_PNG)
280 yCError(IMAGEFILE) << "Not yet implemented";
281 return false;
282#else
283 yCError(IMAGEFILE) << "PNG library not available/not found";
284 return false;
285#endif
286}
287
289// private read methods for PGM/PPM Files
291
292bool ReadHeader_PxM(FILE *fp, int *height, int *width, int *color)
293{
294 char ch;
295 int maxval;
296
297 *color = 0;
298
300 if (fscanf(fp, "P%c\n", &ch) != 1 || (ch!='6'&&ch!='5'))
301 {
302 yCWarning(IMAGEFILE, "file is not in pgm/ppm raw format; cannot read");
303 return false;
304 }
305
306 if (ch == '6') {
307 *color = 1;
308 }
309
310 // skip comments
311 ch = fgetc(fp);
312 while (ch == '#')
313 {
314 do
315 {
316 ch = fgetc(fp);
317 }
318 while (ch != '\n');
319 ch = fgetc(fp);
320 }
321 ungetc(ch, fp);
322
324 int n=fscanf(fp, "%d%d%d", width, height, &maxval);
325 if (n != 3) {
326 return false;
327 }
328
329 fgetc(fp);
330 if (maxval != 255)
331 {
332 //die("image is not true-color (24 bit); read failed");
333 yCWarning(IMAGEFILE, "image is not true-color (24 bit); read failed");
334 return false;
335 }
336
337 return true;
338}
339
340
341bool ImageReadRGB_PxM(ImageOf<PixelRgb> &img, const char *filename)
342{
343 int width, height, color, num;
344 FILE *fp=nullptr;
345 fp = fopen(filename, "rb");
346
347 if(fp==nullptr)
348 {
349 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
350 return false;
351 }
352
353 if (!ReadHeader_PxM(fp, &height, &width, &color))
354 {
355 fclose (fp);
356 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
357 return false;
358 }
359
360 if (!color)
361 {
363 tmp.resize(width,height);
364
365 const int w = tmp.width() * tmp.getPixelSize();
366 const int h = tmp.height();
367 const int pad = tmp.getRowSize();
368 unsigned char *dst = tmp.getRawImage ();
369
370 num = 0;
371 for (int i = 0; i < h; i++)
372 {
373 num += (int)fread((void *) dst, 1, (size_t) w, fp);
374 dst += pad;
375 }
376 fclose(fp);
377 img.copy(tmp);
378 return true;
379 }
380
381 img.resize(width,height);
382
383 const int w = img.width() * img.getPixelSize();
384 const int h = img.height();
385 const int pad = img.getRowSize();
386 unsigned char *dst = img.getRawImage ();
387
388 num = 0;
389 for (int i = 0; i < h; i++)
390 {
391 num += (int)fread((void *) dst, 1, (size_t) w, fp);
392 dst += pad;
393 }
394
395 fclose(fp);
396
397 return true;
398}
399
400#if defined (YARP_HAS_ZLIB)
401bool ImageReadFloat_CompressedHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename)
402{
403 FILE* fp = fopen(filename.c_str(), "rb");
404 if (fp == nullptr) {
405 return false;
406 }
407
408 size_t br = 0;
409
410 //get the file size
411 fseek(fp, 0, SEEK_END);
412 size_t sizeDataCompressed = ftell(fp);
413 rewind(fp);
414
415 //read the compressed data
418 fclose(fp);
419
420 if (br != sizeDataCompressed) { yError() << "problems reading file!"; delete [] dataReadInCompressed; return false; }
421
422 size_t h = ((size_t*)(dataReadInCompressed))[0]; //byte 0
423 size_t w = ((size_t*)(dataReadInCompressed))[1]; //byte 8, because size_t is 8 bytes long
424 size_t hds = 2* sizeof(size_t); //16 bytes
425
426 dest.resize(w, h);
427 unsigned char* destbuff = dest.getRawImage();
428 //this is the size of the image
429 size_t sizeDataUncompressed = dest.getRawImageSize();
430 //this is the size of the buffer. Extra space is required for temporary operations (I choose arbitrarily *2)
432
434
436 switch (z_result)
437 {
438 case Z_OK:
439 break;
440
441 case Z_MEM_ERROR:
442 yCError(IMAGEFILE, "zlib compression: out of memory");
443 delete[] dataUncompressed;
444 return false;
445 break;
446
447 case Z_BUF_ERROR:
448 yCError(IMAGEFILE, "zlib compression: output buffer wasn't large enough");
449 delete[] dataUncompressed;
450 return false;
451 break;
452
453 case Z_DATA_ERROR:
454 yCError(IMAGEFILE, "zlib compression: file contains corrupted data");
455 delete[] dataUncompressed;
456 return false;
457 break;
458 }
459
460 //here I am copy only the size of the image, obviously the extra space is not needed anymore.
461 for (size_t i=0; i< sizeDataUncompressed; i++)
462 {
464 }
465
466 delete [] dataUncompressed;
467 return true;
468}
469#endif
470
471bool ImageReadFloat_PlainHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename)
472{
473 FILE *fp = fopen(filename.c_str(), "rb");
474 if (fp == nullptr) {
475 return false;
476 }
477
478 size_t dims[2];
479 if (fread(dims, sizeof(dims), 1, fp) == 0)
480 {
481 fclose(fp);
482 return false;
483 }
484
485 size_t h = dims[0];
486 size_t w = dims[1];
487 dest.resize(w, h);
488 size_t pad = dest.getRowSize();
489 size_t bytes_to_read_per_row = w* dest.getPixelSize();
490 unsigned char* dst = dest.getRawImage();
491 size_t num = 0;
492 for (size_t i = 0; i < h; i++)
493 {
494 num += (int)fread((void*)dst, 1, bytes_to_read_per_row, fp);
495 dst += pad;
496 }
497
498 fclose(fp);
499 return (num > 0);
500}
501
502bool ImageReadBGR_PxM(ImageOf<PixelBgr> &img, const char *filename)
503{
504 int width, height, color, num;
505 FILE *fp=nullptr;
506 fp = fopen(filename, "rb");
507
508 if(fp==nullptr)
509 {
510 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
511 return false;
512 }
513
514 if (!ReadHeader_PxM(fp, &height, &width, &color))
515 {
516 fclose (fp);
517 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
518 return false;
519 }
520
521 if (!color)
522 {
523 fclose(fp);
524 yCError(IMAGEFILE, "File is grayscale, conversion not yet supported\n");
525 return false;
526 }
527
529 tmpImg.resize(width, height);
530
531 const int w = tmpImg.width() * img.getPixelSize();
532 const int h = tmpImg.height();
533 const int pad = tmpImg.getRowSize();
534 unsigned char *dst = tmpImg.getRawImage ();
535
536 num = 0;
537 for (int i = 0; i < h; i++)
538 {
539 num += (int)fread((void *) dst, 1, (size_t) w, fp);
540 dst += pad;
541 }
542
543 fclose(fp);
544
545 return img.copy(tmpImg);
546}
547
548
549bool ImageReadMono_PxM(ImageOf<PixelMono> &img, const char *filename)
550{
551 int width, height, color, num;
552 FILE *fp=nullptr;
553 fp = fopen(filename, "rb");
554
555 if(fp==nullptr)
556 {
557 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
558 return false;
559 }
560
561 if (!ReadHeader_PxM(fp, &height, &width, &color))
562 {
563 fclose (fp);
564 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
565 return false;
566 }
567
568 if (color)
569 {
570 fclose(fp);
571 yCError(IMAGEFILE, "File is color, conversion not yet supported\n");
572 return false;
573 }
574
575 img.resize(width,height);
576
577 const int w = img.width() * img.getPixelSize();
578 const int h = img.height();
579 const int pad = img.getRowSize();
580 unsigned char *dst = img.getRawImage ();
581
582 num = 0;
583 for (int i = 0; i < h; i++)
584 {
585 num += (int)fread((void *) dst, 1, (size_t) w, fp);
586 dst += pad;
587 }
588
589 fclose(fp);
590
591 return true;
592}
593
595// private write methods
597
598#if defined (YARP_HAS_PNG)
599bool SavePNG(char *src, const char *filename, size_t h, size_t w, size_t rowSize, png_byte color_type, png_byte bit_depth)
600{
601 // create file
602 if (src == nullptr)
603 {
604 yCError(IMAGEFILE, "[write_png_file] Cannot write to file a nullptr image");
605 return false;
606 }
607
608 if (filename == nullptr)
609 {
610 yCError(IMAGEFILE, "[write_png_file] Filename is nullptr");
611 return false;
612 }
613
614 FILE *fp = fopen(filename, "wb");
615 if (!fp)
616 {
617 yCError(IMAGEFILE, "[write_png_file] File %s could not be opened for writing", filename);
618 return false;
619 }
620
621 // initialize stuff
623 if (!png_ptr)
624 {
625 yCError(IMAGEFILE, "[write_png_file] png_create_write_struct failed");
626 fclose(fp);
627 return false;
628 }
629
631 if (!info_ptr)
632 {
633 yCError(IMAGEFILE, "[write_png_file] png_create_info_struct failed");
634 fclose(fp);
635 return false;
636 }
637
638 //init io
640 {
641 yCError(IMAGEFILE, "[write_png_file] Error during init_io");
642 fclose(fp);
643 return false;
644 }
646
647 // write header
649 {
650 yCError(IMAGEFILE, "[write_png_file] Error during writing header");
651 fclose(fp);
652 return false;
653 }
657
658 //write info
660
661 //allocate data space
663
664 for (size_t y = 0; y < h; y++)
665 {
666 //this is an array of pointers. Each element points to a row of the image
667 row_pointers[y] = (png_bytep)(src) + (y * rowSize);
668 }
669
670 // write bytes
672 {
673 yCError(IMAGEFILE, "[write_png_file] Error during writing bytes");
674 delete [] row_pointers;
676 fclose(fp);
677 return false;
678 }
680
681 // end write
683 {
684 yCError(IMAGEFILE, "[write_png_file] Error during end of write");
685 delete [] row_pointers;
687 fclose(fp);
688 return false;
689 }
691
692 // finished. cleanup allocation
693 delete[] row_pointers;
695 fclose(fp);
696 return true;
697}
698#endif
699
700bool SaveJPG(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
701{
702#if defined (YARP_HAS_JPEG)
703 int quality = 100;
704 struct jpeg_compress_struct cinfo;
705 struct jpeg_error_mgr jerr;
706 FILE * outfile = nullptr;
708 int row_stride;
709
710 cinfo.err = jpeg_std_error(&jerr);
711 jpeg_create_compress(&cinfo);
712
713 if ((outfile = fopen(filename, "wb")) == nullptr)
714 {
715 yCError(IMAGEFILE, "can't write file: %s\n", filename);
716 return false;
717 }
718 jpeg_stdio_dest(&cinfo, outfile);
719
720 cinfo.image_width = w;
721 cinfo.image_height = h;
722 cinfo.input_components = 3;
723 cinfo.in_color_space = JCS_RGB;
724 jpeg_set_defaults(&cinfo);
725 jpeg_set_quality(&cinfo, quality, TRUE);
726
727 jpeg_start_compress(&cinfo, TRUE);
728
729 row_stride = w * 3;
730
731 while (cinfo.next_scanline < cinfo.image_height)
732 {
733 row_pointer[0] = (JSAMPROW)&src[cinfo.next_scanline * row_stride];
735 }
736
737 jpeg_finish_compress(&cinfo);
739 jpeg_destroy_compress(&cinfo);
740 return true;
741#else
742 yCError(IMAGEFILE) << "libjpeg not installed";
743 return false;
744#endif
745}
746
747bool SavePGM(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
748{
749 FILE *fp = fopen(filename, "wb");
750 if (!fp)
751 {
752 yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
753 return false;
754 }
755 else
756 {
757 const int inc = rowSize;
758
759 fprintf(fp, "P5\n%zu %zu\n%d\n", w, h, 255);
760 for (size_t i = 0; i < h; i++)
761 {
762 fwrite((void *)src, 1, (size_t)w, fp);
763 src += inc;
764 }
765
766 fclose(fp);
767 }
768
769 return true;
770}
771
772
773bool SavePPM(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
774{
775 FILE *fp = fopen(filename, "wb");
776 if (!fp)
777 {
778 yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
779 return false;
780 }
781 else
782 {
783 const int inc = rowSize;//YARPSimpleOperation::ComputePadding (w*3, YarpImageAlign) + w * 3;
784
785 fprintf(fp, "P6\n%zu %zu\n%d\n", w, h, 255);
786 for (size_t i = 0; i < h; i++)
787 {
788 fwrite((void *)src, 1, (size_t)(w * 3), fp);
789 src += inc;
790 }
791
793 fclose(fp);
794 }
795
796 return true;
797}
798
799#if defined (YARP_HAS_ZLIB)
800bool SaveFloatCompressed(char* src, const char* filename, size_t h, size_t w, size_t rowSize)
801{
802 size_t sizeDataOriginal=w*h*sizeof(float);
803 size_t sizeDataCompressed = (sizeDataOriginal * 1.1) + 12;
805
807 switch (z_result)
808 {
809 case Z_OK:
810 break;
811
812 case Z_MEM_ERROR:
813 yCError(IMAGEFILE, "zlib compression: out of memory");
814 return false;
815 break;
816
817 case Z_BUF_ERROR:
818 yCError(IMAGEFILE, "zlib compression: output buffer wasn't large enough");
819 return false;
820 break;
821 }
822
823 FILE* fp = fopen(filename, "wb");
824 if (fp == nullptr)
825 {
826 return false;
827 }
828
829 size_t bw = 0;
830 size_t dims[2] = { h,w };
831
832 if (fwrite(dims, sizeof(dims), 1, fp) > 0) {
834 }
835
836 fclose(fp);
837 return (bw > 0);
838}
839#endif
840
841bool SaveFloatRaw(char* src, const char* filename, size_t h, size_t w, size_t rowSize)
842{
843 FILE* fp = fopen(filename, "wb");
844 if (fp == nullptr)
845 {
846 return false;
847 }
848
849 size_t dims[2] = { h,w };
850
851 size_t bw = 0;
852 size_t size_ = sizeof(float);
853 auto count_ = (size_t)(dims[0] * dims[1]);
854
855 if (fwrite(dims, sizeof(dims), 1, fp) > 0) {
856 bw = fwrite((void*)src, size_, count_, fp);
857 }
858
859 fclose(fp);
860 return (bw > 0);
861}
862
863bool ImageWriteJPG(ImageOf<PixelRgb>& img, const char *filename)
864{
865 return SaveJPG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
866}
867
868bool ImageWritePNG(ImageOf<PixelRgb>& img, const char *filename)
869{
870#if defined (YARP_HAS_PNG)
871 return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_RGB, 8);
872#else
873 yCError(IMAGEFILE) << "YARP was not built with png support";
874 return false;
875#endif
876}
877
878bool ImageWritePNG(ImageOf<PixelMono>& img, const char *filename)
879{
880#if defined (YARP_HAS_PNG)
881 return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_GRAY, 8);
882#else
883 yCError(IMAGEFILE) << "YARP was not built with png support";
884 return false;
885#endif
886}
887
888bool ImageWriteRGB(ImageOf<PixelRgb>& img, const char *filename)
889{
890 return SavePPM((char*)img.getRawImage(),filename,img.height(),img.width(),img.getRowSize());
891}
892
893bool ImageWriteMono(ImageOf<PixelMono>& img, const char *filename)
894{
895 return SavePGM((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
896}
897
898bool ImageWriteFloat_PlainHeaderless(ImageOf<PixelFloat>& img, const char *filename)
899{
900 return SaveFloatRaw((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
901}
902
903bool ImageWriteFloat_CompressedHeaderless(ImageOf<PixelFloat>& img, const char* filename)
904{
905#if defined (YARP_HAS_ZLIB)
906 return SaveFloatCompressed((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
907#else
908 yCError(IMAGEFILE) << "YARP was not built with zlib support";
909 return false;
910#endif
911}
912} // namespace
913
915// public read methods
917
918bool file::read(ImageOf<PixelRgb> & dest, const std::string& src, image_fileformat format)
919{
920 const char* file_ext = strrchr(src.c_str(), '.');
921 if (file_ext==nullptr)
922 {
923 yCError(IMAGEFILE) << "cannot find file extension in file name";
924 return false;
925 }
926
927 if (strcmp(file_ext, ".pgm")==0 ||
928 strcmp(file_ext, ".ppm")==0 ||
929 format == FORMAT_PGM ||
930 format == FORMAT_PPM)
931 {
932 return ImageReadRGB_PxM(dest,src.c_str());
933 }
934 else if(strcmp(file_ext, ".png")==0 ||
935 format == FORMAT_PNG)
936 {
937 return ImageReadRGB_PNG(dest, src.c_str());
938 }
939 else if(strcmp(file_ext, ".jpg") == 0 ||
940 strcmp(file_ext, ".jpeg") == 0 ||
941 format == FORMAT_JPG)
942 {
943 return ImageReadRGB_JPG(dest, src.c_str());
944 }
945 yCError(IMAGEFILE) << "unsupported file format";
946 return false;
947}
948
949
950bool file::read(ImageOf<PixelBgr> & dest, const std::string& src, image_fileformat format)
951{
952 const char* file_ext = strrchr(src.c_str(), '.');
953 if (file_ext == nullptr)
954 {
955 yCError(IMAGEFILE) << "cannot find file extension in file name";
956 return false;
957 }
958
959 if (strcmp(file_ext, ".pgm") == 0 ||
960 strcmp(file_ext, ".ppm") == 0 ||
961 format == FORMAT_PGM ||
962 format == FORMAT_PPM)
963 {
964 return ImageReadBGR_PxM(dest, src.c_str());
965 }
966 else if (strcmp(file_ext, ".png") == 0 ||
967 format == FORMAT_PNG)
968 {
969 return ImageReadBGR_PNG(dest, src.c_str());
970 }
971 else if (strcmp(file_ext, ".jpg") == 0 ||
972 strcmp(file_ext, ".jpeg") == 0 ||
973 format == FORMAT_JPG)
974 {
975 return ImageReadBGR_JPG(dest, src.c_str());
976 }
977 yCError(IMAGEFILE) << "unsupported file format";
978 return false;
979}
980
981
982bool file::read(ImageOf<PixelRgba> & dest, const std::string& src, image_fileformat format)
983{
984 const char* file_ext = strrchr(src.c_str(), '.');
985 if (file_ext == nullptr)
986 {
987 yCError(IMAGEFILE) << "cannot find file extension in file name";
988 return false;
989 }
990
991 if (strcmp(file_ext, ".pgm") == 0 ||
992 strcmp(file_ext, ".ppm") == 0 ||
993 format == FORMAT_PGM ||
994 format == FORMAT_PPM)
995 {
997 bool ok = ImageReadRGB_PxM(img2, src.c_str());
998 if (ok)
999 {
1000 dest.copy(img2);
1001 }
1002 return ok;
1003 }
1004 else if (strcmp(file_ext, ".png") == 0 ||
1005 format == FORMAT_PNG)
1006 {
1008 bool ok = ImageReadRGB_PNG(img2, src.c_str());
1009 if (ok)
1010 {
1011 dest.copy(img2);
1012 }
1013 return ok;
1014 }
1015 else if (strcmp(file_ext, ".jpg") == 0 ||
1016 strcmp(file_ext, ".jpeg") == 0 ||
1017 format == FORMAT_JPG)
1018 {
1020 bool ok = ImageReadRGB_JPG(img2, src.c_str());
1021 if (ok)
1022 {
1023 dest.copy(img2);
1024 }
1025 return ok;
1026 }
1027 yCError(IMAGEFILE) << "unsupported file format";
1028 return false;
1029}
1030
1031bool file::read(ImageOf<PixelMono> & dest, const std::string& src, image_fileformat format)
1032{
1033 const char* file_ext = strrchr(src.c_str(), '.');
1034 if (file_ext == nullptr)
1035 {
1036 yCError(IMAGEFILE) << "cannot find file extension in file name";
1037 return false;
1038 }
1039
1040 if (strcmp(file_ext, ".pgm") == 0 ||
1041 strcmp(file_ext, ".ppm") == 0 ||
1042 format == FORMAT_PGM ||
1043 format == FORMAT_PPM)
1044 {
1045 return ImageReadMono_PxM(dest, src.c_str());
1046 }
1047 else if (strcmp(file_ext, ".png") == 0 ||
1048 format == FORMAT_PNG)
1049 {
1050 return ImageReadMono_PNG(dest, src.c_str());
1051 }
1052 else if (strcmp(file_ext, ".jpg") == 0 ||
1053 strcmp(file_ext, ".jpeg") == 0 ||
1054 format == FORMAT_JPG)
1055 {
1056 return ImageReadMono_JPG(dest, src.c_str());
1057 }
1058 yCError(IMAGEFILE) << "unsupported file format";
1059 return false;
1060}
1061
1062bool file::read(ImageOf<PixelFloat>& dest, const std::string& src, image_fileformat format)
1063{
1064 const char* file_ext = strrchr(src.c_str(), '.');
1065 if (file_ext == nullptr)
1066 {
1067 yCError(IMAGEFILE) << "cannot find file extension in file name";
1068 return false;
1069 }
1070
1071 if (strcmp(file_ext, ".float") == 0 ||
1072 format == FORMAT_NUMERIC)
1073 {
1074 return ImageReadFloat_PlainHeaderless(dest, src);
1075 }
1076 else if (strcmp(file_ext, ".floatzip") == 0 ||
1077 format == FORMAT_NUMERIC_COMPRESSED)
1078 {
1079#if defined (YARP_HAS_ZLIB)
1080 return ImageReadFloat_CompressedHeaderless(dest, src);
1081#else
1082 yCError(IMAGEFILE) << "YARP was not built with zlib support";
1083 return false;
1084#endif
1085 }
1086 yCError(IMAGEFILE) << "unsupported file format";
1087 return false;
1088}
1089
1093
1094bool file::write(const ImageOf<PixelRgb> & src, const std::string& dest, image_fileformat format)
1095{
1096 if (format == FORMAT_PPM)
1097 {
1098 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1099 }
1100 else if (format == FORMAT_JPG)
1101 {
1102 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1103 }
1104 else if (format == FORMAT_PNG)
1105 {
1106 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1107 }
1108 else
1109 {
1110 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1111 return false;
1112 }
1113}
1114
1115bool file::write(const ImageOf<PixelBgr> & src, const std::string& dest, image_fileformat format)
1116{
1118 imgRGB.copy(src);
1119 if (format == FORMAT_PPM)
1120 {
1121 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1122 }
1123 else if (format == FORMAT_JPG)
1124 {
1125 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1126 }
1127 else if (format == FORMAT_PNG)
1128 {
1129 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1130 }
1131 else
1132 {
1133 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1134 return false;
1135 }
1136}
1137
1138
1139bool file::write(const ImageOf<PixelRgba> & src, const std::string& dest, image_fileformat format)
1140{
1142 imgRGB.copy(src);
1143 if (format == FORMAT_PPM)
1144 {
1145 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1146 }
1147 else if (format == FORMAT_JPG)
1148 {
1149 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1150 }
1151 else if (format == FORMAT_PNG)
1152 {
1153 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1154 }
1155 else
1156 {
1157 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1158 return false;
1159 }
1160}
1161
1162
1163bool file::write(const ImageOf<PixelMono> & src, const std::string& dest, image_fileformat format)
1164{
1165 if (format == FORMAT_PGM)
1166 {
1167 return ImageWriteMono(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
1168 }
1169 else if (format == FORMAT_PNG)
1170 {
1171 return ImageWritePNG(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
1172 }
1173 else
1174 {
1175 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1176 return false;
1177 }
1178}
1179
1180bool file::write(const ImageOf<PixelFloat>& src, const std::string& dest, image_fileformat format)
1181{
1182 if (format == FORMAT_NUMERIC)
1183 {
1184 return ImageWriteFloat_PlainHeaderless(const_cast<ImageOf<PixelFloat> &>(src), dest.c_str());
1185 }
1186 else if (format == FORMAT_NUMERIC_COMPRESSED)
1187 {
1188 return ImageWriteFloat_CompressedHeaderless(const_cast<ImageOf<PixelFloat>&>(src), dest.c_str());
1189 }
1190 else
1191 {
1192 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1193 return false;
1194 }
1195}
1196
1197bool file::write(const Image& src, const std::string& dest, image_fileformat format)
1198{
1199 int code=src.getPixelCode();
1200 if (code == VOCAB_PIXEL_MONO)
1201 {
1202 return write(static_cast<const ImageOf<PixelMono>&>(src), dest, format);
1203 }
1204 else if (code == VOCAB_PIXEL_MONO_FLOAT)
1205 {
1206 return write(static_cast<const ImageOf<PixelFloat>&>(src), dest, format);
1207 }
1208 else if (code == VOCAB_PIXEL_BGR)
1209 {
1210 return write(static_cast<const ImageOf<PixelBgr>&>(src), dest, format);
1211 }
1212 else if (code == VOCAB_PIXEL_RGB)
1213 {
1214 return write(static_cast<const ImageOf<PixelRgb>&>(src), dest, format);
1215 }
1216 else if (code == VOCAB_PIXEL_RGBA)
1217 {
1218 return write(static_cast<const ImageOf<PixelRgba>&>(src), dest, format);
1219 }
1220 else
1221 {
1223 img.copy(src);
1224 return write(img,dest);
1225 }
1226}
1227
1228
@ VOCAB_PIXEL_RGBA
Definition Image.h:45
@ VOCAB_PIXEL_BGR
Definition Image.h:49
@ VOCAB_PIXEL_MONO_FLOAT
Definition Image.h:53
@ VOCAB_PIXEL_MONO
Definition Image.h:42
@ VOCAB_PIXEL_RGB
Definition Image.h:44
#define yError(...)
Definition Log.h:361
A mini-server for performing network communication in the background.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
Typed image class.
Definition Image.h:605
Base class for storing images.
Definition Image.h:79
virtual int getPixelCode() const
Gets pixel type identifier.
Definition Image.cpp:390
#define yCError(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
STL namespace.
An interface to the operating system, including Port based communication.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
@ FORMAT_NUMERIC_COMPRESSED
Definition ImageFile.h:22
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)