static void copyImageData_color( CGImageRef imageRef, cv::Mat &image ) { size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); image = cv::Mat( cv::Size( width, height ), CV_8UC3 ); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char *rawData = image.data; size_t bytesPerPixel = 4; size_t bytesPerRow = bytesPerPixel * width; size_t bitsPerComponent = 8; CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); CGContextRelease(context); }
void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp) { size_t frames = frameCount(); for (size_t i = 0; i < frames; ++i) { CGImageRef image = frameAtIndex(i); if (CGImageGetHeight(image) == static_cast<size_t>(srcSize.height()) && CGImageGetWidth(image) == static_cast<size_t>(srcSize.width())) { size_t currentFrame = m_currentFrame; m_currentFrame = i; draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), styleColorSpace, compositeOp); m_currentFrame = currentFrame; return; } } // No image of the correct size was found, fallback to drawing the current frame IntSize imageSize = BitmapImage::size(); draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), styleColorSpace, compositeOp); }
BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer) : Image(observer) , m_currentFrame(0) , m_frames(0) , m_repetitionCount(cAnimationNone) , m_repetitionCountStatus(Unknown) , m_repetitionsComplete(0) , m_decodedSize(0) , m_decodedPropertiesSize(0) , m_frameCount(1) , m_isSolidColor(false) , m_checkedForSolidColor(false) , m_animationFinished(true) , m_allDataReceived(true) , m_haveSize(true) , m_sizeAvailable(true) , m_haveFrameCount(true) { CGFloat width = CGImageGetWidth(cgImage); CGFloat height = CGImageGetHeight(cgImage); m_decodedSize = width * height * 4; m_size = IntSize(width, height); // Since we don't have a decoder, we can't figure out the image orientation. // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. m_sizeRespectingOrientation = IntSize(width, height); #if PLATFORM(IOS) m_originalSize = IntSize(width, height); m_originalSizeRespectingOrientation = IntSize(width, height); #endif m_frames.grow(1); m_frames[0].m_frame = CGImageRetain(cgImage); m_frames[0].m_hasAlpha = true; m_frames[0].m_haveMetadata = true; #if PLATFORM(IOS) m_frames[0].m_scale = 1; #endif checkForSolidColor(); }
CGImageRef nglImageCGCodec::ReadInfo(nglIStream* pIStream) { mpIStream = pIStream; CGImageRef pCGImage = NULL; const bool shouldInterpolate = true; if (ProbePNG(pIStream)) { pCGImage = CGImageCreateWithPNGDataProvider(mpCGProvider, NULL, shouldInterpolate, kCGRenderingIntentDefault); } else if (ProbeJPEG(pIStream)) { pCGImage = CGImageCreateWithJPEGDataProvider(mpCGProvider, NULL, false, kCGRenderingIntentDefault); } if (pCGImage) { nglImageInfo info; info.mWidth = CGImageGetWidth(pCGImage); info.mHeight = CGImageGetHeight(pCGImage); if (info.mWidth > 0 && info.mHeight > 0) { info.mBufferFormat = eImageFormatRaw; info.mPixelFormat = eImagePixelRGBA; info.mBytesPerPixel = 4; info.mBitDepth = 8 * info.mBytesPerPixel; info.mBytesPerLine = info.mWidth * info.mBytesPerPixel; info.mPreMultAlpha = true; info.mpBuffer = NULL; if (!SendInfo(info)) { CGImageRelease(pCGImage); return NULL; } return pCGImage; } CGImageRelease(pCGImage); } return NULL; }
void BitmapImage::checkForSolidColor() { m_checkedForSolidColor = true; m_isSolidColor = false; if (frameCount() > 1) return; if (!haveFrameAtIndex(0)) { IntSize size = m_source.frameSizeAtIndex(0, 0); if (size.width() != 1 || size.height() != 1) return; if (!ensureFrameIsCached(0)) return; } CGImageRef image = nullptr; if (m_frames.size()) image = m_frames[0].m_frame; if (!image) return; // Currently we only check for solid color in the important special case of a 1x1 image. if (CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) { unsigned char pixel[4]; // RGBA RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big)); if (!bitmapContext) return; GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy); CGRect destinationRect = CGRectMake(0, 0, 1, 1); CGContextDrawImage(bitmapContext.get(), destinationRect, image); if (!pixel[3]) m_solidColor = Color(0, 0, 0, 0); else m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); m_isSolidColor = true; } }
void BitmapImage::checkForSolidColor() { m_checkedForSolidColor = true; if (frameCount() > 1) { m_isSolidColor = false; return; } #if !PLATFORM(IOS) CGImageRef image = frameAtIndex(0); #else // Note, checkForSolidColor() may be called from frameAtIndex(). On iOS frameAtIndex() gets passed a scaleHint // argument which it uses to tell CG to create a scaled down image. Since we don't know the scaleHint here, if // we call frameAtIndex() again, we would pass it the default scale of 1 and would end up recreating the image. // So we do a quick check and call frameAtIndex(0) only if we haven't yet created an image. CGImageRef image = nullptr; if (m_frames.size()) image = m_frames[0].m_frame; if (!image) image = frameAtIndex(0); #endif // Currently we only check for solid color in the important special case of a 1x1 image. if (image && CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) { unsigned char pixel[4]; // RGBA RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big)); if (!bitmapContext) return; GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy); CGRect destinationRect = CGRectMake(0, 0, 1, 1); CGContextDrawImage(bitmapContext.get(), destinationRect, image); if (!pixel[3]) m_solidColor = Color(0, 0, 0, 0); else m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); m_isSolidColor = true; } }
CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass) { m_saveCount = 0; _context = context; _deviceClass = deviceClass; CGContextRetain(_context); CGRect r = CGContextGetClipBoundingBox(context); _width = FXSYS_round(r.size.width); _height = FXSYS_round(r.size.height); _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK; if (_deviceClass != FXDC_DISPLAY) { } else { CGImageRef image = CGBitmapContextCreateImage(_context); if (image) { _renderCaps |= FXRC_GET_BITS; _width = CGImageGetWidth(image); _height = CGImageGetHeight(image); CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); if (kCGImageAlphaPremultipliedFirst == alphaInfo || kCGImageAlphaPremultipliedLast == alphaInfo || kCGImageAlphaOnly == alphaInfo) { _renderCaps |= FXRC_ALPHA_OUTPUT; } } CGImageRelease(image); } CGAffineTransform ctm = CGContextGetCTM(_context); CGContextSaveGState(_context); m_saveCount++; if (ctm.d >= 0) { CGFloat offset_x, offset_y; offset_x = ctm.tx; offset_y = ctm.ty; CGContextTranslateCTM(_context, -offset_x, -offset_y); CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y)); } _foxitDevice2User = CGAffineTransformIdentity; _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); }
String ImageBuffer::toDataURL(const String& mimeType) const { ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); if (!image) return "data:,"; size_t width = CGImageGetWidth(image.get()); size_t height = CGImageGetHeight(image.get()); OwnArrayPtr<uint32_t> imageData(new uint32_t[width * height]); if (!imageData) return "data:,"; RetainPtr<CGImageRef> transformedImage(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); if (!transformedImage) return "data:,"; RetainPtr<CFMutableDataRef> transformedImageData(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); if (!transformedImageData) return "data:,"; RetainPtr<CGImageDestinationRef> imageDestination(AdoptCF, CGImageDestinationCreateWithData(transformedImageData.get(), utiFromMIMEType(mimeType).get(), 1, 0)); if (!imageDestination) return "data:,"; CGImageDestinationAddImage(imageDestination.get(), transformedImage.get(), 0); CGImageDestinationFinalize(imageDestination.get()); Vector<char> in; in.append(CFDataGetBytePtr(transformedImageData.get()), CFDataGetLength(transformedImageData.get())); Vector<char> out; base64Encode(in, out); out.append('\0'); return String::format("data:%s;base64,%s", mimeType.utf8().data(), out.data()); }
//----------------------------------------------------------------------------- void CGDrawContext::fillRectWithBitmap (CBitmap* bitmap, const CRect& srcRect, const CRect& dstRect, float alpha) { if (bitmap == 0 || alpha == 0.f || srcRect.isEmpty () || dstRect.isEmpty ()) return; if (!(srcRect.left == 0 && srcRect.right == 0 && srcRect.right == bitmap->getWidth () && srcRect.bottom == bitmap->getHeight ())) { // CGContextDrawTiledImage does not work with parts of a bitmap CDrawContext::fillRectWithBitmap(bitmap, srcRect, dstRect, alpha); return; } IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (scaleFactor); CPoint bitmapSize = platformBitmap->getSize (); if (srcRect.right > bitmapSize.x || srcRect.bottom > bitmapSize.y) return; CGBitmap* cgBitmap = platformBitmap ? dynamic_cast<CGBitmap*> (platformBitmap) : 0; CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0; if (image) { CGContextRef context = beginCGContext (false, true); if (context) { // TODO: Check if this works with retina images CGRect clipRect = CGRectFromCRect (dstRect); clipRect.origin.y = -(clipRect.origin.y) - clipRect.size.height; clipRect = pixelAlligned (clipRect); CGContextClipToRect (context, clipRect); CGRect r = {}; r.size.width = CGImageGetWidth (image); r.size.height = CGImageGetHeight (image); CGContextDrawTiledImage (context, r, image); releaseCGContext (context); } } }
void DrawSubCGImage (CGContextRef ctx, CGImageRef image, CGRect src, CGRect dst) { float w = (float) CGImageGetWidth(image); float h = (float) CGImageGetHeight(image); CGRect drawRect = CGRectMake(0.0f, 0.0f, w, h); if (!CGRectEqualToRect(src, dst)) { float sx = CGRectGetWidth(dst) / CGRectGetWidth(src); float sy = CGRectGetHeight(dst) / CGRectGetHeight(src); float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); float dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy); drawRect = CGRectMake(dx, dy, w * sx, h * sy); } CGContextSaveGState(ctx); CGContextClipToRect(ctx, dst); CGContextDrawImage(ctx, drawRect, image); CGContextRestoreGState(ctx); }
cv::Mat &osx_cv::toMat( const CGImageRef &image, cv::Mat &out, osx::disp::RGBType destType ) { cv::Mat temp; size_t w = CGImageGetWidth(image), h = CGImageGetHeight(image); if (CGImageGetBitsPerPixel(image) != 32) { throw invalid_argument("`image` must be 32 bits per pixel"); } temp.create(int(h), int(w), CV_8UC4); CGColorSpaceRef colorSpace = CGImageGetColorSpace(image); CGContextRef context = CGBitmapContextCreate( temp.data, w, h, CGImageGetBitsPerComponent(image), CGImageGetBytesPerRow(image), colorSpace, CGImageGetAlphaInfo(image) ); CGContextDrawImage( context, CGRectMake(0, 0, (CGFloat)w, (CGFloat)h), image ); _cvtRGBColor(temp, out, CGImageGetAlphaInfo(image), destType); CGContextRelease(context); return out; }
bool LockTarget(MCStackSurfaceTargetType p_type, void*& r_context) { if (p_type != kMCStackSurfaceTargetCoreGraphics) return false; CGImageRef t_mask; t_mask = nil; if (m_stack -> getwindowshape() != nil) t_mask = (CGImageRef)m_stack -> getwindowshape() -> handle; if (t_mask != nil) { MCRectangle t_card_rect; t_card_rect = m_stack -> getcurcard() -> getrect(); MCRectangle t_rect; t_rect = MCRegionGetBoundingBox(m_region); CGContextClearRect(m_context, CGRectMake(t_rect . x, t_card_rect . height - (t_rect . y + t_rect . height), t_rect . width, t_rect . height)); // MW-2012-07-25: [[ Bug ]] Make sure we use signed arithmetic to // compute the y-origin otherwise it wraps to 2^32! int32_t t_mask_height, t_mask_width; t_mask_width = (int32_t)CGImageGetWidth(t_mask); t_mask_height = (int32_t)CGImageGetHeight(t_mask); CGRect t_dst_rect; t_dst_rect . origin . x = 0; t_dst_rect . origin . y = ((int32_t)t_card_rect . height) - t_mask_height - m_stack -> getscroll(); t_dst_rect . size . width = t_mask_width; t_dst_rect . size . height = t_mask_height; CGContextClipToMask(m_context, t_dst_rect, t_mask); } CGContextSaveGState(m_context); r_context = m_context; return true; }
bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); if (NULL == imageSrc) { return false; } SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL); if (NULL == image) { return false; } SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); const int width = CGImageGetWidth(image); const int height = CGImageGetHeight(image); bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } if (!this->allocPixelRef(bm, NULL)) { return false; } bm->lockPixels(); bm->eraseColor(0); // use the same colorspace, so we don't change the pixels at all CGColorSpaceRef cs = CGImageGetColorSpace(image); CGContextRef cg = CGBitmapContextCreate(bm->getPixels(), width, height, 8, bm->rowBytes(), cs, BITMAP_INFO); CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); CGContextRelease(cg); bm->unlockPixels(); return true; }
cv::Mat CGImageToMat(CGImageRef image) { CGColorSpaceRef colorSpace = CGImageGetColorSpace(image); CGFloat cols = CGImageGetWidth(image); CGFloat rows = CGImageGetHeight(image); cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha) CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data cols, // Width of bitmap rows, // Height of bitmap 8, // Bits per component cvMat.step[0], // Bytes per row colorSpace, // Colorspace kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault); // Bitmap info flags CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image); CGContextRelease(contextRef); return cvMat; }
CGImageRef CGImageMaskCreateWithImageRef(CGImageRef imageRef) { size_t maskWidth = CGImageGetWidth(imageRef); size_t maskHeight = CGImageGetHeight(imageRef); size_t bytesPerRow = maskWidth; size_t bufferSize = maskWidth * maskHeight; CFMutableDataRef dataBuffer = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataSetLength(dataBuffer, bufferSize); CGColorSpaceRef greyColorSpaceRef = CGColorSpaceCreateDeviceGray(); CGContextRef ctx = CGBitmapContextCreate(CFDataGetMutableBytePtr(dataBuffer), maskWidth, maskHeight, 8, bytesPerRow, greyColorSpaceRef, kCGImageAlphaNone); CGContextDrawImage(ctx, CGRectMake(0, 0, maskWidth, maskHeight), imageRef); CGContextRelease(ctx); CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataBuffer); CGImageRef maskImageRef = CGImageMaskCreate(maskWidth, maskHeight, 8, 8, bytesPerRow, dataProvider, NULL, FALSE); CGDataProviderRelease(dataProvider); CGColorSpaceRelease(greyColorSpaceRef); CFRelease(dataBuffer); return maskImageRef; }
GLuint load_texure(const char *filename) { GLuint texid; // ImageIO loader CFStringRef path = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8); CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0); CGImageSourceRef imagesource = CGImageSourceCreateWithURL(url, NULL); CGImageRef image = CGImageSourceCreateImageAtIndex (imagesource, 0, NULL); size_t width = CGImageGetWidth(image); size_t height = CGImageGetHeight(image); CGRect rect = {{0, 0}, {width, height}}; void * data = malloc(width * height * 4); CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGContextRef myBitmapContext = CGBitmapContextCreate (data, width, height, 8, width*4, space, kCGImageAlphaPremultipliedFirst); CGContextDrawImage(myBitmapContext, rect, image); CGContextRelease(myBitmapContext); CGColorSpaceRelease(space); CGImageRelease(image); CFRelease(imagesource); CFRelease(url); CFRelease(path); glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); free(data); return texid; }
static CGContextRef createCGContextFromImage(WKImageRef wkImage, FlipGraphicsContextOrNot flip = DontFlipGraphicsContext) { RetainPtr<CGImageRef> image = adoptCF(WKImageCreateCGImage(wkImage)); size_t pixelsWide = CGImageGetWidth(image.get()); size_t pixelsHigh = CGImageGetHeight(image.get()); size_t rowBytes = (4 * pixelsWide + 63) & ~63; // Creating this bitmap in the device color space should prevent any color conversion when the image of the web view is drawn into it. RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB()); CGContextRef context = CGBitmapContextCreate(0, pixelsWide, pixelsHigh, 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); if (flip == FlipGraphicsContext) { CGContextSaveGState(context); CGContextScaleCTM(context, 1, -1); CGContextTranslateCTM(context, 0, -static_cast<CGFloat>(pixelsHigh)); } CGContextDrawImage(context, CGRectMake(0, 0, pixelsWide, pixelsHigh), image.get()); if (flip == FlipGraphicsContext) CGContextRestoreGState(context); return context; }
block_t *screen_Capture(demux_t *p_demux) { demux_sys_t *p_sys = p_demux->p_sys; screen_data_t *p_data = (screen_data_t *)p_sys->p_data; block_t *p_block; CGRect capture_rect; CGImageRef image; /* forward cursor location */ CGPoint cursor_pos; CGEventRef event = CGEventCreate(NULL); cursor_pos = CGEventGetLocation(event); CFRelease(event); cursor_pos.x -= p_data->screen_left; cursor_pos.y -= p_data->screen_top; if (p_sys->b_follow_mouse) FollowMouse(p_sys, cursor_pos.x, cursor_pos.y); capture_rect.origin.x = p_sys->i_left; capture_rect.origin.y = p_sys->i_top; capture_rect.size.width = p_data->width; capture_rect.size.height = p_data->height; /* fetch image data */ image = CGDisplayCreateImageForRect(p_data->display_id, capture_rect); if (!image) { msg_Warn(p_demux, "no image!"); return NULL; } /* create offscreen context */ if (!p_data->offscreen_context) { CGColorSpaceRef colorspace; colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); p_data->offscreen_bitmap_size = p_sys->fmt.video.i_width * p_sys->fmt.video.i_height * 4; p_data->offscreen_bitmap = calloc(1, p_data->offscreen_bitmap_size); if (p_data->offscreen_bitmap == NULL) { msg_Warn(p_demux, "can't allocate offscreen bitmap"); CFRelease(image); return NULL; } p_data->offscreen_context = CGBitmapContextCreate(p_data->offscreen_bitmap, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height, 8, p_sys->fmt.video.i_width * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); if (!p_data->offscreen_context) { msg_Warn(p_demux, "can't create offscreen bitmap context"); CFRelease(image); return NULL; } CGColorSpaceRelease(colorspace); p_data->offscreen_rect = CGRectMake(0, 0, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height); } /* fetch cursor image */ CGImageRef cursor_image; int cid = CGSMainConnectionID(); CGPoint outHotSpot; cursor_image = CGSCreateRegisteredCursorImage(cid, (char *)"com.apple.coregraphics.GlobalCurrent", &outHotSpot); /* draw screen image and cursor image */ CGRect cursor_rect; cursor_rect.size.width = CGImageGetWidth(cursor_image); cursor_rect.size.height = CGImageGetHeight(cursor_image); cursor_rect.origin.x = cursor_pos.x - p_sys->i_left - outHotSpot.x; cursor_rect.origin.y = p_data->offscreen_rect.size.height - (cursor_pos.y + cursor_rect.size.height - p_sys->i_top - outHotSpot.y); CGContextDrawImage(p_data->offscreen_context, p_data->offscreen_rect, image); CGContextDrawImage(p_data->offscreen_context, cursor_rect, cursor_image); /* build block */ p_block = block_Alloc(p_data->offscreen_bitmap_size); if (!p_block) { msg_Warn(p_demux, "can't get block"); CFRelease(image); return NULL; } memmove(p_block->p_buffer, p_data->offscreen_bitmap, p_data->offscreen_bitmap_size); CFRelease(image); return p_block; }
/* Once we have our image (CGImageRef), we need to get it into an osg::Image */ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) { /* This code is adapted from Apple's Documentation found here: * http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/index.html * Listing 9-4††Using a Quartz image as a texture source. * Unfortunately, this guide doesn't show what to do about * non-RGBA image formats so I'm making the rest up * (and it's probably all wrong). */ size_t the_width = CGImageGetWidth(image_ref); size_t the_height = CGImageGetHeight(image_ref); CGRect the_rect = {{0, 0}, {the_width, the_height}}; size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref); size_t bytes_per_row = CGImageGetBytesPerRow(image_ref); // size_t bits_per_component = CGImageGetBitsPerComponent(image_ref); size_t bits_per_component = 8; CGImageAlphaInfo alpha_info = CGImageGetAlphaInfo(image_ref); GLint internal_format; GLenum pixel_format; GLenum data_type; void* image_data = calloc(the_width * 4, the_height); CGColorSpaceRef color_space; CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref); switch(bits_per_pixel) { // Drat, if 8-bit, how do you distinguish // between a 256 color GIF, a LUMINANCE map // or an ALPHA map? case 8: { // I probably did the formats all wrong for this case, // especially the ALPHA case. if(kCGImageAlphaNone == alpha_info) { /* internal_format = GL_LUMINANCE; pixel_format = GL_LUMINANCE; */ internal_format = GL_RGBA8; pixel_format = GL_BGRA_EXT; data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); // bitmap_info = kCGImageAlphaPremultipliedFirst; #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif } else { internal_format = GL_ALPHA; pixel_format = GL_ALPHA; data_type = GL_UNSIGNED_BYTE; // bytes_per_row = the_width; // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); color_space = CGColorSpaceCreateDeviceGray(); } break; } case 24: { internal_format = GL_RGBA8; pixel_format = GL_BGRA_EXT; data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); // bitmap_info = kCGImageAlphaNone; #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif break; } // // Tatsuhiro Nishioka // 16 bpp grayscale (8 bit white and 8 bit alpha) causes invalid argument combination // in CGBitmapContextCreate. // I guess it is safer to handle 16 bit grayscale image as 32-bit RGBA image. // It works at least on FlightGear // case 16: case 32: case 48: case 64: { internal_format = GL_RGBA8; pixel_format = GL_BGRA_EXT; data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); // bitmap_info = kCGImageAlphaPremultipliedFirst; #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif break; } default: { // OSG_WARN << "Unknown file type in " << fileName.c_str() << " with " << origDepth << std::endl; return NULL; break; } } // Sets up a context to be drawn to with image_data as the area to be drawn to CGContextRef bitmap_context = CGBitmapContextCreate( image_data, the_width, the_height, bits_per_component, bytes_per_row, color_space, bitmap_info ); CGContextTranslateCTM(bitmap_context, 0, the_height); CGContextScaleCTM(bitmap_context, 1.0, -1.0); // Draws the image into the context's image_data CGContextDrawImage(bitmap_context, the_rect, image_ref); CGContextRelease(bitmap_context); if (!image_data) return NULL; // alpha is premultiplied with rgba, undo it vImage_Buffer vb; vb.data = image_data; vb.height = the_height; vb.width = the_width; vb.rowBytes = the_width * 4; vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); // changing it to GL_UNSIGNED_BYTE seems working, but I'm not sure if this is a right way. // data_type = GL_UNSIGNED_BYTE; osg::Image* osg_image = new osg::Image; osg_image->setImage( the_width, the_height, 1, internal_format, pixel_format, data_type, (unsigned char*)image_data, osg::Image::USE_MALLOC_FREE // Assumption: osg_image takes ownership of image_data and will free ); return osg_image; }
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight) { if (URIUtils::GetExtension(texturePath).Equals(".dds")) { // special case for DDS images CDDSImage image; if (image.ReadFile(texturePath)) { Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false); return true; } return false; } #if defined(__APPLE__) && defined(__arm__) XFILE::CFile file; UInt8 *imageBuff = NULL; int64_t imageBuffSize = 0; //open path and read data to buffer //this handles advancedsettings.xml pathsubstitution //and resulting networking if (file.Open(texturePath, 0)) { imageBuffSize =file.GetLength(); imageBuff = new UInt8[imageBuffSize]; imageBuffSize = file.Read(imageBuff, imageBuffSize); file.Close(); } else { CLog::Log(LOGERROR, "Texture manager unable to open file %s", texturePath.c_str()); return false; } if (imageBuffSize <= 0) { CLog::Log(LOGERROR, "Texture manager read texture file failed."); delete [] imageBuff; return false; } // create the image from buffer; CGImageSourceRef imageSource; // create a CFDataRef using CFDataCreateWithBytesNoCopy and kCFAllocatorNull for deallocator. // this allows us to do a nocopy reference and we handle the free of imageBuff CFDataRef cfdata = CFDataCreateWithBytesNoCopy(NULL, imageBuff, imageBuffSize, kCFAllocatorNull); imageSource = CGImageSourceCreateWithData(cfdata, NULL); if (imageSource == nil) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CSpecialProtocol::TranslatePath(texturePath).c_str()); CFRelease(cfdata); delete [] imageBuff; return false; } CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); int rotate = 0; if (autoRotate) { // get the orientation of the image for displaying it correctly CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource,0, NULL); if (imagePropertiesDictionary != nil) { CFNumberRef orientation = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyOrientation); if (orientation != nil) { int value = 0; CFNumberGetValue(orientation, kCFNumberIntType, &value); if (value) rotate = value - 1; } CFRelease(imagePropertiesDictionary); } } CFRelease(imageSource); unsigned int width = CGImageGetWidth(image); unsigned int height = CGImageGetHeight(image); m_hasAlpha = (CGImageGetAlphaInfo(image) != kCGImageAlphaNone); if (originalWidth) *originalWidth = width; if (originalHeight) *originalHeight = height; // check texture size limits and limit to screen size - preserving aspectratio of image if ( width > g_Windowing.GetMaxTextureSize() || height > g_Windowing.GetMaxTextureSize() ) { float aspect; if ( width > height ) { aspect = (float)width / (float)height; width = g_Windowing.GetWidth(); height = (float)width / (float)aspect; } else { aspect = (float)height / (float)width; height = g_Windowing.GetHeight(); width = (float)height / (float)aspect; } CLog::Log(LOGDEBUG, "Texture manager texture clamp:new texture size: %i x %i", width, height); } // use RGBA to skip swizzling Allocate(width, height, XB_FMT_RGBA8); m_orientation = rotate; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // hw convert jmpeg to RGBA CGContextRef context = CGBitmapContextCreate(m_pixels, width, height, 8, GetPitch(), colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); // Flip so that it isn't upside-down //CGContextTranslateCTM(context, 0, height); //CGContextScaleCTM(context, 1.0f, -1.0f); #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 CGContextClearRect(context, CGRectMake(0, 0, width, height)); #else #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 // (just a way of checking whether we're running in 10.5 or later) if (CGContextDrawLinearGradient == 0) CGContextClearRect(context, CGRectMake(0, 0, width, height)); else #endif CGContextSetBlendMode(context, kCGBlendModeCopy); #endif //CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); CGContextRelease(context); CGImageRelease(image); CFRelease(cfdata); delete [] imageBuff; #else DllImageLib dll; if (!dll.Load()) return false; ImageInfo image; memset(&image, 0, sizeof(image)); unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); if(!dll.LoadImage(texturePath.c_str(), width, height, &image)) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str()); return false; } m_hasAlpha = NULL != image.alpha; Allocate(image.width, image.height, XB_FMT_A8R8G8B8); if (autoRotate && image.exifInfo.Orientation) m_orientation = image.exifInfo.Orientation - 1; if (originalWidth) *originalWidth = image.originalwidth; if (originalHeight) *originalHeight = image.originalheight; unsigned int dstPitch = GetPitch(); unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes unsigned char *dst = m_pixels; unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3) { dst2[0] = src2[0]; dst2[1] = src2[1]; dst2[2] = src2[2]; dst2[3] = 0xff; } src -= srcPitch; dst += dstPitch; } if(image.alpha) { dst = m_pixels + 3; src = image.alpha + (m_imageHeight - 1) * m_imageWidth; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2+=4, src2++) *dst2 = *src2; src -= m_imageWidth; dst += dstPitch; } } dll.ReleaseImage(&image); #endif ClampToEdge(); return true; }
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) { if (!nativeImageForCurrentFrame()) return; ASSERT(patternTransform.isInvertible()); if (!patternTransform.isInvertible()) // Avoid a hang under CGContextDrawTiledImage on release builds. return; CGContextRef context = ctxt->platformContext(); ctxt->save(); CGContextClipToRect(context, destRect); ctxt->setCompositeOperation(op); CGContextTranslateCTM(context, destRect.x(), destRect.y() + destRect.height()); CGContextScaleCTM(context, 1, -1); // Compute the scaled tile size. float scaledTileHeight = tileRect.height() * narrowPrecisionToFloat(patternTransform.d()); // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being // the origin). float adjustedX = phase.x() - destRect.x() + tileRect.x() * narrowPrecisionToFloat(patternTransform.a()); // We translated the context so that destRect.x() is the origin, so subtract it out. float adjustedY = destRect.height() - (phase.y() - destRect.y() + tileRect.y() * narrowPrecisionToFloat(patternTransform.d()) + scaledTileHeight); CGImageRef tileImage = nativeImageForCurrentFrame(); float h = CGImageGetHeight(tileImage); RetainPtr<CGImageRef> subImage; if (tileRect.size() == size()) subImage = tileImage; else { // Copying a sub-image out of a partially-decoded image stops the decoding of the original image. It should never happen // because sub-images are only used for border-image, which only renders when the image is fully decoded. ASSERT(h == height()); subImage.adoptCF(CGImageCreateWithImageInRect(tileImage, tileRect)); } // Adjust the color space. subImage = imageWithColorSpace(subImage.get(), styleColorSpace); #ifndef BUILDING_ON_TIGER // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that // its buffer is the same size as the overall image. Because a partially decoded CGImageRef with a smaller width or height than the // overall image buffer needs to tile with "gaps", we can't use the optimized tiling call in that case. // FIXME: Could create WebKitSystemInterface SPI for CGCreatePatternWithImage2 and probably make Tiger tile faster as well. // FIXME: We cannot use CGContextDrawTiledImage with scaled tiles on Leopard, because it suffers from rounding errors. Snow Leopard is ok. float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a()); float w = CGImageGetWidth(tileImage); #ifdef BUILDING_ON_LEOPARD if (w == size().width() && h == size().height() && scaledTileWidth == tileRect.width() && scaledTileHeight == tileRect.height()) #else if (w == size().width() && h == size().height()) #endif CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage.get()); else { #endif // On Leopard, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image. // On Tiger this code runs all the time. This code is suboptimal because the pattern does not reference the image directly, and the // pattern is destroyed before exiting the function. This means any decoding the pattern does doesn't end up cached anywhere, so we // redecode every time we paint. static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL }; CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY); matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context)); // The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top. matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h); RetainPtr<CGPatternRef> pattern(AdoptCF, CGPatternCreate(subImage.get(), CGRectMake(0, 0, tileRect.width(), tileRect.height()), matrix, tileRect.width(), tileRect.height(), kCGPatternTilingConstantSpacing, true, &patternCallbacks)); if (!pattern) { ctxt->restore(); return; } RetainPtr<CGColorSpaceRef> patternSpace(AdoptCF, CGColorSpaceCreatePattern(0)); CGFloat alpha = 1; RetainPtr<CGColorRef> color(AdoptCF, CGColorCreateWithPattern(patternSpace.get(), pattern.get(), &alpha)); CGContextSetFillColorSpace(context, patternSpace.get()); // FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy). wkSetPatternBaseCTM(context, CGAffineTransformIdentity); CGContextSetPatternPhase(context, CGSizeZero); CGContextSetFillColorWithColor(context, color.get()); CGContextFillRect(context, CGContextGetClipBoundingBox(context)); #ifndef BUILDING_ON_TIGER } #endif ctxt->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
static void drawPatternCallback(void* info, CGContextRef context) { CGImageRef image = (CGImageRef)info; CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, 0, CGImageGetWidth(image), CGImageGetHeight(image))), image); }
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) { startAnimation(); RetainPtr<CGImageRef> image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, destRect, solidColor(), styleColorSpace, compositeOp); return; } float currHeight = CGImageGetHeight(image.get()); if (currHeight <= srcRect.y()) return; CGContextRef context = ctxt->platformContext(); ctxt->save(); bool shouldUseSubimage = false; // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image // and then set a clip to the portion that we want to display. FloatRect adjustedDestRect = destRect; FloatSize selfSize = currentFrameSize(); if (srcRect.size() != selfSize) { CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context); // When the image is scaled using high-quality interpolation, we create a temporary CGImage // containing only the portion we want to display. We need to do this because high-quality // interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed // into the destination rect. See <rdar://problem/6112909>. shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && (srcRect.size() != destRect.size() || !ctxt->getCTM().isIdentityOrTranslationOrFlipped()); float xScale = srcRect.width() / destRect.width(); float yScale = srcRect.height() / destRect.height(); if (shouldUseSubimage) { FloatRect subimageRect = srcRect; float leftPadding = srcRect.x() - floorf(srcRect.x()); float topPadding = srcRect.y() - floorf(srcRect.y()); subimageRect.move(-leftPadding, -topPadding); adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale); subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding)); adjustedDestRect.setWidth(subimageRect.width() / xScale); subimageRect.setHeight(ceilf(subimageRect.height() + topPadding)); adjustedDestRect.setHeight(subimageRect.height() / yScale); image.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect)); if (currHeight < srcRect.bottom()) { ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y); adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / yScale); } } else { adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale)); } CGContextClipToRect(context, destRect); } // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. if (!shouldUseSubimage && currHeight < selfSize.height()) adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height()); ctxt->setCompositeOperation(compositeOp); // Flip the coords. CGContextScaleCTM(context, 1, -1); adjustedDestRect.setY(-adjustedDestRect.bottom()); // Adjust the color space. image = imageWithColorSpace(image.get(), styleColorSpace); // Draw the image. CGContextDrawImage(context, adjustedDestRect, image.get()); ctxt->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); if (NULL == imageSrc) { return false; } SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL); if (NULL == image) { return false; } SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); const int width = SkToInt(CGImageGetWidth(image)); const int height = SkToInt(CGImageGetHeight(image)); bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } if (!this->allocPixelRef(bm, NULL)) { return false; } bm->lockPixels(); bm->eraseColor(SK_ColorTRANSPARENT); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGContextRef cg = CGBitmapContextCreate(bm->getPixels(), width, height, 8, bm->rowBytes(), cs, BITMAP_INFO); CFRelease(cs); CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); CGContextRelease(cg); CGImageAlphaInfo info = CGImageGetAlphaInfo(image); switch (info) { case kCGImageAlphaNone: case kCGImageAlphaNoneSkipLast: case kCGImageAlphaNoneSkipFirst: SkASSERT(SkBitmap::ComputeIsOpaque(*bm)); bm->setAlphaType(kOpaque_SkAlphaType); break; default: // we don't know if we're opaque or not, so compute it. if (SkBitmap::ComputeIsOpaque(*bm)) { bm->setAlphaType(kOpaque_SkAlphaType); } } if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) { // CGBitmapContext does not support unpremultiplied, so the image has been premultiplied. // Convert to unpremultiplied. for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { uint32_t* addr = bm->getAddr32(i, j); *addr = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*addr); } } bm->setAlphaType(kUnpremul_SkAlphaType); } bm->unlockPixels(); return true; }
void MusicBoxDialog(void) { OSStatus err; IBNibRef nibRef; if (!cartOpen) return; err = CreateNibReference(kMacS9XCFString, &nibRef); if (err == noErr) { CFURLRef iconURL; FSRef iconFSRef; IconRef actIcon; WindowRef tWindowRef; actIcon = nil; if (musicboxmode == kMBXSoundEmulation) iconURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_ledoff"), CFSTR("icns"), nil); else iconURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_ledon" ), CFSTR("icns"), nil); if (iconURL) { if (CFURLGetFSRef(iconURL, &iconFSRef)) err = RegisterIconRefFromFSRef('~9X~', 'micn', &iconFSRef, &actIcon); CFRelease(iconURL); } err = CreateWindowFromNib(nibRef, CFSTR("MusicBox"), &tWindowRef); if (err == noErr) { EventHandlerRef mboxRef, paneRef; EventHandlerUPP mboxUPP, paneUPP; EventLoopTimerRef timeRef; EventLoopTimerUPP timeUPP; EventTypeSpec mboxEvents[] = { { kEventClassCommand, kEventCommandProcess }, { kEventClassCommand, kEventCommandUpdateStatus } }, paneEvents[] = { { kEventClassControl, kEventControlDraw } }; CFStringRef sref; CGDataProviderRef prov; CGImageRef ipng; CFURLRef iurl; HIViewRef ctl, root, paneView, imageView, contentView; HIViewID cid; HIRect bounds; Rect windowRect, barRect; char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; mboxPause = false; mbxFinished = false; showIndicator = false; so.stereo_switch = ~0; for (int i = 0; i < MAC_MAX_PLAYERS; i++) controlPad[i] = 0; switch (drawingMethod) { case kDrawingOpenGL: Settings.OpenGLEnable = true; break; case kDrawingDirect: case kDrawingBlitGL: Settings.OpenGLEnable = false; } // 107's enhanced SPC player root = HIViewGetRoot(tWindowRef); cid.id = 0; if (musicboxmode == kMBXSoundEmulation) { cid.signature = 'HEAD'; HIViewFindByID(root, cid, &ctl); EnableControl(ctl); StoredAPU = new SAPU; StoredAPURegisters = new SAPURegisters; StoredSoundData = new SSoundData; StoredIAPURAM = new uint8 [0x10000]; SPCPlayFreeze(); } else MusicBoxForceFreeze(); cid.signature = 'Kart'; HIViewFindByID(root, cid, &ctl); SetStaticTextTrunc(ctl, truncEnd, false); _splitpath(Memory.ROMFilename, drive, dir, fname, ext); sref = CFStringCreateWithCString(kCFAllocatorDefault, fname, MAC_PATH_ENCODING); if (sref) { SetStaticTextCFString(ctl, sref, false); CFRelease(sref); } ipng = nil; iurl = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_indicator"), CFSTR("png"), nil); if (iurl) { prov = CGDataProviderCreateWithURL(iurl); if (prov) { ipng = CGImageCreateWithPNGDataProvider(prov, nil, false, kCGRenderingIntentDefault); CGDataProviderRelease(prov); } CFRelease(iurl); } imageView = nil; if (ipng) { HIViewFindByID(root, kHIViewWindowContentID, &contentView); err = HIImageViewCreate(ipng, &imageView); if (err == noErr) { bounds = CGRectMake(30, 64, CGImageGetWidth(ipng), CGImageGetHeight(ipng)); HIViewSetFrame(imageView, &bounds); HIImageViewSetOpaque(imageView, false); HIViewSetVisible(imageView, true); HIViewAddSubview(contentView, imageView); cid.signature = 'iMaG'; SetControlID(imageView, &cid); } CGImageRelease(ipng); } cid.signature = 'Pane'; HIViewFindByID(root, cid, &paneView); HIViewGetBounds(paneView, &bounds); mbxViewWidth = bounds.size.width; mbxViewHeight = bounds.size.height; mbxMarginY = (mbxViewHeight - mbxBarHeight) / 2.0; mbxMarginX = (mbxViewWidth - ((mbxBarWidth * 8.0 + mbxBarSpace * 7.0) * 2.0 + mbxLRSpace)) / 2.0; if (imageView) { HIViewSetZOrder(imageView, kHIViewZOrderBelow, paneView); HIViewAddSubview(imageView, paneView); } cid.signature = 'Tr_i'; HIViewFindByID(root, cid, &ctl); HIViewGetFrame(ctl, &bounds); GetWindowBounds(tWindowRef, kWindowTitleBarRgn, &barRect); mbxClosedHeight = (short) (bounds.origin.y + bounds.size.height + 7.0) + (barRect.bottom - barRect.top); GetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect); mbxOpenedHeight = windowRect.bottom - windowRect.top; windowRect.bottom = windowRect.top + mbxClosedHeight; SetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect); paneUPP = NewEventHandlerUPP(IndicatorEventHandler); err = InstallControlEventHandler(paneView, paneUPP, GetEventTypeCount(paneEvents), paneEvents, (void *) paneView, &paneRef); mboxUPP = NewEventHandlerUPP(MusicBoxEventHandler); err = InstallWindowEventHandler(tWindowRef, mboxUPP, GetEventTypeCount(mboxEvents), mboxEvents, (void *) tWindowRef, &mboxRef); timeUPP = NewEventLoopTimerUPP(MusicBoxTimerHandler); err = InstallEventLoopTimer(GetCurrentEventLoop(), kEventDurationNoWait, kEventDurationSecond * 2.0 / (double) Memory.ROMFramesPerSecond, timeUPP, (void *) paneView, &timeRef); MusicBoxInitIndicator(); stopNow = false; MacStartSound(); pthread_create(&mbxThread, nil, SoundTask, nil); MoveWindowPosition(tWindowRef, kWindowMusicBox, true); GetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect); if (windowRect.bottom - windowRect.top > mbxClosedHeight) { showIndicator = true; SetControl32BitValue(ctl, 1); // Tr_i } ShowWindow(tWindowRef); err = RunAppModalLoopForWindow(tWindowRef); HideWindow(tWindowRef); SaveWindowPosition(tWindowRef, kWindowMusicBox); stopNow = true; pthread_join(mbxThread, nil); MacStopSound(); err = RemoveEventLoopTimer(timeRef); DisposeEventLoopTimerUPP(timeUPP); err = RemoveEventHandler(mboxRef); DisposeEventHandlerUPP(mboxUPP); err = RemoveEventHandler(paneRef); DisposeEventHandlerUPP(paneUPP); ReleaseWindow(tWindowRef); so.stereo_switch = ~0; mbxFinished = true; if (musicboxmode == kMBXSoundEmulation) { SPCPlayDefrost(); delete StoredAPU; delete StoredAPURegisters; delete StoredSoundData; delete [] StoredIAPURAM; } else MusicBoxForceDefrost(); Settings.OpenGLEnable = false; } if (actIcon) err = UnregisterIconRef('~9X~', 'micn'); DisposeNibReference(nibRef); } }
bool wxBitmapDataObject::SetData( const wxDataFormat& format, size_t nSize, const void *pBuf ) { Clear(); if ((pBuf == NULL) || (nSize == 0)) return false; #if wxMAC_USE_CORE_GRAPHICS Handle picHandle = NULL ; m_pictHandle = NewHandle( nSize ); memcpy( *(Handle) m_pictHandle, pBuf, nSize ); if ( format == s_pict ) { // pict for IO expects a 512 byte header picHandle = NewHandle( nSize + 512 ); memset( *picHandle , 0 , 512 ); memcpy( *picHandle+512, pBuf, nSize ); } else { picHandle = (Handle) m_pictHandle; } CGImageRef cgImageRef = 0; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( UMAGetSystemVersion() >= 0x1040 ) { CFDataRef data = NULL; HLock( picHandle ); data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) *picHandle, GetHandleSize(picHandle), kCFAllocatorNull); CGImageSourceRef source = CGImageSourceCreateWithData( data, NULL ); if ( source ) { cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); } CFRelease( source ); CFRelease( data ); HUnlock( picHandle ); } else #endif #ifndef __LP64__ { // import from TIFF GraphicsImportComponent importer = 0; OSStatus err = OpenADefaultComponent(GraphicsImporterComponentType, s_pict == format ? kQTFileTypePicture : kQTFileTypeTIFF, &importer); if (noErr == err) { if ( picHandle ) { ComponentResult result = GraphicsImportSetDataHandle(importer, picHandle); if ( result == noErr ) { Rect frame; GraphicsImportGetNaturalBounds( importer, &frame ); GraphicsImportCreateCGImage( importer, &cgImageRef, kGraphicsImportCreateCGImageUsingCurrentSettings ); } } CloseComponent( importer ); } } #endif if ( format == s_pict ) { DisposeHandle( picHandle ); } if ( cgImageRef ) { m_bitmap.Create( CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); // since our context is upside down we dont use CGContextDrawImage HIViewDrawCGImage( (CGContextRef) m_bitmap.GetHBITMAP() , &r, cgImageRef ) ; CGImageRelease(cgImageRef); cgImageRef = NULL; } #else PicHandle picHandle = (PicHandle)NewHandle( nSize ); memcpy( *picHandle, pBuf, nSize ); m_pictHandle = picHandle; // ownership is transferred to the bitmap m_pictCreated = false; #ifndef __LP64__ Rect frame; wxMacGetPictureBounds( picHandle, &frame ); #if wxUSE_METAFILE wxMetafile mf; mf.SetHMETAFILE( (WXHMETAFILE)m_pictHandle ); #endif wxMemoryDC mdc; m_bitmap.Create( frame.right - frame.left, frame.bottom - frame.top ); mdc.SelectObject( m_bitmap ); #if wxUSE_METAFILE mf.Play( &mdc ); #endif mdc.SelectObject( wxNullBitmap ); #endif #endif return m_bitmap.Ok(); }
void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem) { if (!context().isAcceleratedContext()) { IntRect scaledSourceRect = sourceRect; IntSize scaledSourceSize = sourceSize; if (coordinateSystem == LogicalCoordinateSystem) { scaledSourceRect.scale(m_resolutionScale); scaledSourceSize.scale(m_resolutionScale); } m_data.putData(source, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), false, multiplied == Unmultiplied, 1); return; } #if USE(IOSURFACE_CANVAS_BACKING_STORE) // Make a copy of the source to ensure the bits don't change before being drawn IntSize sourceCopySize(sourceRect.width(), sourceRect.height()); // FIXME (149431): Should this ImageBuffer be unconditionally unaccelerated? Making it match the context seems to break putData(). std::unique_ptr<ImageBuffer> sourceCopy = ImageBuffer::create(sourceCopySize, Unaccelerated, 1, ColorSpaceDeviceRGB); if (!sourceCopy) return; sourceCopy->m_data.putData(source, sourceSize, sourceRect, IntPoint(-sourceRect.x(), -sourceRect.y()), sourceCopy->internalSize(), sourceCopy->context().isAcceleratedContext(), multiplied == Unmultiplied, 1); // Set up context for using drawImage as a direct bit copy CGContextRef destContext = context().platformContext(); CGContextSaveGState(destContext); if (coordinateSystem == LogicalCoordinateSystem) CGContextConcatCTM(destContext, AffineTransform(wkGetUserToBaseCTM(destContext)).inverse()); else CGContextConcatCTM(destContext, AffineTransform(CGContextGetCTM(destContext)).inverse()); CGContextResetClip(destContext); CGContextSetInterpolationQuality(destContext, kCGInterpolationNone); CGContextSetAlpha(destContext, 1.0); CGContextSetBlendMode(destContext, kCGBlendModeCopy); CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0); // Draw the image in CG coordinate space FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.backingStoreSize, internalSize()); IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height()); IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize); CGContextClipToRect(destContext, destRectInCGCoords); RetainPtr<CGImageRef> sourceCopyImage = sourceCopy->copyNativeImage(); FloatRect backingStoreInDestRect = FloatRect(FloatPoint(destPointInCGCoords.x(), destPointInCGCoords.y() + sourceCopySize.height() - (int)CGImageGetHeight(sourceCopyImage.get())), FloatSize(CGImageGetWidth(sourceCopyImage.get()), CGImageGetHeight(sourceCopyImage.get()))); CGContextDrawImage(destContext, backingStoreInDestRect, sourceCopyImage.get()); CGContextRestoreGState(destContext); #endif }
static IconRef CreateIconRefFromImage (CGImageRef srcImage, CGRect srcRect) { OSStatus err; CGContextRef cctx, actx; CGColorSpaceRef color; CGRect dstRect; IconRef iconRef; IconFamilyHandle icns; Handle hdl; SInt32 size; UInt32 rgb[kIconSize * kIconSize]; UInt8 alp[kIconSize * kIconSize]; srcRect.origin.y = CGImageGetHeight(srcImage) - srcRect.origin.y - kIconSize; color = CGColorSpaceCreateDeviceRGB(); if (color) { cctx = CGBitmapContextCreate(rgb, kIconSize, kIconSize, 8, kIconSize * 4, color, kCGImageAlphaNoneSkipFirst); if (cctx) { dstRect = CGRectMake(0, 0, kIconSize, kIconSize); DrawSubCGImage(cctx, srcImage, srcRect, dstRect); actx = CGBitmapContextCreate(alp, kIconSize, kIconSize, 8, kIconSize, NULL, kCGImageAlphaOnly); if (actx) { DrawSubCGImage(actx, srcImage, srcRect, dstRect); CGContextRelease(actx); } CGContextRelease(cctx); } CGColorSpaceRelease(color); } iconRef = NULL; size = sizeof(OSType) + sizeof(SInt32); icns = (IconFamilyHandle) NewHandle(size); if (icns) { // Big-endian: Panther is for PowerPC only (*icns)->resourceType = kIconFamilyType; (*icns)->resourceSize = size; err = PtrToHand(rgb, &hdl, sizeof(rgb)); if (err == noErr) { err = SetIconFamilyData(icns, kSmall32BitData, hdl); DisposeHandle(hdl); if (err == noErr) { err = PtrToHand(alp, &hdl, sizeof(alp)); if (err == noErr) { err = SetIconFamilyData(icns, kSmall8BitMask, hdl); DisposeHandle(hdl); } } } if (err == noErr) err = GetIconRefFromIconFamilyPtr(*icns, GetHandleSize((Handle) icns), &iconRef); DisposeHandle((Handle) icns); } return (iconRef); }
// Once we have our image, we need to get it into an SDL_Surface static SDL_Surface* Create_SDL_Surface_From_CGImage(CGImageRef image_ref) { /* This code is adapted from Apple's Documentation found here: * http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/index.html * Listing 9-4††Using a Quartz image as a texture source. * Unfortunately, this guide doesn't show what to do about * non-RGBA image formats so I'm making the rest up. * All this code should be scrutinized. */ size_t w = CGImageGetWidth(image_ref); size_t h = CGImageGetHeight(image_ref); CGRect rect = {{0, 0}, {w, h}}; CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image_ref); //size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref); size_t bits_per_component = 8; SDL_Surface* surface; Uint32 Amask; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; CGContextRef bitmap_context; CGBitmapInfo bitmap_info; CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); if (alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast) { bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */ Amask = 0x00000000; } else { /* kCGImageAlphaFirst isn't supported */ //bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */ Amask = 0xFF000000; } Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask); if (surface) { // Sets up a context to be drawn to with surface->pixels as the area to be drawn to bitmap_context = CGBitmapContextCreate( surface->pixels, surface->w, surface->h, bits_per_component, surface->pitch, color_space, bitmap_info ); // Draws the image into the context's image_data CGContextDrawImage(bitmap_context, rect, image_ref); CGContextRelease(bitmap_context); // FIXME: Reverse the premultiplied alpha if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { int i, j; Uint8 *p = (Uint8 *)surface->pixels; for (i = surface->h * surface->pitch/4; i--; ) { #if __LITTLE_ENDIAN__ Uint8 A = p[3]; if (A) { for (j = 0; j < 3; ++j) { p[j] = (p[j] * 255) / A; } } #else Uint8 A = p[0]; if (A) { for (j = 1; j < 4; ++j) { p[j] = (p[j] * 255) / A; } } #endif /* ENDIAN */ p += 4; } } } if (color_space) { CGColorSpaceRelease(color_space); } return surface; }
static void _GraphicsScreen_imageFromFile (GraphicsScreen me, const wchar_t *relativeFileName, double x1, double x2, double y1, double y2) { long x1DC = wdx (x1), x2DC = wdx (x2), y1DC = wdy (y1), y2DC = wdy (y2); long width = x2DC - x1DC, height = my yIsZeroAtTheTop ? y1DC - y2DC : y2DC - y1DC; #if 0 structMelderFile file = { 0 }; Melder_relativePathToFile (relativeFileName, & file); try { autoPhoto photo = Photo_readFromImageFile (& file); if (x1 == x2 && y1 == y2) { width = photo -> nx, x1DC -= width / 2, x2DC = x1DC + width; height = photo -> ny, y2DC -= height / 2, y1DC = y2DC + height; } else if (x1 == x2) { width = height * (double) photo -> nx / (double) photo -> ny; x1DC -= width / 2, x2DC = x1DC + width; } else if (y1 == y2) { height = width * (double) photo -> ny / (double) photo -> nx; y2DC -= height / 2, y1DC = y2DC + height; } autoNUMmatrix <double_rgbt> z (1, photo -> ny, 1, photo -> nx); for (long iy = 1; iy <= photo -> ny; iy ++) { for (long ix = 1; ix <= photo -> nx; ix ++) { z [iy] [ix]. red = photo -> d_red -> z [iy] [ix]; z [iy] [ix]. green = photo -> d_green -> z [iy] [ix]; z [iy] [ix]. blue = photo -> d_blue -> z [iy] [ix]; z [iy] [ix]. transparency = photo -> d_transparency -> z [iy] [ix]; } } _cellArrayOrImage (me, NULL, z.peek(), NULL, 1, photo -> nx, x1DC, x2DC, 1, photo -> ny, y1DC, y2DC, 0.0, 1.0, //wdx (my d_x1WC), wdx (my d_x2WC), wdy (my d_y1WC), wdy (my d_y2WC), // in case of clipping LONG_MIN, LONG_MAX, LONG_MAX, LONG_MIN, // in case of no clipping true); } catch (MelderError) { Melder_clearError (); } #elif win if (my d_useGdiplus) { structMelderFile file = { 0 }; Melder_relativePathToFile (relativeFileName, & file); Gdiplus::Bitmap image (file. path); if (x1 == x2 && y1 == y2) { width = image. GetWidth (), x1DC -= width / 2, x2DC = x1DC + width; height = image. GetHeight (), y2DC -= height / 2, y1DC = y2DC + height; } else if (x1 == x2) { width = height * (double) image. GetWidth () / (double) image. GetHeight (); x1DC -= width / 2, x2DC = x1DC + width; } else if (y1 == y2) { height = width * (double) image. GetHeight () / (double) image. GetWidth (); y2DC -= height / 2, y1DC = y2DC + height; } Gdiplus::Graphics dcplus (my d_gdiGraphicsContext); Gdiplus::Rect rect (x1DC, y2DC, width, height); dcplus. DrawImage (& image, rect); } else { } #elif mac structMelderFile file = { 0 }; Melder_relativePathToFile (relativeFileName, & file); char utf8 [500]; Melder_wcsTo8bitFileRepresentation_inline (file. path, utf8); CFStringRef path = CFStringCreateWithCString (NULL, utf8, kCFStringEncodingUTF8); CFURLRef url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, false); CFRelease (path); CGImageSourceRef imageSource = CGImageSourceCreateWithURL (url, NULL); CFRelease (url); if (imageSource != NULL) { CGImageRef image = CGImageSourceCreateImageAtIndex (imageSource, 0, NULL); CFRelease (imageSource); if (image != NULL) { if (x1 == x2 && y1 == y2) { width = CGImageGetWidth (image), x1DC -= width / 2, x2DC = x1DC + width; height = CGImageGetHeight (image), y2DC -= height / 2, y1DC = y2DC + height; } else if (x1 == x2) { width = height * (double) CGImageGetWidth (image) / (double) CGImageGetHeight (image); x1DC -= width / 2, x2DC = x1DC + width; } else if (y1 == y2) { height = width * (double) CGImageGetHeight (image) / (double) CGImageGetWidth (image); y2DC -= height / 2, y1DC = y2DC + height; } GraphicsQuartz_initDraw (me); CGContextSaveGState (my d_macGraphicsContext); NSCAssert(my d_macGraphicsContext, @"nil context"); CGContextTranslateCTM (my d_macGraphicsContext, 0, y1DC); CGContextScaleCTM (my d_macGraphicsContext, 1.0, -1.0); CGContextDrawImage (my d_macGraphicsContext, CGRectMake (x1DC, 0, width, height), image); CGContextRestoreGState (my d_macGraphicsContext); GraphicsQuartz_exitDraw (me); CGImageRelease (image); } } #endif }