Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImageToolkit/CopyPaste.cpp view on Meta::CPAN
src_bits += left * bytespp;
}
break;
}
// point to x = 0
BYTE *dst_bits = FreeImage_GetBits(dst);
// copy the palette
memcpy(FreeImage_GetPalette(dst), FreeImage_GetPalette(src), FreeImage_GetColorsUsed(src) * sizeof(RGBQUAD));
// copy the bits
if(bpp == 1) {
BOOL value;
unsigned y_src, y_dst;
for(int y = 0; y < dst_height; y++) {
y_src = y * src_pitch;
y_dst = y * dst_pitch;
for(int x = 0; x < dst_width; x++) {
// get bit at (y, x) in src image
value = (src_bits[y_src + ((left+x) >> 3)] & (0x80 >> ((left+x) & 0x07))) != 0;
// set bit at (y, x) in dst image
value ? dst_bits[y_dst + (x >> 3)] |= (0x80 >> (x & 0x7)) : dst_bits[y_dst + (x >> 3)] &= (0xff7f >> (x & 0x7));
}
}
}
else if(bpp == 4) {
BYTE shift, value;
unsigned y_src, y_dst;
for(int y = 0; y < dst_height; y++) {
y_src = y * src_pitch;
y_dst = y * dst_pitch;
for(int x = 0; x < dst_width; x++) {
// get nibble at (y, x) in src image
shift = (BYTE)((1 - (left+x) % 2) << 2);
value = (src_bits[y_src + ((left+x) >> 1)] & (0x0F << shift)) >> shift;
// set nibble at (y, x) in dst image
shift = (BYTE)((1 - x % 2) << 2);
dst_bits[y_dst + (x >> 1)] &= ~(0x0F << shift);
dst_bits[y_dst + (x >> 1)] |= ((value & 0x0F) << shift);
}
}
}
else if(bpp >= 8) {
for(int y = 0; y < dst_height; y++) {
memcpy(dst_bits + (y * dst_pitch), src_bits + (y * src_pitch), dst_line);
}
}
// copy metadata from src to dst
FreeImage_CloneMetadata(dst, src);
// copy transparency table
FreeImage_SetTransparencyTable(dst, FreeImage_GetTransparencyTable(src), FreeImage_GetTransparencyCount(src));
// copy background color
RGBQUAD bkcolor;
if( FreeImage_GetBackgroundColor(src, &bkcolor) ) {
FreeImage_SetBackgroundColor(dst, &bkcolor);
}
// clone resolution
FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(src));
FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(src));
// clone ICC profile
FIICCPROFILE *src_profile = FreeImage_GetICCProfile(src);
FIICCPROFILE *dst_profile = FreeImage_CreateICCProfile(dst, src_profile->data, src_profile->size);
dst_profile->flags = src_profile->flags;
return dst;
}
/**
Alpha blend or combine a sub part image with the current image.
The bit depth of dst bitmap must be greater than or equal to the bit depth of src.
Upper promotion of src is done internally. Supported bit depth equals to 1, 4, 8, 16, 24 or 32.
@param src Source subimage
@param left Specifies the left position of the sub image.
@param top Specifies the top position of the sub image.
@param alpha Alpha blend factor. The source and destination images are alpha blended if
alpha = 0..255. If alpha > 255, then the source image is combined to the destination image.
@return Returns TRUE if successful, FALSE otherwise.
*/
BOOL DLL_CALLCONV
FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha) {
BOOL bResult = FALSE;
if(!FreeImage_HasPixels(src) || !FreeImage_HasPixels(dst)) return FALSE;
// check the size of src image
if((left < 0) || (top < 0)) {
return FALSE;
}
if((left + FreeImage_GetWidth(src) > FreeImage_GetWidth(dst)) || (top + FreeImage_GetHeight(src) > FreeImage_GetHeight(dst))) {
return FALSE;
}
// check data type
const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dst);
if(image_type != FreeImage_GetImageType(src)) {
// no conversion between data type is done
return FALSE;
}
if(image_type == FIT_BITMAP) {
FIBITMAP *clone = NULL;
// check the bit depth of src and dst images
unsigned bpp_src = FreeImage_GetBPP(src);
unsigned bpp_dst = FreeImage_GetBPP(dst);
BOOL isRGB565 = FALSE;
if ((FreeImage_GetRedMask(dst) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dst) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dst) == FI16_565_BLUE_MASK)) {
isRGB565 = TRUE;
} else {
src/Source/FreeImageToolkit/CopyPaste.cpp view on Meta::CPAN
return FALSE;
}
if(!clone) return FALSE;
// paste src to dst
switch(FreeImage_GetBPP(dst)) {
case 1:
bResult = Combine1(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
break;
case 4:
bResult = Combine4(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
break;
case 8:
bResult = Combine8(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
break;
case 16:
if (isRGB565) {
bResult = Combine16_565(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
} else {
// includes case where all the masks are 0
bResult = Combine16_555(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
}
break;
case 24:
bResult = Combine24(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
break;
case 32:
bResult = Combine32(dst, clone, (unsigned)left, (unsigned)top, (unsigned)alpha);
break;
}
if(clone != src)
FreeImage_Unload(clone);
}
else { // any type other than FITBITMAP
bResult = CombineSameType(dst, src, (unsigned)left, (unsigned)top);
}
return bResult;
}
// ----------------------------------------------------------
/** @brief Creates a dynamic read/write view into a FreeImage bitmap.
A dynamic view is a FreeImage bitmap with its own width and height, that,
however, shares its bits with another FreeImage bitmap. Typically, views
are used to define one or more rectangular sub-images of an existing
bitmap. All FreeImage operations, like saving, displaying and all the
toolkit functions, when applied to the view, only affect the view's
rectangular area.
Although the view's backing image's bits not need to be copied around,
which makes the view much faster than similar solutions using
FreeImage_Copy, a view uses some private memory that needs to be freed by
calling FreeImage_Unload on the view's handle to prevent memory leaks.
Only the backing image's pixels are shared by the view. For all other image
data, notably for the resolution, background color, color palette,
transparency table and for the ICC profile, the view gets a private copy
of the data. By default, the backing image's metadata is NOT copied to
the view.
As with all FreeImage functions that take a rectangle region, top and left
positions are included, whereas right and bottom positions are excluded
from the rectangle area.
Since the memory block shared by the backing image and the view must start
at a byte boundary, the value of parameter left must be a multiple of 8
for 1-bit images and a multiple of 2 for 4-bit images.
@param dib The FreeImage bitmap on which to create the view.
@param left The left position of the view's area.
@param top The top position of the view's area.
@param right The right position of the view's area.
@param bottom The bottom position of the view's area.
@return Returns a handle to the newly created view or NULL if the view
was not created.
*/
FIBITMAP * DLL_CALLCONV
FreeImage_CreateView(FIBITMAP *dib, unsigned left, unsigned top, unsigned right, unsigned bottom) {
if (!FreeImage_HasPixels(dib)) {
return NULL;
}
// normalize the rectangle
if (right < left) {
INPLACESWAP(left, right);
}
if (bottom < top) {
INPLACESWAP(top, bottom);
}
// check the size of the sub image
unsigned width = FreeImage_GetWidth(dib);
unsigned height = FreeImage_GetHeight(dib);
if (left < 0 || right > width || top < 0 || bottom > height) {
return NULL;
}
unsigned bpp = FreeImage_GetBPP(dib);
BYTE *bits = FreeImage_GetScanLine(dib, height - bottom);
switch (bpp) {
case 1:
if (left % 8 != 0) {
// view can only start at a byte boundary
return NULL;
}
bits += (left / 8);
break;
case 4:
if (left % 2 != 0) {
// view can only start at a byte boundary
return NULL;
}
bits += (left / 2);
break;
default:
bits += left * (bpp / 8);
break;
}
FIBITMAP *dst = FreeImage_AllocateHeaderForBits(bits, FreeImage_GetPitch(dib), FreeImage_GetImageType(dib),
right - left, bottom - top,
bpp,
FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));
if (dst == NULL) {
return NULL;
}
// copy some basic image properties needed for displaying and saving
// resolution
FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(dib));
FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(dib));
// background color
RGBQUAD bkcolor;
if (FreeImage_GetBackgroundColor(dib, &bkcolor)) {
FreeImage_SetBackgroundColor(dst, &bkcolor);
}
// palette
memcpy(FreeImage_GetPalette(dst), FreeImage_GetPalette(dib), FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD));
// transparency table
FreeImage_SetTransparencyTable(dst, FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
// ICC profile
FIICCPROFILE *src_profile = FreeImage_GetICCProfile(dib);
FIICCPROFILE *dst_profile = FreeImage_CreateICCProfile(dst, src_profile->data, src_profile->size);
dst_profile->flags = src_profile->flags;
return dst;
}
( run in 1.091 second using v1.01-cache-2.11-cpan-0d23b851a93 )