YARP  2.3.70
Yet Another Robot Platform
ImageFile.cpp
Go to the documentation of this file.
1 /*
2 * Author: Lorenzo Natale, Giorgio Metta and Paul Fitzpatrick.
3 * Copyright (C) 2006 The Robotcub consortium
4 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
5 */
6 
7 
8 
9 #include <yarp/sig/ImageFile.h>
10 #include <yarp/os/Log.h>
11 
12 #include <cstdio>
13 #include <cstdlib>
14 
15 using namespace std;
16 using namespace yarp::os;
17 using namespace yarp::sig;
18 
19 
20 static void warn(const char *message)
21 {
22  fprintf(stderr, "pgm/ppm: Error - %s\n", message);
23 }
24 
25 
27 {
28  FILE *fp = fopen(dest.c_str(), "w");
29  if (fp==NULL) {
30  return false;
31  }
32 
33  for (int i=0; i<src.height(); i++) {
34  for (int j=0; j<src.width(); j++) {
35  fprintf(fp,"%g ", src(j,i));
36  }
37  fprintf(fp,"\n");
38  }
39  fclose(fp);
40  return false;
41 }
42 
43 
45 {
46  int hh = 0, ww = 0;
47 
48  FILE *fp = fopen(src.c_str(), "r");
49  if (fp==NULL) {
50  return false;
51  }
52  int blank = 1;
53  int curr = 0;
54  while (!feof(fp)) {
55  int ch = fgetc(fp);
56  if (ch==' ' || ch == '\t' || ch == '\r' ||ch == '\n'|| feof(fp)){
57  if (!blank) {
58  if (curr==0) {
59  hh++;
60  }
61  curr++;
62  if (curr>ww) {
63  ww = curr;
64  }
65  }
66  blank = 1;
67  if (ch=='\n') {
68  curr = 0;
69  }
70  } else {
71  blank = 0;
72  }
73  }
74  fclose(fp);
75  fp = fopen(src.c_str(), "rb");
76  if (fp==NULL) {
77  return false;
78  }
79  dest.resize(ww,hh);
80  hh = 0; ww = 0;
81  {
82  char buf[256];
83  int idx = 0;
84  int blank = 1;
85  int curr = 0;
86  while (!feof(fp)) {
87  int ch = fgetc(fp);
88  if (ch==' ' || ch == '\t' ||ch == '\r'||ch == '\n' || feof(fp)){
89  if (!blank) {
90  if (curr==0) {
91  hh++;
92  }
93  curr++;
94  if (curr>ww) {
95  ww = curr;
96  }
97  buf[idx] = '\0';
98  dest(curr-1,hh-1) = float(atof(buf));
99  idx = 0;
100  }
101  blank = 1;
102  if (ch=='\n') {
103  curr = 0;
104  }
105  } else {
106  buf[idx] = ch;
107  idx++;
108  yAssert(((unsigned int)idx)<sizeof(buf));
109  blank = 0;
110  }
111  }
112  }
113  fclose(fp);
114  return true;
115 }
116 
117 
118 static bool SavePGM(char *src, const char *filename, int h, int w, int rowSize)
119 {
120  FILE *fp = fopen(filename, "wb");
121  if (!fp)
122  {
123  printf("cannot open file %s for writing\n", filename);
124  return false;
125  }
126  else
127  {
128  const int inc = rowSize;
129 
130  fprintf(fp, "P5\n%d %d\n%d\n", w, h, 255);
131  for (int i = 0; i < h; i++)
132  {
133  fwrite((void *) src, 1, (size_t) w, fp);
134  src += inc;
135  }
136 
137  fclose(fp);
138  }
139 
140  return true;
141 }
142 
143 
144 static bool SavePPM(char *src, const char *filename, int h, int w, int rowSize)
145 {
146  FILE *fp = fopen(filename, "wb");
147  if (!fp)
148  {
149  printf("cannot open file %s for writing\n", filename);
150  return false;
151  }
152  else
153  {
154  const int inc = rowSize;//YARPSimpleOperation::ComputePadding (w*3, YarpImageAlign) + w * 3;
155 
156  fprintf(fp, "P6\n%d %d\n%d\n", w, h, 255);
157  for (int i = 0; i < h; i++)
158  {
159  fwrite((void *) src, 1, (size_t) (w*3), fp);
160  src += inc;
161  }
162 
164  fclose(fp);
165  }
166 
167  return true;
168 }
169 
170 
171 static bool ReadHeader(FILE *fp, int *height, int *width, int *color)
172 {
173  char ch;
174  int maxval;
175 
176  *color = 0;
177 
179  if (fscanf(fp, "P%c\n", &ch) != 1 || (ch!='6'&&ch!='5'))
180  //die("file is not in pgm/ppm raw format; cannot read");
181  {
182  warn("file is not in pgm/ppm raw format; cannot read");
183  return false;
184  }
185 
186  if (ch=='6') *color = 1;
187 
188  // skip comments
189  ch = fgetc(fp);
190  while (ch == '#')
191  {
192  do
193  {
194  ch = fgetc(fp);
195  }
196  while (ch != '\n');
197  ch = fgetc(fp);
198  }
199  ungetc(ch, fp);
200 
202  int n=fscanf(fp, "%d%d%d", width, height, &maxval);
203  if (n!=3)
204  return false;
205 
206  fgetc(fp);
207  if (maxval != 255)
208  {
209  //die("image is not true-color (24 bit); read failed");
210  warn("image is not true-color (24 bit); read failed");
211  return false;
212  }
213 
214  return true;
215 }
216 
217 
218 static bool ImageReadRGB(ImageOf<PixelRgb> &img, const char *filename)
219 {
220  int width, height, color, num;
221  FILE *fp=0;
222  fp = fopen(filename, "rb");
223 
224  if(fp==0)
225  {
226  fprintf(stderr, "Error opening %s, check if file exists.\n", filename);
227  return false;
228  }
229 
230  if (!ReadHeader(fp, &height, &width, &color))
231  {
232  fclose (fp);
233  fprintf(stderr, "Error reading header, is file a valid ppm/pgm?\n");
234  return false;
235  }
236 
237  if (!color)
238  {
239  ImageOf<PixelMono> tmp;
240  tmp.resize(width,height);
241 
242  const int w = tmp.width() * tmp.getPixelSize();
243  const int h = tmp.height();
244  const int pad = tmp.getRowSize();
245  unsigned char *dst = tmp.getRawImage ();
246 
247  num = 0;
248  for (int i = 0; i < h; i++)
249  {
250  num += (int)fread((void *) dst, 1, (size_t) w, fp);
251  dst += pad;
252  }
253  fclose(fp);
254  img.copy(tmp);
255  return true;
256  }
257 
258  img.resize(width,height);
259 
260  const int w = img.width() * img.getPixelSize();
261  const int h = img.height();
262  const int pad = img.getRowSize();
263  unsigned char *dst = img.getRawImage ();
264 
265  num = 0;
266  for (int i = 0; i < h; i++)
267  {
268  num += (int)fread((void *) dst, 1, (size_t) w, fp);
269  dst += pad;
270  }
271 
272  fclose(fp);
273 
274  return true;
275 }
276 
277 
278 static bool ImageReadBGR(ImageOf<PixelBgr> &img, const char *filename)
279 {
280  int width, height, color, num;
281  FILE *fp=0;
282  fp = fopen(filename, "rb");
283 
284  if(fp==0)
285  {
286  fprintf(stderr, "Error opening %s, check if file exists.\n", filename);
287  return false;
288  }
289 
290  if (!ReadHeader(fp, &height, &width, &color))
291  {
292  fclose (fp);
293  fprintf(stderr, "Error reading header, is file a valid ppm/pgm?\n");
294  return false;
295  }
296  if (!color)
297  {
298  fclose(fp);
299  fprintf(stderr, "File is grayscale, conversion not yet supported\n");
300  return false;
301  }
302 
303  ImageOf<PixelRgb> tmpImg;
304  tmpImg.resize(width, height);
305 
306  const int w = tmpImg.width() * img.getPixelSize();
307  const int h = tmpImg.height();
308  const int pad = tmpImg.getRowSize();
309  unsigned char *dst = tmpImg.getRawImage ();
310 
311  num = 0;
312  for (int i = 0; i < h; i++)
313  {
314  num += (int)fread((void *) dst, 1, (size_t) w, fp);
315  dst += pad;
316  }
317 
318  fclose(fp);
319 
320  return img.copy(tmpImg);
321 }
322 
323 
324 static bool ImageReadMono(ImageOf<PixelMono> &img, const char *filename)
325 {
326  int width, height, color, num;
327  FILE *fp=0;
328  fp = fopen(filename, "rb");
329 
330  if(fp==0)
331  {
332  fprintf(stderr, "Error opening %s, check if file exists.\n", filename);
333  return false;
334  }
335 
336  if (!ReadHeader(fp, &height, &width, &color))
337  {
338  fclose (fp);
339  fprintf(stderr, "Error reading header, is file a valid ppm/pgm?\n");
340  return false;
341  }
342  if (color)
343  {
344  fclose(fp);
345  fprintf(stderr, "File is color, conversion not yet supported\n");
346  return false;
347  }
348 
349  img.resize(width,height);
350 
351  const int w = img.width() * img.getPixelSize();
352  const int h = img.height();
353  const int pad = img.getRowSize();
354  unsigned char *dst = img.getRawImage ();
355 
356  num = 0;
357  for (int i = 0; i < h; i++)
358  {
359  num += (int)fread((void *) dst, 1, (size_t) w, fp);
360  dst += pad;
361  }
362 
363  fclose(fp);
364 
365  return true;
366 }
367 
368 
369 static bool ImageWriteRGB(ImageOf<PixelRgb>& img, const char *filename)
370 {
371  return SavePPM((char*)img.getRawImage(),filename,img.height(),img.width(),img.getRowSize());
372 }
373 
374 
375 static bool ImageWriteBGR(ImageOf<PixelBgr>& img, const char *filename)
376 {
377  ImageOf<PixelRgb> img2;
378  img2.copy(img);
379  return SavePPM((char*)img2.getRawImage(),filename,img2.height(), img2.width(), img2.getRowSize());
380 }
381 
382 
383 static bool ImageWriteMono(ImageOf<PixelMono>& img, const char *filename)
384 {
385  return SavePGM((char*)img.getRawImage(), filename, img.height(), img.width(), img.getRowSize());
386 }
387 
388 
390 {
391  return ImageReadRGB(dest,src.c_str());
392 }
393 
394 
396 {
397  return ImageReadBGR(dest,src.c_str());
398 }
399 
400 
402 {
403  ImageOf<PixelRgb> img2;
404  bool ok = ImageReadRGB(img2,src.c_str());
405  if (ok) {
406  dest.copy(img2);
407  }
408  return ok;
409 }
410 
411 
413 {
414  return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(src), dest.c_str());
415 }
416 
417 
419 {
420  return ImageWriteBGR(const_cast<ImageOf<PixelBgr> &>(src), dest.c_str());
421 }
422 
423 
425 {
426  ImageOf<PixelRgb> img2;
427  img2.copy(src);
428  return ImageWriteRGB(const_cast<ImageOf<PixelRgb> &>(img2), dest.c_str());
429 }
430 
431 
433 {
434  return ImageReadMono(dest,src.c_str());
435 }
436 
437 
439 {
440  return ImageWriteMono(const_cast<ImageOf<PixelMono> &>(src), dest.c_str());
441 }
442 
443 
444 bool file::write(const Image& src, const ConstString& dest)
445 {
446  int code=src.getPixelCode();
447  if (code==VOCAB_PIXEL_MONO)
448  return write(static_cast<const ImageOf<PixelMono>&>(src),dest);
449  else if (code==VOCAB_PIXEL_MONO_FLOAT)
450  return write(static_cast<const ImageOf<PixelFloat>&>(src),dest);
451  else if (code==VOCAB_PIXEL_BGR)
452  return write(static_cast<const ImageOf<PixelBgr>&>(src),dest);
453  else if (code==VOCAB_PIXEL_RGB)
454  return write(static_cast<const ImageOf<PixelRgb>&>(src),dest);
455  else if (code==VOCAB_PIXEL_RGBA)
456  return write(static_cast<const ImageOf<PixelRgba>&>(src),dest);
457  else
458  {
459  ImageOf<PixelRgb> img;
460  img.copy(src);
461  return write(img,dest);
462  }
463 }
464 
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:725
bool copy(const Image &alt)
Copy operator.
Definition: Image.cpp:1006
static bool ImageReadRGB(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:218
bool write(const ImageOf< PixelRgb > &src, const yarp::os::ConstString &dest)
Definition: ImageFile.cpp:412
STL namespace.
int width() const
Gets width of image in pixels.
Definition: Image.h:101
static bool SavePGM(char *src, const char *filename, int h, int w, int rowSize)
Definition: ImageFile.cpp:118
* dest
Definition: ImageCopy.cpp:72
static bool ReadHeader(FILE *fp, int *height, int *width, int *color)
Definition: ImageFile.cpp:171
A string with almost the same api as std::string.
Definition: ConstString.h:44
void resize(int imgWidth, int imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition: Image.cpp:656
Base class for storing images.
Definition: Image.h:48
virtual int getPixelSize() const
Gets pixel size in memory in bytes.
Definition: Image.h:559
bool read(ImageOf< PixelRgb > &dest, const yarp::os::ConstString &src)
Definition: ImageFile.cpp:389
static bool ImageReadBGR(ImageOf< PixelBgr > &img, const char *filename)
Definition: ImageFile.cpp:278
static void warn(const char *message)
Definition: ImageFile.cpp:20
static bool SavePPM(char *src, const char *filename, int h, int w, int rowSize)
Definition: ImageFile.cpp:144
int getRowSize() const
Size of the underlying image buffer rows.
Definition: Image.h:127
#define yAssert(x)
Definition: Log.h:118
static bool ImageWriteRGB(ImageOf< PixelRgb > &img, const char *filename)
Definition: ImageFile.cpp:369
const char * c_str() const
Accesses the character sequence stored in this object.
Definition: ConstString.cpp:88
Typed image class.
Definition: Image.h:23
dest h
Definition: ImageCopy.cpp:63
static bool ImageWriteMono(ImageOf< PixelMono > &img, const char *filename)
Definition: ImageFile.cpp:383
An interface to the operating system, including Port based communication.
static bool ImageWriteBGR(ImageOf< PixelBgr > &img, const char *filename)
Definition: ImageFile.cpp:375
static bool ImageReadMono(ImageOf< PixelMono > &img, const char *filename)
Definition: ImageFile.cpp:324
Signal processing.
Definition: Image.h:20
int height() const
Gets height of image in pixels.
Definition: Image.h:107
virtual int getPixelCode() const
Gets pixel type identifier.
Definition: Image.cpp:644