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 yCError(IMAGEFILE) << "PNG internal error";
171 return false;
172 }
173
175 if (!info)
176 {
177 yCError(IMAGEFILE) << "PNG internal error";
178 return false;
179 }
180
181 if (setjmp(png_jmpbuf(png)))
182 {
183 yCError(IMAGEFILE) << "PNG internal error";
184 return false;
185 }
186
188
190
191 int width = png_get_image_width(png, info);
192 int height = png_get_image_height(png, info);
195
196 // Read any color_type into 8bit depth, RGBA format.
197 // See http://www.libpng.org/pub/png/libpng-manual.txt
198
199 if (bit_depth == 16) {
201 }
202
205 }
206
207 // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
210 }
211
214 }
215
216 // These color_type don't have an alpha channel then fill it with 0xff.
219 }
220
223 }
224
226
227 png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
228 for (int y = 0; y < height; y++)
229 {
231 }
232
234 fclose(fp);
235
236 img.resize(width,height);
237 for (int y = 0; y < height; y++)
238 {
240 for (int x = 0; x < width; x++)
241 {
242 png_bytep px = &(row[x * 4]);
243 unsigned char* address = img.getPixelAddress(x,y);
244 address[0] = px[0];
245 address[1] = px[1];
246 address[2] = px[2];
247 }
248 }
249
251 for (int y = 0; y < height; y++)
252 {
253 free(row_pointers[y]);
254 }
256 return true;
257#else
258 yCError(IMAGEFILE) << "PNG library not available/not found";
259 return false;
260#endif
261}
262
263bool ImageReadBGR_PNG(ImageOf<PixelBgr>& img, const char* filename)
264{
265#if defined (YARP_HAS_PNG)
266 yCError(IMAGEFILE) << "Not yet implemented";
267 return false;
268#else
269 yCError(IMAGEFILE) << "PNG library not available/not found";
270 return false;
271#endif
272}
273
274bool ImageReadMono_PNG(ImageOf<PixelMono>& img, const char* filename)
275{
276#if defined (YARP_HAS_PNG)
277 yCError(IMAGEFILE) << "Not yet implemented";
278 return false;
279#else
280 yCError(IMAGEFILE) << "PNG library not available/not found";
281 return false;
282#endif
283}
284
286// private read methods for PGM/PPM Files
288
289bool ReadHeader_PxM(FILE *fp, int *height, int *width, int *color)
290{
291 char ch;
292 int maxval;
293
294 *color = 0;
295
297 if (fscanf(fp, "P%c\n", &ch) != 1 || (ch!='6'&&ch!='5'))
298 {
299 yCWarning(IMAGEFILE, "file is not in pgm/ppm raw format; cannot read");
300 return false;
301 }
302
303 if (ch == '6') {
304 *color = 1;
305 }
306
307 // skip comments
308 ch = fgetc(fp);
309 while (ch == '#')
310 {
311 do
312 {
313 ch = fgetc(fp);
314 }
315 while (ch != '\n');
316 ch = fgetc(fp);
317 }
318 ungetc(ch, fp);
319
321 int n=fscanf(fp, "%d%d%d", width, height, &maxval);
322 if (n != 3) {
323 return false;
324 }
325
326 fgetc(fp);
327 if (maxval != 255)
328 {
329 //die("image is not true-color (24 bit); read failed");
330 yCWarning(IMAGEFILE, "image is not true-color (24 bit); read failed");
331 return false;
332 }
333
334 return true;
335}
336
337
338bool ImageReadRGB_PxM(ImageOf<PixelRgb> &img, const char *filename)
339{
340 int width, height, color, num;
341 FILE *fp=nullptr;
342 fp = fopen(filename, "rb");
343
344 if(fp==nullptr)
345 {
346 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
347 return false;
348 }
349
350 if (!ReadHeader_PxM(fp, &height, &width, &color))
351 {
352 fclose (fp);
353 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
354 return false;
355 }
356
357 if (!color)
358 {
360 tmp.resize(width,height);
361
362 const int w = tmp.width() * tmp.getPixelSize();
363 const int h = tmp.height();
364 const int pad = tmp.getRowSize();
365 unsigned char *dst = tmp.getRawImage ();
366
367 num = 0;
368 for (int i = 0; i < h; i++)
369 {
370 num += (int)fread((void *) dst, 1, (size_t) w, fp);
371 dst += pad;
372 }
373 fclose(fp);
374 img.copy(tmp);
375 return true;
376 }
377
378 img.resize(width,height);
379
380 const int w = img.width() * img.getPixelSize();
381 const int h = img.height();
382 const int pad = img.getRowSize();
383 unsigned char *dst = img.getRawImage ();
384
385 num = 0;
386 for (int i = 0; i < h; i++)
387 {
388 num += (int)fread((void *) dst, 1, (size_t) w, fp);
389 dst += pad;
390 }
391
392 fclose(fp);
393
394 return true;
395}
396
397#if defined (YARP_HAS_ZLIB)
398bool ImageReadFloat_CompressedHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename)
399{
400 FILE* fp = fopen(filename.c_str(), "rb");
401 if (fp == nullptr) {
402 return false;
403 }
404
405 size_t br = 0;
406
407 //get the file size
408 fseek(fp, 0, SEEK_END);
409 size_t sizeDataCompressed = ftell(fp);
410 rewind(fp);
411
412 //read the compressed data
415 fclose(fp);
416
417 if (br != sizeDataCompressed) { yError() << "problems reading file!"; delete [] dataReadInCompressed; return false; }
418
419 size_t h = ((size_t*)(dataReadInCompressed))[0]; //byte 0
420 size_t w = ((size_t*)(dataReadInCompressed))[1]; //byte 8, because size_t is 8 bytes long
421 size_t hds = 2* sizeof(size_t); //16 bytes
422
423 dest.resize(w, h);
424 unsigned char* destbuff = dest.getRawImage();
425 //this is the size of the image
426 size_t sizeDataUncompressed = dest.getRawImageSize();
427 //this is the size of the buffer. Extra space is required for temporary operations (I choose arbitrarily *2)
429
431
433 switch (z_result)
434 {
435 case Z_OK:
436 break;
437
438 case Z_MEM_ERROR:
439 yCError(IMAGEFILE, "zlib compression: out of memory");
440 delete[] dataUncompressed;
441 return false;
442 break;
443
444 case Z_BUF_ERROR:
445 yCError(IMAGEFILE, "zlib compression: output buffer wasn't large enough");
446 delete[] dataUncompressed;
447 return false;
448 break;
449
450 case Z_DATA_ERROR:
451 yCError(IMAGEFILE, "zlib compression: file contains corrupted data");
452 delete[] dataUncompressed;
453 return false;
454 break;
455 }
456
457 //here I am copy only the size of the image, obviously the extra space is not needed anymore.
458 for (size_t i=0; i< sizeDataUncompressed; i++)
459 {
461 }
462
463 delete [] dataUncompressed;
464 return true;
465}
466#endif
467
468bool ImageReadFloat_PlainHeaderless(ImageOf<PixelFloat>& dest, const std::string& filename)
469{
470 FILE *fp = fopen(filename.c_str(), "rb");
471 if (fp == nullptr) {
472 return false;
473 }
474
475 size_t dims[2];
476 if (fread(dims, sizeof(dims), 1, fp) == 0)
477 {
478 fclose(fp);
479 return false;
480 }
481
482 size_t h = dims[0];
483 size_t w = dims[1];
484 dest.resize(w, h);
485 size_t pad = dest.getRowSize();
486 size_t bytes_to_read_per_row = w* dest.getPixelSize();
487 unsigned char* dst = dest.getRawImage();
488 size_t num = 0;
489 for (size_t i = 0; i < h; i++)
490 {
491 num += (int)fread((void*)dst, 1, bytes_to_read_per_row, fp);
492 dst += pad;
493 }
494
495 fclose(fp);
496 return (num > 0);
497}
498
499bool ImageReadBGR_PxM(ImageOf<PixelBgr> &img, const char *filename)
500{
501 int width, height, color, num;
502 FILE *fp=nullptr;
503 fp = fopen(filename, "rb");
504
505 if(fp==nullptr)
506 {
507 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
508 return false;
509 }
510
511 if (!ReadHeader_PxM(fp, &height, &width, &color))
512 {
513 fclose (fp);
514 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
515 return false;
516 }
517
518 if (!color)
519 {
520 fclose(fp);
521 yCError(IMAGEFILE, "File is grayscale, conversion not yet supported\n");
522 return false;
523 }
524
526 tmpImg.resize(width, height);
527
528 const int w = tmpImg.width() * img.getPixelSize();
529 const int h = tmpImg.height();
530 const int pad = tmpImg.getRowSize();
531 unsigned char *dst = tmpImg.getRawImage ();
532
533 num = 0;
534 for (int i = 0; i < h; i++)
535 {
536 num += (int)fread((void *) dst, 1, (size_t) w, fp);
537 dst += pad;
538 }
539
540 fclose(fp);
541
542 return img.copy(tmpImg);
543}
544
545
546bool ImageReadMono_PxM(ImageOf<PixelMono> &img, const char *filename)
547{
548 int width, height, color, num;
549 FILE *fp=nullptr;
550 fp = fopen(filename, "rb");
551
552 if(fp==nullptr)
553 {
554 yCError(IMAGEFILE, "Error opening %s, check if file exists.\n", filename);
555 return false;
556 }
557
558 if (!ReadHeader_PxM(fp, &height, &width, &color))
559 {
560 fclose (fp);
561 yCError(IMAGEFILE, "Error reading header, is file a valid ppm/pgm?\n");
562 return false;
563 }
564
565 if (color)
566 {
567 fclose(fp);
568 yCError(IMAGEFILE, "File is color, conversion not yet supported\n");
569 return false;
570 }
571
572 img.resize(width,height);
573
574 const int w = img.width() * img.getPixelSize();
575 const int h = img.height();
576 const int pad = img.getRowSize();
577 unsigned char *dst = img.getRawImage ();
578
579 num = 0;
580 for (int i = 0; i < h; i++)
581 {
582 num += (int)fread((void *) dst, 1, (size_t) w, fp);
583 dst += pad;
584 }
585
586 fclose(fp);
587
588 return true;
589}
590
592// private write methods
594
595#if defined (YARP_HAS_PNG)
596bool SavePNG(char *src, const char *filename, size_t h, size_t w, size_t rowSize, png_byte color_type, png_byte bit_depth)
597{
598 // create file
599 if (src == nullptr)
600 {
601 yCError(IMAGEFILE, "[write_png_file] Cannot write to file a nullptr image");
602 return false;
603 }
604
605 if (filename == nullptr)
606 {
607 yCError(IMAGEFILE, "[write_png_file] Filename is nullptr");
608 return false;
609 }
610
611 FILE *fp = fopen(filename, "wb");
612 if (!fp)
613 {
614 yCError(IMAGEFILE, "[write_png_file] File %s could not be opened for writing", filename);
615 return false;
616 }
617
618 // initialize stuff
620 if (!png_ptr)
621 {
622 yCError(IMAGEFILE, "[write_png_file] png_create_write_struct failed");
623 fclose(fp);
624 return false;
625 }
626
628 if (!info_ptr)
629 {
630 yCError(IMAGEFILE, "[write_png_file] png_create_info_struct failed");
631 fclose(fp);
632 return false;
633 }
634
635 //init io
637 {
638 yCError(IMAGEFILE, "[write_png_file] Error during init_io");
639 fclose(fp);
640 return false;
641 }
643
644 // write header
646 {
647 yCError(IMAGEFILE, "[write_png_file] Error during writing header");
648 fclose(fp);
649 return false;
650 }
654
655 //write info
657
658 //allocate data space
660
661 for (size_t y = 0; y < h; y++)
662 {
663 //this is an array of pointers. Each element points to a row of the image
664 row_pointers[y] = (png_bytep)(src) + (y * rowSize);
665 }
666
667 // write bytes
669 {
670 yCError(IMAGEFILE, "[write_png_file] Error during writing bytes");
671 delete [] row_pointers;
673 fclose(fp);
674 return false;
675 }
677
678 // end write
680 {
681 yCError(IMAGEFILE, "[write_png_file] Error during end of write");
682 delete [] row_pointers;
684 fclose(fp);
685 return false;
686 }
688
689 // finished. cleanup allocation
690 delete[] row_pointers;
692 fclose(fp);
693 return true;
694}
695#endif
696
697bool SaveJPG(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
698{
699#if defined (YARP_HAS_JPEG)
700 int quality = 100;
701 struct jpeg_compress_struct cinfo;
702 struct jpeg_error_mgr jerr;
703 FILE * outfile = nullptr;
705 int row_stride;
706
707 cinfo.err = jpeg_std_error(&jerr);
708 jpeg_create_compress(&cinfo);
709
710 if ((outfile = fopen(filename, "wb")) == nullptr)
711 {
712 yCError(IMAGEFILE, "can't write file: %s\n", filename);
713 return false;
714 }
715 jpeg_stdio_dest(&cinfo, outfile);
716
717 cinfo.image_width = w;
718 cinfo.image_height = h;
719 cinfo.input_components = 3;
720 cinfo.in_color_space = JCS_RGB;
721 jpeg_set_defaults(&cinfo);
722 jpeg_set_quality(&cinfo, quality, TRUE);
723
724 jpeg_start_compress(&cinfo, TRUE);
725
726 row_stride = w * 3;
727
728 while (cinfo.next_scanline < cinfo.image_height)
729 {
730 row_pointer[0] = (JSAMPROW)&src[cinfo.next_scanline * row_stride];
732 }
733
734 jpeg_finish_compress(&cinfo);
736 jpeg_destroy_compress(&cinfo);
737 return true;
738#else
739 yCError(IMAGEFILE) << "libjpeg not installed";
740 return false;
741#endif
742}
743
744bool SavePGM(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
745{
746 FILE *fp = fopen(filename, "wb");
747 if (!fp)
748 {
749 yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
750 return false;
751 }
752 else
753 {
754 const int inc = rowSize;
755
756 fprintf(fp, "P5\n%zu %zu\n%d\n", w, h, 255);
757 for (size_t i = 0; i < h; i++)
758 {
759 fwrite((void *)src, 1, (size_t)w, fp);
760 src += inc;
761 }
762
763 fclose(fp);
764 }
765
766 return true;
767}
768
769
770bool SavePPM(char *src, const char *filename, size_t h, size_t w, size_t rowSize)
771{
772 FILE *fp = fopen(filename, "wb");
773 if (!fp)
774 {
775 yCError(IMAGEFILE, "cannot open file %s for writing\n", filename);
776 return false;
777 }
778 else
779 {
780 const int inc = rowSize;//YARPSimpleOperation::ComputePadding (w*3, YarpImageAlign) + w * 3;
781
782 fprintf(fp, "P6\n%zu %zu\n%d\n", w, h, 255);
783 for (size_t i = 0; i < h; i++)
784 {
785 fwrite((void *)src, 1, (size_t)(w * 3), fp);
786 src += inc;
787 }
788
790 fclose(fp);
791 }
792
793 return true;
794}
795
796#if defined (YARP_HAS_ZLIB)
797bool SaveFloatCompressed(char* src, const char* filename, size_t h, size_t w, size_t rowSize)
798{
799 size_t sizeDataOriginal=w*h*sizeof(float);
800 size_t sizeDataCompressed = (sizeDataOriginal * 1.1) + 12;
802
804 switch (z_result)
805 {
806 case Z_OK:
807 break;
808
809 case Z_MEM_ERROR:
810 yCError(IMAGEFILE, "zlib compression: out of memory");
811 return false;
812 break;
813
814 case Z_BUF_ERROR:
815 yCError(IMAGEFILE, "zlib compression: output buffer wasn't large enough");
816 return false;
817 break;
818 }
819
820 FILE* fp = fopen(filename, "wb");
821 if (fp == nullptr)
822 {
823 return false;
824 }
825
826 size_t bw = 0;
827 size_t dims[2] = { h,w };
828
829 if (fwrite(dims, sizeof(dims), 1, fp) > 0) {
831 }
832
833 fclose(fp);
834 return (bw > 0);
835}
836#endif
837
838bool SaveFloatRaw(char* src, const char* filename, size_t h, size_t w, size_t rowSize)
839{
840 FILE* fp = fopen(filename, "wb");
841 if (fp == nullptr)
842 {
843 return false;
844 }
845
846 size_t dims[2] = { h,w };
847
848 size_t bw = 0;
849 size_t size_ = sizeof(float);
850 auto count_ = (size_t)(dims[0] * dims[1]);
851
852 if (fwrite(dims, sizeof(dims), 1, fp) > 0) {
853 bw = fwrite((void*)src, size_, count_, fp);
854 }
855
856 fclose(fp);
857 return (bw > 0);
858}
859
860bool ImageWriteJPG(ImageOf<PixelRgb>& img, const char *filename)
861{
862 return SaveJPG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
863}
864
865bool ImageWritePNG(ImageOf<PixelRgb>& img, const char *filename)
866{
867#if defined (YARP_HAS_PNG)
868 return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_RGB, 8);
869#else
870 yCError(IMAGEFILE) << "YARP was not built with png support";
871 return false;
872#endif
873}
874
875bool ImageWritePNG(ImageOf<PixelMono>& img, const char *filename)
876{
877#if defined (YARP_HAS_PNG)
878 return SavePNG((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_GRAY, 8);
879#else
880 yCError(IMAGEFILE) << "YARP was not built with png support";
881 return false;
882#endif
883}
884
885bool ImageWriteRGB(ImageOf<PixelRgb>& img, const char *filename)
886{
887 return SavePPM((char*)img.getRawImage(),filename,img.height(),img.width(),img.getRowSize());
888}
889
890bool ImageWriteMono(ImageOf<PixelMono>& img, const char *filename)
891{
892 return SavePGM((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
893}
894
895bool ImageWriteFloat_PlainHeaderless(ImageOf<PixelFloat>& img, const char *filename)
896{
897 return SaveFloatRaw((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
898}
899
900bool ImageWriteFloat_CompressedHeaderless(ImageOf<PixelFloat>& img, const char* filename)
901{
902#if defined (YARP_HAS_ZLIB)
903 return SaveFloatCompressed((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
904#else
905 yCError(IMAGEFILE) << "YARP was not built with zlib support";
906 return false;
907#endif
908}
909} // namespace
910
912// public read methods
914
915bool file::read(ImageOf<PixelRgb> & dest, const std::string& src, image_fileformat format)
916{
917 const char* file_ext = strrchr(src.c_str(), '.');
918 if (file_ext==nullptr)
919 {
920 yCError(IMAGEFILE) << "cannot find file extension in file name";
921 return false;
922 }
923
924 if (strcmp(file_ext, ".pgm")==0 ||
925 strcmp(file_ext, ".ppm")==0 ||
926 format == FORMAT_PGM ||
927 format == FORMAT_PPM)
928 {
929 return ImageReadRGB_PxM(dest,src.c_str());
930 }
931 else if(strcmp(file_ext, ".png")==0 ||
932 format == FORMAT_PNG)
933 {
934 return ImageReadRGB_PNG(dest, src.c_str());
935 }
936 else if(strcmp(file_ext, ".jpg") == 0 ||
937 strcmp(file_ext, ".jpeg") == 0 ||
938 format == FORMAT_JPG)
939 {
940 return ImageReadRGB_JPG(dest, src.c_str());
941 }
942 yCError(IMAGEFILE) << "unsupported file format";
943 return false;
944}
945
946
947bool file::read(ImageOf<PixelBgr> & dest, const std::string& src, image_fileformat format)
948{
949 const char* file_ext = strrchr(src.c_str(), '.');
950 if (file_ext == nullptr)
951 {
952 yCError(IMAGEFILE) << "cannot find file extension in file name";
953 return false;
954 }
955
956 if (strcmp(file_ext, ".pgm") == 0 ||
957 strcmp(file_ext, ".ppm") == 0 ||
958 format == FORMAT_PGM ||
959 format == FORMAT_PPM)
960 {
961 return ImageReadBGR_PxM(dest, src.c_str());
962 }
963 else if (strcmp(file_ext, ".png") == 0 ||
964 format == FORMAT_PNG)
965 {
966 return ImageReadBGR_PNG(dest, src.c_str());
967 }
968 else if (strcmp(file_ext, ".jpg") == 0 ||
969 strcmp(file_ext, ".jpeg") == 0 ||
970 format == FORMAT_JPG)
971 {
972 return ImageReadBGR_JPG(dest, src.c_str());
973 }
974 yCError(IMAGEFILE) << "unsupported file format";
975 return false;
976}
977
978
979bool file::read(ImageOf<PixelRgba> & dest, const std::string& src, image_fileformat format)
980{
981 const char* file_ext = strrchr(src.c_str(), '.');
982 if (file_ext == nullptr)
983 {
984 yCError(IMAGEFILE) << "cannot find file extension in file name";
985 return false;
986 }
987
988 if (strcmp(file_ext, ".pgm") == 0 ||
989 strcmp(file_ext, ".ppm") == 0 ||
990 format == FORMAT_PGM ||
991 format == FORMAT_PPM)
992 {
994 bool ok = ImageReadRGB_PxM(img2, src.c_str());
995 if (ok)
996 {
997 dest.copy(img2);
998 }
999 return ok;
1000 }
1001 else if (strcmp(file_ext, ".png") == 0 ||
1002 format == FORMAT_PNG)
1003 {
1005 bool ok = ImageReadRGB_PNG(img2, src.c_str());
1006 if (ok)
1007 {
1008 dest.copy(img2);
1009 }
1010 return ok;
1011 }
1012 else if (strcmp(file_ext, ".jpg") == 0 ||
1013 strcmp(file_ext, ".jpeg") == 0 ||
1014 format == FORMAT_JPG)
1015 {
1017 bool ok = ImageReadRGB_JPG(img2, src.c_str());
1018 if (ok)
1019 {
1020 dest.copy(img2);
1021 }
1022 return ok;
1023 }
1024 yCError(IMAGEFILE) << "unsupported file format";
1025 return false;
1026}
1027
1028bool file::read(ImageOf<PixelMono> & dest, const std::string& src, image_fileformat format)
1029{
1030 const char* file_ext = strrchr(src.c_str(), '.');
1031 if (file_ext == nullptr)
1032 {
1033 yCError(IMAGEFILE) << "cannot find file extension in file name";
1034 return false;
1035 }
1036
1037 if (strcmp(file_ext, ".pgm") == 0 ||
1038 strcmp(file_ext, ".ppm") == 0 ||
1039 format == FORMAT_PGM ||
1040 format == FORMAT_PPM)
1041 {
1042 return ImageReadMono_PxM(dest, src.c_str());
1043 }
1044 else if (strcmp(file_ext, ".png") == 0 ||
1045 format == FORMAT_PNG)
1046 {
1047 return ImageReadMono_PNG(dest, src.c_str());
1048 }
1049 else if (strcmp(file_ext, ".jpg") == 0 ||
1050 strcmp(file_ext, ".jpeg") == 0 ||
1051 format == FORMAT_JPG)
1052 {
1053 return ImageReadMono_JPG(dest, src.c_str());
1054 }
1055 yCError(IMAGEFILE) << "unsupported file format";
1056 return false;
1057}
1058
1059bool file::read(ImageOf<PixelFloat>& dest, const std::string& src, image_fileformat format)
1060{
1061 const char* file_ext = strrchr(src.c_str(), '.');
1062 if (file_ext == nullptr)
1063 {
1064 yCError(IMAGEFILE) << "cannot find file extension in file name";
1065 return false;
1066 }
1067
1068 if (strcmp(file_ext, ".float") == 0 ||
1069 format == FORMAT_NUMERIC)
1070 {
1071 return ImageReadFloat_PlainHeaderless(dest, src);
1072 }
1073 else if (strcmp(file_ext, ".floatzip") == 0 ||
1074 format == FORMAT_NUMERIC_COMPRESSED)
1075 {
1076#if defined (YARP_HAS_ZLIB)
1077 return ImageReadFloat_CompressedHeaderless(dest, src);
1078#else
1079 yCError(IMAGEFILE) << "YARP was not built with zlib support";
1080 return false;
1081#endif
1082 }
1083 yCError(IMAGEFILE) << "unsupported file format";
1084 return false;
1085}
1086
1090
1091bool file::write(const ImageOf<PixelRgb> & src, const std::string& dest, image_fileformat format)
1092{
1093 if (format == FORMAT_PPM)
1094 {
1095 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1096 }
1097 else if (format == FORMAT_JPG)
1098 {
1099 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1100 }
1101 else if (format == FORMAT_PNG)
1102 {
1103 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
1104 }
1105 else
1106 {
1107 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1108 return false;
1109 }
1110}
1111
1112bool file::write(const ImageOf<PixelBgr> & src, const std::string& dest, image_fileformat format)
1113{
1115 imgRGB.copy(src);
1116 if (format == FORMAT_PPM)
1117 {
1118 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1119 }
1120 else if (format == FORMAT_JPG)
1121 {
1122 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1123 }
1124 else if (format == FORMAT_PNG)
1125 {
1126 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1127 }
1128 else
1129 {
1130 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1131 return false;
1132 }
1133}
1134
1135
1136bool file::write(const ImageOf<PixelRgba> & src, const std::string& dest, image_fileformat format)
1137{
1139 imgRGB.copy(src);
1140 if (format == FORMAT_PPM)
1141 {
1142 return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1143 }
1144 else if (format == FORMAT_JPG)
1145 {
1146 return ImageWriteJPG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1147 }
1148 else if (format == FORMAT_PNG)
1149 {
1150 return ImageWritePNG(const_cast<ImageOf<PixelRgb> &>(imgRGB), dest.c_str());
1151 }
1152 else
1153 {
1154 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1155 return false;
1156 }
1157}
1158
1159
1160bool file::write(const ImageOf<PixelMono> & src, const std::string& dest, image_fileformat format)
1161{
1162 if (format == FORMAT_PGM)
1163 {
1164 return ImageWriteMono(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
1165 }
1166 else if (format == FORMAT_PNG)
1167 {
1168 return ImageWritePNG(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
1169 }
1170 else
1171 {
1172 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1173 return false;
1174 }
1175}
1176
1177bool file::write(const ImageOf<PixelFloat>& src, const std::string& dest, image_fileformat format)
1178{
1179 if (format == FORMAT_NUMERIC)
1180 {
1181 return ImageWriteFloat_PlainHeaderless(const_cast<ImageOf<PixelFloat> &>(src), dest.c_str());
1182 }
1183 else if (format == FORMAT_NUMERIC_COMPRESSED)
1184 {
1185 return ImageWriteFloat_CompressedHeaderless(const_cast<ImageOf<PixelFloat>&>(src), dest.c_str());
1186 }
1187 else
1188 {
1189 yCError(IMAGEFILE) << "Invalid format, operation not supported";
1190 return false;
1191 }
1192}
1193
1194bool file::write(const Image& src, const std::string& dest, image_fileformat format)
1195{
1196 int code=src.getPixelCode();
1197 if (code == VOCAB_PIXEL_MONO)
1198 {
1199 return write(static_cast<const ImageOf<PixelMono>&>(src), dest, format);
1200 }
1201 else if (code == VOCAB_PIXEL_MONO_FLOAT)
1202 {
1203 return write(static_cast<const ImageOf<PixelFloat>&>(src), dest, format);
1204 }
1205 else if (code == VOCAB_PIXEL_BGR)
1206 {
1207 return write(static_cast<const ImageOf<PixelBgr>&>(src), dest, format);
1208 }
1209 else if (code == VOCAB_PIXEL_RGB)
1210 {
1211 return write(static_cast<const ImageOf<PixelRgb>&>(src), dest, format);
1212 }
1213 else if (code == VOCAB_PIXEL_RGBA)
1214 {
1215 return write(static_cast<const ImageOf<PixelRgba>&>(src), dest, format);
1216 }
1217 else
1218 {
1220 img.copy(src);
1221 return write(img,dest);
1222 }
1223}
1224
1225
size_t size_t
@ 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:616
Base class for storing images.
Definition Image.h:79
virtual int getPixelCode() const
Gets pixel type identifier.
Definition Image.cpp:441
#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)