// 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; }
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); }
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); }
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; }