15 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wdocumentation"
17 #include <FreeImage.h>
18 #pragma clang diagnostic pop
20 #include <OpenGL/CGLMacro.h>
28 "title" :
"VuoImageGet",
42 __attribute__((constructor))
static void VuoImageGet_init(
void)
44 FreeImage_Initialise(
true);
52 if (fif != FIF_UNKNOWN)
53 VUserLog(
"Error: %s (%s format)", message, FreeImage_GetFormatFromFIF(fif));
73 if (!
VuoUrl_getParts(resolvedUrl, NULL, NULL, NULL, NULL, &path, NULL, NULL))
82 if (path[lastDot-6] ==
'%' && path[lastDot-5] ==
'4' && path[lastDot-4] ==
'0' && path[lastDot-2] ==
'x')
84 char c = path[lastDot-3];
85 if (c >=
'1' && c <=
'9')
100 if (!imageURL || !strlen(imageURL))
104 unsigned int dataLength;
113 unsigned char *pixels;
114 unsigned long pixelsWide;
115 unsigned long pixelsHigh;
117 FIMEMORY *hmem = FreeImage_OpenMemory((BYTE *)data, dataLength);
119 FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
120 if (fif == FIF_UNKNOWN)
122 VUserLog(
"Error: '%s': Couldn't determine image type.", imageURL);
125 if (!FreeImage_FIFSupportsReading(fif))
127 VUserLog(
"Error: '%s': This image type doesn't support reading.", imageURL);
131 dib = FreeImage_LoadFromMemory(fif, hmem, JPEG_EXIFROTATE);
132 FreeImage_CloseMemory(hmem);
136 VUserLog(
"Error: '%s': Failed to read image.", imageURL);
140 pixelsWide = FreeImage_GetWidth(dib);
141 pixelsHigh = FreeImage_GetHeight(dib);
143 const FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
144 const unsigned int bpp = FreeImage_GetBPP(dib);
145 const FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(dib);
146 const FIICCPROFILE *colorProfile = FreeImage_GetICCProfile(dib);
147 FITAG *exifColorSpace = NULL;
148 FreeImage_GetMetadata(FIMD_EXIF_EXIF, dib,
"ColorSpace", &exifColorSpace);
149 VDebugLog(
"ImageFormat=%d ImageType=%d BPP=%d colorType=%s Profile=%s(%d) EXIF_ColorSpace=%s", fif, type, bpp,
150 colorType == FIC_MINISWHITE ?
"minIsWhite" :
151 (colorType == FIC_MINISBLACK ?
"minIsBlack" :
152 (colorType == FIC_RGB ?
"RGB" :
153 (colorType == FIC_PALETTE ?
"indexed" :
154 (colorType == FIC_RGBALPHA ?
"RGBA" :
155 (colorType == FIC_CMYK ?
"CMYK" :
"unknown"))))),
156 colorProfile->flags & FIICC_COLOR_IS_CMYK ?
"CMYK" :
"RGB",
158 FreeImage_TagToString(FIMD_EXIF_EXIF, exifColorSpace));
160 if (type == FIT_FLOAT
161 || type == FIT_DOUBLE
162 || type == FIT_UINT16
164 || type == FIT_UINT32
165 || type == FIT_INT32)
168 colorDepth = VuoImageColorDepth_32;
169 format = GL_LUMINANCE;
171 FIBITMAP *dibFloat = FreeImage_ConvertToFloat(dib);
172 FreeImage_Unload(dib);
175 else if (type == FIT_RGB16
179 colorDepth = VuoImageColorDepth_32;
182 FIBITMAP *dibFloat = FreeImage_ConvertToRGBF(dib);
183 FreeImage_Unload(dib);
186 else if (type == FIT_RGBA16
187 || type == FIT_RGBAF)
190 colorDepth = VuoImageColorDepth_32;
193 FIBITMAP *dibFloat = FreeImage_ConvertToRGBAF(dib);
194 FreeImage_Unload(dib);
198 float *pixels = (
float *)FreeImage_GetBits(dib);
201 VUserLog(
"Error: '%s': Couldn't get pixels from image.", imageURL);
202 FreeImage_Unload(dib);
205 for (
int y = 0; y < pixelsHigh; ++y)
206 for (
int x = 0; x < pixelsWide; ++x)
208 float alpha = pixels[(y*pixelsWide + x)*4 + 3];
209 pixels[(y*pixelsWide + x)*4 + 0] *= alpha;
210 pixels[(y*pixelsWide + x)*4 + 1] *= alpha;
211 pixels[(y*pixelsWide + x)*4 + 2] *= alpha;
217 colorDepth = VuoImageColorDepth_8;
219 if (colorType == FIC_MINISWHITE
220 || colorType == FIC_MINISBLACK)
222 format = GL_LUMINANCE;
224 FIBITMAP *dibConverted = FreeImage_ConvertTo8Bits(dib);
225 FreeImage_Unload(dib);
228 else if (colorType == FIC_RGB
229 || (colorType == FIC_PALETTE && !FreeImage_IsTransparent(dib)))
233 FIBITMAP *dibConverted = FreeImage_ConvertTo24Bits(dib);
234 FreeImage_Unload(dib);
237 else if (colorType == FIC_RGBALPHA
238 || (colorType == FIC_PALETTE && FreeImage_IsTransparent(dib)))
242 FIBITMAP *dibConverted = FreeImage_ConvertTo32Bits(dib);
243 FreeImage_Unload(dib);
246 if (!FreeImage_PreMultiplyWithAlpha(dib))
247 VUserLog(
"Warning: Premultiplication failed.");
251 VUserLog(
"Error: '%s': Unknown colorType %d.", imageURL, colorType);
252 FreeImage_Unload(dib);
257 pixels = FreeImage_GetBits(dib);
260 VUserLog(
"Error: '%s': Couldn't get pixels from image.", imageURL);
261 FreeImage_Unload(dib);
270 bytesPerRow = (bytesPerRow + 3) & ~0x3;
273 FreeImage_Unload(dib);