bool MCGRasterToCGImage(const MCGRaster &p_raster, const MCGIntegerRectangle &p_src_rect, CGColorSpaceRef p_colorspace, bool p_copy, bool p_invert, CGImageRef &r_image) { bool t_success = true; CGImageRef t_image = nil; CGDataProviderRef t_data_provider = nil; uint32_t t_dst_stride; if (t_success) t_success = MCGRasterCreateCGDataProvider(p_raster, p_src_rect, p_copy, p_invert, t_data_provider, t_dst_stride); // IM-2014-05-20: [[ GraphicsPerformance ]] Opaque rasters should indicate no alpha in the bitmap info bool t_alpha; t_alpha = p_raster.format != kMCGRasterFormat_xRGB; // IM-2013-08-21: [[ RefactorGraphics ]] Refactor CGImage creation code to be pixel-format independent CGBitmapInfo t_bm_info; t_bm_info = MCGPixelFormatToCGBitmapInfo(kMCGPixelFormatNative, t_alpha); if (t_success) { t_image = CGImageCreate(p_src_rect.size.width, p_src_rect.size.height, 8, 32, t_dst_stride, p_colorspace, t_bm_info, t_data_provider, nil, true, kCGRenderingIntentDefault); t_success = t_image != nil; } CGDataProviderRelease(t_data_provider); if (t_success) r_image = t_image; return t_success; }
bool MCTileCacheCoreGraphicsCompositor_AllocateTile(void *p_context, int32_t p_size, const void *p_bits, uint32_t p_stride, void*& r_tile) { MCTileCacheCoreGraphicsCompositorContext *self; self = (MCTileCacheCoreGraphicsCompositorContext *)p_context; // If the stride is exactly one tile wide, we don't need a copy. void *t_data; t_data = nil; if (p_stride == p_size * sizeof(uint32_t)) t_data = (void *)p_bits; else if (MCMemoryAllocate(p_size * p_size * sizeof(uint32_t), t_data)) { // Copy across each scanline of the tile into the buffer. for(int32_t y = 0; y < p_size; y++) memcpy((uint8_t *)t_data + y * p_size * sizeof(uint32_t), (uint8_t *)p_bits + p_stride * y, p_size * sizeof(uint32_t)); } CGImageRef t_tile; t_tile = nil; if (t_data != nil) { // IM-2013-08-21: [[ RefactorGraphics ]] Refactor CGImage creation code to be pixel-format independent CGBitmapInfo t_bm_info; t_bm_info = MCGPixelFormatToCGBitmapInfo(kMCGPixelFormatNative, true); CGContextRef t_cgcontext; t_cgcontext = CGBitmapContextCreate((void *)t_data, p_size, p_size, 8, p_size * sizeof(uint32_t), self -> colorspace, t_bm_info); if (t_cgcontext != nil) { t_tile = CGBitmapContextCreateImage(t_cgcontext); CGContextRelease(t_cgcontext); } } if (t_data != p_bits) MCMemoryDeallocate(t_data); if (t_tile == nil) return false; r_tile = t_tile; return true; }
bool MCGImageToCGImage(MCGImageRef p_src, const MCGIntegerRectangle &p_src_rect, CGColorSpaceRef p_colorspace, bool p_invert, CGImageRef &r_image) { MCGRaster t_raster; if (!MCGImageGetRaster(p_src, t_raster)) return false; if (p_invert) { return MCGRasterToCGImage(t_raster, p_src_rect, p_colorspace, true, true, r_image); } // If we don't need to modify the data then create image with data provider that references the MCGImageRef bool t_success = true; CGImageRef t_image = nil; CGDataProviderRef t_data_provider = nil; if (t_success) t_success = MCGImageCreateCGDataProvider(p_src, p_src_rect, t_data_provider); bool t_alpha; t_alpha = !MCGImageIsOpaque(p_src); CGBitmapInfo t_bm_info; t_bm_info = MCGPixelFormatToCGBitmapInfo(kMCGPixelFormatNative, t_alpha); if (t_success) { t_image = CGImageCreate(p_src_rect.size.width, p_src_rect.size.height, 8, 32, t_raster.stride, p_colorspace, t_bm_info, t_data_provider, nil, true, kCGRenderingIntentDefault); t_success = t_image != nil; } CGDataProviderRelease(t_data_provider); if (t_success) r_image = t_image; return t_success; }
bool MCGRasterToCGImage(const MCGRaster &p_raster, MCGRectangle p_src_rect, CGColorSpaceRef p_colorspace, bool p_copy, bool p_invert, CGImageRef &r_image) { bool t_success = true; int32_t t_x, t_y; uint32_t t_width, t_height; t_x = p_src_rect.origin.x; t_y = p_src_rect.origin.y; t_width = p_src_rect.size.width; t_height = p_src_rect.size.height; /* OVERHAUL - REVISIT: pixel formats */ const uint8_t *t_src_ptr = (uint8_t*)p_raster.pixels; t_src_ptr += t_y * p_raster.stride + t_x * sizeof(uint32_t); uint32_t t_dst_stride; if (p_invert) p_copy = true; CGImageRef t_image = nil; CGDataProviderRef t_data_provider = nil; if (!p_copy) { t_dst_stride = p_raster.stride; t_success = nil != (t_data_provider = CGDataProviderCreateWithData(nil, t_src_ptr, t_height * p_raster.stride, nil)); } else { uint8_t* t_buffer = nil; t_dst_stride = t_width * sizeof(uint32_t); uindex_t t_buffer_size = t_height * t_dst_stride; t_success = MCMemoryAllocate(t_buffer_size, t_buffer); if (t_success) { int32_t t_src_stride; uint8_t* t_dst_ptr = t_buffer; if (!p_invert) { t_src_stride = p_raster.stride; } else { t_src_ptr += ((int32_t)t_height - 1) * p_raster.stride; t_src_stride = -p_raster.stride; } for (uindex_t y = 0; y < t_height; y++) { MCMemoryCopy(t_dst_ptr, t_src_ptr, t_dst_stride); t_dst_ptr += t_dst_stride; t_src_ptr += t_src_stride; } } if (t_success) t_success = nil != (t_data_provider = CGDataProviderCreateWithData(nil, t_buffer, t_buffer_size, __CGDataProviderDeallocate)); if (!t_success) MCMemoryDeallocate(t_buffer); } // IM-2013-08-21: [[ RefactorGraphics ]] Refactor CGImage creation code to be pixel-format independent CGBitmapInfo t_bm_info; t_bm_info = MCGPixelFormatToCGBitmapInfo(kMCGPixelFormatNative, true); if (t_success) t_success = nil != (t_image = CGImageCreate(t_width, t_height, 8, 32, t_dst_stride, p_colorspace, t_bm_info, t_data_provider, nil, true, kCGRenderingIntentDefault)); CGDataProviderRelease(t_data_provider); if (t_success) r_image = t_image; return t_success; }