Exemplo n.º 1
0
void MCCachedImageRep::ReleaseFrames()
{
	if (m_lock_count > 0 || m_frames == nil)
		return;

	s_cache_size -= GetFrameByteCount();

	MCImageFreeFrames(m_frames, m_frame_count);
	m_frames = nil;
}
Exemplo n.º 2
0
bool MCResampledImageRep::LoadImageFrames(MCBitmapFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied)
{
	uindex_t t_src_width, t_src_height;
	if (!m_source->GetGeometry(t_src_width, t_src_height))
		return false;
	
	bool t_success = true;
	
	MCBitmapFrame *t_frames = nil;
	uindex_t t_frame_count = 0;
	
	t_frame_count = m_source->GetFrameCount();
	
	// IM-2013-07-03: [[ Bug 11018 ]] fail here if the source has no frames
	t_success = t_frame_count != 0;

	if (t_success)
		t_success = MCMemoryNewArray(t_frame_count, t_frames);
	
	MCGFloat t_scale;
	t_scale = MCMax(m_target_width / (float)t_src_width, m_target_height / (float)t_src_height);
	
	for (uindex_t i = 0; t_success && i < t_frame_count; i++)
	{
		MCBitmapFrame *t_src_frame = nil;
		
		t_success = m_source->LockBitmapFrame(i, t_scale, t_src_frame);
		if (t_success)
		{
			t_frames[i].duration = t_src_frame->duration;
			
			t_success = MCImageScaleBitmap(t_src_frame->image, m_target_width, m_target_height, INTERPOLATION_BICUBIC, t_frames[i].image);
			if (t_success)
				MCImageFlipBitmapInPlace(t_frames[i].image, m_h_flip, m_v_flip);
		}
		m_source->UnlockBitmapFrame(i, t_src_frame);
	}
	
	if (t_success)
	{
		r_frames = t_frames;
		r_frame_count = t_frame_count;
		r_frames_premultiplied = false;
	}
	else
		MCImageFreeFrames(t_frames, t_frame_count);
	
	return t_success;
}
Exemplo n.º 3
0
bool MCCompressedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied)
{
	bool t_success = true;

	MCImageFrame *t_frame = nil;
	t_success = MCMemoryNewArray(1, t_frame);
	if (t_success)
		t_success = MCImageDecompressRLE(m_compressed, t_frame->image);

	if (t_success)
	{
		t_frame->density = 1.0;
		
		r_frames = t_frame;
		r_frame_count = 1;
		r_frames_premultiplied = false;
	}
	else
		MCImageFreeFrames(t_frame, 1);

	return t_success;
}
Exemplo n.º 4
0
bool MCGIFImageLoader::LoadFrames(MCBitmapFrame *&r_frames, uint32_t &r_count)
{
	bool t_success;
	t_success = true;
	
	MCImageBitmap *t_canvas;
	t_canvas = nil;
	
	// restoration info
	MCImageBitmap *t_restore_image = nil;
	int t_disposal_mode = DISPOSAL_UNSPECIFIED;
	MCRectangle t_disposal_region = kMCEmptyRectangle;

	// The list of frames.
	MCBitmapFrame *t_frames = nil;

	t_success = GIF_OK == DGifSlurp(m_gif);

	// Fetch the width and height of the virtual canvas.
	int32_t t_width, t_height;

	if (t_success)
	{
		t_width = m_gif -> SWidth;
		t_height = m_gif -> SHeight;

		// create the canvas image
		t_success = MCImageBitmapCreate(t_width, t_height, t_canvas);
	}

	// The current frame count. The number of frames is the same as the
	// number of images in the GIF.
	uint32_t t_frame_count;
	t_frame_count = 0;
	
	// If true, the new image will be merged with the old - otherwise the mask
	// replaces it.
	bool t_overlay;
	t_overlay = false;
	
	// Loop through all the images, making frames as we go.
	for(uindex_t i = 0; t_success && i < m_gif -> ImageCount; i++)
	{
		// Process the disposal.
		switch (t_disposal_mode)
		{
		case DISPOSE_BACKGROUND:
			gif_fill_image_region(t_canvas, t_disposal_region, 0);
			break;

		case DISPOSE_PREVIOUS:
			if (t_restore_image != nil)
				gif_paste_image(t_canvas, t_restore_image, t_disposal_region.x, t_disposal_region.y);
			break;

		case DISPOSE_DO_NOT:
			t_overlay = true;
			break;

		default:
			t_overlay = false;
			break;
		}

		// Fetch the image information.
		GraphicsControlBlock t_image_gcb;
		MCRectangle t_image_region;
		ColorMapObject *t_image_colors = nil;
		int32_t t_image_transparency;
		int32_t t_image_delay;
		int32_t t_image_disposal;
		GifByteType *t_image_raster;

		// First the information from the image description.
		t_image_region.x = m_gif -> SavedImages[i] . ImageDesc . Left;
		t_image_region.y = m_gif -> SavedImages[i] . ImageDesc . Top;
		t_image_region.width = m_gif -> SavedImages[i] . ImageDesc . Width;
		t_image_region.height = m_gif -> SavedImages[i] . ImageDesc . Height;
		t_image_colors = m_gif -> SavedImages[i] . ImageDesc . ColorMap;
		t_image_raster = m_gif -> SavedImages[i] . RasterBits;
		if (t_image_colors == nil)
			t_image_colors = m_gif -> SColorMap;
		
		// Then the information from the GCB.
		if (GIF_OK == DGifSavedExtensionToGCB(m_gif, i, &t_image_gcb))
		{
			t_image_transparency = t_image_gcb . TransparentColor;
			t_image_delay = t_image_gcb . DelayTime;
			t_image_disposal = t_image_gcb . DisposalMode;
		}
		else
		{
			t_image_transparency = -1;
			t_image_delay = 0;
			t_image_disposal = DISPOSAL_UNSPECIFIED;
			}
			
		// If disposal is 'previous' then cache the portion of the canvas we are
		// about to affect.
		if (t_image_disposal == DISPOSE_PREVIOUS)
			{
			if (t_restore_image != nil)
			{
				if (t_disposal_mode != DISPOSE_PREVIOUS ||
					!MCU_equal_rect(t_disposal_region, t_image_region))
				{
					MCImageFreeBitmap(t_restore_image);
					t_restore_image = nil;
				}
			}
			if (t_restore_image == nil)
				t_success = MCImageCopyBitmapRegion(t_canvas, t_image_region, t_restore_image);
		}
		
		if (t_success)
		{
			// Render the image into the canvas.
			gif_draw_image_into_canvas(t_canvas, t_image_raster,
				t_image_region.x, t_image_region.y, t_image_region.width, t_image_region.height,
				t_image_colors, t_image_transparency, t_overlay);
			
			// Generate our frame.
			t_success = MCMemoryResizeArray(t_frame_count + 1, t_frames, t_frame_count);
		}

		MCImageBitmap *t_frame_bitmap = nil;
		if (t_success)
			t_success = MCImageCopyBitmap(t_canvas, t_frame_bitmap);
			
		if (t_success)
		{
			MCImageBitmapCheckTransparency(t_frame_bitmap);
			t_frames[t_frame_count - 1].image = t_frame_bitmap;
			t_frames[t_frame_count - 1].duration = t_image_delay * 10; // convert 1/100 seconds to milliseconds
			t_frames[t_frame_count - 1].x_scale = t_frames[t_frame_count - 1].y_scale = 1.0;
		}

		t_disposal_region = t_image_region;
		t_disposal_mode = t_image_disposal;
	}
	
	MCImageFreeBitmap(t_canvas);
	MCImageFreeBitmap(t_restore_image);
	
	if (t_success)
	{
		r_frames = t_frames;
		r_count = t_frame_count;
	}
	else
		MCImageFreeFrames(t_frames, t_frame_count);

	return t_success;
}
Exemplo n.º 5
0
// if the image is in a directly supported format return the raw data otherwise decode & return the bitmap
bool MCImageImport(IO_handle p_stream, IO_handle p_mask_stream, MCPoint &r_hotspot, MCStringRef&r_name, MCImageCompressedBitmap *&r_compressed, MCImageBitmap *&r_bitmap)
{
	bool t_success;
	t_success = true;

	// IM-2014-07-31: [[ ImageLoader ]] Update to use MCImageLoader class
	MCImageLoaderFormat t_format;

	if (t_success)
		t_success = MCImageLoader::IdentifyFormat(p_stream, t_format);

	if (t_success)
	{
		uint32_t t_compression;
		if (MCImageLoaderFormatToCompression(t_format, t_compression))
		{
			t_success = MCImageCreateCompressedBitmap(t_compression, r_compressed);
			if (t_success)
			{
				uint32_t t_width, t_height;
				t_width = t_height = 0;
				
				if (t_success && t_compression == F_PICT)
					t_success = MCImageGetMetafileGeometry(p_stream, t_width, t_height);
				
				if (t_success)
					t_success = read_all(p_stream, r_compressed->data, r_compressed->size);

				r_compressed->width = t_width;
				r_compressed->height = t_height;
			}
		}
		else
		{
			MCImageLoader *t_loader;
			t_loader = nil;
			
			t_success = MCImageLoader::LoaderForStreamWithFormat(p_stream, t_format, t_loader);
			
			uint32_t t_xhot, t_yhot;
			
			MCAutoStringRef t_name;
			
			MCBitmapFrame *t_frames;
			t_frames = nil;
			
			uint32_t t_count;
            t_count = 0;
			
			if (t_success)
				t_success = t_loader->GetHotSpot(t_xhot, t_yhot);
			
			if (t_success)
				t_success = t_loader->GetName(&t_name);
			
			if (t_success)
				t_success = t_loader->TakeFrames(t_frames, t_count);
            
            if (t_success && p_mask_stream != nil && t_loader->GetFormat() == kMCImageFormatNetPBM)
				{
					MCImageBitmap *t_mask = nil;
					t_success = MCImageDecodeNetPBM(p_mask_stream, t_mask) &&
				MCImageBitmapApplyMask(t_frames[0].image, t_mask);
					MCImageFreeBitmap(t_mask);
				}

			if (t_success)
			{
				r_hotspot.x = t_xhot;
				r_hotspot.y = t_yhot;
                r_name = MCValueRetain(*t_name);
				r_bitmap = t_frames[0].image;
				t_frames[0].image = nil;
            }
			else
                r_name = MCValueRetain(kMCEmptyString);
			
			MCImageFreeFrames(t_frames, t_count);
			
			if (t_loader != nil)
				delete t_loader;
		}
	}

	return t_success;
}
Exemplo n.º 6
0
bool MCTransformedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count)
{
	uindex_t t_target_width, t_target_height;
	if (!GetGeometry(t_target_width, t_target_height))
		return false;
	
	bool t_success = true;
	
	MCImageFrame *t_frames = nil;
	uindex_t t_frame_count = 0;
	
	t_frame_count = m_source->GetFrameCount();
	
	t_success = MCMemoryNewArray(t_frame_count, t_frames);
	
	for (uindex_t i = 0; t_success && i < t_frame_count; i++)
	{
		MCImageFrame *t_src_frame = nil;
		
		t_success = m_source->LockImageFrame(i, t_src_frame);
		if (t_success)
		{
			t_frames[i].duration = t_src_frame->duration;
			if (m_angle != 0)
			{
				// rotate
				MCImageBitmap *t_bitmap = nil;
				MCImageBitmap *t_rotated = nil;
				t_success = MCImageCopyBitmap(t_src_frame->image, t_bitmap);
				if (t_success)
				{
					MCImageBitmapPremultiply(t_bitmap);
					t_success = MCImageRotateBitmap(t_bitmap, m_angle, m_quality, 0x0, t_rotated);
				}
				
				MCImageFreeBitmap(t_bitmap);
				
				bool t_scaled = false;
				
				if (t_success && (t_rotated->width != t_target_width || t_rotated->height != t_target_height))
				{
					MCImageBitmap *t_sbitmap = nil;
					t_success = MCImageScaleBitmap(t_rotated, t_target_width, t_target_height, m_quality, t_sbitmap);
					MCImageFreeBitmap(t_rotated);
					t_rotated = t_sbitmap;
					t_scaled = true;
				}
				
				if (t_success)
				{
					if (t_scaled && (m_quality == INTERPOLATION_BICUBIC))
						MCImageBitmapUnpremultiplyChecking(t_rotated);
					else
						MCImageBitmapUnpremultiply(t_rotated);
					
					t_frames[i].image = t_rotated;
				}
				else
					MCImageFreeBitmap(t_rotated);
				
			}
			else
			{
				// resize
				if (t_src_frame->image->width == t_target_width && t_src_frame->image->height == t_target_height)
					t_success = MCImageCopyBitmap(t_src_frame->image, t_frames[i].image);
				else
					t_success = MCImageScaleBitmap(t_src_frame->image, t_target_width, t_target_height, m_quality, t_frames[i].image);
			}
		}
		m_source->UnlockImageFrame(i, t_src_frame);
	}
	
	if (t_success)
	{
		r_frames = t_frames;
		r_frame_count = t_frame_count;
	}
	else
		MCImageFreeFrames(t_frames, t_frame_count);
	
	return t_success;
}