示例#1
0
bool CResizeEngine::scale (CDIBSection *src, CDIBSection *dst, ILongTimeRunCallback *pCallback) {
	assert(src != NULL && dst != NULL);
	uint src_width  = (uint)src->getWidth();
	uint src_height = (uint)src->getHeight();
	uint dst_width = (uint)dst->getWidth();
	uint dst_height = (uint)dst->getHeight();
	int bitcount = src->getBitCounts();
	assert(dst_width > 0 && dst_height > 0);
	assert(bitcount == 24 || bitcount == 32);

	if (m_pFilter == NULL) {
		_FastScale(src, dst);
		return true;
	}

	if(dst_width * src_height <= dst_height * src_width) {
		CDIBSectionPtr tmp = CDIBSection::createDIBSection(dst_width, src_height, bitcount, false);
		if (!tmp) {
			return false;
		}

		if (!horizontalFilter(src, src_height, tmp.get(), 0, src_height, pCallback)) {
			assert(pCallback && pCallback->shouldStop());
			return false;
		}
		if (!verticalFilter(tmp.get(), dst, pCallback)) {
			assert(pCallback && pCallback->shouldStop());
			return false;
		}

	} else {
		CDIBSectionPtr tmp = CDIBSection::createDIBSection(src_width, dst_height, bitcount, false);
		if (!tmp) {
			return false;
		}
		if (!verticalFilter(src, tmp.get(), pCallback)) {
			assert(pCallback && pCallback->shouldStop());
			return false;
		}
		if (!horizontalFilter(tmp.get(), dst_height, dst, 0, dst_height, pCallback)) {
			assert(pCallback && pCallback->shouldStop());
			return false;
		}
	}

	return true;
}
示例#2
0
FIBITMAP* CResizeEngine::scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height) { 
	DWORD src_width  = FreeImage_GetWidth(src); 
	DWORD src_height = FreeImage_GetHeight(src);

	unsigned redMask	= FreeImage_GetRedMask(src);
	unsigned greenMask	= FreeImage_GetGreenMask(src);
	unsigned blueMask	= FreeImage_GetBlueMask(src);

	unsigned bpp = FreeImage_GetBPP(src);

	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);

	// allocate the dst image
	FIBITMAP *dst = FreeImage_AllocateT(image_type, dst_width, dst_height, bpp, redMask, greenMask, blueMask);
	if(!dst) return NULL;
	
	if(bpp == 8) {
		if(FreeImage_GetColorType(src) == FIC_MINISWHITE) {
			// build an inverted greyscale palette
			RGBQUAD *dst_pal = FreeImage_GetPalette(dst);
			for(int i = 0; i < 256; i++) {
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)(255 - i);
			}
		} else {
			// build a greyscale palette
			RGBQUAD *dst_pal = FreeImage_GetPalette(dst);
			for(int i = 0; i < 256; i++) {
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)i;
			}
		}
	}

	// decide which filtering order (xy or yx) is faster for this mapping by
	// counting convolution multiplies

	if(dst_width*src_height <= dst_height*src_width) {
		// xy filtering
		// -------------

		// allocate a temporary image
		FIBITMAP *tmp = FreeImage_AllocateT(image_type, dst_width, src_height, bpp, redMask, greenMask, blueMask);
		if(!tmp) {
			FreeImage_Unload(dst);
			return NULL;
		}

		// scale source image horizontally into temporary image
		horizontalFilter(src, src_width, src_height, tmp, dst_width, src_height);

		// scale temporary image vertically into result image    
		verticalFilter(tmp, dst_width, src_height, dst, dst_width, dst_height);

		// free temporary image
		FreeImage_Unload(tmp);

	} else {
		// yx filtering
		// -------------

		// allocate a temporary image
		FIBITMAP *tmp = FreeImage_AllocateT(image_type, src_width, dst_height, bpp, redMask, greenMask, blueMask);
		if(!tmp) {
			FreeImage_Unload(dst);
			return NULL;
		}

		// scale source image vertically into temporary image
		verticalFilter(src, src_width, src_height, tmp, src_width, dst_height);

		// scale temporary image horizontally into result image    
		horizontalFilter(tmp, src_width, dst_height, dst, dst_width, dst_height);

		// free temporary image
		FreeImage_Unload(tmp);
	}

	return dst;
}