ImageLoader.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Graphics/ImageLoader.hpp>
00029 #include <iostream>
00030 #undef _UNICODE
00031 #include <IL/il.h>
00032 
00033 
00034 namespace sf_private
00035 {
00039 sfImageLoader& sfImageLoader::GetInstance()
00040 {
00041     static sfImageLoader Instance;
00042 
00043     return Instance;
00044 }
00045 
00046 
00050 sfImageLoader::sfImageLoader()
00051 {
00052     // Initialize DevIL
00053     ilInit();
00054     ILenum ErrorCode = ilGetError();
00055     if (ErrorCode != IL_NO_ERROR)
00056     {
00057         std::cerr << "Failed to initialize DevIL library (error code : " << ErrorCode << ")" << std::endl;
00058         return;
00059     }
00060 
00061     // Check DevIL version
00062     ILint ILVersion = ilGetInteger(IL_VERSION_NUM);
00063     if (ILVersion < IL_VERSION)
00064     {
00065         std::cerr << "DevIL library has incorrect version (is " << ILVersion << ", should be " << IL_VERSION << ")" << std::endl;
00066         return;
00067     }
00068 
00069     // Allow files to be overwritten by save operations if they already exist
00070     ilEnable(IL_FILE_OVERWRITE);
00071 
00072     // Force image origin to upper left corner
00073     ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
00074     ilEnable(IL_ORIGIN_SET);
00075 
00076     // Force load format to 32 bits RGBA
00077     ilSetInteger(IL_FORMAT_MODE, IL_RGBA);
00078     ilEnable(IL_FORMAT_SET);
00079 }
00080 
00081 
00085 sfImageLoader::~sfImageLoader()
00086 {
00087     // Shutdown DevIL library
00088     ilShutDown();
00089 }
00090 
00091 
00095 bool sfImageLoader::LoadImageFromFile(const std::string& Filename, std::vector<sfUint32>& Pixels, unsigned int& Width, unsigned int& Height)
00096 {
00097     // First generate a new DevIL image
00098     ILuint Image;
00099     ilGenImages(1, &Image);
00100     ilBindImage(Image);
00101 
00102     // Load from file
00103     if (ilLoadImage(const_cast<char*>(Filename.c_str())) == false)
00104     {
00105         std::cerr << "Failed to load image from file \"" << Filename << "\"" << std::endl;
00106         ilDeleteImages(1, &Image);
00107         return false;
00108     }
00109 
00110     // Get image dimensions
00111     Width  = ilGetInteger(IL_IMAGE_WIDTH);
00112     Height = ilGetInteger(IL_IMAGE_HEIGHT);
00113 
00114     // Copy pixels to pixel buffer
00115     const sfUint32* PixelsPtr = reinterpret_cast<const sfUint32*>(ilGetData());
00116     Pixels.assign(PixelsPtr, PixelsPtr + Width * Height);
00117 
00118     // Destroy DevIL image, we don't need it anymore
00119     ilDeleteImages(1, &Image);
00120 
00121     return true;
00122 }
00123 
00124 
00128 bool sfImageLoader::SaveImageToFile(const std::string& Filename, const std::vector<sfUint32>& Pixels, unsigned int Width, unsigned int Height)
00129 {
00130     // Flip original image
00131     std::vector<sfUint32> TempPixels(Width * Height, 0);
00132     for (unsigned int i = 0; i < Width; ++i)
00133         for (unsigned int j = 0; j < Height; ++j)
00134             TempPixels[i + j * Width] = Pixels[i + (Height - 1 - j) * Width];
00135 
00136     // Generate a new DevIL image
00137     ILuint Image;
00138     ilGenImages(1, &Image);
00139     ilBindImage(Image);
00140 
00141     // Set its size and format to match those of the image to save
00142     if (!ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, const_cast<sfUint32*>(&TempPixels[0])))
00143     {
00144         std::cerr << "Failed to save image to file \"" << Filename << "\"" << std::endl;
00145         ilDeleteImages(1, &Image);
00146         return false;
00147     }
00148 
00149     // Save image
00150     if (!ilSaveImage(const_cast<char*>(Filename.c_str())))
00151     {
00152         std::cerr << "Failed to save image to file \"" << Filename << "\"" << std::endl;
00153         ilDeleteImages(1, &Image);
00154         return false;
00155     }
00156 
00157     // Destroy DevIL image, we don't need it anymore
00158     ilDeleteImages(1, &Image);
00159 
00160     return true;
00161 }
00162 
00163 } // namespace sf_private