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 )