]> git.sesse.net Git - casparcg/blob - modules/image/util/image_loader.cpp
[image_producer] #558 Fixed inconsistency in what file extensions are supported and...
[casparcg] / modules / image / util / image_loader.cpp
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Robert Nagy, ronag89@gmail.com
20 */
21
22 #include "image_loader.h"
23
24 #include <common/except.h>
25 #include <common/utf.h>
26
27 #if defined(_MSC_VER)
28 #pragma warning (disable : 4714) // marked as __forceinline not inlined
29 #endif
30
31 #include <boost/exception/errinfo_file_name.hpp>
32 #include <boost/filesystem.hpp>
33
34 #include "image_algorithms.h"
35 #include "image_view.h"
36
37 namespace caspar { namespace image {
38
39 std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename)
40 {
41         if(!boost::filesystem::exists(filename))
42                 CASPAR_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(u8(filename)));
43
44 #ifdef WIN32
45         FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeU(filename.c_str(), 0);
46 #else
47         FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(u8(filename).c_str(), 0);
48 #endif
49
50         if (fif == FIF_UNKNOWN)
51 #ifdef WIN32
52                 fif = FreeImage_GetFIFFromFilenameU(filename.c_str());
53 #else
54                 fif = FreeImage_GetFIFFromFilename(u8(filename).c_str());
55 #endif
56
57         if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif))
58                 CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format."));
59
60 #ifdef WIN32
61         auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_LoadU(fif, filename.c_str(), 0), FreeImage_Unload);
62 #else
63         auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Load(fif, u8(filename).c_str(), 0), FreeImage_Unload);
64 #endif
65
66         if(FreeImage_GetBPP(bitmap.get()) != 32)
67         {
68                 bitmap = std::shared_ptr<FIBITMAP>(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload);
69                 if(!bitmap)
70                         CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format."));
71         }
72
73         //PNG-images need to be premultiplied with their alpha
74         if(fif == FIF_PNG)
75         {
76                 image_view<bgra_pixel> original_view(FreeImage_GetBits(bitmap.get()), FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()));
77                 premultiply(original_view);
78         }
79
80         return bitmap;
81 }
82
83 std::shared_ptr<FIBITMAP> load_png_from_memory(const void* memory_location, size_t size)
84 {
85         FREE_IMAGE_FORMAT fif = FIF_PNG;
86
87         auto memory = std::unique_ptr<FIMEMORY, decltype(&FreeImage_CloseMemory)>(
88                         FreeImage_OpenMemory(static_cast<BYTE*>(const_cast<void*>(memory_location)), static_cast<DWORD>(size)),
89                         FreeImage_CloseMemory);
90         auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_LoadFromMemory(fif, memory.get(), 0), FreeImage_Unload);
91
92         if (FreeImage_GetBPP(bitmap.get()) != 32)
93         {
94                 bitmap = std::shared_ptr<FIBITMAP>(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload);
95
96                 if (!bitmap)
97                         CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format."));
98         }
99
100         return bitmap;
101 }
102
103 const std::set<std::wstring>& supported_extensions()
104 {
105         static const std::set<std::wstring> extensions =
106         {
107                 L".png",
108                 L".tga",
109                 L".bmp",
110                 L".jpg",
111                 L".jpeg",
112                 L".gif",
113                 L".tiff",
114                 L".tif",
115                 L".jp2",
116                 L".jpx",
117                 L".j2k",
118                 L".j2c"
119         };
120
121         return extensions;
122 }
123
124 }}