Example #1
0
// MW-2011-09-13: [[ Masks ]] Updated to store data in an MCWindowMask struct.
MCWindowShape *MCImage::makewindowshape(void)
{	
	bool t_success = true;
	
	MCWindowShape *t_mask = nil;
	CGImageRef t_mask_image = nil;
	MCImageBitmap *t_bitmap = nil;
	uint8_t *t_alpha = nil;
	uindex_t t_alpha_stride = 0;
	uindex_t t_width, t_height;
	
	t_success = lockbitmap(t_bitmap, true);
	
	if (t_success)
		t_success = MCImageBitmapHasTransparency(t_bitmap);
	
	if (t_success)
	{
		t_width = t_bitmap->width;
		t_height = t_bitmap->height;
		
		t_alpha_stride = (t_width + 3) & ~3;
		t_success = MCMemoryAllocate(t_alpha_stride * t_height, t_alpha);
	}
	
	if (t_success)
	{
		surface_extract_alpha(t_bitmap->data, t_bitmap->stride, t_alpha, t_alpha_stride, t_width, t_height);
		
		t_success = MCAlphaToCGImage(t_width, t_height, t_alpha, t_alpha_stride, t_mask_image);
	}
	
	if (t_success)
		t_success = MCMemoryNew(t_mask);
	
	unlockbitmap(t_bitmap);
	
	
	if (!t_success)
	{
		CGImageRelease(t_mask_image);
		MCMemoryDeallocate(t_mask);
		MCMemoryDeallocate(t_alpha);
		
		return nil;
	}
	
	t_mask->width = t_width;
	t_mask->height = t_height;
	t_mask->is_sharp = false;
	
	t_mask->data = (char*)t_alpha;
	t_mask->stride = t_alpha_stride;
	
	t_mask->handle = t_mask_image;
	
	return t_mask;
}
Example #2
0
bool MCImageBitmapToCGImage(MCImageBitmap *p_bitmap, CGColorSpaceRef p_colorspace, bool p_copy, bool p_invert, CGImageRef &r_image)
{
    if (p_bitmap == nil)
        return false;
	bool t_mask;
	t_mask = MCImageBitmapHasTransparency(p_bitmap);
	
	MCGRaster t_raster;
	t_raster = MCImageBitmapGetMCGRaster(p_bitmap, true);
	
	return MCGRasterToCGImage(t_raster, MCGIntegerRectangleMake(0, 0, p_bitmap->width, p_bitmap->height), p_colorspace, p_copy, p_invert, r_image);
}
Example #3
0
bool MCImageBitmapToCGImage(MCImageBitmap *p_bitmap, CGColorSpaceRef p_colorspace, bool p_copy, bool p_invert, CGImageRef &r_image)
{
    if (p_bitmap == nil)
        return false;
	bool t_mask;
	t_mask = MCImageBitmapHasTransparency(p_bitmap);
	
	MCGRaster t_raster;
	t_raster.width = p_bitmap->width;
	t_raster.height = p_bitmap->height;
	t_raster.pixels = p_bitmap->data;
	t_raster.stride = p_bitmap->stride;
	t_raster.format = t_mask ? kMCGRasterFormat_ARGB : kMCGRasterFormat_xRGB;
	
	return MCGRasterToCGImage(t_raster, MCGRectangleMake(0, 0, p_bitmap->width, p_bitmap->height), p_colorspace, p_copy, p_invert, r_image);
}
Example #4
0
bool MCImageEncodePNG(MCImageBitmap *p_bitmap, IO_handle p_stream, uindex_t &r_bytes_written)
{
	bool t_success = true;

	MCPNGWriteContext t_context;
	t_context.stream = p_stream;
	t_context.byte_count = 0;

	png_structp t_png_ptr = nil;
	png_infop t_info_ptr = nil;
	png_color *t_png_palette = nil;
	png_byte *t_png_transparency = nil;

	png_bytep t_data_ptr = nil;
	uindex_t t_stride = 0;

	MCImageIndexedBitmap *t_indexed = nil;
	if (MCImageConvertBitmapToIndexed(p_bitmap, false, t_indexed))
	{
		t_success = MCImageEncodePNG(t_indexed, p_stream, r_bytes_written);
		MCImageFreeIndexedBitmap(t_indexed);
		return t_success;
	}

	/*init png stuff*/
	if (t_success)
	{
		t_success = nil != (t_png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
			(png_voidp)NULL, (png_error_ptr)NULL,
			(png_error_ptr)NULL));
	}

	if (t_success)
		t_success = nil != (t_info_ptr = png_create_info_struct(t_png_ptr));

	/*in case of png error*/
	if (setjmp(png_jmpbuf(t_png_ptr)))
		t_success = false;

	if (t_success)
		png_set_write_fn(t_png_ptr,(png_voidp)&t_context,fakewrite,fakeflush);

	bool t_fully_opaque = true;
	if (t_success)
	{
		t_fully_opaque = !MCImageBitmapHasTransparency(p_bitmap);

		png_set_IHDR(t_png_ptr, t_info_ptr, p_bitmap->width, p_bitmap->height, 8,
			t_fully_opaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
		png_set_gAMA(t_png_ptr, t_info_ptr, 1/MCgamma);
	}

	if (t_success)
	{
		png_write_info(t_png_ptr, t_info_ptr);

		//32 bit compensate for byte swapped systems
		if (t_fully_opaque)
			png_set_filler(t_png_ptr, 0, MCswapbytes ? PNG_FILLER_AFTER : PNG_FILLER_BEFORE);
		if (MCswapbytes)
			png_set_bgr(t_png_ptr);
		else
			png_set_swap_alpha(t_png_ptr);
	}

	if (t_success)
	{
		t_data_ptr = (png_bytep)p_bitmap->data;
		t_stride = p_bitmap->stride;
	}

	if (t_success)
	{
		for (uindex_t i = 0; i < p_bitmap->height; i++)
		{
			png_write_row(t_png_ptr, t_data_ptr);
			t_data_ptr += t_stride;
		}
	}

	if (t_success)
		png_write_end(t_png_ptr, t_info_ptr);

	if (t_png_ptr != nil)
		png_destroy_write_struct(&t_png_ptr, &t_info_ptr);
	if (t_png_palette != nil)
		MCMemoryDeleteArray(t_png_palette);
	if (t_png_transparency != nil)
		MCMemoryDeallocate(t_png_transparency);

	if (t_success)
		r_bytes_written = t_context.byte_count;

	return t_success;
}