Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
break;
case 32:
out = FreeImage_ConvertTo32Bits(tmp);
break;
default:
break;
}
if (tmp != src) {
FreeImage_Unload(tmp);
tmp = NULL;
}
}
return (out != src) ? out : FreeImage_Clone(src);
}
RGBQUAD pal_buffer[256];
RGBQUAD *src_pal = NULL;
// provide the source image's palette to the rescaler for
// FIC_PALETTE type images (this includes palletized greyscale
// images with an unordered palette as well as transparent images)
if (color_type == FIC_PALETTE) {
if (dst_bpp == 32) {
// a 32-bit destination image signals transparency, so
// create an RGBA palette from the source palette
src_pal = GetRGBAPalette(src, pal_buffer);
} else {
src_pal = FreeImage_GetPalette(src);
}
}
// allocate the dst image
FIBITMAP *dst = FreeImage_AllocateT(image_type, dst_width, dst_height, dst_bpp, 0, 0, 0);
if (!dst) {
return NULL;
}
if (dst_bpp == 8) {
RGBQUAD * const dst_pal = FreeImage_GetPalette(dst);
if (color_type == FIC_MINISWHITE) {
// build an inverted greyscale palette
CREATE_GREYSCALE_PALETTE_REVERSE(dst_pal, 256);
}
/*
else {
// build a default greyscale palette
// Currently, FreeImage_AllocateT already creates a default
// greyscale palette for 8 bpp images, so we can skip this here.
CREATE_GREYSCALE_PALETTE(dst_pal, 256);
}
*/
}
// calculate x and y offsets; since FreeImage uses bottom-up bitmaps, the
// value of src_offset_y is measured from the bottom of the image
unsigned src_offset_x = src_left;
unsigned src_offset_y = FreeImage_GetHeight(src) - src_height - src_top;
/*
Decide which filtering order (xy or yx) is faster for this mapping.
--- The theory ---
Try to minimize calculations by counting the number of convolution multiplies
if(dst_width*src_height <= src_width*dst_height) {
// xy filtering
} else {
// yx filtering
}
--- The practice ---
Try to minimize calculations by counting the number of vertical convolutions (the most time consuming task)
if(dst_width*dst_height <= src_width*dst_height) {
// xy filtering
} else {
// yx filtering
}
*/
if (dst_width <= src_width) {
// xy filtering
// -------------
FIBITMAP *tmp = NULL;
if (src_width != dst_width) {
// source and destination widths are different so, we must
// filter horizontally
if (src_height != dst_height) {
// source and destination heights are also different so, we need
// a temporary image
tmp = FreeImage_AllocateT(image_type, dst_width, src_height, dst_bpp_s1, 0, 0, 0);
if (!tmp) {
FreeImage_Unload(dst);
return NULL;
}
} else {
// source and destination heights are equal so, we can directly
// scale into destination image (second filter method will not
// be invoked)
tmp = dst;
}
// scale source image horizontally into temporary (or destination) image
horizontalFilter(src, src_height, src_width, src_offset_x, src_offset_y, src_pal, tmp, dst_width);
// set x and y offsets to zero for the second filter method
// invocation (the temporary image only contains the portion of
// the image to be rescaled with no offsets)
src_offset_x = 0;
src_offset_y = 0;
// also ensure, that the second filter method gets no source
// palette (the temporary image is palletized only, if it is
// greyscale; in that case, it is an 8-bit image with a linear
// palette so, the source palette is not needed or will even be
// mismatching, if the source palette is unordered)
src_pal = NULL;
} else {
// source and destination widths are equal so, just copy the
// image pointer
tmp = src;
}
( run in 1.380 second using v1.01-cache-2.11-cpan-172d661cebc )