2

I am writing small C program using Cimg graphics library and need to test that a file is an image.

I attempted to load the file/image with

CImg<unsigned char> srcimg(filename)

and catch the exemption but the cimg flattly quits with:

convert.im6: improper image header `pok.txt' @ error/bmp.c/ReadBMPImage/603.
convert.im6: no images defined `pnm:-' @ error/convert.c/ConvertImageCommand/3044.
sh: 1: gm: not found
terminate called after throwing an instance of 'cimg_library::CImgIOException'
  what():  [instance(0,0,0,0,(nil),non-shared)] CImg<unsigned char>::load() : Failed to recognize format of file 'pok.txt'.
Aborted

Of course, the file is txt, but ignoring the suffix, is there a proper way how to test this? Without involving another dependencies/libraries.

Thanks

user2389519
  • 270
  • 2
  • 10

4 Answers4

1

As proposed above, the best thing to do is to catch the exception when there is one thrown by CImg, and skip that particular file when it happens. Something like :

CImg<> img;
const char *const filename[] = { "foo.txt", "foo.bmp", "foo.jpg" }
for (unsigned int i = 0; i<3; ++i) {
   try { img.load(filename[i]); } catch (CImgException) { img.assign(); }
   if (img) {
       .. Do what you want on your image now.
   } 
}
bvalabas
  • 41
  • 1
0

Do you need an exhaustive test, or do you only have to differ between a number of candidates?

To quickly find an appropriate file type, all you need to do is read the first bytes out of the file. Then,

  • if these are 'BM' it's a Windows BMP
  • if these are 0x89 'PNG' it's a PNG
  • both 'II' and 'MM' indicate a TIFF file
  • the sequence 0xFF 0xD8 0xFF 0xE0 is a typical start of a JPEG file (there are some others).

Once you find a possible file format, you can attempt load the image with the proper routine in your image library, and if that fails it wasn't a valid image to begin with.

An exhaustive test -- say, you find it's possibly a BMP file because it starts with BM -- is far more work. You then need to read the whole file and validate its entire contents, according to the specifications of each separate image type.

Jongware
  • 22,200
  • 8
  • 54
  • 100
  • Well, I dont like this approach. This is complicated and unreliable :( Cimg is very versatile, I believe there must be more simpler solution... I do not even care about format of input image, I will take content of pixels from cimg and go on with own processing. – user2389519 Sep 05 '13 at 18:27
  • In that case don't rename your images to '.txt'. You *are* making a simple, existing solution complicated -- checking the file extension. It seems CImg is just not as versatile as you thought. – Jongware Sep 06 '13 at 08:46
  • well, my application is for batch processing of images so it would be nice if it could go over all files and determine what is image... Of course, check based on extensions is possible as well, but the programm will not cope with situation when there will be broken *.jpg file and whole processing will crash – user2389519 Sep 08 '13 at 20:37
0

Well, the answer is (for my purposes at least) simple: Cimg exception handling: http://cimg.sourceforge.net/reference/structcimg__library_1_1CImgException.html

This way I can go on with processing of next images

user2389519
  • 270
  • 2
  • 10
0

My version of CImg (148) has a function file_type(). Is that not reliable?

M Katz
  • 5,098
  • 3
  • 44
  • 66