15 #if defined (YARP_HAS_JPEG)
19 #if defined (YARP_HAS_PNG)
23 #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_JPEG)
84 struct jpeg_decompress_struct cinfo;
85 struct jpeg_error_mgr jerr;
86 jpeg_create_decompress(&cinfo);
87 cinfo.err = jpeg_std_error(&jerr);
89 FILE* fp = fopen(filename,
"rb");
92 yCError(IMAGEFILE) <<
"Error: failed to open" << filename;
96 jpeg_stdio_src(&cinfo, fp);
97 jpeg_read_header(&cinfo, TRUE);
98 jpeg_start_decompress(&cinfo);
100 uint32_t j_width = cinfo.image_width;
101 uint32_t j_height = cinfo.image_height;
102 uint32_t j_ch = cinfo.num_components;
104 uint8_t* j_data = NULL;
105 j_data = (uint8_t*)malloc(
sizeof(uint8_t) * j_width * j_height * j_ch);
108 uint8_t* j_row = j_data;
109 const uint32_t j_stride = j_width * j_ch;
110 for (
size_t y = 0; y < j_height; y++)
112 jpeg_read_scanlines(&cinfo, &j_row, 1);
116 jpeg_finish_decompress(&cinfo);
117 jpeg_destroy_decompress(&cinfo);
120 img.
resize(j_width, j_height);
121 for (
size_t y = 0; y < j_height; y++)
123 for (
size_t x = 0; x < j_width; x++)
126 address[0] = j_data[y * j_width * j_ch + x * j_ch + 0];
127 address[1] = j_data[y * j_width * j_ch + x * j_ch + 1];
128 address[2] = j_data[y * j_width * j_ch + x * j_ch + 2];
137 yCError(IMAGEFILE) <<
"JPG library not available/not found";
144 #if defined (YARP_HAS_JPEG)
145 yCError(IMAGEFILE) <<
"Not yet implemented";
148 yCError(IMAGEFILE) <<
"JPG library not available/not found";
155 #if defined (YARP_HAS_JPEG)
156 yCError(IMAGEFILE) <<
"Not yet implemented";
159 yCError(IMAGEFILE) <<
"JPG library not available/not found";
171 #if defined (YARP_HAS_PNG)
172 FILE* fp = fopen(filename,
"rb");
174 png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
177 yCError(IMAGEFILE) <<
"PNG internal error";
181 png_infop info = png_create_info_struct(png);
184 yCError(IMAGEFILE) <<
"PNG internal error";
188 if (setjmp(png_jmpbuf(png)))
190 yCError(IMAGEFILE) <<
"PNG internal error";
194 png_init_io(png, fp);
196 png_read_info(png, info);
198 int width = png_get_image_width(png, info);
199 int height = png_get_image_height(png, info);
200 png_byte color_type = png_get_color_type(png, info);
201 png_byte bit_depth = png_get_bit_depth(png, info);
206 if (bit_depth == 16) {
207 png_set_strip_16(png);
210 if (color_type == PNG_COLOR_TYPE_PALETTE) {
211 png_set_palette_to_rgb(png);
215 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
216 png_set_expand_gray_1_2_4_to_8(png);
219 if (png_get_valid(png, info, PNG_INFO_tRNS)) {
220 png_set_tRNS_to_alpha(png);
224 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) {
225 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
228 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
229 png_set_gray_to_rgb(png);
232 png_read_update_info(png, info);
234 png_bytep* row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * height);
235 for (
int y = 0; y < height; y++)
237 row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
240 png_read_image(png, row_pointers);
244 for (
int y = 0; y < height; y++)
246 png_bytep row = row_pointers[y];
247 for (
int x = 0; x < width; x++)
249 png_bytep px = &(row[x * 4]);
257 png_destroy_read_struct(&png, &info, NULL);
258 for (
int y = 0; y < height; y++)
260 free(row_pointers[y]);
265 yCError(IMAGEFILE) <<
"PNG library not available/not found";
272 #if defined (YARP_HAS_PNG)
273 yCError(IMAGEFILE) <<
"Not yet implemented";
276 yCError(IMAGEFILE) <<
"PNG library not available/not found";
283 #if defined (YARP_HAS_PNG)
284 yCError(IMAGEFILE) <<
"Not yet implemented";
287 yCError(IMAGEFILE) <<
"PNG library not available/not found";
296 bool ReadHeader_PxM(FILE *fp,
int *height,
int *width,
int *color)
304 if (fscanf(fp,
"P%c\n", &ch) != 1 || (ch!=
'6'&&ch!=
'5'))
306 yCWarning(IMAGEFILE,
"file is not in pgm/ppm raw format; cannot read");
328 int n=fscanf(fp,
"%d%d%d", width, height, &maxval);
337 yCWarning(IMAGEFILE,
"image is not true-color (24 bit); read failed");
347 int width, height, color, num;
349 fp = fopen(filename,
"rb");
353 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
357 if (!ReadHeader_PxM(fp, &height, &width, &color))
360 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
370 const int h = tmp.
height();
375 for (
int i = 0; i < h; i++)
377 num += (int)fread((
void *) dst, 1, (
size_t) w, fp);
388 const int h = img.
height();
393 for (
int i = 0; i < h; i++)
395 num += (int)fread((
void *) dst, 1, (
size_t) w, fp);
404 #if defined (YARP_HAS_ZLIB)
405 bool ImageReadFloat_CompressedHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename)
407 FILE* fp = fopen(filename.c_str(),
"rb");
415 fseek(fp, 0, SEEK_END);
416 size_t sizeDataCompressed = ftell(fp);
420 char* dataReadInCompressed =
new char[sizeDataCompressed];
421 br = fread(dataReadInCompressed, 1, sizeDataCompressed, fp);
424 if (br != sizeDataCompressed) {
yError() <<
"problems reading file!";
delete [] dataReadInCompressed;
return false; }
426 size_t h = ((
size_t*)(dataReadInCompressed))[0];
427 size_t w = ((
size_t*)(dataReadInCompressed))[1];
428 size_t hds = 2*
sizeof(
size_t);
435 size_t sizeDataUncompressedExtra = sizeDataUncompressed*2;
437 char* dataUncompressed =
new char[sizeDataUncompressedExtra];
439 int z_result = uncompress((Bytef*) dataUncompressed, (uLongf*)&sizeDataUncompressedExtra, (
const Bytef*)dataReadInCompressed+ hds, sizeDataCompressed- hds);
446 yCError(IMAGEFILE,
"zlib compression: out of memory");
447 delete[] dataUncompressed;
452 yCError(IMAGEFILE,
"zlib compression: output buffer wasn't large enough");
453 delete[] dataUncompressed;
458 yCError(IMAGEFILE,
"zlib compression: file contains corrupted data");
459 delete[] dataUncompressed;
465 for (
size_t i=0; i< sizeDataUncompressed; i++)
467 destbuff[i] = dataUncompressed[i];
470 delete [] dataUncompressed;
475 bool ImageReadFloat_PlainHeaderless(
ImageOf<PixelFloat>& dest,
const std::string& filename)
477 FILE *fp = fopen(filename.c_str(),
"rb");
483 if (fread(dims,
sizeof(dims), 1, fp) == 0)
496 for (
size_t i = 0; i < h; i++)
498 num += (int)fread((
void*)dst, 1, bytes_to_read_per_row, fp);
508 int width, height, color, num;
510 fp = fopen(filename,
"rb");
514 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
518 if (!ReadHeader_PxM(fp, &height, &width, &color))
521 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
528 yCError(IMAGEFILE,
"File is grayscale, conversion not yet supported\n");
533 tmpImg.
resize(width, height);
536 const int h = tmpImg.
height();
541 for (
int i = 0; i < h; i++)
543 num += (int)fread((
void *) dst, 1, (
size_t) w, fp);
549 return img.
copy(tmpImg);
555 int width, height, color, num;
557 fp = fopen(filename,
"rb");
561 yCError(IMAGEFILE,
"Error opening %s, check if file exists.\n", filename);
565 if (!ReadHeader_PxM(fp, &height, &width, &color))
568 yCError(IMAGEFILE,
"Error reading header, is file a valid ppm/pgm?\n");
575 yCError(IMAGEFILE,
"File is color, conversion not yet supported\n");
582 const int h = img.
height();
587 for (
int i = 0; i < h; i++)
589 num += (int)fread((
void *) dst, 1, (
size_t) w, fp);
602 #if defined (YARP_HAS_PNG)
603 bool SavePNG(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize, png_byte color_type, png_byte bit_depth)
608 yCError(IMAGEFILE,
"[write_png_file] Cannot write to file a nullptr image");
612 if (filename ==
nullptr)
614 yCError(IMAGEFILE,
"[write_png_file] Filename is nullptr");
618 FILE *fp = fopen(filename,
"wb");
621 yCError(IMAGEFILE,
"[write_png_file] File %s could not be opened for writing", filename);
626 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
629 yCError(IMAGEFILE,
"[write_png_file] png_create_write_struct failed");
634 png_infop info_ptr = png_create_info_struct(png_ptr);
637 yCError(IMAGEFILE,
"[write_png_file] png_create_info_struct failed");
643 if (setjmp(png_jmpbuf(png_ptr)))
645 yCError(IMAGEFILE,
"[write_png_file] Error during init_io");
649 png_init_io(png_ptr, fp);
652 if (setjmp(png_jmpbuf(png_ptr)))
654 yCError(IMAGEFILE,
"[write_png_file] Error during writing header");
658 png_set_IHDR(png_ptr, info_ptr, w, h,
659 bit_depth, color_type, PNG_INTERLACE_NONE,
660 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
663 png_write_info(png_ptr, info_ptr);
666 png_bytep* row_pointers =
new png_bytep[h];
668 for (
size_t y = 0; y < h; y++)
671 row_pointers[y] = (png_bytep)(src) + (y * rowSize);
675 if (setjmp(png_jmpbuf(png_ptr)))
677 yCError(IMAGEFILE,
"[write_png_file] Error during writing bytes");
678 delete [] row_pointers;
679 png_destroy_write_struct(&png_ptr, &info_ptr);
683 png_write_image(png_ptr, row_pointers);
686 if (setjmp(png_jmpbuf(png_ptr)))
688 yCError(IMAGEFILE,
"[write_png_file] Error during end of write");
689 delete [] row_pointers;
690 png_destroy_write_struct(&png_ptr, &info_ptr);
694 png_write_end(png_ptr, info_ptr);
697 delete[] row_pointers;
698 png_destroy_write_struct(&png_ptr, &info_ptr);
704 bool SaveJPG(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
706 #if defined (YARP_HAS_JPEG)
708 struct jpeg_compress_struct cinfo;
709 struct jpeg_error_mgr jerr;
710 FILE * outfile =
nullptr;
711 JSAMPROW row_pointer[1];
714 cinfo.err = jpeg_std_error(&jerr);
715 jpeg_create_compress(&cinfo);
717 if ((outfile = fopen(filename,
"wb")) ==
nullptr)
719 yCError(IMAGEFILE,
"can't write file: %s\n", filename);
722 jpeg_stdio_dest(&cinfo, outfile);
724 cinfo.image_width = w;
725 cinfo.image_height = h;
726 cinfo.input_components = 3;
727 cinfo.in_color_space = JCS_RGB;
728 jpeg_set_defaults(&cinfo);
729 jpeg_set_quality(&cinfo, quality, TRUE);
731 jpeg_start_compress(&cinfo, TRUE);
735 while (cinfo.next_scanline < cinfo.image_height)
737 row_pointer[0] = (JSAMPROW)&src[cinfo.next_scanline * row_stride];
738 (
void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
741 jpeg_finish_compress(&cinfo);
743 jpeg_destroy_compress(&cinfo);
746 yCError(IMAGEFILE) <<
"libjpeg not installed";
751 bool SavePGM(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
753 FILE *fp = fopen(filename,
"wb");
756 yCError(IMAGEFILE,
"cannot open file %s for writing\n", filename);
761 const int inc = rowSize;
763 fprintf(fp,
"P5\n%zu %zu\n%d\n", w, h, 255);
764 for (
size_t i = 0; i < h; i++)
766 fwrite((
void *)src, 1, (
size_t)w, fp);
777 bool SavePPM(
char *src,
const char *filename,
size_t h,
size_t w,
size_t rowSize)
779 FILE *fp = fopen(filename,
"wb");
782 yCError(IMAGEFILE,
"cannot open file %s for writing\n", filename);
787 const int inc = rowSize;
789 fprintf(fp,
"P6\n%zu %zu\n%d\n", w, h, 255);
790 for (
size_t i = 0; i < h; i++)
792 fwrite((
void *)src, 1, (
size_t)(w * 3), fp);
803 #if defined (YARP_HAS_ZLIB)
804 bool SaveFloatCompressed(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize)
806 size_t sizeDataOriginal=w*h*
sizeof(float);
807 size_t sizeDataCompressed = (sizeDataOriginal * 1.1) + 12;
808 char* dataCompressed = (
char*)malloc(sizeDataCompressed);
810 int z_result = compress((Bytef*) dataCompressed,(uLongf*) &sizeDataCompressed, (Bytef*)src, sizeDataOriginal);
817 yCError(IMAGEFILE,
"zlib compression: out of memory");
822 yCError(IMAGEFILE,
"zlib compression: output buffer wasn't large enough");
827 FILE* fp = fopen(filename,
"wb");
834 size_t dims[2] = { h,w };
836 if (fwrite(dims,
sizeof(dims), 1, fp) > 0) {
837 bw = fwrite((
void*)dataCompressed, sizeDataCompressed, 1, fp);
845 bool SaveFloatRaw(
char* src,
const char* filename,
size_t h,
size_t w,
size_t rowSize)
847 FILE* fp = fopen(filename,
"wb");
853 size_t dims[2] = { h,w };
856 size_t size_ =
sizeof(float);
857 auto count_ = (
size_t)(dims[0] * dims[1]);
859 if (fwrite(dims,
sizeof(dims), 1, fp) > 0) {
860 bw = fwrite((
void*)src, size_, count_, fp);
874 #if defined (YARP_HAS_PNG)
877 yCError(IMAGEFILE) <<
"YARP was not built with png support";
884 #if defined (YARP_HAS_PNG)
887 yCError(IMAGEFILE) <<
"YARP was not built with png support";
909 #if defined (YARP_HAS_ZLIB)
912 yCError(IMAGEFILE) <<
"YARP was not built with zlib support";
924 const char* file_ext = strrchr(src.c_str(),
'.');
925 if (file_ext==
nullptr)
927 yCError(IMAGEFILE) <<
"cannot find file extension in file name";
931 if (strcmp(file_ext,
".pgm")==0 ||
932 strcmp(file_ext,
".ppm")==0 ||
936 return ImageReadRGB_PxM(dest,src.c_str());
938 else if(strcmp(file_ext,
".png")==0 ||
941 return ImageReadRGB_PNG(dest, src.c_str());
943 else if(strcmp(file_ext,
".jpg") == 0 ||
944 strcmp(file_ext,
".jpeg") == 0 ||
947 return ImageReadRGB_JPG(dest, src.c_str());
949 yCError(IMAGEFILE) <<
"unsupported file format";
956 const char* file_ext = strrchr(src.c_str(),
'.');
957 if (file_ext ==
nullptr)
959 yCError(IMAGEFILE) <<
"cannot find file extension in file name";
963 if (strcmp(file_ext,
".pgm") == 0 ||
964 strcmp(file_ext,
".ppm") == 0 ||
968 return ImageReadBGR_PxM(dest, src.c_str());
970 else if (strcmp(file_ext,
".png") == 0 ||
973 return ImageReadBGR_PNG(dest, src.c_str());
975 else if (strcmp(file_ext,
".jpg") == 0 ||
976 strcmp(file_ext,
".jpeg") == 0 ||
979 return ImageReadBGR_JPG(dest, src.c_str());
981 yCError(IMAGEFILE) <<
"unsupported file format";
988 const char* file_ext = strrchr(src.c_str(),
'.');
989 if (file_ext ==
nullptr)
991 yCError(IMAGEFILE) <<
"cannot find file extension in file name";
995 if (strcmp(file_ext,
".pgm") == 0 ||
996 strcmp(file_ext,
".ppm") == 0 ||
1001 bool ok = ImageReadRGB_PxM(img2, src.c_str());
1008 else if (strcmp(file_ext,
".png") == 0 ||
1012 bool ok = ImageReadRGB_PNG(img2, src.c_str());
1019 else if (strcmp(file_ext,
".jpg") == 0 ||
1020 strcmp(file_ext,
".jpeg") == 0 ||
1024 bool ok = ImageReadRGB_JPG(img2, src.c_str());
1031 yCError(IMAGEFILE) <<
"unsupported file format";
1037 const char* file_ext = strrchr(src.c_str(),
'.');
1038 if (file_ext ==
nullptr)
1040 yCError(IMAGEFILE) <<
"cannot find file extension in file name";
1044 if (strcmp(file_ext,
".pgm") == 0 ||
1045 strcmp(file_ext,
".ppm") == 0 ||
1049 return ImageReadMono_PxM(dest, src.c_str());
1051 else if (strcmp(file_ext,
".png") == 0 ||
1054 return ImageReadMono_PNG(dest, src.c_str());
1056 else if (strcmp(file_ext,
".jpg") == 0 ||
1057 strcmp(file_ext,
".jpeg") == 0 ||
1060 return ImageReadMono_JPG(dest, src.c_str());
1062 yCError(IMAGEFILE) <<
"unsupported file format";
1068 const char* file_ext = strrchr(src.c_str(),
'.');
1069 if (file_ext ==
nullptr)
1071 yCError(IMAGEFILE) <<
"cannot find file extension in file name";
1075 if (strcmp(file_ext,
".float") == 0 ||
1078 return ImageReadFloat_PlainHeaderless(dest, src);
1080 else if (strcmp(file_ext,
".floatzip") == 0 ||
1083 #if defined (YARP_HAS_ZLIB)
1084 return ImageReadFloat_CompressedHeaderless(dest, src);
1086 yCError(IMAGEFILE) <<
"YARP was not built with zlib support";
1090 yCError(IMAGEFILE) <<
"unsupported file format";
1114 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1137 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1161 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1179 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1188 return ImageWriteFloat_PlainHeaderless(
const_cast<ImageOf<PixelFloat> &
>(src), dest.c_str());
1192 return ImageWriteFloat_CompressedHeaderless(
const_cast<ImageOf<PixelFloat>&
>(src), dest.c_str());
1196 yCError(IMAGEFILE) <<
"Invalid format, operation not supported";
1228 return write(img,dest);
size_t getPixelSize() const override
Gets pixel size in memory in bytes.
Base class for storing images.
unsigned char * getPixelAddress(size_t x, size_t y) const
Get address of a pixel in memory.
size_t width() const
Gets width of image in pixels.
size_t getRowSize() const
Size of the underlying image buffer rows.
unsigned char * getRawImage() const
Access to the internal image buffer.
bool copy(const Image &alt)
Copy operator.
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
size_t height() const
Gets height of image in pixels.
virtual int getPixelCode() const
Gets pixel type identifier.
#define yCError(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
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
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)