22 #if defined (YARP_HAS_PNG)
26 #if defined (YARP_HAS_ZLIB)
45 bool ReadHeader_PxM(FILE* fp,
int* height,
int* width,
int* color);
50 bool ImageReadFloat_PlainHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename);
51 #if defined (YARP_HAS_ZLIB)
52 bool ImageReadFloat_CompressedHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename);
55 bool SaveJPG(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize);
56 bool SavePGM(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize);
57 bool SavePPM(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize);
58 #if defined (YARP_HAS_PNG)
59 bool SavePNG(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize, png_byte color_type, png_byte bit_depth);
61 bool SaveFloatRaw(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize);
62 #if defined (YARP_HAS_ZLIB)
63 bool SaveFloatCompressed(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize);
82 #if defined (YARP_HAS_PNG)
83 FILE* fp = fopen(filename,
"rb");
85 png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
88 yCError(IMAGEFILE) <<
"PNG internal error";
92 png_infop info = png_create_info_struct(png);
95 yCError(IMAGEFILE) <<
"PNG internal error";
99 if (setjmp(png_jmpbuf(png)))
101 yCError(IMAGEFILE) <<
"PNG internal error";
105 png_init_io(png, fp);
107 png_read_info(png, info);
109 int width = png_get_image_width(png, info);
110 int height = png_get_image_height(png, info);
111 png_byte color_type = png_get_color_type(png, info);
112 png_byte bit_depth = png_get_bit_depth(png, info);
118 png_set_strip_16(png);
120 if (color_type == PNG_COLOR_TYPE_PALETTE)
121 png_set_palette_to_rgb(png);
124 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
125 png_set_expand_gray_1_2_4_to_8(png);
127 if (png_get_valid(png, info, PNG_INFO_tRNS))
128 png_set_tRNS_to_alpha(png);
131 if (color_type == PNG_COLOR_TYPE_RGB ||
132 color_type == PNG_COLOR_TYPE_GRAY ||
133 color_type == PNG_COLOR_TYPE_PALETTE)
134 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
136 if (color_type == PNG_COLOR_TYPE_GRAY ||
137 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
138 png_set_gray_to_rgb(png);
140 png_read_update_info(png, info);
142 png_bytep* row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * height);
143 for (
int y = 0; y < height; y++)
145 row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
148 png_read_image(png, row_pointers);
151 img.resize(width,height);
152 for (
int y = 0; y < height; y++)
154 png_bytep row = row_pointers[y];
155 for (
int x = 0; x < width; x++)
157 png_bytep px = &(row[x * 4]);
158 unsigned char* address = img.getPixelAddress(x,y);
165 png_destroy_read_struct(&png, &info, NULL);
166 for (
int y = 0; y < height; y++)
168 free(row_pointers[y]);
173 yCError(IMAGEFILE) <<
"PNG library not available/not found";
180 #if defined (YARP_HAS_PNG)
181 yCError(IMAGEFILE) <<
"Not yet implemented";
184 yCError(IMAGEFILE) <<
"PNG library not available/not found";
191 #if defined (YARP_HAS_PNG)
192 yCError(IMAGEFILE) <<
"Not yet implemented";
195 yCError(IMAGEFILE) <<
"PNG library not available/not found";
204 bool ReadHeader_PxM(FILE *fp,
int *height,
int *width,
int *color)
212 if (fscanf(fp,
"P%c\n", &ch) != 1 || (ch!=
'6'&&ch!=
'5'))
214 yCWarning(IMAGEFILE,
"file is not in pgm/ppm raw format; cannot read");
218 if (ch==
'6') *color = 1;
234 int n=fscanf(fp,
"%d%d%d", width, height, &maxval);
242 yCWarning(IMAGEFILE,
"image is not true-color (24 bit); read failed");
252 int width, height, color, num;
254 fp = fopen(filename,
"rb");
258 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
262 if (!ReadHeader_PxM(fp, &height, &width, &color))
265 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
272 tmp.resize(width,height);
275 const int h = tmp.height();
276 const int pad = tmp.getRowSize();
277 unsigned char *dst = tmp.getRawImage ();
280 for (
int i = 0; i < h; i++)
282 num += (int)fread((
void *) dst, 1, (size_t) w, fp);
290 img.resize(width,height);
293 const int h = img.height();
294 const int pad = img.getRowSize();
295 unsigned char *dst = img.getRawImage ();
298 for (
int i = 0; i < h; i++)
300 num += (int)fread((
void *) dst, 1, (size_t) w, fp);
309 #if defined (YARP_HAS_ZLIB)
310 bool ImageReadFloat_CompressedHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename)
312 FILE* fp = fopen(filename.c_str(),
"rb");
320 fseek(fp, 0, SEEK_END);
321 size_t sizeDataCompressed = ftell(fp);
325 char* dataReadInCompressed =
new char[sizeDataCompressed];
326 br = fread(dataReadInCompressed, 1, sizeDataCompressed, fp);
329 if (br != sizeDataCompressed) {
yError() <<
"problems reading file!";
delete [] dataReadInCompressed;
return false; }
331 size_t h = ((
size_t*)(dataReadInCompressed))[0];
332 size_t w = ((
size_t*)(dataReadInCompressed))[1];
333 size_t hds = 2*
sizeof(size_t);
336 unsigned char* destbuff = dest.getRawImage();
338 size_t sizeDataUncompressed = dest.getRawImageSize();
340 size_t sizeDataUncompressedExtra = sizeDataUncompressed*2;
342 char* dataUncompressed =
new char[sizeDataUncompressedExtra];
344 int z_result = uncompress((Bytef*) dataUncompressed, (uLongf*)&sizeDataUncompressedExtra, (
const Bytef*)dataReadInCompressed+ hds, sizeDataCompressed- hds);
351 yCError(IMAGEFILE,
"zlib compression: out of memory");
352 delete[] dataUncompressed;
357 yCError(IMAGEFILE,
"zlib compression: output buffer wasn't large enough");
358 delete[] dataUncompressed;
363 yCError(IMAGEFILE,
"zlib compression: file contains corrupted data");
364 delete[] dataUncompressed;
370 for (
size_t i=0; i< sizeDataUncompressed; i++)
372 destbuff[i] = dataUncompressed[i];
375 delete [] dataUncompressed;
380 bool ImageReadFloat_PlainHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename)
382 FILE *fp = fopen(filename.c_str(),
"rb");
388 if (fread(dims,
sizeof(dims), 1, fp) == 0)
397 size_t pad = dest.getRowSize();
399 unsigned char* dst = dest.getRawImage();
401 for (
size_t i = 0; i < h; i++)
403 num += (int)fread((
void*)dst, 1, bytes_to_read_per_row, fp);
413 int width, height, color, num;
415 fp = fopen(filename,
"rb");
419 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
423 if (!ReadHeader_PxM(fp, &height, &width, &color))
426 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
433 yCError(IMAGEFILE,
"File is grayscale, conversion not yet supported\n");
438 tmpImg.resize(width, height);
441 const int h = tmpImg.height();
442 const int pad = tmpImg.getRowSize();
443 unsigned char *dst = tmpImg.getRawImage ();
446 for (
int i = 0; i < h; i++)
448 num += (int)fread((
void *) dst, 1, (size_t) w, fp);
454 return img.copy(tmpImg);
460 int width, height, color, num;
462 fp = fopen(filename,
"rb");
466 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
470 if (!ReadHeader_PxM(fp, &height, &width, &color))
473 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
480 yCError(IMAGEFILE,
"File is color, conversion not yet supported\n");
484 img.resize(width,height);
487 const int h = img.height();
488 const int pad = img.getRowSize();
489 unsigned char *dst = img.getRawImage ();
492 for (
int i = 0; i < h; i++)
494 num += (int)fread((
void *) dst, 1, (size_t) w, fp);
507 #if defined (YARP_HAS_PNG)
508 bool SavePNG(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize, png_byte color_type, png_byte bit_depth)
513 yCError(IMAGEFILE,
"[write_png_file] Cannot write to file a nullptr image");
517 if (filename ==
nullptr)
519 yCError(IMAGEFILE,
"[write_png_file] Filename is nullptr");
523 FILE *fp = fopen(filename,
"wb");
526 yCError(IMAGEFILE,
"[write_png_file] File %s could not be opened for writing", filename);
531 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
534 yCError(IMAGEFILE,
"[write_png_file] png_create_write_struct failed");
539 png_infop info_ptr = png_create_info_struct(png_ptr);
542 yCError(IMAGEFILE,
"[write_png_file] png_create_info_struct failed");
548 if (setjmp(png_jmpbuf(png_ptr)))
550 yCError(IMAGEFILE,
"[write_png_file] Error during init_io");
554 png_init_io(png_ptr, fp);
557 if (setjmp(png_jmpbuf(png_ptr)))
559 yCError(IMAGEFILE,
"[write_png_file] Error during writing header");
563 png_set_IHDR(png_ptr, info_ptr, w, h,
564 bit_depth, color_type, PNG_INTERLACE_NONE,
565 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
568 png_write_info(png_ptr, info_ptr);
571 png_bytep* row_pointers =
new png_bytep[h];
573 for (
size_t y = 0; y < h; y++)
576 row_pointers[y] = (png_bytep)(src) + (y * rowSize);
580 if (setjmp(png_jmpbuf(png_ptr)))
582 yCError(IMAGEFILE,
"[write_png_file] Error during writing bytes");
583 delete [] row_pointers;
584 png_destroy_write_struct(&png_ptr, &info_ptr);
588 png_write_image(png_ptr, row_pointers);
591 if (setjmp(png_jmpbuf(png_ptr)))
593 yCError(IMAGEFILE,
"[write_png_file] Error during end of write");
594 delete [] row_pointers;
595 png_destroy_write_struct(&png_ptr, &info_ptr);
599 png_write_end(png_ptr, info_ptr);
602 delete[] row_pointers;
603 png_destroy_write_struct(&png_ptr, &info_ptr);
609 bool SaveJPG(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
613 struct jpeg_compress_struct cinfo;
614 struct jpeg_error_mgr jerr;
615 FILE * outfile =
nullptr;
616 JSAMPROW row_pointer[1];
619 cinfo.err = jpeg_std_error(&jerr);
620 jpeg_create_compress(&cinfo);
622 if ((outfile = fopen(filename,
"wb")) ==
nullptr)
624 yCError(IMAGEFILE,
"can't write file: %s\n", filename);
627 jpeg_stdio_dest(&cinfo, outfile);
629 cinfo.image_width = w;
630 cinfo.image_height = h;
631 cinfo.input_components = 3;
632 cinfo.in_color_space = JCS_RGB;
633 jpeg_set_defaults(&cinfo);
634 jpeg_set_quality(&cinfo, quality, TRUE);
636 jpeg_start_compress(&cinfo, TRUE);
640 while (cinfo.next_scanline < cinfo.image_height)
642 row_pointer[0] = (JSAMPROW)&src[cinfo.next_scanline * row_stride];
643 (
void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
646 jpeg_finish_compress(&cinfo);
648 jpeg_destroy_compress(&cinfo);
651 yCError(IMAGEFILE) <<
"libjpeg not installed";
656 bool SavePGM(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
658 FILE *fp = fopen(filename,
"wb");
661 yCError(IMAGEFILE,
"cannot open file %s for writing\n", filename);
666 const int inc = rowSize;
668 fprintf(fp,
"P5\n%zu %zu\n%d\n", w, h, 255);
669 for (
size_t i = 0; i < h; i++)
671 fwrite((
void *)src, 1, (
size_t)w, fp);
682 bool SavePPM(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
684 FILE *fp = fopen(filename,
"wb");
687 yCError(IMAGEFILE,
"cannot open file %s for writing\n", filename);
692 const int inc = rowSize;
694 fprintf(fp,
"P6\n%zu %zu\n%d\n", w, h, 255);
695 for (
size_t i = 0; i < h; i++)
697 fwrite((
void *)src, 1, (
size_t)(w * 3), fp);
708 #if defined (YARP_HAS_ZLIB)
709 bool SaveFloatCompressed(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize)
711 size_t sizeDataOriginal=w*h*
sizeof(float);
712 size_t sizeDataCompressed = (sizeDataOriginal * 1.1) + 12;
713 char* dataCompressed = (
char*)malloc(sizeDataCompressed);
715 int z_result = compress((Bytef*) dataCompressed,(uLongf*) &sizeDataCompressed, (Bytef*)src, sizeDataOriginal);
722 yCError(IMAGEFILE,
"zlib compression: out of memory");
727 yCError(IMAGEFILE,
"zlib compression: output buffer wasn't large enough");
732 FILE* fp = fopen(filename,
"wb");
739 size_t dims[2] = { h,w };
741 if (fwrite(dims,
sizeof(dims), 1, fp) > 0) {
742 bw = fwrite((
void*)dataCompressed, sizeDataCompressed, 1, fp);
750 bool SaveFloatRaw(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize)
752 FILE* fp = fopen(filename,
"wb");
758 size_t dims[2] = { h,w };
761 size_t size_ =
sizeof(float);
762 auto count_ = (size_t)(dims[0] * dims[1]);
764 if (fwrite(dims,
sizeof(dims), 1, fp) > 0) {
765 bw = fwrite((
void*)src, size_, count_, fp);
774 return SaveJPG((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
779 #if defined (YARP_HAS_PNG)
780 return SavePNG((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_RGB, 8);
782 yCError(IMAGEFILE) <<
"YARP was not built with png support";
789 #if defined (YARP_HAS_PNG)
790 return SavePNG((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize(), PNG_COLOR_TYPE_GRAY, 8);
792 yCError(IMAGEFILE) <<
"YARP was not built with png support";
799 return SavePPM((
char*)img.getRawImage(),filename,img.height(),img.width(),img.getRowSize());
804 return SavePGM((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
809 return SaveFloatRaw((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
814 #if defined (YARP_HAS_ZLIB)
815 return SaveFloatCompressed((
char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
817 yCError(IMAGEFILE) <<
"YARP was not built with zlib support";
829 const char* file_ext = strrchr(src.c_str(),
'.');
830 if (strcmp(file_ext,
".pgm")==0 ||
831 strcmp(file_ext,
".ppm")==0 ||
835 return ImageReadRGB_PxM(dest,src.c_str());
837 else if(strcmp(file_ext,
".png")==0 ||
840 return ImageReadRGB_PNG(dest, src.c_str());
842 else if(strcmp(file_ext,
".jpg") == 0 ||
843 strcmp(file_ext,
".jpeg") == 0 ||
846 yCError(IMAGEFILE) <<
"jpeg not yet implemented";
849 yCError(IMAGEFILE) <<
"unsupported file format";
856 const char* file_ext = strrchr(src.c_str(),
'.');
857 if (strcmp(file_ext,
".pgm") == 0 ||
858 strcmp(file_ext,
".ppm") == 0 ||
862 return ImageReadBGR_PxM(dest, src.c_str());
864 else if (strcmp(file_ext,
".png") == 0 ||
867 return ImageReadBGR_PNG(dest, src.c_str());
869 else if (strcmp(file_ext,
".jpg") == 0 ||
870 strcmp(file_ext,
".jpeg") == 0 ||
873 yCError(IMAGEFILE) <<
"jpeg not yet implemented";
876 yCError(IMAGEFILE) <<
"unsupported file format";
883 const char* file_ext = strrchr(src.c_str(),
'.');
884 if (strcmp(file_ext,
".pgm") == 0 ||
885 strcmp(file_ext,
".ppm") == 0 ||
890 bool ok = ImageReadRGB_PxM(img2, src.c_str());
897 else if (strcmp(file_ext,
".png") == 0 ||
901 bool ok = ImageReadRGB_PNG(img2, src.c_str());
908 else if (strcmp(file_ext,
".jpg") == 0 ||
909 strcmp(file_ext,
".jpeg") == 0 ||
912 yCError(IMAGEFILE) <<
"jpeg not yet implemented";
915 yCError(IMAGEFILE) <<
"unsupported file format";
921 const char* file_ext = strrchr(src.c_str(),
'.');
922 if (strcmp(file_ext,
".pgm") == 0 ||
923 strcmp(file_ext,
".ppm") == 0 ||
927 return ImageReadMono_PxM(dest, src.c_str());
929 else if (strcmp(file_ext,
".png") == 0 ||
932 return ImageReadMono_PNG(dest, src.c_str());
934 else if (strcmp(file_ext,
".jpg") == 0 ||
935 strcmp(file_ext,
".jpeg") == 0 ||
938 yCError(IMAGEFILE) <<
"jpeg not yet implemented";
941 yCError(IMAGEFILE) <<
"unsupported file format";
947 const char* file_ext = strrchr(src.c_str(),
'.');
948 if (strcmp(file_ext,
".float") == 0 ||
951 return ImageReadFloat_PlainHeaderless(dest, src);
953 else if (strcmp(file_ext,
".floatzip") == 0 ||
956 #if defined (YARP_HAS_ZLIB)
957 return ImageReadFloat_CompressedHeaderless(dest, src);
959 yCError(IMAGEFILE) <<
"YARP was not built with zlib support";
963 yCError(IMAGEFILE) <<
"unsupported file format";
987 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1010 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1034 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1052 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1061 return ImageWriteFloat_PlainHeaderless(
const_cast<ImageOf<PixelFloat> &
>(src), dest.c_str());
1065 return ImageWriteFloat_CompressedHeaderless(
const_cast<ImageOf<PixelFloat>&
>(src), dest.c_str());
1069 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1101 return write(img,dest);