diff options
Diffstat (limited to 'ml/dlib/dlib/image_loader/load_image.h')
-rw-r--r-- | ml/dlib/dlib/image_loader/load_image.h | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/ml/dlib/dlib/image_loader/load_image.h b/ml/dlib/dlib/image_loader/load_image.h new file mode 100644 index 00000000..64ccea9f --- /dev/null +++ b/ml/dlib/dlib/image_loader/load_image.h @@ -0,0 +1,226 @@ +// Copyright (C) 2011 Davis E. King (davis@dlib.net), Nils Labugt, Changjiang Yang (yangcha@leidos.com) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_LOAd_IMAGE_Hh_ +#define DLIB_LOAd_IMAGE_Hh_ + +#include "load_image_abstract.h" +#include "../string.h" +#include "png_loader.h" +#include "jpeg_loader.h" +#include "image_loader.h" +#include <fstream> +#include <sstream> +#ifdef DLIB_GIF_SUPPORT +#include <gif_lib.h> +#endif + +namespace dlib +{ + namespace image_file_type + { + enum type + { + BMP, + JPG, + PNG, + DNG, + GIF, + UNKNOWN + }; + + inline type read_type(const std::string& file_name) + { + std::ifstream file(file_name.c_str(), std::ios::in|std::ios::binary); + if (!file) + throw image_load_error("Unable to open file: " + file_name); + + char buffer[9]; + file.read((char*)buffer, 8); + buffer[8] = 0; + + // Determine the true image type using link: + // http://en.wikipedia.org/wiki/List_of_file_signatures + + if (strcmp(buffer, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") == 0) + return PNG; + else if(buffer[0]=='\xff' && buffer[1]=='\xd8' && buffer[2]=='\xff') + return JPG; + else if(buffer[0]=='B' && buffer[1]=='M') + return BMP; + else if(buffer[0]=='D' && buffer[1]=='N' && buffer[2] == 'G') + return DNG; + else if(buffer[0]=='G' && buffer[1]=='I' && buffer[2] == 'F') + return GIF; + + return UNKNOWN; + } + }; + +// ---------------------------------------------------------------------------------------- + +// handle the differences in API between libgif v5 and older. +#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 +#define DLIB_GIFLIB_HANDLE_DIFF_VERSIONS ,0 +#else +#define DLIB_GIFLIB_HANDLE_DIFF_VERSIONS +#endif + + template <typename image_type> + void load_image ( + image_type& image, + const std::string& file_name + ) + { + const image_file_type::type im_type = image_file_type::read_type(file_name); + switch (im_type) + { + case image_file_type::BMP: load_bmp(image, file_name); return; + case image_file_type::DNG: load_dng(image, file_name); return; +#ifdef DLIB_PNG_SUPPORT + case image_file_type::PNG: load_png(image, file_name); return; +#endif +#ifdef DLIB_JPEG_SUPPORT + case image_file_type::JPG: load_jpeg(image, file_name); return; +#endif +#ifdef DLIB_GIF_SUPPORT + case image_file_type::GIF: + { + image_view<image_type> img(image); + GifFileType* gif = DGifOpenFileName(file_name.c_str() DLIB_GIFLIB_HANDLE_DIFF_VERSIONS); + try + { + if (gif == 0) throw image_load_error("Couldn't open file " + file_name); + if (DGifSlurp(gif) != GIF_OK) + throw image_load_error("Error reading from " + file_name); + + if (gif->ImageCount != 1) throw image_load_error("Dlib only supports reading GIF files containing one image."); + if (gif->SavedImages == 0) throw image_load_error("Unsupported GIF format 1."); + + ColorMapObject* cmo=gif->SColorMap?gif->SColorMap:gif->SavedImages->ImageDesc.ColorMap; + + if (cmo==0) throw image_load_error("Unsupported GIF format 2."); + if (cmo->Colors == 0) throw image_load_error("Unsupported GIF format 3."); + if (gif->SavedImages->ImageDesc.Width != gif->SWidth) throw image_load_error("Unsupported GIF format 4."); + if (gif->SavedImages->ImageDesc.Height != gif->SHeight) throw image_load_error("Unsupported GIF format 5."); + if (gif->SavedImages->RasterBits == 0) throw image_load_error("Unsupported GIF format 6."); + if (gif->Image.Top != 0) throw image_load_error("Unsupported GIF format 7."); + if (gif->Image.Left != 0) throw image_load_error("Unsupported GIF format 8."); + + img.set_size(gif->SHeight, gif->SWidth); + unsigned char* raster = gif->SavedImages->RasterBits; + GifColorType* colormap = cmo->Colors; + if (gif->Image.Interlace) + { + const long interlaced_offset[] = { 0, 4, 2, 1 }; + const long interlaced_jumps[] = { 8, 8, 4, 2 }; + for (int i = 0; i < 4; ++i) + { + for (long r = interlaced_offset[i]; r < img.nr(); r += interlaced_jumps[i]) + { + for (long c = 0; c < img.nc(); ++c) + { + if (*raster >= cmo->ColorCount) + throw image_load_error("Invalid GIF color value"); + rgb_pixel p; + p.red = colormap[*raster].Red; + p.green = colormap[*raster].Green; + p.blue = colormap[*raster].Blue; + assign_pixel(img[r][c], p); + ++raster; + } + } + } + } + else + { + for (long r = 0; r < img.nr(); ++r) + { + for (long c = 0; c < img.nc(); ++c) + { + if (*raster >= cmo->ColorCount) + throw image_load_error("Invalid GIF color value"); + rgb_pixel p; + p.red = colormap[*raster].Red; + p.green = colormap[*raster].Green; + p.blue = colormap[*raster].Blue; + assign_pixel(img[r][c], p); + ++raster; + } + } + } + DGifCloseFile(gif DLIB_GIFLIB_HANDLE_DIFF_VERSIONS); + } + catch(...) + { + if (gif) + DGifCloseFile(gif DLIB_GIFLIB_HANDLE_DIFF_VERSIONS); + throw; + } + return; + } +#endif + default: ; + } + + if (im_type == image_file_type::JPG) + { + std::ostringstream sout; + sout << "Unable to load image in file " + file_name + ".\n" + + "You must #define DLIB_JPEG_SUPPORT and link to libjpeg to read JPEG files.\n" + + "Do this by following the instructions at http://dlib.net/compile.html.\n\n"; +#ifdef _MSC_VER + sout << "Note that you must cause DLIB_JPEG_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, add it to the C/C++->Preprocessor->Preprocessor Definitions\n"; + sout << "field in Visual Studio's Property Pages window so it takes effect for your entire application."; +#else + sout << "Note that you must cause DLIB_JPEG_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, use a compiler switch like -DDLIB_JPEG_SUPPORT\n"; + sout << "so it takes effect for your entire application."; +#endif + throw image_load_error(sout.str()); + } + else if (im_type == image_file_type::PNG) + { + std::ostringstream sout; + sout << "Unable to load image in file " + file_name + ".\n" + + "You must #define DLIB_PNG_SUPPORT and link to libpng to read PNG files.\n" + + "Do this by following the instructions at http://dlib.net/compile.html.\n\n"; +#ifdef _MSC_VER + sout << "Note that you must cause DLIB_PNG_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, add it to the C/C++->Preprocessor->Preprocessor Definitions\n"; + sout << "field in Visual Studio's Property Pages window so it takes effect for your entire application.\n"; +#else + sout << "Note that you must cause DLIB_PNG_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, use a compiler switch like -DDLIB_PNG_SUPPORT\n"; + sout << "so it takes effect for your entire application."; +#endif + throw image_load_error(sout.str()); + } + else if (im_type == image_file_type::GIF) + { + std::ostringstream sout; + sout << "Unable to load image in file " + file_name + ".\n" + + "You must #define DLIB_GIF_SUPPORT and link to libgif to read GIF files.\n\n"; +#ifdef _MSC_VER + sout << "Note that you must cause DLIB_GIF_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, add it to the C/C++->Preprocessor->Preprocessor Definitions\n"; + sout << "field in Visual Studio's Property Pages window so it takes effect for your entire application.\n"; +#else + sout << "Note that you must cause DLIB_GIF_SUPPORT to be defined for your entire project.\n"; + sout << "So don't #define it in one file. Instead, use a compiler switch like -DDLIB_GIF_SUPPORT\n"; + sout << "so it takes effect for your entire application."; +#endif + throw image_load_error(sout.str()); + } + else + { + throw image_load_error("Unknown image file format: Unable to load image in file " + file_name); + } + } + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_LOAd_IMAGE_Hh_ + |