#include <stdio.h>
#include <cldib.h>
#include "fi.h"
void fiInit()
{
dib_set_load_proc(cldib_load);
dib_set_save_proc(cldib_save);
}
FIBITMAP *fi_load(const char *fpath)
{
FREE_IMAGE_FORMAT fif= FreeImage_GetFIFFromFilename(fpath);
if( (fif == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(fif) )
return NULL;
return FreeImage_Load(fif, fpath, 0);
}
bool fi_save(FIBITMAP *fi, const char *fpath)
{
if(fi == NULL)
return false;
FREE_IMAGE_FORMAT fif= FreeImage_GetFIFFromFilename(fpath);
if( (fif == FIF_UNKNOWN) || !FreeImage_FIFSupportsWriting(fif) )
return false;
return FreeImage_Save(fif, fi, fpath, 0)==TRUE;
}
FIBITMAP *dib2fi(CLDIB *dib)
{
if(dib == NULL)
return NULL;
int dibW= dib_get_width(dib);
int dibH= dib_get_height(dib);
int dibB= dib_get_bpp(dib);
FIBITMAP *fi= FreeImage_Allocate(dibW, dibH, dibB);
if(fi == NULL)
return NULL;
memcpy(FreeImage_GetBits(fi), dib_get_img(dib),
dib_get_size_img(dib));
int nclrs= dib_get_nclrs(dib);
if(nclrs > 0)
memcpy(FreeImage_GetPalette(fi), dib_get_pal(dib), nclrs*RGB_SIZE);
return fi;
}
FI_SUPPORT_MODE fiGetSupportModes(FREE_IMAGE_FORMAT fif)
{
DWORD fsm= 0;
if( FreeImage_IsPluginEnabled(fif) != TRUE )
return (FI_SUPPORT_MODE)0;
if( FreeImage_FIFSupportsReading(fif) )
fsm |= FIF_MODE_READ;
if( FreeImage_FIFSupportsWriting(fif) )
fsm |= FIF_MODE_WRITE;
int ii, bpps[7]= { 1, 2, 4, 8, 16, 24, 32 };
for(ii=0; ii<7; ii++)
{
if( FreeImage_FIFSupportsExportBPP(fif, bpps[ii]) )
fsm |= 1 << (FIF_MODE_EXP_SHIFT+ii);
}
return (FI_SUPPORT_MODE)fsm;
}
int fiFillOfnFilter(char *szFilter, FI_SUPPORT_MODE fsm,
FREE_IMAGE_FORMAT *fifs, int fif_count)
{
int ii, jj=0, count= FreeImage_GetFIFCount();
int *fiflist= (int*)malloc(count*sizeof(int));
FREE_IMAGE_FORMAT fif;
if(fifs == NULL)
{
for(ii=0; ii<count; ii++)
{
if( fiGetSupportModes((FREE_IMAGE_FORMAT)ii) & fsm )
fiflist[jj++]= ii;
}
}
else
{
count= MIN(count, fif_count);
for(ii=0; ii<count; ii++)
{
if( fiGetSupportModes(fifs[ii]) & fsm )
fiflist[jj++]= fifs[ii];
}
}
count= jj;
fif_count= count>1 ? count+1 : count;
char filter[1024], str[64], *token;
filter[0]= '\0';
if(count > 1)
{
for(ii=0; ii<count; ii++)
{
fif= (FREE_IMAGE_FORMAT)fiflist[ii];
strcat(filter, FreeImage_GetFIFExtensionList(fif));
strcat(filter, ",");
}
filter[strlen(filter)-1]= '\0';
strcpy(szFilter, "Supported image files |");
token = strtok(filter, ",");
while(token != NULL)
{
sprintf(str, "*.%s;", token);
strcat(szFilter, str);
token = strtok(NULL, ",");
}
szFilter[strlen(szFilter)-1] = '|';
}
for(ii=0; ii<count; ii++)
{
fif= (FREE_IMAGE_FORMAT)fiflist[ii];
sprintf(filter, "%s (%s)|",
FreeImage_GetFIFDescription(fif),
FreeImage_GetFIFExtensionList(fif));
strcat(szFilter, filter);
strcpy(filter, FreeImage_GetFIFExtensionList(fif));
token = strtok(filter, ",");
while(token != NULL)
{
sprintf(str, "*.%s;", token);
strcat(szFilter, str);
token = strtok(NULL, ",");
}
szFilter[strlen(szFilter)-1] = '|';
}
strcat(szFilter, "|");
free(fiflist);
return fif_count;
}
CLDIB *fi2dib(FIBITMAP *fi)
{
if(fi == NULL)
return NULL;
int fiW= FreeImage_GetWidth(fi);
int fiH= FreeImage_GetHeight(fi);
int fiB= FreeImage_GetBPP(fi);
BYTE *fiD= FreeImage_GetBits(fi);
CLDIB *dib= dib_alloc(fiW, fiH, fiB, fiD);
if(dib == NULL)
return NULL;
int nclrs= FreeImage_GetColorsUsed(fi);
if(nclrs > 0)
memcpy(dib_get_pal(dib), FreeImage_GetPalette(fi), nclrs*RGB_SIZE);
dib_vflip(dib);
return dib;
}
CLDIB *cldib_load(const char *fpath, void *extra)
{
FIBITMAP *fi= fi_load(fpath);
if(fi == NULL)
return NULL;
CLDIB *dib= fi2dib(fi);
FreeImage_Unload(fi);
return dib;
}
bool cldib_save(const CLDIB *dib, const char *fpath, void *extra)
{
FIBITMAP *fi= dib2fi((CLDIB*)dib);
if(fi == NULL)
return false;
FreeImage_FlipVertical(fi);
bool res= fi_save(fi, fpath);
FreeImage_Unload(fi);
return res;
}