OSStatus GenerateThumbnailForURL(void *thisInterface, 
								 QLThumbnailRequestRef thumbnail,
								 CFURLRef url, CFStringRef contentTypeUTI, 
								 CFDictionaryRef options, CGSize maxSize)
{
	CGFloat minCartDrawSize = 64;
	CGFloat size = fmin(maxSize.width, maxSize.height);
	CGContextRef qlContext = NULL;
	if (size < minCartDrawSize) { 
		size = 32;
		qlContext = QLThumbnailRequestCreateContext(thumbnail, CGSizeMake(size,size), true, NULL);
	}
	else 
	{
		qlContext = QLThumbnailRequestCreateContext(thumbnail, CGSizeMake(size,size), false, NULL);
	}
	
	if (qlContext) {
		NDSHeader header;	
		NDSIcon icon;
		int pathlen = 2047;
		UInt8 path[pathlen+1];
		if (CFURLGetFileSystemRepresentation(url, true, path, pathlen)) { 
			
			if (size < minCartDrawSize) { // at smaller sizes we only draw the game icon at native size and let QL do the scaling
				parseNDSInfo(path, &header, &icon);
				CGImageRef image = CGImageCreateWithNDSIcon(&icon);
				if (image) {
					CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), image);
					CGImageRelease(image);
				}
			}
			else 
			{
				CGContextClearRect(qlContext, CGRectMake(0,0,size,size));
				
				// draw cartridge background
				CFURLRef bgURL = CFBundleCopyResourceURL(CFBundleGetBundleWithIdentifier(
																						 CFSTR("net.mironer.nds.quicklookgenerator")), CFSTR("background"), CFSTR("png"), NULL);
				if (bgURL) {
					CGDataProviderRef bgPNG = CGDataProviderCreateWithURL(bgURL);
					if (bgPNG) {
						CGImageRef bg = CGImageCreateWithPNGDataProvider(bgPNG, NULL, true, kCGRenderingIntentDefault);
						if (bg) {
							CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), bg);				
							CGImageRelease(bg);
						}
						CGDataProviderRelease(bgPNG);
					}
					CFRelease(bgURL);
				}			
				
				// draw game icon
				parseNDSInfo(path, &header, &icon);
				CGImageRef image = CGImageCreateWithNDSIcon(&icon);
				if (image) {
					CGContextDrawImage(qlContext, CGRectMake(size / 5, size / 5, size * 3 / 5, size * 3 / 5), image);
					CGImageRelease(image);
				}
				
				// draw cartridge overlay
				CFURLRef ovrURL = CFBundleCopyResourceURL( 
														  CFBundleGetBundleWithIdentifier(
																						  CFSTR("net.mironer.nds.quicklookgenerator")), CFSTR("overlay"), CFSTR("png"), NULL);
				if (ovrURL) {
					CGDataProviderRef ovrPNG = CGDataProviderCreateWithURL(ovrURL);
					if (ovrPNG) {
						CGImageRef ovr = CGImageCreateWithPNGDataProvider(ovrPNG, NULL, true, kCGRenderingIntentDefault);
						if (ovr) {
							CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), ovr);				
							CGImageRelease(ovr);
						}
						CGDataProviderRelease(ovrPNG);
					}
					CFRelease(ovrURL);
				}			
				
				// draw serial number
				CFStringRef serial = CFStringCreateWithSerialNumber(&header);
				CFAttributedStringRef aString = CFAttributedStringCreate(kCFAllocatorDefault, serial, NULL);
				CFMutableAttributedStringRef attrStr = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 128, aString);
				CFIndex len =  CFAttributedStringGetLength(attrStr);
				CTFontRef font = CTFontCreateWithName(CFSTR("Lucida Sans"), size / 16, NULL);
				CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, len), kCTFontAttributeName, font);		
				
				CTTextAlignment rightAlign = kCTRightTextAlignment;
				CTParagraphStyleSetting styleSettings[] = { {kCTParagraphStyleSpecifierAlignment, sizeof(rightAlign), &rightAlign} };
				CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(styleSettings, 1);
				CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, len), kCTParagraphStyleAttributeName, paragraphStyle);
				
				CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrStr);
				CFRelease(attrStr);
				CFRelease(aString);
				CFRelease(serial);
				CFRelease(font);
				
				CGMutablePathRef path = CGPathCreateMutable();
				CGPathAddRect(path, NULL, CGRectMake(-size * 1.55 / 8, -size * 6.1 / 8, size, size));			
				CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
				CTFrameDraw(frame, qlContext);
				CFRelease(frame);
				CFRelease(framesetter); 
				CFRelease(paragraphStyle);
				CFRelease(path);
			}
		}
		QLThumbnailRequestFlushContext(thumbnail, qlContext);
        CFRelease(qlContext);
    }
    return noErr;
}
static OSStatus MakeImageDocument(CFURLRef url, CFStringRef imageType, const ExportInfo *exportInfo)
{
    OSStatus err = noErr;
    CGContextRef c = NULL;
    CGImageRef image;
    Boolean useDisplayColorSpace;
    // First make a bitmap context for a US Letter size
    // raster at the requested resolution. 
    int dpi = exportInfo->dpi;
    size_t width = (size_t)(8.5*dpi), height = (size_t)11*dpi;

    // For JPEG output type the bitmap should not be transparent. If other types are added that
	// do not support transparency, this code should be updated to check for those types as well.
    Boolean needTransparentBitmap = 
	    !(CFStringCompare(imageType, kUTTypeJPEG, kCFCompareCaseInsensitive) == kCFCompareEqualTo);

    // Create an RGB Bitmap context using the generic calibrated RGB color space
    // instead of the display color space.
    useDisplayColorSpace = false;
    c = createRGBBitmapContext(width, height, useDisplayColorSpace, 
						    needTransparentBitmap);
    
    if(c == NULL){
		fprintf(stderr, "Couldn't make destination bitmap context!\n");
		// Users of this code should update this to be an error code they find useful.
		return memFullErr;
    }
      
    // Scale the coordinate system based on the resolution in dots per inch.
    CGContextScaleCTM(c, dpi/72, dpi/72);
    
    // Set the font smoothing parameter to false since it's better to
    // draw any text without special LCD text rendering when creating
    // rendered data for export.
    if(CGContextSetShouldSmoothFonts != NULL)
		CGContextSetShouldSmoothFonts(c, false);

    // Set the scaling factor for shadows. This is a hack so that
    // drawing code that needs to know the scaling factor can
    // obtain it. Better would be that DispatchDrawing and the code
    // it calls would take this scaling factor as a parameter.
    setScalingFactor(dpi/72);
    
    // Draw into that raster...
    DispatchDrawing(c, exportInfo->command);
    
    // Set the scaling factor back to 1.0.
    setScalingFactor(1.0);
    
    // Create an image from the raster data. Calling
	// createImageFromBitmapContext gives up ownership
	// of the raster data used by the context.
    image = createImageFromBitmapContext(c);

	// Release the context now that the image is created.
    CGContextRelease(c);
	c = NULL;

    if(image == NULL){
		// Users of this code should update this to be an error code they find useful.
		return memFullErr;  
    }

    // Now export the image.
    if(exportInfo->useQTForExport)
		exportCGImageToFileWithQT(image, url, imageType, exportInfo->dpi);
    else
		exportCGImageToFileWithDestination(image, url, imageType, exportInfo->dpi);
    
    CGImageRelease(image);
    return err;
}
Пример #3
0
/*******************************************************************************
**	TileBadge
*******************************************************************************/
void TileBadge( Boolean inRestoreTileBeforeBadging )
{
	OSStatus	theErr;
	PicHandle	theBadge;
	PicHandle	theBadgeMask;
	GWorldPtr	theBadgeWorld;
	GWorldPtr	theBadgeMaskWorld;
	Rect		theRect = { 0, 0, 128, 128 };
	CGImageRef	theBadgeImage;
	GDHandle	theSavedDevice;
	GrafPtr		theSavedPort;

	// ***
	//
	// PITFALL!
	//
	// Rebadging the tile will composite over the old one!
	// You might want to restore the tile before badging.
	//
	// ***
	if ( inRestoreTileBeforeBadging )
		RestoreApplicationDockTileImage();

	// Load the pictures
	theBadge = GetPicture( kBadge );
	require( theBadge != NULL, CantLoadBadge );
	theBadgeMask = GetPicture( kBadgeMask );
	require( theBadgeMask != NULL, CantLoadBadgeMask );

	// Make some GWorlds
	theErr = NewGWorld( &theBadgeWorld, 32, &theRect, NULL, NULL, 0 );
	require_noerr( theErr, CantMakeBadgeWorld );
	theErr = NewGWorld( &theBadgeMaskWorld, 32, &theRect, NULL, NULL, 0 );
	require_noerr( theErr, CantMakeBadgeMaskWorld );

	// Draw the pictures into the GWorlds
	GetGWorld( &theSavedPort, &theSavedDevice );
	SetGWorld( theBadgeWorld, NULL );
	DrawPicture( theBadge, &theRect );
	SetGWorld( theBadgeMaskWorld, NULL );
	DrawPicture( theBadgeMask, &theRect );
	SetGWorld( theSavedPort, theSavedDevice );

	// ***
	//
	// Make a CGImage from the GWorlds' pixmaps
	//
	// ***
	theErr = CreateCGImageFromPixMaps( GetGWorldPixMap( theBadgeWorld ),
		GetGWorldPixMap( theBadgeMaskWorld ), &theBadgeImage );
	if ( theErr != noErr )
		SysBeep( 0 );
	require_noerr( theErr, CantMakeBadgeImage );

	// ***
	//
	// Badge the tile
	//
	// ***
	theErr = OverlayApplicationDockTileImage( theBadgeImage );

	if ( theBadgeImage != NULL )
		CGImageRelease( theBadgeImage );

CantMakeBadgeImage:
	DisposeGWorld( theBadgeMaskWorld );

CantMakeBadgeMaskWorld:
	DisposeGWorld( theBadgeWorld );

CantMakeBadgeWorld:
	ReleaseResource( (Handle) theBadgeMask );

CantLoadBadgeMask:
	ReleaseResource( (Handle) theBadge );

CantLoadBadge:
	;
}
Пример #4
0
static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
#ifndef NO_FFMPEG
	AVCodecContext av_context;
	int got_picture=0;
	AVFrame orig;
	mblk_t *ret;
	struct SwsContext *sws_ctx;
	AVPacket pkt;
	MSPicture dest;
	AVCodec *codec=avcodec_find_decoder(CODEC_ID_MJPEG);

	if (codec==NULL){
		ms_error("Could not find MJPEG decoder in ffmpeg.");
		return NULL;
	}

	avcodec_get_context_defaults(&av_context);
	if (avcodec_open(&av_context,codec)<0){
		ms_error("jpeg2yuv: avcodec_open failed");
		return NULL;
	}
	av_init_packet(&pkt);
	pkt.data=jpgbuf;
	pkt.size=bufsize;

	if (avcodec_decode_video2(&av_context,&orig,&got_picture,&pkt) < 0) {
		ms_error("jpeg2yuv: avcodec_decode_video failed");
		avcodec_close(&av_context);
		return NULL;
	}
	ret=ms_yuv_buf_alloc(&dest, reqsize->width,reqsize->height);
	/* not using SWS_FAST_BILINEAR because it doesn't play well with
	 * av_context.pix_fmt set to PIX_FMT_YUVJ420P by jpeg decoder */
	sws_ctx=sws_getContext(av_context.width,av_context.height,av_context.pix_fmt,
		reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_BILINEAR,
                NULL, NULL, NULL);
	if (sws_ctx==NULL) {
		ms_error("jpeg2yuv: ms_sws_getContext() failed.");
		avcodec_close(&av_context);
		freemsg(ret);
		return NULL;
	}

#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0)	
	if (sws_scale(sws_ctx,(const uint8_t* const *)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){
#else
	if (sws_scale(sws_ctx,(uint8_t**)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){
#endif
		ms_error("jpeg2yuv: ms_sws_scale() failed.");
		sws_freeContext(sws_ctx);
		avcodec_close(&av_context);
		freemsg(ret);
		return NULL;
	}
	sws_freeContext(sws_ctx);
	avcodec_close(&av_context);
	return ret;
#elif TARGET_OS_IPHONE
	MSPicture dest;
	CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, jpgbuf, bufsize, NULL);
	// use the data provider to get a CGImage; release the data provider
	CGImageRef image = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, FALSE, 
						kCGRenderingIntentDefault);
						CGDataProviderRelease(dataProvider);
	reqsize->width = CGImageGetWidth(image);
	reqsize->height = CGImageGetHeight(image);

	uint8_t* tmp = (uint8_t*) malloc(reqsize->width * reqsize->height * 4);
	mblk_t* ret=ms_yuv_buf_alloc(&dest, reqsize->width, reqsize->height);
	CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
	CGContextRef imageContext =
	CGBitmapContextCreate(tmp, reqsize->width, reqsize->height, 8, reqsize->width*4, colourSpace, kCGImageAlphaNoneSkipLast);
	CGColorSpaceRelease(colourSpace);
	// draw the image to the context, release it
	CGContextDrawImage(imageContext, CGRectMake(0, 0, reqsize->width, reqsize->height), image);
	CGImageRelease(image);

	/* convert tmp/RGB -> ret/YUV */
	for(int y=0; y<reqsize->height; y++) {
		for(int x=0; x<reqsize->width; x++) {
			uint8_t r = tmp[y * reqsize->width * 4 + x * 4 + 0];
			uint8_t g = tmp[y * reqsize->width * 4 + x * 4 + 1];
			uint8_t b = tmp[y * reqsize->width * 4 + x * 4 + 2];

			// Y
			*dest.planes[0]++ = (uint8_t)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);		

			// U/V subsampling
			if ((y % 2==0) && (x%2==0)) {
				uint32_t r32=0, g32=0, b32=0;
				for(int i=0; i<2; i++) {
					for(int j=0; j<2; j++) {
						r32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 0];
						g32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 1];
						b32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 2];
					}
				}
				r32 = (uint32_t)(r32 * 0.25f); g32 = (uint32_t)(g32 * 0.25f); b32 = (uint32_t) (b32 * 0.25f);

				// U
				*dest.planes[1]++ = (uint8_t)(-(0.148 * r32) - (0.291 * g32) + (0.439 * b32) + 128);
				// V
				*dest.planes[2]++ = (uint8_t)((0.439 * r32) - (0.368 * g32) - (0.071 * b32) + 128);
			}
		}
	}
	free(tmp);
	return ret;
#else
	return NULL;
#endif
}




mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
#if defined(WIN32)
	mblk_t *m=NULL;
	DWORD st_sizel;
	DWORD st_sizeh;
	uint8_t *jpgbuf;
	DWORD err;
	HANDLE fd;
	
#ifdef UNICODE
	WCHAR wUnicode[1024];
	MultiByteToWideChar(CP_UTF8, 0, jpgpath, -1, wUnicode, 1024);
	fd = CreateFile(wUnicode, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, 0, NULL);
#else
	fd = CreateFile(jpgpath, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, 0, NULL);
#endif
	if (fd==INVALID_HANDLE_VALUE){
		ms_error("Failed to open %s",jpgpath);
		return NULL;
	}
	st_sizel=0;
	st_sizeh=0;
	st_sizel = GetFileSize(fd, &st_sizeh);
	if (st_sizeh>0 || st_sizel<=0)
	{
		CloseHandle(fd);
		ms_error("Can't load file %s",jpgpath);
		return NULL;
	}
	jpgbuf=(uint8_t*)ms_malloc0(st_sizel);
	if (jpgbuf==NULL)
	{
		CloseHandle(fd);
		ms_error("Cannot allocate buffer for %s",jpgpath);
		return NULL;
	}
	err=0;
	ReadFile(fd, jpgbuf, st_sizel, &err, NULL) ;            
	
	if (err!=st_sizel){
		  ms_error("Could not read as much as wanted !");
	}
	m=jpeg2yuv(jpgbuf,st_sizel,reqsize);
	ms_free(jpgbuf);
	if (m==NULL)
	{
		CloseHandle(fd);
		ms_error("Cannot load image from buffer for %s",jpgpath);
		return NULL;
	}
	CloseHandle(fd);
	return m;
#else
	mblk_t *m=NULL;
	struct stat statbuf;
	uint8_t *jpgbuf;
	int err;
	int fd=open(jpgpath,O_RDONLY);

	if (fd!=-1){
		fstat(fd,&statbuf);
		if (statbuf.st_size<=0)
		{
			close(fd);
			ms_error("Cannot load %s",jpgpath);
			return NULL;
		}
		jpgbuf=(uint8_t*)ms_malloc0(statbuf.st_size + FF_INPUT_BUFFER_PADDING_SIZE);
		if (jpgbuf==NULL)
		{
			close(fd);
			ms_error("Cannot allocate buffer for %s",jpgpath);
			return NULL;
		}
		err=read(fd,jpgbuf,statbuf.st_size);
		if (err!=statbuf.st_size){
			ms_error("Could not read as much as wanted: %i<>%li !",err,(long)statbuf.st_size);
		}
		m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize);
		ms_free(jpgbuf);
		if (m==NULL)
		{
			close(fd);
			ms_error("Cannot load image from buffer for %s",jpgpath);
			return NULL;
		}
	}else{
		ms_error("Cannot load %s",jpgpath);
		return NULL;
	}
	close(fd);
	return m;
#endif
}
Пример #5
0
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);
  }

  Allocate(width, height, XB_FMT_A8R8G8B8);
  m_orientation = rotate;
    
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

  CGContextRef context = CGBitmapContextCreate(m_pixels,
    width, height, 8, GetPitch(), colorSpace,
    kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);

  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;
}
Пример #6
0
/***********************************************************************
 *              create_app_icon_images
 */
CFArrayRef create_app_icon_images(void)
{
    HRSRC res_info;
    HGLOBAL res_data;
    GRPICONDIR *icon_dir;
    CFMutableArrayRef images = NULL;
    int i;

    TRACE("()\n");

    res_info = NULL;
    EnumResourceNamesW(NULL, (LPCWSTR)RT_GROUP_ICON, get_first_resource, (LONG_PTR)&res_info);
    if (!res_info)
    {
        WARN("found no RT_GROUP_ICON resource\n");
        return NULL;
    }

    if (!(res_data = LoadResource(NULL, res_info)))
    {
        WARN("failed to load RT_GROUP_ICON resource\n");
        return NULL;
    }

    if (!(icon_dir = LockResource(res_data)))
    {
        WARN("failed to lock RT_GROUP_ICON resource\n");
        goto cleanup;
    }

    images = CFArrayCreateMutable(NULL, icon_dir->idCount, &kCFTypeArrayCallBacks);
    if (!images)
    {
        WARN("failed to create images array\n");
        goto cleanup;
    }

    for (i = 0; i < icon_dir->idCount; i++)
    {
        int width = icon_dir->idEntries[i].bWidth;
        int height = icon_dir->idEntries[i].bHeight;
        BOOL found_better_bpp = FALSE;
        int j;
        LPCWSTR name;
        HGLOBAL icon_res_data;
        BYTE *icon_bits;

        if (!width) width = 256;
        if (!height) height = 256;

        /* If there's another icon at the same size but with better
           color depth, skip this one.  We end up making CGImages that
           are all 32 bits per pixel, so Cocoa doesn't get the original
           color depth info to pick the best representation itself. */
        for (j = 0; j < icon_dir->idCount; j++)
        {
            int jwidth = icon_dir->idEntries[j].bWidth;
            int jheight = icon_dir->idEntries[j].bHeight;

            if (!jwidth) jwidth = 256;
            if (!jheight) jheight = 256;

            if (j != i && jwidth == width && jheight == height &&
                icon_dir->idEntries[j].wBitCount > icon_dir->idEntries[i].wBitCount)
            {
                found_better_bpp = TRUE;
                break;
            }
        }

        if (found_better_bpp) continue;

        name = MAKEINTRESOURCEW(icon_dir->idEntries[i].nID);
        res_info = FindResourceW(NULL, name, (LPCWSTR)RT_ICON);
        if (!res_info)
        {
            WARN("failed to find RT_ICON resource %d with ID %hd\n", i, icon_dir->idEntries[i].nID);
            continue;
        }

        icon_res_data = LoadResource(NULL, res_info);
        if (!icon_res_data)
        {
            WARN("failed to load icon %d with ID %hd\n", i, icon_dir->idEntries[i].nID);
            continue;
        }

        icon_bits = LockResource(icon_res_data);
        if (icon_bits)
        {
            static const BYTE png_magic[] = { 0x89, 0x50, 0x4e, 0x47 };
            CGImageRef cgimage = NULL;

            if (!memcmp(icon_bits, png_magic, sizeof(png_magic)))
            {
                CFDataRef data = CFDataCreate(NULL, (UInt8*)icon_bits, icon_dir->idEntries[i].dwBytesInRes);
                if (data)
                {
                    CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
                    CFRelease(data);
                    if (provider)
                    {
                        cgimage = CGImageCreateWithPNGDataProvider(provider, NULL, FALSE,
                                                                   kCGRenderingIntentDefault);
                        CGDataProviderRelease(provider);
                    }
                }
            }

            if (!cgimage)
            {
                HICON icon;
                icon = CreateIconFromResourceEx(icon_bits, icon_dir->idEntries[i].dwBytesInRes,
                                                TRUE, 0x00030000, width, height, 0);
                if (icon)
                {
                    cgimage = create_cgimage_from_icon(icon, width, height);
                    DestroyIcon(icon);
                }
                else
                    WARN("failed to create icon %d from resource with ID %hd\n", i, icon_dir->idEntries[i].nID);
            }

            if (cgimage)
            {
                CFArrayAppendValue(images, cgimage);
                CGImageRelease(cgimage);
            }
        }
        else
            WARN("failed to lock RT_ICON resource %d with ID %hd\n", i, icon_dir->idEntries[i].nID);

        FreeResource(icon_res_data);
    }

cleanup:
    if (images && !CFArrayGetCount(images))
    {
        CFRelease(images);
        images = NULL;
    }
    FreeResource(res_data);

    return images;
}
Пример #7
0
OSStatus DrawPage(PrintingLogicPtr printJob,CGContextRef printingContext)
{
    OSStatus status = noErr; 
    Rect	dstRect = { 0, 0, 0, 0 };
    Rect	srcRect = { 0, 0, 0, 0 };
	static CGColorSpaceRef colorspace = NULL;

	if (colorspace == NULL) {
			// Get the Systems Profile for the main display
		CMProfileRef sysprof = NULL;
		if (CMGetSystemProfile(&sysprof) == noErr) {
			// Create a colorspace with the systems profile
			colorspace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);
			CMCloseProfile(sysprof);
		} else 
			colorspace = CGColorSpaceCreateDeviceRGB();
	}
    
		dstRect.top = printJob->offsetHeight;
        dstRect.left = printJob->offsetWidth;
        dstRect.right = printJob->width*printJob->scaleW + printJob->offsetWidth;
        dstRect.bottom = printJob->height*printJob->scaleH + printJob->offsetHeight;

	if (printJob->formBitMap != nil) {
    
        srcRect.right = printJob->width;
        srcRect.bottom = printJob->height;

        HLock((Handle)stPixMap);
        (*stPixMap)->baseAddr = (void *) printJob->formBitMap;
        (*stPixMap)->rowBytes = (((((printJob->width * printJob->depth) + 31) / 32) * 4) & 0x1FFF) | 0x8000;
        (*stPixMap)->bounds = srcRect;
        (*stPixMap)->pixelSize = printJob->depth;
    
        if (printJob->depth<=8) { 
            (*stPixMap)->cmpSize = printJob->depth;
            (*stPixMap)->cmpCount = 1;
        } else if (printJob->depth==16) {
            (*stPixMap)->cmpSize = 5;
            (*stPixMap)->cmpCount = 3;
        } else if (printJob->depth==32) {
            (*stPixMap)->cmpSize = 8;
            (*stPixMap)->cmpCount = 3;
        }

         
		{
            PixMapHandle thePix;
            int			pitch;
			CGDataProviderRef provider;			
			CGImageRef image;
			CGRect		clip;
			Ptr			baseAddr;
			
            if (printJob->depth == 32) {
				pitch =  (((((printJob->width * printJob->depth) + 31) / 32) * 4) & 0x1FFF);
				baseAddr =  (void *) printJob->formBitMap;
			} else {
				if (printJob->aGWorld == NULL)
					NewGWorld(&printJob->aGWorld, 32, &srcRect, stColorTable, NULL, keepLocal+useTempMem+pixelsLocked);
					
				thePix = GetGWorldPixMap (printJob->aGWorld);
				CopyBits((BitMap *) *stPixMap, (BitMap *) *thePix, &srcRect, &srcRect, srcCopy, NULL);
				
				pitch = GetPixRowBytes(thePix);
				baseAddr = GetPixBaseAddr(thePix);
			}
			
			provider = CGDataProviderCreateDirectAccess((void*)baseAddr, pitch * (srcRect.bottom-srcRect.top), &gProviderCallbacks);
			image = CGImageCreate( srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, 8 /* bitsPerComponent */, 32 /* bitsPerPixel */, 
				pitch, colorspace, kCGImageAlphaNoneSkipFirst | (printJob->depth==32 ? kCGBitmapByteOrder32Host : 0), provider, NULL, 0, kCGRenderingIntentDefault);

			clip = CGRectMake(dstRect.left+(printJob->pageRect.left-printJob->paperRect.left),
				(printJob->paperRect.bottom-printJob->pageRect.bottom) + (printJob->pageRect.bottom - printJob->pageRect.top) - (dstRect.bottom-dstRect.top) - dstRect.top, 
				dstRect.right-dstRect.left, 
				dstRect.bottom-dstRect.top);
			
			CGContextDrawImage(printingContext, clip, image);
			CGContextFlush(printingContext);
			CGImageRelease(image);
			CGDataProviderRelease(provider);
       }
        HUnlock((Handle)stPixMap);
    }
	else {
	}
	
#if TARGET_API_MAC_CARBON	
     if (printJob->allowPostscript && printJob->postscriptLength > 0) {
	
		CGDataProviderRef provider,providerFakeImage;			
		CGImageRef image,imageFake;
		CGRect		clip;
		static long  dirt=0xBBBBBBBB;
		
		//PMPrinter  currentPrinter = NULL;
		//CFArrayRef mimeTypes;
		//status = PMSessionGetCurrentPrinter(printJob->printSession,&currentPrinter);
		//status = PMPrinterGetMimeTypes(currentPrinter,printJob->printSettings,&mimeTypes);
 		
		provider = CGDataProviderCreateDirectAccess((void*)printJob->postscript,printJob->postscriptLength, &gProviderCallbacks);
		providerFakeImage = CGDataProviderCreateDirectAccess((void*)&dirt,4, &gProviderCallbacks);
		
		//OK make fake image using tiny bit of data
		imageFake = CGImageCreate(1, 1, 8 /* bitsPerComponent */, 32 /* bitsPerPixel */, 4, colorspace, kCGImageAlphaNoneSkipFirst , providerFakeImage, NULL, 0, kCGRenderingIntentDefault);
		image = PMCGImageCreateWithEPSDataProvider(provider,imageFake);


		dstRect.top = 0;
		dstRect.left = 0;
		dstRect.bottom = CGImageGetHeight(image);
		dstRect.right = CGImageGetWidth(image);
		
		clip = CGRectMake(dstRect.left+(printJob->pageRect.left-printJob->paperRect.left),
			(printJob->paperRect.bottom-printJob->pageRect.bottom) + (printJob->pageRect.bottom - printJob->pageRect.top) - (dstRect.bottom-dstRect.top) - dstRect.top, 
			dstRect.right-dstRect.left, 
			dstRect.bottom-dstRect.top); 
			
		//PMPrinterPrintWithProvider
		
		CGContextDrawImage(printingContext, clip, image);
		CGContextFlush(printingContext);
		CGImageRelease(image);
		CGImageRelease(imageFake);
		CGDataProviderRelease(provider);
		CGDataProviderRelease(providerFakeImage);
    }   
#else
	return PrError();
#endif
		
    return status;
}	//	DrawPage
Пример #8
0
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        const FX_RECT*              srcRect,
        int                         dest_left,
        int                         dest_top,
        int                         blendType,
        int                         alphaFlag       ,
        void*                       iccTransform    )
{
    SaveState();
    CGFloat src_left, src_top, src_width, src_height;
    if (srcRect) {
        src_left = srcRect->left;
        src_top = srcRect->top;
        src_width = srcRect->Width();
        src_height = srcRect->Height();
    } else {
        src_left = src_top = 0;
        src_width = pBitmap->GetWidth();
        src_height = pBitmap->GetHeight();
    }
    CGAffineTransform ctm = CGContextGetCTM(_context);
    CGFloat scale_x = FXSYS_fabs(ctm.a);
    CGFloat scale_y = FXSYS_fabs(ctm.d);
    src_left /= scale_x;
    src_top /= scale_y;
    src_width /= scale_x;
    src_height /= scale_y;
    CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
    CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
    CGContextBeginPath(_context);
    CGContextAddRect(_context, rect_usr);
    CGContextClip(_context);
    rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
    rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
    CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect_usr, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect_usr);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    int blend_mode = blendType;
    if (FXDIB_BLEND_HARDLIGHT == blendType) {
        blend_mode = kCGBlendModeSoftLight;
    } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
        blend_mode = kCGBlendModeHardLight;
    } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) {
        blend_mode = blendType - 9;
    } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
        blend_mode = kCGBlendModeNormal;
    }
    CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
    CGContextDrawImage(_context, rect_usr, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}
Пример #9
0
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        int                         dest_left,
        int                         dest_top,
        int                         dest_width,
        int                         dest_height,
        const FX_RECT*              clipRect,
        FX_DWORD                    flags,
        int                         alphaFlag	   ,
        void*                       iccTransform ,
        int							blend_type)
{
    SaveState();
    if (clipRect) {
        CGContextBeginPath(_context);
        CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
        rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
        CGContextAddRect(_context, rect_clip);
        CGContextClip(_context);
    }
    CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
    rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
    if (FXDIB_BICUBIC_INTERPOL == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
    } else if (FXDIB_DOWNSAMPLE == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
    } else {
        CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
    }
    CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    CGContextDrawImage(_context, rect, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}
Пример #10
0
SourceSurfaceCG::~SourceSurfaceCG()
{
  CGImageRelease(mImage);
}
Пример #11
0
SourceSurfaceCGBitmapContext::~SourceSurfaceCGBitmapContext()
{
  if (mImage)
    CGImageRelease(mImage);
}
Пример #12
0
DataSourceSurfaceCG::~DataSourceSurfaceCG()
{
  CGImageRelease(mImage);
  free(CGBitmapContextGetData(mCg));
  CGContextRelease(mCg);
}
Пример #13
0
    bool GCPVideoRenderer::OnWindowRefresh(FB::RefreshEvent* pEvt)
    {
        FB::CoreGraphicsDraw* pCgDrawEvt(static_cast<FB::CoreGraphicsDraw*>(pEvt));
        CGContextRef pContext = pCgDrawEvt->context;
        boost::mutex::scoped_lock winLock(m_winMutex);

        const int stride = m_width*4;    
        const int frameBufferSize = m_height*stride;
        static SInt32 osMajorVersion = 0;
        static SInt32 osMinorVersion = 0;
        static CGInterpolationQuality interpolationMode = kCGInterpolationNone;
        
        if(0 == osMajorVersion || 0 == osMinorVersion)
        {
            if(noErr != Gestalt(gestaltSystemVersionMajor, &osMajorVersion))
            {
                osMajorVersion = 10;
            }
            if(noErr != Gestalt(gestaltSystemVersionMinor, &osMinorVersion))
            {
                osMinorVersion = 6;
            }
            if(10 <= osMajorVersion && 7 <= osMinorVersion)
            {
                interpolationMode = kCGInterpolationDefault;
            }
        }
        
        if(NULL == pContext || NULL == m_pFrameBuffer)
        {
            return false;
        }
        
        int winWidth = pCgDrawEvt->bounds.right - pCgDrawEvt->bounds.left;
        int winHeight = pCgDrawEvt->bounds.bottom - pCgDrawEvt->bounds.top;
        
        if(winWidth<=1 || winHeight<=1)
            return false;
        
        CGContextSaveGState(pContext);        
        CGContextSetShouldAntialias(pContext, true);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGImageRef cgImage = CGImageCreate(m_width, m_height, 8, 32, stride, colorSpace, 
                                           kCGImageAlphaNoneSkipLast,
                                           CGDataProviderCreateWithData(NULL,
                                                                        m_pFrameBuffer,
                                                                        frameBufferSize,
                                                                        NULL),
                                           NULL, false, kCGRenderingIntentDefault);
        if(NULL == cgImage)
        {
            CGColorSpaceRelease(colorSpace);
            CGContextRestoreGState(pContext);
            return false;
        }
        
        CGContextSetInterpolationQuality(pContext, interpolationMode);
        CGContextTranslateCTM(pContext, 0, winHeight);
        CGContextScaleCTM(pContext, 1, -1);
        CGContextDrawImage(pContext, CGRectMake(0, 0, winWidth, winHeight), cgImage);
        
        CGImageRelease(cgImage);
        CGColorSpaceRelease(colorSpace);
        CGContextRestoreGState(pContext);
        
        return true;
    }
Пример #14
0
static void patternReleaseOnMainThreadCallback(void* info)
{
    CGImageRelease(static_cast<CGImageRef>(info));
}
Пример #15
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp)
{
    startAnimation();

    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(), compositeOp);
        return;
    }

    float currHeight = CGImageGetHeight(image);
    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();
        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 = CGImageCreateWithImageInRect(image, subimageRect);
            if (currHeight < srcRect.bottom()) {
                ASSERT(CGImageGetHeight(image) == currHeight - CGRectIntegral(srcRect).origin.y);
                adjustedDestRect.setHeight(CGImageGetHeight(image) / 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());

    // Draw the image.
    CGContextDrawImage(context, adjustedDestRect, image);

    if (shouldUseSubimage)
        CGImageRelease(image);

    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Пример #16
0
result_t MMMaker_make(const char **sourceMaskDirs,
                      int          nSourceMaskDirs,
                      const char  *filename)
{
#define MAX_FILENAMES 500

  result_t           err;
  char             **sourceMaskFilenames;
  int                nSourceMaskFilenames = 0;
  char              *sourceMaskFilenamesBuffer = NULL;
  motionmaskmaker_t *maker = NULL;
  int                i;
  CGImageRef         makerSource[MAX_FILENAMES];
  CGBitmapInfo       bitmapInfo;
  pixelfmt_t         pixelfmt;
  bitmap_set_t       makerBitmaps;
  CFDataRef          pixels[MAX_FILENAMES];
  void              *makerBitmapBases[MAX_FILENAMES];

  err = findfilesbyregexp(sourceMaskDirs,
                          nSourceMaskDirs,
                          ".*\\.png",
                          &sourceMaskFilenames,
                          &nSourceMaskFilenames,
                          &sourceMaskFilenamesBuffer);
  if (err)
    goto failure;

  if (nSourceMaskFilenames <= 0 || nSourceMaskFilenames > MAX_FILENAMES)
  {
    err = result_TOO_BIG;
    goto failure;
  }

  for (i = 0; i < nSourceMaskFilenames; i++)
    pixels[i] = NULL;

  err = motionmaskmaker_create(&maker);
  if (err)
    goto failure;

  for (i = 0; i < nSourceMaskFilenames; i++)
  {
    logf_info("sourcing mask %d from %s", i, sourceMaskFilenames[i]);

    makerSource[i] = createCGImageFromPNGFile(sourceMaskFilenames[i]);

    bitmapInfo = CGImageGetBitmapInfo(makerSource[i]);
    pixelfmt = bitmapInfoToPixelfmt(bitmapInfo);
    if (pixelfmt == pixelfmt_unknown)
    {
      logf_error("MMMaker_make: Unknown pixelfmt.");
      return result_BAD_ARG;
    }

    // bodge pixelfmt to be something we can currently cope with

    if (pixelfmt == pixelfmt_rgba8888)
      pixelfmt = pixelfmt_rgbx8888;
    if (pixelfmt == pixelfmt_abgr8888)
      pixelfmt = pixelfmt_xbgr8888;

    // turn the image into greyscale if it's anything else

    if (pixelfmt != pixelfmt_y8)
    {
      CGImageRef greyCopy;

      greyCopy = BitmapTransform_createGreyscaleCopy(makerSource[i]);

      CGImageRelease(makerSource[i]);

      makerSource[i] = greyCopy;

      bitmapInfo = CGImageGetBitmapInfo(makerSource[i]);
      pixelfmt = bitmapInfoToPixelfmt(bitmapInfo);
      if (pixelfmt == pixelfmt_unknown)
        return result_BAD_ARG;
    }

    pixels[i] = copyImagePixels(makerSource[i]);
    if (pixels[i] == NULL)
      goto failure;

    makerBitmapBases[i] = (void *) CFDataGetBytePtr(pixels[i]);
  }

  makerBitmaps.width    = (int) CGImageGetWidth(makerSource[0]);
  makerBitmaps.height   = (int) CGImageGetHeight(makerSource[0]);
  makerBitmaps.format   = pixelfmt;
  makerBitmaps.rowbytes = (int) CGImageGetBytesPerRow(makerSource[0]);
  makerBitmaps.nbases   = nSourceMaskFilenames;
  makerBitmaps.bases    = makerBitmapBases;

  err = motionmaskmaker_pack(maker, &makerBitmaps);
  if (err)
    goto failure;

  err = motionmaskmaker_save(maker, filename);
  if (err)
    goto failure;

  /* cleanup */

failure:

  for (i = 0; i < nSourceMaskFilenames; i++)
    if (pixels[i])
      CFRelease(pixels[i]);

  motionmaskmaker_destroy(maker);
  maker = NULL;

  free(sourceMaskFilenamesBuffer);
  free(sourceMaskFilenames);

  return err;
}
Пример #17
0
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform,
                        const FloatPoint& phase, 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);

    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 = CGImageCreateWithImageInRect(tileImage, tileRect);
    }
    
#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);
    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);
    CGPatternRef pattern = CGPatternCreate(subImage, CGRectMake(0, 0, tileRect.width(), tileRect.height()),
                                           matrix, tileRect.width(), tileRect.height(), 
                                           kCGPatternTilingConstantSpacing, true, &patternCallbacks);
    if (pattern == NULL) {
        if (subImage != tileImage)
            CGImageRelease(subImage);
        ctxt->restore();
        return;
    }

    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
    
    CGFloat alpha = 1;
    CGColorRef color = CGColorCreateWithPattern(patternSpace, pattern, &alpha);
    CGContextSetFillColorSpace(context, patternSpace);
    CGColorSpaceRelease(patternSpace);
    CGPatternRelease(pattern);

    // FIXME: Really want a public API for this.  It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy).
    wkSetPatternBaseCTM(context, CGAffineTransformIdentity);
    CGContextSetPatternPhase(context, CGSizeZero);

    CGContextSetFillColorWithColor(context, color);
    CGContextFillRect(context, CGContextGetClipBoundingBox(context));
    
    CGColorRelease(color);
    
#ifndef BUILDING_ON_TIGER
    }
#endif

    if (subImage != tileImage)
        CGImageRelease(subImage);
    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Пример #18
0
void process_1_image (args cli_flags, char *files) {
	
	char *out_file_name = get_out_filename (files, cli_flags);
	
	if (file_exists (out_file_name)) {
		printf ("| Output file %s already exists. skipping... ", out_file_name);
		return;
	}
	
	// Origional Image Properties struct
	img_prop o = (img_prop) malloc (sizeof (image_properties));
	
	// set all the vales in the imapg properties struct to -1
	null_ip (o);
	
	// Create a data provider
	CGDataProviderRef source_image_provider = CGDataProviderCreateWithFilename (files);
	
	// Check for a null returned value
	if (source_image_provider == NULL) {
		
		// something went wrong 
		printf ("error: Couldn't create CGDataProvider from URL.\n"); 
		exit (0);
	}
	
	// get the information from the image exif here
	o->image_rot = get_exif_rot (source_image_provider);
	

	// Create the image in memory from the JPEG data
	CGImageRef source_image = CGImageCreateWithJPEGDataProvider (source_image_provider, NULL, no, kCGRenderingIntentDefault);
	
  /********************************************/
  /* Getting the colour space **/
  
  o->colorSpace = CGImageGetColorSpace(source_image);
  
  /********************************************/
  
	// populate the image info struct
	pop_img_props (source_image, o);
	
	// create a data provider from the decoded JPEG data
	CGDataProviderRef image_data_provider = CGImageGetDataProvider (source_image);
	
	// Create a pointer to the data section of the image in memory
	CFDataRef source_data_ptr = CGDataProviderCopyData (image_data_provider);

	// The vImage_Buffers we will use
	vImage_Buffer *vImage_source = (vImage_Buffer*) malloc (sizeof (vImage_Buffer));
	
	// Check for NULL
	if (NULL == vImage_source) {
		printf ("Cannot malloc vImage_source buffer\n");
		exit (0);
	}
	
	if (o->bits_ppixel == 24) {
		
		// convert from 24bit to 32bit by adding the alpha channel.
		source_data_ptr = convert24_32bit (source_data_ptr, o);
		
	}
	
	// Setup the vImage Buffer for the image
	setupBuffer (vImage_source, o->image_h, o->image_w, o->bytes_row);

	// Assign the data to the vImage Buffer for the source
	vImage_source->data = (void *) CFDataGetBytePtr (source_data_ptr);
	
	// Check for NULL
	if (vImage_source->data == NULL) 
		printf ("Unable to get the vimage.data pointer\n");

	if (o->image_rot != 1 && o->image_rot != 4 && o->image_rot != 2) // rotate the image
		rotate_image (vImage_source, o, NULL);
	
	// flip the image
	if (o->image_rot == 2  || o->image_rot == 4 || o->image_rot == 7 || o->image_rot == 5)
		flip_image (vImage_source, o, NULL);
	
  
	// Resize the images
	resize_image (vImage_source, o, cli_flags);

    // Create a colour space to be compared against
    CGColorSpaceRef rgb = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
    if (NULL == rgb) {
        fprintf(stderr, "Unable to create the reference colourspace.\n");
        exit(0);
    }
    
    // Convert the colourspace to RGB
    if (!CFEqual(rgb, o->colorSpace) && !cli_flags->disableCC) {
        vImage_source->data = convert_space(vImage_source->data, o->image_w, o->image_h);
        if (NULL == vImage_source->data) exit(0);
    }
    
    // release the reference colour space
    CGColorSpaceRelease(rgb);
    
	// save the image
	save_image (vImage_source, o, cli_flags->quality, out_file_name);
	
	// Release the source provider
	CGDataProviderRelease (source_image_provider);
	source_image_provider = NULL;
	
	// Release the source image
	CGImageRelease (source_image);
	source_image = NULL;
	
	free(source_data_ptr);
    
	// Free the filename created by get_out_filename ()
	free (out_file_name);
	out_file_name = NULL;
	
	// free the image properties
	free (o);
	o = NULL;
	
	// if there is info in the buffer
	if (vImage_source->data != NULL) {
		free (vImage_source->data);
		vImage_source->data = NULL;
	}
	
	// free the buffer
	free (vImage_source);
	vImage_source = NULL;

} // Process 1 image
Пример #19
0
/***********************************************************************
 *              create_cgimage_from_icon_bitmaps
 */
CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP hbmColor,
                                            unsigned char *color_bits, int color_size, HBITMAP hbmMask,
                                            unsigned char *mask_bits, int mask_size, int width,
                                            int height, int istep)
{
    int i, has_alpha = FALSE;
    DWORD *ptr;
    CGBitmapInfo alpha_format;
    CGColorSpaceRef colorspace;
    CFDataRef data;
    CGDataProviderRef provider;
    CGImageRef cgimage;

    /* draw the cursor frame to a temporary buffer then create a CGImage from that */
    memset(color_bits, 0x00, color_size);
    SelectObject(hdc, hbmColor);
    if (!DrawIconEx(hdc, 0, 0, icon, width, height, istep, NULL, DI_NORMAL))
    {
        WARN("Could not draw frame %d (walk past end of frames).\n", istep);
        return NULL;
    }

    /* check if the cursor frame was drawn with an alpha channel */
    for (i = 0, ptr = (DWORD*)color_bits; i < width * height; i++, ptr++)
        if ((has_alpha = (*ptr & 0xff000000) != 0)) break;

    if (has_alpha)
        alpha_format = kCGImageAlphaFirst;
    else
        alpha_format = kCGImageAlphaNoneSkipFirst;

    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    if (!colorspace)
    {
        WARN("failed to create colorspace\n");
        return NULL;
    }

    data = CFDataCreate(NULL, (UInt8*)color_bits, color_size);
    if (!data)
    {
        WARN("failed to create data\n");
        CGColorSpaceRelease(colorspace);
        return NULL;
    }

    provider = CGDataProviderCreateWithCFData(data);
    CFRelease(data);
    if (!provider)
    {
        WARN("failed to create data provider\n");
        CGColorSpaceRelease(colorspace);
        return NULL;
    }

    cgimage = CGImageCreate(width, height, 8, 32, width * 4, colorspace,
                            alpha_format | kCGBitmapByteOrder32Little,
                            provider, NULL, FALSE, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorspace);
    if (!cgimage)
    {
        WARN("failed to create image\n");
        return NULL;
    }

    /* if no alpha channel was drawn then generate it from the mask */
    if (!has_alpha)
    {
        unsigned int width_bytes = (width + 31) / 32 * 4;
        CGImageRef cgmask, temp;

        /* draw the cursor mask to a temporary buffer */
        memset(mask_bits, 0xFF, mask_size);
        SelectObject(hdc, hbmMask);
        if (!DrawIconEx(hdc, 0, 0, icon, width, height, istep, NULL, DI_MASK))
        {
            WARN("Failed to draw frame mask %d.\n", istep);
            CGImageRelease(cgimage);
            return NULL;
        }

        data = CFDataCreate(NULL, (UInt8*)mask_bits, mask_size);
        if (!data)
        {
            WARN("failed to create data\n");
            CGImageRelease(cgimage);
            return NULL;
        }

        provider = CGDataProviderCreateWithCFData(data);
        CFRelease(data);
        if (!provider)
        {
            WARN("failed to create data provider\n");
            CGImageRelease(cgimage);
            return NULL;
        }

        cgmask = CGImageMaskCreate(width, height, 1, 1, width_bytes, provider, NULL, FALSE);
        CGDataProviderRelease(provider);
        if (!cgmask)
        {
            WARN("failed to create mask\n");
            CGImageRelease(cgimage);
            return NULL;
        }

        temp = CGImageCreateWithMask(cgimage, cgmask);
        CGImageRelease(cgmask);
        CGImageRelease(cgimage);
        if (!temp)
        {
            WARN("failed to create masked image\n");
            return NULL;
        }
        cgimage = temp;
    }

    return cgimage;
}
Пример #20
0
// save the image
void save_image (vImage_Buffer *src_i, img_prop o, float compression, char *o_file) {
	
	// Create a CFDataRef from the rotated data in the destination vImage_Buffer
	CFDataRef output_Data = CFDataCreate (NULL, src_i->data, src_i->height * src_i->rowBytes);
	
	if (o->bits_ppixel == 32) {
		
		// convert from 24bit to 32bit by adding the alpha channel.
		output_Data = convert32_24bit (output_Data, o);
		src_i->rowBytes = src_i->width * 3;
	}

    
	// Check for a NULL value.
	if (NULL == output_Data) {
		printf ("Could not create CFDataRef from vImage_Buffer.\n"); 
		exit (0);
	}
	
	// Create a Data provider from the rotated data
	CGDataProviderRef destination_data_provider = CGDataProviderCreateWithCFData (output_Data);
	
	// Check for null
	if (NULL == destination_data_provider) {
		printf ("Could not create CGDataProviderRef from CGDataRef.\n"); 
		exit (0);
	}
  
    CGImageRef processed_image;

  
    // Create the image with sRGB for the colour space
    processed_image = CGImageCreate (src_i->width, // 1 width
                                                src_i->height, // 2 height
                                                (size_t)o->bits_ppixel/ (o->bits_ppixel/8), // bitsPerComponent
                                                (size_t)o->bits_ppixel, //bitsPerPixel
                                                src_i->rowBytes, // bytesPerRow
                                                CGColorSpaceCreateDeviceRGB(), // Generic ColourSpace
                                                kCGBitmapByteOrder32Big, // bitmapInfo
                                                destination_data_provider, // Data provider ** DataProviderRef 
                                                NULL, // decode
                                                0, // Interpolate
                                                kCGRenderingIntentSaturation); // rendering intent
  	if (NULL == processed_image) exit (0);
/*    
  } else {

    // release the reference colour space
    CGColorSpaceRelease(rgb);

    // Create the image with sRGB for the colour space
    processed_image = CGImageCreate (src_i->width, // 1 width
                                     src_i->height, // 2 height
                                     (size_t)o->bits_ppixel/ (o->bits_ppixel/8), // bitsPerComponent
                                     (size_t)o->bits_ppixel, //bitsPerPixel
                                     src_i->rowBytes, // bytesPerRow
                                     o->colorSpace, // ColourSpace of original
                                     kCGBitmapByteOrder32Big, // bitmapInfo
                                     destination_data_provider, // Data provider ** DataProviderRef 
                                     NULL, // decode
                                     0, // Interpolate
                                     kCGRenderingIntentSaturation); // rendering intent
  	if (NULL == processed_image) exit (0);
    
  }*/
  
	// create a CFStringRef from the C string
	CFStringRef fn = CFStringCreateWithCString (NULL, o_file, kCFStringEncodingUTF8);
	if (NULL == fn) exit (0);
	
	// Convert the CFStringRef to a CFURLRef
	CFURLRef fon = CFURLCreateWithFileSystemPath (NULL, fn, kCFURLPOSIXPathStyle, false);
	if (NULL == fon) exit (0);

	// Create an image destination
	CGImageDestinationRef image_destination = CGImageDestinationCreateWithURL (fon, kUTTypeJPEG, 1, NULL);

	// Release the CFURLRef
	CFRelease (fon);
	fon = NULL;
	
	// release the CFStringRef
	CFRelease (fn);
	fn = NULL;

	// Check for a NULL value in image_destination
	if (NULL == image_destination) {
		printf ("Null Image_destination: Could not create the CGImageDestinationRef from the supplied URL.\n");
		exit (0);
	}

	// Set the compression factor for the images
	CFStringRef keys[1];
	CFTypeRef value[1];
	
	// Use compression key
	keys[0] = kCGImageDestinationLossyCompressionQuality;

	// set the compression amount. 1 = no compression 0 = max compression
	value[0] = CFNumberCreate (NULL, kCFNumberFloatType, &compression);
	
	// Pointer to the image attribs dictionary
	CFDictionaryRef options;
	
	// create the dictionary
	options = CFDictionaryCreate (kCFAllocatorDefault, (void *)keys, (void *)value, 1, NULL, NULL);
	
	// Copy data to the output information to the destination
	CGImageDestinationAddImage (image_destination, processed_image, options);
	
	// Check for a NULL value in image_destination
	if (NULL == image_destination) {
		printf ("Null Image_destination: Could not add the rotated image.\n"); 
		exit (0);
	}
	
	// Write the image to disk
	if (!CGImageDestinationFinalize (image_destination)) {
		// Could not write the file for some reason
		printf ("Could not write the file to disk.\n"); 
		exit (1);
	}

	// Release the pointer the the scaled buffer
	CFRelease (output_Data);
	output_Data = NULL;
	
	// Release the dictionary
	CFRelease (keys[0]);
	CFRelease (value[0]);
	CFRelease (options);
	options = NULL;
	
	// Release the rotated image.
	CGImageRelease (processed_image);
	processed_image = NULL;
	
	// Release a data provider
	CGDataProviderRelease (destination_data_provider);
	destination_data_provider = NULL;
	
	// Release the image destination
	CFRelease (image_destination);
	image_destination = NULL;

} // save_image
Пример #21
0
/* the error does not contain the filename as the caller already has it */
gboolean
_cogl_bitmap_from_file (CoglBitmap  *bmp,
			const gchar *filename,
			GError     **error)
{
  g_assert (bmp != NULL);
  g_assert (filename != NULL);
  g_assert (error == NULL || *error == NULL);

  CFURLRef url = CFURLCreateFromFileSystemRepresentation (NULL, (guchar*)filename, strlen(filename), false);
  CGImageSourceRef image_source = CGImageSourceCreateWithURL (url, NULL);
  int save_errno = errno;
  CFRelease (url);
  if (image_source == NULL)
    {
      /* doesn't exist, not readable, etc. */
      g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_FAILED,
                   "%s", g_strerror (save_errno));
      return FALSE;
    }

  /* Unknown images would be cleanly caught as zero width/height below, but try
   * to provide better error message
   */
  CFStringRef type = CGImageSourceGetType (image_source);
  if (type == NULL)
    {
      CFRelease (image_source);
      g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_UNKNOWN_TYPE,
                   "Unknown image type");
      return FALSE;
    }
  CFRelease (type);

  CGImageRef image = CGImageSourceCreateImageAtIndex (image_source, 0, NULL);
  CFRelease (image_source);

  size_t width = CGImageGetWidth (image);
  size_t height = CGImageGetHeight (image);
  if (width == 0 || height == 0)
    {
      /* incomplete or corrupt */
      CFRelease (image);
      g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_CORRUPT_IMAGE,
                   "Image has zero width or height");
      return FALSE;
    }

  /* allocate buffer big enough to hold pixel data */
  size_t rowstride;
  CGBitmapInfo bitmap_info = CGImageGetBitmapInfo (image);
  if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaNone)
    {
      bitmap_info = kCGImageAlphaNone;
      rowstride = 3 * width;
    }
  else
    {
      bitmap_info = kCGImageAlphaPremultipliedFirst;
      rowstride = 4 * width;
    }
  guint8 *out_data = g_malloc0 (height * rowstride);

  /* render to buffer */
  CGColorSpaceRef color_space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
  CGContextRef bitmap_context = CGBitmapContextCreate (out_data,
                                                       width, height, 8,
                                                       rowstride, color_space,
                                                       bitmap_info);
  CGColorSpaceRelease (color_space);

  const CGRect rect = {{0, 0}, {width, height}};
  CGContextDrawImage (bitmap_context, rect, image);

  CGImageRelease (image);
  CGContextRelease (bitmap_context);

  /* store bitmap info */
  bmp->data = out_data;
  bmp->format = bitmap_info == kCGImageAlphaPremultipliedFirst
                ? COGL_PIXEL_FORMAT_ARGB_8888
                : COGL_PIXEL_FORMAT_RGB_888;
  bmp->width = width;
  bmp->height = height;
  bmp->rowstride = rowstride;

  return TRUE;
}
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatRect& srcRect,
    const FloatRect& dstRect, ExceptionCode& ec)
{
    ASSERT(canvas);

    ec = 0;

    FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size());
    if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 
            && dstRect.width() >= 0 && dstRect.height() >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (srcRect.isEmpty() || dstRect.isEmpty())
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;
        
    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    FloatRect destRect = c->roundToDevicePixels(dstRect);
        
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    CGImageRef platformImage = canvas->createPlatformImage();
    if (!platformImage)
        return;

    willDraw(destRect);

    float iw = CGImageGetWidth(platformImage);
    float ih = CGImageGetHeight(platformImage);
    if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) {
        // Fast path, yay!
        CGContextDrawImage(c->platformContext(), destRect, platformImage);
    } else {
        // Slow path, boo!
        // Create a new bitmap of the appropriate size and then draw that into our context.

        size_t csw = static_cast<size_t>(ceilf(sourceRect.width()));
        size_t csh = static_cast<size_t>(ceilf(sourceRect.height()));

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        size_t bytesPerRow = csw * 4;
        void* buffer = fastMalloc(csh * bytesPerRow);

        CGContextRef clippedSourceContext = CGBitmapContextCreate(buffer, csw, csh,
            8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(colorSpace);
        CGContextTranslateCTM(clippedSourceContext, -sourceRect.x(), -sourceRect.y());
        CGContextDrawImage(clippedSourceContext, CGRectMake(0, 0, iw, ih), platformImage);

        CGImageRef clippedSourceImage = CGBitmapContextCreateImage(clippedSourceContext);
        CGContextRelease(clippedSourceContext);

        CGContextDrawImage(c->platformContext(), destRect, clippedSourceImage);
        CGImageRelease(clippedSourceImage);
        
        fastFree(buffer);
    }

    CGImageRelease(platformImage);
#elif PLATFORM(QT)
    QPixmap px = canvas->createPlatformImage();
    if (px.isNull())
        return;
    willDraw(dstRect);
    QPainter* painter = static_cast<QPainter*>(c->platformContext());
    painter->drawPixmap(dstRect, px, srcRect);
#endif
}
Пример #23
0
/* the error does not contain the filename as the caller already has it */
CoglBitmap *
_cogl_bitmap_from_file (const char  *filename,
			GError     **error)
{
  CFURLRef url;
  CGImageSourceRef image_source;
  CGImageRef image;
  int save_errno;
  CFStringRef type;
  size_t width, height, rowstride;
  uint8_t *out_data;
  CGColorSpaceRef color_space;
  CGContextRef bitmap_context;
  CoglBitmap *bmp;

  _COGL_GET_CONTEXT (ctx, NULL);

  g_assert (filename != NULL);
  g_assert (error == NULL || *error == NULL);

  url = CFURLCreateFromFileSystemRepresentation (NULL,
                                                 (guchar *) filename,
                                                 strlen (filename),
                                                 false);
  image_source = CGImageSourceCreateWithURL (url, NULL);
  save_errno = errno;
  CFRelease (url);

  if (image_source == NULL)
    {
      /* doesn't exist, not readable, etc. */
      g_set_error_literal (error,
                           COGL_BITMAP_ERROR,
                           COGL_BITMAP_ERROR_FAILED,
                           g_strerror (save_errno));
      return NULL;
    }

  /* Unknown images would be cleanly caught as zero width/height below, but try
   * to provide better error message
   */
  type = CGImageSourceGetType (image_source);
  if (type == NULL)
    {
      CFRelease (image_source);
      g_set_error_literal (error,
                           COGL_BITMAP_ERROR,
                           COGL_BITMAP_ERROR_UNKNOWN_TYPE,
                           "Unknown image type");
      return NULL;
    }

  CFRelease (type);

  image = CGImageSourceCreateImageAtIndex (image_source, 0, NULL);
  CFRelease (image_source);

  width = CGImageGetWidth (image);
  height = CGImageGetHeight (image);
  if (width == 0 || height == 0)
    {
      /* incomplete or corrupt */
      CFRelease (image);
      g_set_error_literal (error,
                           COGL_BITMAP_ERROR,
                           COGL_BITMAP_ERROR_CORRUPT_IMAGE,
                           "Image has zero width or height");
      return NULL;
    }

  /* allocate buffer big enough to hold pixel data */
  bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
                                             width, height,
                                             COGL_PIXEL_FORMAT_ARGB_8888);
  rowstride = cogl_bitmap_get_rowstride (bmp);
  out_data = _cogl_bitmap_map (bmp,
                               COGL_BUFFER_ACCESS_WRITE,
                               COGL_BUFFER_MAP_HINT_DISCARD);

  /* render to buffer */
  color_space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
  bitmap_context = CGBitmapContextCreate (out_data,
                                          width, height, 8,
                                          rowstride, color_space,
                                          kCGImageAlphaPremultipliedFirst);
  CGColorSpaceRelease (color_space);

  {
    const CGRect rect = {{0, 0}, {width, height}};

    CGContextDrawImage (bitmap_context, rect, image);
  }

  CGImageRelease (image);
  CGContextRelease (bitmap_context);

  _cogl_bitmap_unmap (bmp);

  /* store bitmap info */
  return bmp;
}
Пример #24
0
void UIFrameBufferQuartz2D::paintEvent(QPaintEvent *aEvent)
{
    /* If the machine is NOT in 'running' state,
     * the link between framebuffer and video memory
     * is broken, we should go fallback now... */
    if (m_fUsesGuestVRAM &&
        !m_pMachineView->uisession()->isRunning() &&
        !m_pMachineView->uisession()->isPaused() &&
        /* Online snapshotting: */
        m_pMachineView->uisession()->machineState() != KMachineState_Saving)
    {
        /* Simulate fallback through fake resize-event: */
        UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480);
        resizeEvent(&event);
    }

    /* For debugging /Developer/Applications/Performance Tools/Quartz
     * Debug.app is a nice tool to see which parts of the screen are
     * updated.*/
    Assert(m_image);

    QWidget* viewport = m_pMachineView->viewport();
    Assert(VALID_PTR(viewport));
    /* Get the dimensions of the viewport */
    CGRect viewRect = ::darwinToCGRect(viewport->geometry());
    /* Get the context of this window from Qt */
    CGContextRef ctx = ::darwinToCGContextRef(viewport);
    Assert(VALID_PTR(ctx));

    /* Flip the context */
    CGContextTranslateCTM(ctx, 0, viewRect.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);

    /* We handle the seamless mode as a special case. */
    if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
    {
        /* Clear the background (make the rect fully transparent): */
        CGContextClearRect(ctx, viewRect);

#ifdef OVERLAY_CLIPRECTS
        /* Enable overlay above the seamless mask: */
        CGContextSetRGBFillColor(ctx, 0.0, 0.0, 5.0, 0.7);
        CGContextFillRect(ctx, viewRect);
#endif /* OVERLAY_CLIPRECTS */
#ifdef COMP_WITH_SHADOW
        /* Enable shadows: */
        CGContextSetShadow(ctx, CGSizeMake (10, -10), 10);
        CGContextBeginTransparencyLayer(ctx, NULL);
#endif /* COMP_WITH_SHADOW */

        /* Determine current visible region: */
        RegionRects *pRgnRcts = ASMAtomicXchgPtrT(&mRegion, NULL, RegionRects*);
        if (pRgnRcts)
        {
            /* If visible region is determined: */
            if (pRgnRcts->used > 0)
            {
                /* Add the clipping rects all at once (they are defined in SetVisibleRegion): */
                CGContextBeginPath(ctx);
                CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used);
                /* Now convert the path to a clipping path: */
                CGContextClip(ctx);
            }

            /* Put back the visible region, free if we cannot (2+ SetVisibleRegion calls): */
            if (   !ASMAtomicCmpXchgPtr(&mRegion, pRgnRcts, NULL)
                && !ASMAtomicCmpXchgPtr(&mRegionUnused, pRgnRcts, NULL))
            {
                RTMemFree(pRgnRcts);
                pRgnRcts = NULL;
            }
        }

        /* If visible region is still determined: */
        if (pRgnRcts && pRgnRcts->used > 0)
        {
            /* Create a subimage of the current view.
             * Currently this subimage is the whole screen. */
            CGImageRef subImage;
            if (!m_pMachineView->pauseShot().isNull())
            {
                CGImageRef pauseImg = ::darwinToCGImageRef(&m_pMachineView->pauseShot());
                subImage = CGImageCreateWithImageInRect(pauseImg, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
                CGImageRelease(pauseImg);
            }
            else
            {
#ifdef RT_ARCH_AMD64
                /* Not sure who to blame, but it seems on 64bit there goes
                 * something terrible wrong (on a second monitor) when directly
                 * using CGImageCreateWithImageInRect without making a copy. We saw
                 * something like this already with the scale mode. */
                CGImageRef tmpImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
                subImage = CGImageCreateCopy(tmpImage);
                CGImageRelease(tmpImage);
#else /* RT_ARCH_AMD64 */
                subImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
#endif /* !RT_ARCH_AMD64 */
            }
            Assert(VALID_PTR(subImage));

            /* In any case clip the drawing to the view window: */
            CGContextClipToRect(ctx, viewRect);
            /* At this point draw the real vm image: */
            CGContextDrawImage(ctx, ::darwinFlipCGRect(viewRect, viewRect.size.height), subImage);

            /* Release the subimage: */
            CGImageRelease(subImage);
        }

#ifdef COMP_WITH_SHADOW
        CGContextEndTransparencyLayer(ctx);
#endif /* COMP_WITH_SHADOW */
#ifdef OVERLAY_CLIPRECTS
        if (pRgnRcts && pRgnRcts->used > 0)
        {
            CGContextBeginPath(ctx);
            CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used);
            CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 0.7);
            CGContextDrawPath(ctx, kCGPathStroke);
        }
        CGContextSetRGBStrokeColor(ctx, 0.0, 1.0, 0.0, 0.7);
        CGContextStrokeRect(ctx, viewRect);
#endif /* OVERLAY_CLIPRECTS */
    }
void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
{
    Q_D(QRasterWindowSurface);

    // Not ready for painting yet, bail out. This can happen in
    // QWidget::create_sys()
    if (!d->image || rgn.rectCount() == 0)
        return;

#ifdef Q_WS_WIN
    QRect br = rgn.boundingRect();

#ifndef Q_WS_WINCE
    if (!qt_widget_private(window())->isOpaque
        && window()->testAttribute(Qt::WA_TranslucentBackground)
        && (qt_widget_private(window())->data.window_flags & Qt::FramelessWindowHint))
    {
        QRect r = window()->frameGeometry();
        QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft();
        QRect dirtyRect = br.translated(offset + frameOffset);

        SIZE size = {r.width(), r.height()};
        POINT ptDst = {r.x(), r.y()};
        POINT ptSrc = {0, 0};
        BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA};
        RECT dirty = {dirtyRect.x(), dirtyRect.y(),
            dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
        Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty};
        ptrUpdateLayeredWindowIndirect(window()->internalWinId(), &info);
    } else
#endif
    {
        QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();

        HDC widget_dc = widget->getDC();

        QRect wbr = br.translated(-wOffset);
        BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(),
               d->image->hdc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY);
        widget->releaseDC(widget_dc);
    }

#ifndef QT_NO_DEBUG
    static bool flush = !qgetenv("QT_FLUSH_WINDOWSURFACE").isEmpty();
    if (flush) {
        SelectObject(qt_win_display_dc(), GetStockObject(BLACK_BRUSH));
        Rectangle(qt_win_display_dc(), 0, 0, d->image->width() + 2, d->image->height() + 2);
        BitBlt(qt_win_display_dc(), 1, 1, d->image->width(), d->image->height(),
               d->image->hdc, 0, 0, SRCCOPY);
    }
#endif

#endif

#ifdef Q_WS_X11
    extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp
    extern QWidgetData* qt_widget_data(QWidget *);
    QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();

    if (widget->window() != window()) {
        XFreeGC(X11->display, d_ptr->gc);
        d_ptr->gc = XCreateGC(X11->display, widget->handle(), 0, 0);
    }

    QRegion wrgn(rgn);
    if (!wOffset.isNull())
        wrgn.translate(-wOffset);
    QRect wbr = wrgn.boundingRect();

    if (wrgn.rectCount() != 1) {
        int num;
        XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
        XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded);
    }

    QRect br = rgn.boundingRect().translated(offset);
#ifndef QT_NO_MITSHM
    if (d_ptr->image->xshmpm) {
        XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc,
                  br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y());
        XSync(X11->display, False);
    } else if (d_ptr->image->xshmimg) {
        const QImage &src = d->image->image;
        br = br.intersected(src.rect());
        XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg,
                     br.x(), br.y(), wbr.x(), wbr.y(), br.width(), br.height(), False);
        XSync(X11->display, False);
    } else
#endif
    {
        const QImage &src = d->image->image;
        br = br.intersected(src.rect());
        if (src.format() != QImage::Format_RGB32 || widget->x11Info().depth() < 24) {
            Q_ASSERT(src.depth() >= 16);
            const QImage sub_src(src.scanLine(br.y()) + br.x() * (uint(src.depth()) / 8),
                                 br.width(), br.height(), src.bytesPerLine(), src.format());
            QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
            data->xinfo = widget->x11Info();
            data->fromImage(sub_src, Qt::NoOpaqueDetection);
            QPixmap pm = QPixmap(data);
            XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, 0 , 0 , br.width(), br.height(), wbr.x(), wbr.y());
        } else {
            // qpaintengine_x11.cpp
            extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth);
            qt_x11_drawImage(br, wbr.topLeft(), src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), widget->x11Info().depth());
        }
    }

    if (wrgn.rectCount() != 1)
        XSetClipMask(X11->display, d_ptr->gc, XNone);
#endif // FALCON

#ifdef Q_WS_MAC

//     qDebug() << "Flushing" << widget << rgn << offset;

//     d->image->image.save("flush.png");

    Q_UNUSED(offset);
    // Get a context for the widget.
#ifndef QT_MAC_USE_COCOA
    CGContextRef context;
    CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
    QDBeginCGContext(port, &context);
#else
    extern CGContextRef qt_mac_graphicsContextFor(QWidget *);
    CGContextRef context = qt_mac_graphicsContextFor(widget);
#endif
    CGContextSaveGState(context);

    // Flip context.
    CGContextTranslateCTM(context, 0, widget->height());
    CGContextScaleCTM(context, 1, -1);

    // Clip to region.
    const QVector<QRect> &rects = rgn.rects();
    for (int i = 0; i < rects.size(); ++i) {
        const QRect &rect = rects.at(i);
        CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
    }
    CGContextClip(context);

    QRect r = rgn.boundingRect();
    const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height());
    CGImageRef image = CGBitmapContextCreateImage(d->image->cg);
    CGImageRef subImage = CGImageCreateWithImageInRect(image, area);

    qt_mac_drawCGImage(context, &area, subImage);
    CGImageRelease(subImage);
    CGImageRelease(image);

//     CGSize size = { d->image->image.width(), d->image->image.height() };
//     CGLayerRef layer = CGLayerCreateWithContext(d->image->cg, size, 0);
//     CGPoint pt = { 0, 0 };
//     CGContextDrawLayerAtPoint(context, pt, layer);
//     CGLayerRelease(layer);

    // Restore context.
    CGContextRestoreGState(context);
#ifndef QT_MAC_USE_COCOA
    QDEndCGContext(port, &context);
#endif
#endif // Q_WS_MAC

#ifdef Q_OS_SYMBIAN
    Q_UNUSED(widget);
    Q_UNUSED(rgn);
    Q_UNUSED(offset);
#endif
}
Пример #26
0
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int						 nChars,
        const FXTEXT_CHARPOS *	 pCharPos,
        CFX_Font *				 pFont,
        CFX_FontCache *			 pCache,
        const CFX_AffineMatrix * pObject2Device,
        FX_FLOAT				 font_size,
        FX_DWORD				 argb,
        int alpha_flag, void* pIccTransform)
{
    if (!pFont) {
        return FALSE;
    }
    FX_BOOL bBold = pFont->IsBold();
    if (!bBold && pFont->GetSubstFont() &&
            pFont->GetSubstFont()->m_Weight >= 500 &&
            pFont->GetSubstFont()->m_Weight <= 600) {
        return FALSE;
    }
    for (int i = 0; i < nChars; i ++) {
        if (pCharPos[i].m_bGlyphAdjust) {
            return FALSE;
        }
    }
    CGContextRef ctx = CGContextRef(m_pPlatformGraphics);
    if (NULL == ctx) {
        return FALSE;
    }
    CGContextSaveGState(ctx);
    CGContextSetTextDrawingMode(ctx, kCGTextFillClip);
    CGRect rect_cg;
    CGImageRef pImageCG = NULL;
    if (m_pClipRgn) {
        rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height());
        const CFX_DIBitmap*	pClipMask = m_pClipRgn->GetMask();
        if (pClipMask) {
            CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL,
                    pClipMask->GetBuffer(),
                    pClipMask->GetPitch() * pClipMask->GetHeight(),
                    _DoNothing);
            CGFloat decode_f[2] = {255.f, 0.f};
            pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(),
                                         8, 8, pClipMask->GetPitch(), pClipMaskDataProvider,
                                         decode_f, FALSE);
            CGDataProviderRelease(pClipMaskDataProvider);
        }
    } else {
        rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
    }
    rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg);
    if (pImageCG) {
        CGContextClipToMask(ctx, rect_cg, pImageCG);
    } else {
        CGContextClipToRect(ctx, rect_cg);
    }
    FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform);
    if (pImageCG) {
        CGImageRelease(pImageCG);
    }
    CGContextRestoreGState(ctx);
    return ret;
}
void TilePDFWithOffscreenBitmap(CGContextRef context, CFURLRef url)
{
    // Again this should really be computed based on
    // the area intended to be tiled.
    float fillwidth = 612., fillheight = 792.;
    float tileX, tileY, tileOffsetX, tileOffsetY, extraOffset = 6;
    float w, h;
    CGContextRef bitmapContext;
    Boolean useDisplayColorSpace;
    Boolean needTransparentBitmap;

    CGPDFDocumentRef pdfDoc = getThePDFDoc(url, 
				    &tileX,
				    &tileY);
    if(pdfDoc == NULL){
	    fprintf(stderr, "Couldn't get the PDF document!\n");
	    return;
    }

#if DOSCALING
    // Make the tiles 1/3 the size of the PDF document.
    tileX /= 3;
    tileY /= 3;
	extraOffset /= 3;
#endif

    // Space the tiles by the tile width and height
    // plus extraOffset units in each dimension.
    tileOffsetX = extraOffset + tileX;
    tileOffsetY = extraOffset + tileY;
    
    // Since the bitmap context is for use with the display
    // and should capture alpha, these are the values
    // to pass to createRGBBitmapContext.
    useDisplayColorSpace = true;
    needTransparentBitmap = true;
    bitmapContext = createRGBBitmapContext(tileX, tileY, 
					useDisplayColorSpace, 
					needTransparentBitmap);
    if(bitmapContext == NULL){
		fprintf(stderr, "Couldn't create bitmap context!\n");
		return;
    }

    // Draw the PDF document one time into the bitmap context.
    CGContextDrawPDFDocument(bitmapContext, 
		    CGRectMake(0, 0, tileX, tileY), pdfDoc, 1);

    // Create an image from the raster data. Calling
	// createImageFromBitmapContext gives up ownership
	// of the raster data used by the context.
    CGImageRef image = createImageFromBitmapContext(bitmapContext);

	// Release the context now that the image is created.
    CGContextRelease(bitmapContext);

    if(image == NULL){
		return;
    }
    
    // Now tile the image.
    for(h = 0; h < fillheight ; h += tileOffsetY)
		for(w = 0; w < fillwidth ; w += tileOffsetX){
			CGContextDrawImage(context, CGRectMake(w, h, tileX, tileY), image);
		}
	
    CGImageRelease(image);
}
Пример #28
0
bool FBVLC_Mac::onCoreGraphicsDraw(FB::CoreGraphicsDraw *evt, FB::PluginWindowMacCG*)
{
    boost::lock_guard<boost::mutex> lock( m_frameGuard );

    FB::Rect bounds(evt->bounds);
    //FB::Rect clip(evt->clip);
    short width = bounds.right - bounds.left, height = bounds.bottom - bounds.top;

    CGContextRef cgContext(evt->context);

    CGContextSaveGState(cgContext);

    CGContextTranslateCTM(cgContext, 0.0, height);
    CGContextScaleCTM(cgContext, 1.0, -1.0);

    CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
    CGContextSetFillColorSpace(cgContext, cSpace);

    CGColorRef bgColor = CGColorCreate(cSpace, m_bgComponents);
    CGContextSetFillColorWithColor(cgContext, bgColor);

    if ( 0 != m_media_width && 0 != m_media_height ) {
        CGRect imgRect = {
            { (width - m_media_width) / 2, (height - m_media_height) / 2 },
            { m_media_width, m_media_height }
        };

        const std::vector<char>& fb = vlc::vmem::frame_buf();
        CGContextRef frameBmpCtx =
            CGBitmapContextCreate( (void*)&fb[0], m_media_width, m_media_height, 8,
                                   m_media_width * vlc::DEF_PIXEL_BYTES, cSpace,
                                   kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little );
        CGImageRef frameImage = CGBitmapContextCreateImage( frameBmpCtx );

        CGContextDrawImage( cgContext, imgRect, frameImage );

        CGImageRelease( frameImage );
        CGContextRelease( frameBmpCtx );

        if( m_media_width < width ) {
            CGRect bgLeft = {
                { 0, 0 },
                { imgRect.origin.x, height }
            };
            CGContextFillRect(cgContext, bgLeft);

            CGRect bgRight = {
                { imgRect.origin.x + imgRect.size.width, 0 },
                { width - (imgRect.origin.x + imgRect.size.width), height }
            };
            CGContextFillRect(cgContext, bgRight);

        } else if( m_media_height < height ){
            CGRect bgTop = {
                { 0, 0 },
                { width, imgRect.origin.y }
            };
            CGContextFillRect(cgContext, bgTop);

            CGRect bgBottom = {
                { 0, imgRect.origin.y + imgRect.size.height },
                { width, height - (imgRect.origin.y + imgRect.size.height) }
            };
            CGContextFillRect(cgContext, bgBottom);
        }
    } else {
        CGRect cgBounds = {
            { 0, 0 },
            { width, height }
        };
        CGContextFillRect(cgContext, cgBounds);
    }

    CGColorRelease(bgColor);
    CGColorSpaceRelease(cSpace);
    CGContextRestoreGState(cgContext);

    return true; // This is handled
}
Пример #29
0
static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_float, double_rgbt **z_rgbt, unsigned char **z_byte,
	long ix1, long ix2, long x1DC, long x2DC,
	long iy1, long iy2, long y1DC, long y2DC,
	double minimum, double maximum,
	long clipx1, long clipx2, long clipy1, long clipy2, int interpolate)
{
	/*long t=clock();*/
	long nx = ix2 - ix1 + 1;   /* The number of cells along the horizontal axis. */
	long ny = iy2 - iy1 + 1;   /* The number of cells along the vertical axis. */
	double dx = (double) (x2DC - x1DC) / (double) nx;   /* Horizontal pixels per cell. Positive. */
	double dy = (double) (y2DC - y1DC) / (double) ny;   /* Vertical pixels per cell. Negative. */
	double scale = 255.0 / (maximum - minimum), offset = 255.0 + minimum * scale;
	if (x2DC <= x1DC || y1DC <= y2DC) return;
	trace ("scale %f", scale);
	/* Clip by the intersection of the world window and the outline of the cells. */
	//Melder_casual ("clipy1 %ld clipy2 %ld", clipy1, clipy2);
	if (clipx1 < x1DC) clipx1 = x1DC;
	if (clipx2 > x2DC) clipx2 = x2DC;
	if (clipy1 > y1DC) clipy1 = y1DC;
	if (clipy2 < y2DC) clipy2 = y2DC;
	/*
	 * The first decision is whether we are going to use the standard rectangle drawing
	 * (cellArray only), or whether we are going to write into a bitmap.
	 * The standard drawing is best for small numbers of cells,
	 * provided that some cells are larger than a pixel.
	 */
	if (! interpolate && nx * ny < 3000 && (dx > 1.0 || dy < -1.0)) {
		try {
			/*unsigned int cellWidth = (unsigned int) dx + 1;*/
			unsigned int cellHeight = (unsigned int) (- (int) dy) + 1;
			long ix, iy;
			#if cairo
				cairo_pattern_t *grey [256];
				for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey ++) {
					double v = igrey / ((double) (sizeof (grey) / sizeof (*grey)) - 1.0);
					grey [igrey] = cairo_pattern_create_rgb (v, v, v);
				}
			#elif win
				static HBRUSH greyBrush [256];
				RECT rect;
				if (! greyBrush [0])
					for (int igrey = 0; igrey <= 255; igrey ++)
						greyBrush [igrey] = CreateSolidBrush (RGB (igrey, igrey, igrey));   // once
			#elif mac
				GraphicsQuartz_initDraw (me);
				CGContextSetAlpha (my d_macGraphicsContext, 1.0);
				CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal);
			#endif
			autoNUMvector <long> lefts (ix1, ix2 + 1);
			for (ix = ix1; ix <= ix2 + 1; ix ++)
				lefts [ix] = x1DC + (long) ((ix - ix1) * dx);
			for (iy = iy1; iy <= iy2; iy ++) {
				long bottom = y1DC + (long) ((iy - iy1) * dy), top = bottom - cellHeight;
				if (top > clipy1 || bottom < clipy2) continue;
				if (top < clipy2) top = clipy2;
				if (bottom > clipy1) bottom = clipy1;
				#if win
					rect. bottom = bottom; rect. top = top;
				#endif
				for (ix = ix1; ix <= ix2; ix ++) {
					long left = lefts [ix], right = lefts [ix + 1];
					if (right < clipx1 || left > clipx2) continue;
					if (left < clipx1) left = clipx1;
					if (right > clipx2) right = clipx2;
					if (z_rgbt) {
						#if cairo
							// NYI
						#elif win
							// NYI
						#elif mac
							double red          = z_rgbt [iy] [ix]. red;
							double green        = z_rgbt [iy] [ix]. green;
							double blue         = z_rgbt [iy] [ix]. blue;
							double transparency = z_rgbt [iy] [ix]. transparency;
							red =   ( red   <= 0.0 ? 0.0 : red   >= 1.0 ? 1.0 : red   );
							green = ( green <= 0.0 ? 0.0 : green >= 1.0 ? 1.0 : green );
							blue =  ( blue  <= 0.0 ? 0.0 : blue  >= 1.0 ? 1.0 : blue  );
							CGContextSetRGBFillColor (my d_macGraphicsContext, red, green, blue, 1.0 - transparency);
							CGContextFillRect (my d_macGraphicsContext, CGRectMake (left, top, right - left, bottom - top));
						#endif
					} else {
						#if cairo
							long value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] );
							cairo_set_source (my d_cairoGraphicsContext, grey [value <= 0 ? 0 : value >= sizeof (grey) / sizeof (*grey) ? sizeof (grey) / sizeof (*grey) : value]);
							cairo_rectangle (my d_cairoGraphicsContext, left, top, right - left, bottom - top);
							cairo_fill (my d_cairoGraphicsContext);
						#elif win
							long value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] );
							rect. left = left; rect. right = right;
							FillRect (my d_gdiGraphicsContext, & rect, greyBrush [value <= 0 ? 0 : value >= 255 ? 255 : value]);
						#elif mac
							double value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] );
							double igrey = ( value <= 0 ? 0 : value >= 255 ? 255 : value ) / 255.0;
							CGContextSetRGBFillColor (my d_macGraphicsContext, igrey, igrey, igrey, 1.0);
							CGContextFillRect (my d_macGraphicsContext, CGRectMake (left, top, right - left, bottom - top));
						#endif
					}
				}
			}
			
			#if cairo
				for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey ++)
					cairo_pattern_destroy (grey [igrey]);
			#elif mac
				CGContextSetRGBFillColor (my d_macGraphicsContext, 0.0, 0.0, 0.0, 1.0);
				GraphicsQuartz_exitDraw (me);
			#endif
		} catch (MelderError) { }
	} else {
		long xDC, yDC;
		long undersampling = 1;
		/*
		 * Prepare for off-screen bitmap drawing.
		 */
		#if cairo
			long arrayWidth = clipx2 - clipx1;
			long arrayHeight = clipy1 - clipy2;
			trace ("arrayWidth %f, arrayHeight %f", (double) arrayWidth, (double) arrayHeight);
			cairo_surface_t *sfc = cairo_image_surface_create (CAIRO_FORMAT_RGB24, arrayWidth, arrayHeight);
			unsigned char *bits = cairo_image_surface_get_data (sfc);
			int scanLineLength = cairo_image_surface_get_stride (sfc);
			unsigned char grey [256];
			trace ("image surface address %p, bits address %p, scanLineLength %d, numberOfGreys %d", sfc, bits, scanLineLength, sizeof(grey)/sizeof(*grey));
			for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey++)
				grey [igrey] = 255 - (unsigned char) (igrey * 255.0 / (sizeof (grey) / sizeof (*grey) - 1));
		#elif win
			long bitmapWidth = clipx2 - clipx1, bitmapHeight = clipy1 - clipy2;
			int igrey;
			/*
			 * Create a device-independent bitmap, 32 bits deep.
			 */
			struct { BITMAPINFOHEADER header; } bitmapInfo;
			long scanLineLength = bitmapWidth * 4;   // for 24 bits: (bitmapWidth * 3 + 3) & ~3L;
			HBITMAP bitmap;
			unsigned char *bits;   // a pointer to memory allocated by VirtualAlloc or by CreateDIBSection ()
			bitmapInfo. header.biSize = sizeof (BITMAPINFOHEADER);
			bitmapInfo. header.biWidth = bitmapWidth;   // scanLineLength;
			bitmapInfo. header.biHeight = bitmapHeight;
			bitmapInfo. header.biPlanes = 1;
			bitmapInfo. header.biBitCount = 32;
			bitmapInfo. header.biCompression = 0;
			bitmapInfo. header.biSizeImage = 0;
			bitmapInfo. header.biXPelsPerMeter = 0;
			bitmapInfo. header.biYPelsPerMeter = 0;
			bitmapInfo. header.biClrUsed = 0;
			bitmapInfo. header.biClrImportant = 0;
			bitmap = CreateDIBSection (my d_gdiGraphicsContext /* ignored */, (CONST BITMAPINFO *) & bitmapInfo,
				DIB_RGB_COLORS, (VOID **) & bits, NULL, 0);
		#elif mac
			long bytesPerRow = (clipx2 - clipx1) * 4;
			Melder_assert (bytesPerRow > 0);
			long numberOfRows = clipy1 - clipy2;
			Melder_assert (numberOfRows > 0);
			unsigned char *imageData = Melder_malloc_f (unsigned char, bytesPerRow * numberOfRows);
		#endif
		/*
		 * Draw into the bitmap.
		 */
		#if cairo
			#define ROW_START_ADDRESS  (bits + (clipy1 - 1 - yDC) * scanLineLength)
			#define PUT_PIXEL \
				if (1) { \
					unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = 0; \
				}
		#elif win
			#define ROW_START_ADDRESS  (bits + (clipy1 - 1 - yDC) * scanLineLength)
			#define PUT_PIXEL \
				if (1) { \
					unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = 0; \
				}
		#elif mac
			#define ROW_START_ADDRESS  (imageData + (clipy1 - 1 - yDC) * bytesPerRow)
			#define PUT_PIXEL \
				if (my colourScale == kGraphics_colourScale_GREY) { \
					unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = kar; \
					*pixelAddress ++ = 0; \
				} else if (my colourScale == kGraphics_colourScale_BLUE_TO_RED) { \
					if (value < 0.0) { \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 63; \
						*pixelAddress ++ = 0; \
					} else if (value < 64.0) { \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = (int) (value * 3 + 63.999); \
						*pixelAddress ++ = 0; \
					} else if (value < 128.0) { \
						*pixelAddress ++ = (int) (value * 4 - 256.0); \
						*pixelAddress ++ = (int) (value * 4 - 256.0); \
						*pixelAddress ++ = 255; \
						*pixelAddress ++ = 0; \
					} else if (value < 192.0) { \
						*pixelAddress ++ = 255; \
						*pixelAddress ++ = (int) ((256.0 - value) * 4 - 256.0); \
						*pixelAddress ++ = (int) ((256.0 - value) * 4 - 256.0); \
						*pixelAddress ++ = 0; \
					} else if (value < 256.0) { \
						*pixelAddress ++ = (int) ((256.0 - value) * 3 + 63.999); \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
					} else { \
						*pixelAddress ++ = 63; \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
						*pixelAddress ++ = 0; \
					} \
				}
		#else
			#define ROW_START_ADDRESS  NULL
			#define PUT_PIXEL
		#endif
		if (interpolate) {
			try {
				autoNUMvector <long> ileft (clipx1, clipx2);
				autoNUMvector <long> iright (clipx1, clipx2);
				autoNUMvector <double> rightWeight (clipx1, clipx2);
				autoNUMvector <double> leftWeight (clipx1, clipx2);
				for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
					double ix_real = ix1 - 0.5 + ((double) nx * (xDC - x1DC)) / (x2DC - x1DC);
					ileft [xDC] = floor (ix_real), iright [xDC] = ileft [xDC] + 1;
					rightWeight [xDC] = ix_real - ileft [xDC], leftWeight [xDC] = 1.0 - rightWeight [xDC];
					if (ileft [xDC] < ix1) ileft [xDC] = ix1;
					if (iright [xDC] > ix2) iright [xDC] = ix2;
				}
				for (yDC = clipy2; yDC < clipy1; yDC += undersampling) {
					double iy_real = iy2 + 0.5 - ((double) ny * (yDC - y2DC)) / (y1DC - y2DC);
					long itop = ceil (iy_real), ibottom = itop - 1;
					double bottomWeight = itop - iy_real, topWeight = 1.0 - bottomWeight;
					unsigned char *pixelAddress = ROW_START_ADDRESS;
					if (itop > iy2) itop = iy2;
					if (ibottom < iy1) ibottom = iy1;
					if (z_float) {
						double *ztop = z_float [itop], *zbottom = z_float [ibottom];
						for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
							double interpol =
								rightWeight [xDC] *
									(topWeight * ztop [iright [xDC]] + bottomWeight * zbottom [iright [xDC]]) +
								leftWeight [xDC] *
									(topWeight * ztop [ileft [xDC]] + bottomWeight * zbottom [ileft [xDC]]);
							double value = offset - scale * interpol;
							PUT_PIXEL
						}
					} else if (z_rgbt) {
						double_rgbt *ztop = z_rgbt [itop], *zbottom = z_rgbt [ibottom];
						for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
							double red =
								rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. red + bottomWeight * zbottom [iright [xDC]]. red) +
								leftWeight  [xDC] * (topWeight * ztop [ileft  [xDC]]. red + bottomWeight * zbottom [ileft  [xDC]]. red);
							double green =
								rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. green + bottomWeight * zbottom [iright [xDC]]. green) +
								leftWeight  [xDC] * (topWeight * ztop [ileft  [xDC]]. green + bottomWeight * zbottom [ileft  [xDC]]. green);
							double blue =
								rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. blue + bottomWeight * zbottom [iright [xDC]]. blue) +
								leftWeight  [xDC] * (topWeight * ztop [ileft  [xDC]]. blue + bottomWeight * zbottom [ileft  [xDC]]. blue);
							double transparency =
								rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. transparency + bottomWeight * zbottom [iright [xDC]]. transparency) +
								leftWeight  [xDC] * (topWeight * ztop [ileft  [xDC]]. transparency + bottomWeight * zbottom [ileft  [xDC]]. transparency);
							if (red          < 0.0) red          = 0.0; else if (red          > 1.0) red          = 1.0;
							if (green        < 0.0) green        = 0.0; else if (green        > 1.0) green        = 1.0;
							if (blue         < 0.0) blue         = 0.0; else if (blue         > 1.0) blue         = 1.0;
							if (transparency < 0.0) transparency = 0.0; else if (transparency > 1.0) transparency = 1.0;
							#if win
								*pixelAddress ++ = blue         * 255.0;
								*pixelAddress ++ = green        * 255.0;
								*pixelAddress ++ = red          * 255.0;
								*pixelAddress ++ = 0;
							#elif mac
								*pixelAddress ++ = red          * 255.0;
								*pixelAddress ++ = green        * 255.0;
								*pixelAddress ++ = blue         * 255.0;
								*pixelAddress ++ = transparency * 255.0;
							#elif cairo
								*pixelAddress ++ = blue         * 255.0;
								*pixelAddress ++ = green        * 255.0;
								*pixelAddress ++ = red          * 255.0;
								*pixelAddress ++ = transparency * 255.0;
							#endif
						}
					} else {
						unsigned char *ztop = z_byte [itop], *zbottom = z_byte [ibottom];
						for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
							double interpol =
								rightWeight [xDC] *
									(topWeight * ztop [iright [xDC]] + bottomWeight * zbottom [iright [xDC]]) +
								leftWeight [xDC] *
									(topWeight * ztop [ileft [xDC]] + bottomWeight * zbottom [ileft [xDC]]);
							double value = offset - scale * interpol;
							PUT_PIXEL
						}
					}
				}
			} catch (MelderError) { Melder_clearError (); }
		} else {
			try {
				autoNUMvector <long> ix (clipx1, clipx2);
				for (xDC = clipx1; xDC < clipx2; xDC += undersampling)
					ix [xDC] = floor (ix1 + (nx * (xDC - x1DC)) / (x2DC - x1DC));
				for (yDC = clipy2; yDC < clipy1; yDC += undersampling) {
					long iy = ceil (iy2 - (ny * (yDC - y2DC)) / (y1DC - y2DC));
					unsigned char *pixelAddress = ROW_START_ADDRESS;
					Melder_assert (iy >= iy1 && iy <= iy2);
					if (z_float) {
						double *ziy = z_float [iy];
						for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
							double value = offset - scale * ziy [ix [xDC]];
							PUT_PIXEL
						}
					} else {
						unsigned char *ziy = z_byte [iy];
						for (xDC = clipx1; xDC < clipx2; xDC += undersampling) {
							double value = offset - scale * ziy [ix [xDC]];
							PUT_PIXEL
						}
					}
				}
			} catch (MelderError) { Melder_clearError (); }
		}
		/*
		 * Copy the bitmap to the screen.
		 */
		#if cairo
			cairo_matrix_t clip_trans;
			cairo_matrix_init_identity (& clip_trans);
			cairo_matrix_scale (& clip_trans, 1, -1);		// we painted in the reverse y-direction
			cairo_matrix_translate (& clip_trans, - clipx1, - clipy1);
			cairo_pattern_t *bitmap_pattern = cairo_pattern_create_for_surface (sfc);
			trace ("bitmap pattern %p", bitmap_pattern);
			if (cairo_status_t status = cairo_pattern_status (bitmap_pattern)) {
				Melder_casual ("bitmap pattern status: %s", cairo_status_to_string (status));
			} else {
				cairo_pattern_set_matrix (bitmap_pattern, & clip_trans);
				cairo_save (my d_cairoGraphicsContext);
				cairo_set_source (my d_cairoGraphicsContext, bitmap_pattern);
				cairo_paint (my d_cairoGraphicsContext);
				cairo_restore (my d_cairoGraphicsContext);
			}
			cairo_pattern_destroy (bitmap_pattern);
		#elif win
			SetDIBitsToDevice (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight,
				bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS);
			//StretchDIBits (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight,
			//	bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
		#elif mac
			CGImageRef image;
			static CGColorSpaceRef colourSpace = NULL;
			if (colourSpace == NULL) {
				colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);   // used to be kCGColorSpaceUserRGB
				Melder_assert (colourSpace != NULL);
			}
			if (1) {
				CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL,
					imageData,
					bytesPerRow * numberOfRows,
					_mac_releaseDataCallback   // we need this because we cannot release the image data immediately after drawing,
						// because in PDF files the imageData has to stay available through EndPage
				);
				Melder_assert (dataProvider != NULL);
				image = CGImageCreate (clipx2 - clipx1, numberOfRows,
					8, 32, bytesPerRow, colourSpace, kCGImageAlphaNone, dataProvider, NULL, false, kCGRenderingIntentDefault);
				CGDataProviderRelease (dataProvider);
			} else if (0) {
				Melder_assert (CGBitmapContextCreate != NULL);
				CGContextRef bitmaptest = CGBitmapContextCreate (imageData, 100, 100,
					8, 800, colourSpace, 0);
				Melder_assert (bitmaptest != NULL);
				CGContextRef bitmap = CGBitmapContextCreate (NULL/*imageData*/, clipx2 - clipx1, numberOfRows,
					8, bytesPerRow, colourSpace, kCGImageAlphaLast);
				Melder_assert (bitmap != NULL);
				image = CGBitmapContextCreateImage (bitmap);
				// release bitmap?
			}
			Melder_assert (image != NULL);
			GraphicsQuartz_initDraw (me);
			CGContextDrawImage (my d_macGraphicsContext, CGRectMake (clipx1, clipy2, clipx2 - clipx1, clipy1 - clipy2), image);
			GraphicsQuartz_exitDraw (me);
			//CGColorSpaceRelease (colourSpace);
			CGImageRelease (image);
		#endif
		/*
		 * Clean up.
		 */
		#if cairo
			cairo_surface_destroy (sfc);
		#elif win
			DeleteBitmap (bitmap);
		#endif
	}
Пример #30
0
void  ImageIODecoder::close()
{
    CGImageRelease( imageRef );
    imageRef = NULL;
}