Skip to content

Commit f8e3752

Browse files
guiltSiegeLord
authored andcommitted
Add preliminary FreeImage support in image addon.
1 parent 46fa045 commit f8e3752

File tree

9 files changed

+441
-0
lines changed

9 files changed

+441
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ option(WANT_IMAGE "Enable image load/save addon" on)
141141
if (NOT IPHONE)
142142
option(WANT_IMAGE_JPG "Enable JPEG support in image addon" on)
143143
option(WANT_IMAGE_PNG "Enable PNG support in image addon" on)
144+
option(WANT_IMAGE_FREEIMAGE "Enable FreeImage support in image addon" on)
144145
endif (NOT IPHONE)
145146
option(WANT_IMAGE_WEBP "Enable WebP support in image addon" on)
146147

addons/image/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ if(WANT_NATIVE_IMAGE_LOADER)
8080
endif(WANT_NATIVE_IMAGE_LOADER)
8181

8282
# Now look for third party libraries to handle the unsupported formats
83+
if(WANT_IMAGE_FREEIMAGE)
84+
find_package(FREEIMAGE)
85+
if(FREEIMAGE_FOUND)
86+
# HAVE_FREEIMAGE means libfreeimage is available (and should be used)
87+
set(ALLEGRO_CFG_IIO_HAVE_FREEIMAGE 1)
88+
set(ALLEGRO_CFG_IIO_SUPPORT_FREEIMAGE 1)
89+
list(APPEND IMAGE_SOURCES freeimage.c)
90+
list(APPEND IMAGE_LIBRARIES ${FREEIMAGE_LIBRARIES})
91+
list(APPEND IMAGE_DEFINES ${FREEIMAGE_DEFINITIONS})
92+
list(APPEND IMAGE_INCLUDE_DIRECTORIES ${FREEIMAGE_INCLUDE_PATH})
93+
include_directories(SYSTEM ${FREEIMAGE_INCLUDE_PATH})
94+
else(FREEIMAGE_FOUND)
95+
message("WARNING: FreeImage not found, disabling support")
96+
endif(FREEIMAGE_FOUND)
97+
endif(WANT_IMAGE_FREEIMAGE)
8398

8499
if(WANT_IMAGE_PNG AND NOT ALLEGRO_CFG_IIO_SUPPORT_PNG)
85100
find_package(PNG)

addons/image/allegro5/internal/aintern_image.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ ALLEGRO_IIO_FUNC(bool, _al_identify_png, (ALLEGRO_FILE *f));
4949
ALLEGRO_IIO_FUNC(bool, _al_identify_jpg, (ALLEGRO_FILE *f));
5050
ALLEGRO_IIO_FUNC(bool, _al_identify_webp, (ALLEGRO_FILE *f));
5151

52+
#ifdef ALLEGRO_CFG_IIO_HAVE_FREEIMAGE
53+
ALLEGRO_IIO_FUNC(bool, _al_init_fi, (void));
54+
ALLEGRO_IIO_FUNC(void, _al_shutdown_fi, (void));
55+
ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_fi_bitmap, (const char *filename, int flags));
56+
ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_fi_bitmap_f, (ALLEGRO_FILE *f, int flags));
57+
ALLEGRO_IIO_FUNC(bool, _al_identify_fi, (ALLEGRO_FILE *f));
58+
#endif
59+
5260
#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS
5361
ALLEGRO_IIO_FUNC(bool, _al_init_gdiplus, (void));
5462
ALLEGRO_IIO_FUNC(void, _al_shutdown_gdiplus, (void));

addons/image/allegro5/internal/aintern_image_cfg.h.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#cmakedefine ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER
22

33
/* which libraries are present and needed? */
4+
#cmakedefine ALLEGRO_CFG_IIO_HAVE_FREEIMAGE
45
#cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS
56
#cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H
67
#cmakedefine ALLEGRO_CFG_IIO_HAVE_ANDROID

addons/image/freeimage.c

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/* Allegro wrapper routines for FreeImage
2+
* by Karthik Kumar Viswanathan <[email protected]>.
3+
*/
4+
5+
#include <FreeImage.h>
6+
7+
#include "allegro5/allegro.h"
8+
#include "allegro5/allegro_image.h"
9+
#include "allegro5/internal/aintern_exitfunc.h"
10+
#include "allegro5/internal/aintern_image.h"
11+
12+
#include "iio.h"
13+
14+
ALLEGRO_DEBUG_CHANNEL("image")
15+
16+
static bool freeimage_initialized = false;
17+
18+
bool _al_init_fi(void)
19+
{
20+
if(freeimage_initialized)
21+
return true;
22+
FreeImage_Initialise(FALSE);
23+
_al_add_exit_func(_al_shutdown_fi, "_al_shutdown_fi");
24+
return true;
25+
}
26+
27+
void _al_shutdown_fi(void)
28+
{
29+
if(!freeimage_initialized)
30+
return;
31+
FreeImage_DeInitialise();
32+
freeimage_initialized = false;
33+
}
34+
35+
static ALLEGRO_BITMAP *_al_fi_to_al_bitmap(FIBITMAP *fib) {
36+
int width = 0, height = 0;
37+
ALLEGRO_BITMAP *bitmap = NULL;
38+
width = FreeImage_GetWidth(fib);
39+
height = FreeImage_GetHeight(fib);
40+
bitmap = al_create_bitmap(width, height);
41+
if(bitmap) {
42+
ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap(bitmap,
43+
ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY);
44+
if (a_lock) {
45+
unsigned char *out = (unsigned char *)a_lock->data;
46+
int out_inc = a_lock->pitch - (width*4);
47+
for(int j=height - 1; j > -1; --j) {
48+
for(int i=0; i < width; ++i) {
49+
RGBQUAD color;
50+
if(FreeImage_GetPixelColor(fib, i, j, &color) == FALSE) {
51+
ALLEGRO_ERROR("Unable to get pixel data at %d,%d\n", i , j);
52+
}
53+
*out++ = (unsigned char) color.rgbBlue;
54+
*out++ = (unsigned char) color.rgbGreen;
55+
*out++ = (unsigned char) color.rgbRed;
56+
*out++ = (unsigned char) color.rgbReserved;
57+
}
58+
out += out_inc;
59+
}
60+
al_unlock_bitmap(bitmap);
61+
}
62+
}
63+
return bitmap;
64+
}
65+
66+
ALLEGRO_BITMAP *_al_load_fi_bitmap(const char *filename, int flags)
67+
{
68+
FIBITMAP *fib = NULL;
69+
ALLEGRO_BITMAP *bitmap = NULL;
70+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
71+
72+
ASSERT(filename);
73+
ASSERT(freeimage_initialized == true);
74+
75+
fif = FreeImage_GetFIFFromFilename(filename);
76+
if(fif == FIF_UNKNOWN)
77+
fif = FreeImage_GetFileType(filename, 0);
78+
if(fif == FIF_UNKNOWN)
79+
return bitmap;
80+
81+
{
82+
FIBITMAP *fibRaw = FreeImage_Load(fif, filename, flags);
83+
if(!fibRaw)
84+
return bitmap;
85+
fib = FreeImage_ConvertTo32Bits(fibRaw);
86+
FreeImage_Unload(fibRaw);
87+
if(!fib)
88+
return bitmap;
89+
}
90+
91+
bitmap = _al_fi_to_al_bitmap(fib);
92+
FreeImage_Unload(fib);
93+
return bitmap;
94+
}
95+
96+
static unsigned int _fiio_al_read(void *buffer, unsigned size, unsigned count, fi_handle handle) {
97+
return (unsigned int) al_fread((ALLEGRO_FILE *)handle, buffer, (count * size));
98+
}
99+
100+
static unsigned int _fiio_al_write(void *buffer, unsigned size, unsigned count, fi_handle handle) {
101+
return (unsigned int) al_fwrite((ALLEGRO_FILE *)handle, buffer, (count * size));
102+
}
103+
104+
static int _fiio_al_fseek(fi_handle handle, long offset, int origin) {
105+
return al_fseek((ALLEGRO_FILE *)handle, offset, origin);
106+
}
107+
108+
static long _fiio_al_ftell(fi_handle handle) {
109+
return (long) al_ftell((ALLEGRO_FILE *)handle);
110+
}
111+
112+
ALLEGRO_BITMAP *_al_load_fi_bitmap_f(ALLEGRO_FILE *f, int flags)
113+
{
114+
FreeImageIO fio;
115+
ALLEGRO_BITMAP *bitmap = NULL;
116+
FIBITMAP *fib = NULL;
117+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
118+
119+
ASSERT(f);
120+
ASSERT(freeimage_initialized == true);
121+
122+
fio.read_proc = _fiio_al_read;
123+
fio.write_proc = _fiio_al_write;
124+
fio.seek_proc = _fiio_al_fseek;
125+
fio.tell_proc = _fiio_al_ftell;
126+
127+
fif = FreeImage_GetFileTypeFromHandle(&fio, (fi_handle)f, 0);
128+
if(fif == FIF_UNKNOWN)
129+
return bitmap;
130+
131+
{
132+
FIBITMAP *fibRaw = FreeImage_LoadFromHandle(fif, &fio, (fi_handle)f, 0);
133+
if(!fibRaw)
134+
return bitmap;
135+
fib = FreeImage_ConvertTo32Bits(fibRaw);
136+
FreeImage_Unload(fibRaw);
137+
if(!fib)
138+
return bitmap;
139+
}
140+
141+
bitmap = _al_fi_to_al_bitmap(fib);
142+
FreeImage_Unload(fib);
143+
return bitmap;
144+
}
145+
146+
bool _al_identify_fi(ALLEGRO_FILE *f)
147+
{
148+
FreeImageIO fio;
149+
ALLEGRO_BITMAP *bitmap = NULL;
150+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
151+
152+
ASSERT(f);
153+
ASSERT(freeimage_initialized == true);
154+
155+
fio.read_proc = _fiio_al_read;
156+
fio.write_proc = _fiio_al_write;
157+
fio.seek_proc = _fiio_al_fseek;
158+
fio.tell_proc = _fiio_al_ftell;
159+
160+
fif = FreeImage_GetFileTypeFromHandle(&fio, (fi_handle)f, 0);
161+
if(fif == FIF_UNKNOWN)
162+
return false;
163+
164+
return true;
165+
}
166+
167+
168+
/* vim: set sts=3 sw=3 et: */

addons/image/iio.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,25 @@ bool al_init_image_addon(void)
5252
should be used. i.e., ALLEGRO_CFG_IIO_HAVE_GDIPLUS and
5353
ALLEGRO_CFG_IIO_HAVE_PNG will never both be set. */
5454

55+
#ifdef ALLEGRO_CFG_IIO_HAVE_FREEIMAGE
56+
{
57+
char const *extensions[] = {".ico", ".jng", ".koala", ".lbm",
58+
".iff", ".mng", ".pbm", ".pcd", ".pgm", ".ppm", ".ras", ".wbmp",
59+
".psd", ".cut", ".xpm", ".hdr", ".fax", ".sgi", ".exr", ".raw",
60+
".j2k", ".jp2", ".jpf", ".jpm", ".jpx", ".mj2", ".pfm", ".pict",
61+
".jxr", ".jbg", NULL};
62+
int i;
63+
64+
if (_al_init_fi()) {
65+
for (i = 0; extensions[i]; i++) {
66+
success |= al_register_bitmap_loader(extensions[i], _al_load_fi_bitmap);
67+
success |= al_register_bitmap_loader_f(extensions[i], _al_load_fi_bitmap_f);
68+
success |= al_register_bitmap_identifier(extensions[i], _al_load_fi_bitmap_f);
69+
}
70+
}
71+
}
72+
#endif
73+
5574
#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS
5675
{
5776
char const *extensions[] = {".tif", ".tiff", ".jpg", ".jpeg", ".gif",

cmake/FindFreeImage.cmake

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# Try to find the FreeImage library and include path.
3+
# Once done this will define
4+
#
5+
# FREEIMAGE_FOUND
6+
# FREEIMAGE_INCLUDE_PATH
7+
# FREEIMAGE_LIBRARY
8+
#
9+
10+
IF (WIN32)
11+
FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
12+
$ENV{FI_HOME}/include
13+
${FREEIMAGE_ROOT_DIR}/include
14+
${FREEIMAGE_ROOT_DIR}
15+
DOC "The directory where FreeImage.h resides")
16+
FIND_LIBRARY( FREEIMAGE_LIBRARY
17+
NAMES FreeImage freeimage
18+
PATHS
19+
$ENV{FI_HOME}/lib/$ENV{PROCESSOR_ARCHITECTURE}
20+
${FREEIMAGE_ROOT_DIR}/lib
21+
${FREEIMAGE_ROOT_DIR}
22+
DOC "The FreeImage library")
23+
ELSE (WIN32)
24+
FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
25+
/usr/include
26+
/usr/local/include
27+
/sw/include
28+
/opt/local/include
29+
DOC "The directory where FreeImage.h resides")
30+
FIND_LIBRARY( FREEIMAGE_LIBRARY
31+
NAMES FreeImage freeimage
32+
PATHS
33+
/usr/lib64
34+
/usr/lib
35+
/usr/local/lib64
36+
/usr/local/lib
37+
/sw/lib
38+
/opt/local/lib
39+
DOC "The FreeImage library")
40+
ENDIF (WIN32)
41+
42+
SET(FREEIMAGE_LIBRARIES ${FREEIMAGE_LIBRARY})
43+
44+
IF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
45+
SET( FREEIMAGE_FOUND TRUE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
46+
ELSE (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
47+
SET( FREEIMAGE_FOUND FALSE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
48+
ENDIF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
49+
50+
MARK_AS_ADVANCED(
51+
FREEIMAGE_FOUND
52+
FREEIMAGE_LIBRARY
53+
FREEIMAGE_LIBRARIES
54+
FREEIMAGE_INCLUDE_PATH)
55+

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ if(ANDROID)
114114
endif(ANDROID)
115115

116116
example(ex_bitmap ${IMAGE} ${DATA_IMAGES})
117+
example(ex_bitmap_file ${IMAGE} ${DATA_IMAGES})
117118
example(ex_bitmap_flip ${IMAGE} ${FONT} ${DATA_IMAGES})
118119
example(ex_blend ${FONT} ${IMAGE} ${PRIM} ${DATA_IMAGES})
119120
example(ex_blend2 ex_blend2.cpp ${NIHGUI} ${IMAGE} ${DATA_IMAGES})

0 commit comments

Comments
 (0)