PDL-IO-Image
view release on metacpan or search on metacpan
}
break;
case FIT_RGBAF: /* 128-bit RGBA float image: 4 x 32-bit IEEE floating point */
{
PDL_Float *pdata = (PDL_Float *) pixels->data;
for(y = 0; y < h; y++) {
FIRGBAF *bits = (FIRGBAF*) FreeImage_GetScanLine(dib, y);
for(x = 0; x < w; x++) {
bits[x].red = pdata[(h-1-y)*w + x];
bits[x].green = pdata[(h-1-y)*w + x + wxh];
bits[x].blue = pdata[(h-1-y)*w + x + 2*wxh];
bits[x].alpha = pdata[(h-1-y)*w + x + 3*wxh];
}
}
}
break;
default:
warn("FAIL: unknown image type '%d'", fit);
break;
}
cu = FreeImage_GetColorsUsed(dib);
if (palsize > 0 && cu > 0) {
if (palsize > cu) palsize = cu;
BYTE *pdata = palette->data;
RGBQUAD *pal = FreeImage_GetPalette(dib);
for (i = 0; i < palsize; i++) {
pal[i].rgbRed = pdata[i*3];
pal[i].rgbGreen = pdata[i*3 + 1];
pal[i].rgbBlue = pdata[i*3 + 2];
pal[i].rgbReserved = 0;
}
}
if (palsize > 0 && cu == 0) {
warn("ignoring palete piddle");
}
Newz(0, RETVAL, 1, struct img_struct);
if (RETVAL == NULL) croak("FAIL: Newz failed");
RETVAL->dib = dib;
}
OUTPUT:
RETVAL
PDL::IO::Image
clone(PDL::IO::Image self)
CODE:
{
Newz(0, RETVAL, 1, struct img_struct);
if (RETVAL == NULL) croak("FAIL: Newz failed");
FIBITMAP *newdib = FreeImage_Clone(self->dib);
if (newdib == NULL) croak("FAIL: FreeImage_Clone failed");
RETVAL->dib = newdib;
}
OUTPUT:
RETVAL
void
dump_bitmap(PDL::IO::Image self, int target_bpp=0)
PPCODE:
{
SV *bmp_sv, *pal_sv;
unsigned char *bmp = NULL, *pal = NULL;
unsigned w, h, bpp, cu, it, sz, szp, szl, y, i;
FIBITMAP *newdib = NULL, *b = NULL;
/* FIRST: we need FIT_BITMAP */
it = FreeImage_GetImageType(self->dib);
if (it==FIT_RGB16 || it==FIT_RGBA16 || it==FIT_RGBF || it==FIT_RGBAF) {
newdib = FreeImage_ToneMapping(self->dib, FITMO_REINHARD05, 0, 0);
}
else {
newdib = FreeImage_ConvertToType(self->dib, FIT_BITMAP, 1);
}
if (!newdib) {
warn("dump_bitmap failed to convert image into a BITMAP");
XSRETURN_UNDEF;
}
/* SECOND: we only want 8/24/32-bpp output */
bpp = FreeImage_GetBPP(newdib);
if (target_bpp!=8 && target_bpp!=24 && target_bpp!=32) target_bpp = 0;
if (target_bpp==0 && (bpp==1 || bpp==4 || bpp==8)) target_bpp = 8;
if (target_bpp==0 && (bpp==16 || bpp==24)) target_bpp = 24;
if (target_bpp==0 && bpp>=32) target_bpp = 32;
if (target_bpp==8 && bpp!=8) {
/* XXX BEWARE: high-color bitmap (16, 24 or 32-bit) is converted into a greyscale bitmap */
b = FreeImage_ConvertTo8Bits(newdib);
}
else if (target_bpp==24 && bpp!=24) {
b = FreeImage_ConvertTo24Bits(newdib);
}
else if (target_bpp==32 && bpp!=32) {
b = FreeImage_ConvertTo32Bits(newdib);
}
if (b) {
FreeImage_Unload(newdib);
newdib = b;
}
bpp = FreeImage_GetBPP(newdib);
w = FreeImage_GetWidth(newdib);
h = FreeImage_GetHeight(newdib);
cu = FreeImage_GetColorsUsed(newdib);
szp = (bpp/8); /* pixel size */
szl = szp * w; /* line size */
sz = szl * h; /* picture size */
if (bpp==32 || bpp==24 || bpp==8) {
bmp_sv = NEWSV(0, sz);
SvPOK_only(bmp_sv);
SvCUR_set(bmp_sv, sz);
bmp = (unsigned char *)SvPV_nolen(bmp_sv);
for(i = 0, y = 0; y < h; y++) {
BYTE *bits = FreeImage_GetScanLine(newdib, h-y-1);
Copy(bits, bmp + i, szl, BYTE);
i += szl;
}
XPUSHs(sv_2mortal(newSViv(w)));
XPUSHs(sv_2mortal(newSViv(h)));
XPUSHs(sv_2mortal(newSViv(bpp)));
XPUSHs(sv_2mortal(bmp_sv));
if (cu>0) {
RGBQUAD *p = FreeImage_GetPalette(newdib);
pal_sv = NEWSV(0, cu*3);
SvPOK_only(pal_sv);
SvCUR_set(pal_sv, cu*3);
pal = (unsigned char *)SvPV_nolen(pal_sv);
for (i = 0; i < cu; i++) {
pal[i*3] = (unsigned char) p[i].rgbRed;
pal[i*3 + 1] = (unsigned char) p[i].rgbGreen;
pal[i*3 + 2] = (unsigned char) p[i].rgbBlue;
}
XPUSHs(sv_2mortal(pal_sv));
}
}
else {
warn("dump_bitmap: unexpected bpp");
}
FreeImage_Unload(newdib);
}
const char*
free_image_version(SV *class)
CODE:
RETVAL = FreeImage_GetVersion();
OUTPUT:
RETVAL
void
format_list(SV *class)
PPCODE:
{
int i;
for(i = 0; i < FreeImage_GetFIFCount(); i++) {
if(FreeImage_IsPluginEnabled((FREE_IMAGE_FORMAT)i)) {
const char *f = FreeImage_GetFormatFromFIF((FREE_IMAGE_FORMAT)i);
XPUSHs(sv_2mortal(newSVpvn(f, strlen(f))));
}
}
}
const char*
format_extension_list(SV *class, SV *f)
CODE:
RETVAL = FreeImage_GetFIFExtensionList(_sv2fif(f));
OUTPUT:
RETVAL
const char*
format_mime_type(SV *class, SV *f)
CODE:
RETVAL = FreeImage_GetFIFMimeType(_sv2fif(f));
OUTPUT:
RETVAL
const char*
format_description(SV *class, SV *f)
CODE:
RETVAL = FreeImage_GetFIFDescription(_sv2fif(f));
OUTPUT:
RETVAL
int
format_can_read(SV *class, SV *f)
CODE:
RETVAL = FreeImage_IsPluginEnabled(_sv2fif(f)) && FreeImage_FIFSupportsReading(_sv2fif(f));
OUTPUT:
RETVAL
int
format_can_write(SV *class, SV *f)
CODE:
RETVAL = FreeImage_IsPluginEnabled(_sv2fif(f)) && FreeImage_FIFSupportsWriting(_sv2fif(f));
OUTPUT:
RETVAL
int
format_can_export_type(SV *class, SV *f, SV *t)
CODE:
RETVAL = FreeImage_FIFSupportsExportType(_sv2fif(f), _sv2fit(t));
OUTPUT:
RETVAL
int
format_can_export_bpp(SV *class, SV *f, int bpp)
CODE:
RETVAL = FreeImage_FIFSupportsExportBPP(_sv2fif(f), bpp);
OUTPUT:
RETVAL
const char *
format_from_mime(SV *class, const char *mime)
CODE:
RETVAL = FreeImage_GetFormatFromFIF(FreeImage_GetFIFFromMime(mime));
OUTPUT:
RETVAL
const char *
format_from_file(SV *class, const char *filename)
CODE:
int fif = FreeImage_GetFileType(filename, 0);
if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename);
RETVAL = FreeImage_GetFormatFromFIF(fif);
OUTPUT:
RETVAL
const char*
get_image_type(PDL::IO::Image self)
CODE:
RETVAL = _fit2str(FreeImage_GetImageType(self->dib));
OUTPUT:
RETVAL
unsigned
get_colors_used(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetColorsUsed(self->dib);
OUTPUT:
RETVAL
unsigned
get_bpp(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetBPP(self->dib);
OUTPUT:
RETVAL
unsigned
get_width(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetWidth(self->dib);
OUTPUT:
RETVAL
unsigned
get_height(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetHeight(self->dib);
OUTPUT:
RETVAL
unsigned
get_dots_per_meter_x(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetDotsPerMeterX(self->dib);
OUTPUT:
RETVAL
void
set_dots_per_meter_x(PDL::IO::Image self, unsigned res)
PPCODE:
FreeImage_SetDotsPerMeterX(self->dib, res);
XPUSHs(ST(0)); /* return self */
unsigned
get_dots_per_meter_y(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetDotsPerMeterY(self->dib);
OUTPUT:
RETVAL
void
set_dots_per_meter_y(PDL::IO::Image self, unsigned res)
PPCODE:
FreeImage_SetDotsPerMeterY(self->dib, res);
XPUSHs(ST(0)); /* return self */
const char*
get_color_type(PDL::IO::Image self)
CODE:
RETVAL = _fic2str(FreeImage_GetColorType(self->dib));
OUTPUT:
RETVAL
int
is_transparent(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_IsTransparent(self->dib);
OUTPUT:
RETVAL
int
get_transparent_index(PDL::IO::Image self)
CODE:
RETVAL = FreeImage_GetTransparentIndex(self->dib);
OUTPUT:
RETVAL
void
set_transparent_index(PDL::IO::Image self, int index)
PPCODE:
FreeImage_SetTransparentIndex(self->dib, index);
XPUSHs(ST(0)); /* return self */
void
flip_horizontal(PDL::IO::Image self)
PPCODE:
if(!FreeImage_FlipHorizontal(self->dib)) {
warn("FreeImage_FlipHorizontal failed");
}
XPUSHs(ST(0)); /* return self */
void
flip_vertical(PDL::IO::Image self)
PPCODE:
if(!FreeImage_FlipVertical(self->dib)) {
warn("FreeImage_FlipVertical failed");
}
XPUSHs(ST(0)); /* return self */
void
convert_image_type(PDL::IO::Image self, SV * dst_image_type, int scale_linear=1)
PPCODE:
{
FREE_IMAGE_TYPE fit = _sv2fit(dst_image_type);
if (fit == FIT_UNKNOWN) {
warn("invalid dst_image_type");
}
else {
FIBITMAP *newdib = FreeImage_ConvertToType(self->dib, fit, scale_linear);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertToType (fit=%d) failed", fit);
}
}
XPUSHs(ST(0)); /* return self */
}
void
adjust_colors(PDL::IO::Image self, double brightness=0, double contrast=0, double gamma=0, int invert=0)
PPCODE:
if(!FreeImage_AdjustColors(self->dib, brightness, contrast, gamma, invert)) {
warn("FreeImage_AdjustColors failed");
}
XPUSHs(ST(0)); /* return self */
void
tone_mapping(PDL::IO::Image self, int tmo, double p1=0, double p2=0)
PPCODE:
if (tmo == FITMO_DRAGO03 || tmo == FITMO_REINHARD05 || tmo == FITMO_FATTAL02) {
FIBITMAP *newdib = FreeImage_ToneMapping(self->dib, tmo, p1, p2);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ToneMapping (tmp=%d) failed", tmo);
}
}
else {
warn("invalid tone mapping operator");
}
XPUSHs(ST(0)); /* return self */
void
rotate(PDL::IO::Image self, double angle, ...)
PPCODE:
{
FIBITMAP *newdib = NULL;
unsigned bpp = FreeImage_GetBPP(self->dib);
FREE_IMAGE_TYPE fit = FreeImage_GetImageType(self->dib);
if (items > 2) {
switch(fit) {
case FIT_BITMAP:
switch(bpp) {
case 8:
{
BYTE color = (BYTE)SvUV(ST(2));
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
case 24:
case 32:
{
RGBQUAD color = { 0, 0, 0, 0 };
if (items >= 3) color.rgbRed = (BYTE)SvUV(ST(2));
if (items >= 4) color.rgbGreen = (BYTE)SvUV(ST(3));
if (items >= 5) color.rgbBlue = (BYTE)SvUV(ST(4));
if (items >= 6) color.rgbReserved = (BYTE)SvUV(ST(5));
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
default:
/* warn("FAIL: do not know how to handle bpp '%d'", bpp); */
break;
}
break;
case FIT_UINT16:
{
WORD color = (WORD)SvUV(ST(2));;
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
case FIT_RGB16:
case FIT_RGBA16:
{
FIRGBA16 color = { 0, 0, 0, 0 };
if (items >= 3) color.red = (WORD)SvUV(ST(2));
if (items >= 4) color.green = (WORD)SvUV(ST(3));
if (items >= 5) color.blue = (WORD)SvUV(ST(4));
if (items >= 6) color.alpha = (WORD)SvUV(ST(5));
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
case FIT_FLOAT:
{
float color = (float)SvNV(ST(2));
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
case FIT_RGBF:
case FIT_RGBAF:
{
FIRGBAF color = { 0, 0, 0, 0 };
if (items >= 3) color.red = (float)SvNV(ST(2));
if (items >= 4) color.green = (float)SvNV(ST(3));
if (items >= 5) color.blue = (float)SvNV(ST(4));
if (items >= 6) color.alpha = (float)SvNV(ST(5));
newdib = FreeImage_Rotate(self->dib, angle, &color);
}
break;
default:
/* warn("FAIL: do not know how to handle image type '%d'", fit); */
break;
}
}
if (!newdib) {
newdib = FreeImage_Rotate(self->dib, angle, NULL);
}
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_Rotate failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_dither(PDL::IO::Image self, int algorithm=FID_FS)
PPCODE:
{
FIBITMAP *newdib = FreeImage_Dither(self->dib, algorithm);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_Dither failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_threshhold(PDL::IO::Image self, unsigned threshold=127)
PPCODE:
{
FIBITMAP *newdib = FreeImage_Threshold(self->dib, (BYTE)threshold);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_Threshold failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_quantize(PDL::IO::Image self, int quantize=FIQ_WUQUANT)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ColorQuantize(self->dib, quantize);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ColorQuantize failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_4bpp(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo4Bits(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo4Bits failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_8bpp(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo8Bits(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo8Bits failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_8bpp_grey(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertToGreyscale(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertToGreyscale failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_16bpp_555(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo16Bits555(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo16Bits555 failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_16bpp_565(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo16Bits565(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo16Bits565 failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_24bpp(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo24Bits(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo24Bits failed");
}
XPUSHs(ST(0)); /* return self */
}
void
color_to_32bpp(PDL::IO::Image self)
PPCODE:
{
FIBITMAP *newdib = FreeImage_ConvertTo32Bits(self->dib);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_ConvertTo32Bits failed");
}
XPUSHs(ST(0)); /* return self */
}
void
rescale(PDL::IO::Image self, int dst_width=0, int dst_height=0, int filter=FILTER_CATMULLROM)
PPCODE:
{
if (dst_height<=0 && dst_width>0) {
double ratio = (double)dst_width / (double)FreeImage_GetWidth(self->dib);
dst_height = (int)floor(0.5 + ratio * (double)FreeImage_GetHeight(self->dib));
}
else if (dst_width<=0 && dst_height>0) {
double ratio = (double)dst_height / (double)FreeImage_GetHeight(self->dib);
dst_width = (int)floor(0.5 + ratio * (double)FreeImage_GetWidth(self->dib));
}
if (dst_height>0 && dst_width>0) {
FIBITMAP *newdib = FreeImage_Rescale(self->dib, dst_width, dst_height, filter);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_Rescale failed");
}
}
XPUSHs(ST(0)); /* return self */
}
void
rescale_pct(PDL::IO::Image self, double dst_width_pct=0, double dst_height_pct=0, int filter=FILTER_CATMULLROM)
PPCODE:
{
int dst_height = (int)floor(0.5 + (double)FreeImage_GetHeight(self->dib) * dst_height_pct / 100.0);
int dst_width = (int)floor(0.5 + (double)FreeImage_GetWidth(self->dib) * dst_width_pct / 100.0);
if (dst_height<=0 && dst_width>0) {
double ratio = (double)dst_width / (double)FreeImage_GetWidth(self->dib);
dst_height = (int)floor(0.5 + ratio * (double)FreeImage_GetHeight(self->dib));
}
else if (dst_width<=0 && dst_height>0) {
double ratio = (double)dst_height / (double)FreeImage_GetHeight(self->dib);
dst_width = (int)floor(0.5 + ratio * (double)FreeImage_GetWidth(self->dib));
}
if (dst_height>0 && dst_width>0) {
FIBITMAP *newdib = FreeImage_Rescale(self->dib, dst_width, dst_height, filter);
if (newdib) {
if (self->dib) FreeImage_Unload(self->dib);
self->dib = newdib;
}
else {
warn("FreeImage_Rescale failed");
}
}
XPUSHs(ST(0)); /* return self */
}
void
save(PDL::IO::Image self, SV * destination, SV * f=NULL, int flags=0);
PPCODE:
{
if (self->dib) {
FIMEMORY *hmem = NULL;
BYTE *mem_buffer = NULL;
DWORD size_in_bytes = 0;
FREE_IMAGE_FORMAT fif = _sv2fif(f);
FREE_IMAGE_TYPE fit = FreeImage_GetImageType(self->dib);
if(SvROK(destination) && SvTYPE(SvRV(destination)) < SVt_PVAV) {
/* destination is a reference to scalar */
SV *output = SvRV(destination);
BYTE *output_ptr = NULL;
if (fif == FIF_UNKNOWN) croak("FAIL: unspecified format");
hmem = FreeImage_OpenMemory(NULL, 0);
if (!FreeImage_SaveToMemory(fif, self->dib, hmem, flags)) {
warn("FreeImage_SaveToMemory failed (format '%d', image type '%d')", fif, fit);
}
FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes);
sv_setpvn(output, "", 0);
output_ptr = SvGROW(output, size_in_bytes);
SvCUR_set(output, size_in_bytes);
SvPOK_only(output);
Copy(mem_buffer, output_ptr, size_in_bytes, BYTE);
FreeImage_CloseMemory(hmem);
}
else {
/* destination is a filename */
STRLEN flen = 0;
char * filename = SvPV(destination, flen);
if (!filename || flen<=0) croak("FAIL: invalid filename");
if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename);
if (fif == FIF_UNKNOWN) croak("FAIL: unspecified format");
if (!FreeImage_Save(fif, self->dib, filename, flags)) {
warn("FreeImage_Save failed (format '%d', image type '%d')", fif, fit);
}
}
}
XPUSHs(ST(0)); /* return self */
}
pdl*
palette_to_pdl(PDL::IO::Image self)
CODE:
{
pdl *pal_pdl = NULL;
PDL_Indx dims[] = {0, 0, 0};
int cu = FreeImage_GetColorsUsed(self->dib);
if (cu==0) XSRETURN_UNDEF;
PDL_Byte *pdata;
int i;
dims[0] = 3;
dims[1] = cu;
pal_pdl = PDL->pdlnew();
pal_pdl->datatype = PDL_B;
PDL->setdims (pal_pdl, dims, 2);
PDL->allocdata (pal_pdl);
pdata = (PDL_Byte *) pal_pdl->data;
RGBQUAD *pal = FreeImage_GetPalette(self->dib);
for (i = 0; i < cu; i++) {
( run in 1.841 second using v1.01-cache-2.11-cpan-5511b514fd6 )