CGImageRef
CreateCGImage(void *aInfo,
              const void *aData,
              const IntSize &aSize,
              int32_t aStride,
              SurfaceFormat aFormat)
{
  //XXX: we should avoid creating this colorspace everytime
  CGColorSpaceRef colorSpace = nullptr;
  CGBitmapInfo bitinfo = 0;
  int bitsPerComponent = 0;
  int bitsPerPixel = 0;

  switch (aFormat) {
    case SurfaceFormat::B8G8R8A8:
      colorSpace = CGColorSpaceCreateDeviceRGB();
      bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
      bitsPerComponent = 8;
      bitsPerPixel = 32;
      break;

    case SurfaceFormat::B8G8R8X8:
      colorSpace = CGColorSpaceCreateDeviceRGB();
      bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
      bitsPerComponent = 8;
      bitsPerPixel = 32;
      break;

    case SurfaceFormat::A8:
      // XXX: why don't we set a colorspace here?
      bitsPerComponent = 8;
      bitsPerPixel = 8;
      break;

    default:
      MOZ_CRASH();
  }

  size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
  if (bufLen == 0) {
    return nullptr;
  }
  CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo,
                                                                aData,
                                                                bufLen,
                                                                releaseCallback);

  CGImageRef image;
  if (aFormat == SurfaceFormat::A8) {
    CGFloat decode[] = {1.0, 0.0};
    image = CGImageMaskCreate (aSize.width, aSize.height,
                               bitsPerComponent,
                               bitsPerPixel,
                               aStride,
                               dataProvider,
                               decode,
                               true);
  } else {
    image = CGImageCreate (aSize.width, aSize.height,
                           bitsPerComponent,
                           bitsPerPixel,
                           aStride,
                           colorSpace,
                           bitinfo,
                           dataProvider,
                           nullptr,
                           true,
                           kCGRenderingIntentDefault);
  }

  CGDataProviderRelease(dataProvider);
  CGColorSpaceRelease(colorSpace);

  return image;
}
Beispiel #2
0
bool sdl_osd_interface::font_get_bitmap(osd_font font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
{
	UniChar uni_char;
	CGGlyph glyph;
	CTFontRef ct_font = (CTFontRef)font;
	const CFIndex count = 1;
	CGRect bounding_rect, success_rect;
	CGContextRef context_ref;

	if( chnum == ' ' )
	{
		uni_char = 'n';
		CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count );
		success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count );
		uni_char = chnum;
		CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count );
	}
	else
	{
		uni_char = chnum;
		CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count );
		success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count );
	}

	if( CGRectEqualToRect( success_rect, CGRectNull ) == false )
	{
		size_t bitmap_width;
		size_t bitmap_height;

		bitmap_width = ceilf(bounding_rect.size.width * EXTRA_WIDTH);
		bitmap_width = bitmap_width == 0 ? 1 : bitmap_width;

		bitmap_height = ceilf( (CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font)) * EXTRA_HEIGHT);

		xoffs = yoffs = 0;
		width = bitmap_width;

		size_t bits_per_component;
		CGColorSpaceRef color_space;
		CGBitmapInfo bitmap_info = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst;

		color_space = CGColorSpaceCreateDeviceRGB();
		bits_per_component = 8;

		bitmap.allocate(bitmap_width, bitmap_height);

		context_ref = CGBitmapContextCreate( bitmap.raw_pixptr(0), bitmap_width, bitmap_height, bits_per_component, bitmap.rowpixels()*4, color_space, bitmap_info );

		if( context_ref != NULL )
		{
			CGFontRef font_ref;
			font_ref = CTFontCopyGraphicsFont( ct_font, NULL );
			CGContextSetTextPosition(context_ref, -bounding_rect.origin.x*EXTRA_WIDTH, CTFontGetDescent(ct_font)+CTFontGetLeading(ct_font) );
			CGContextSetRGBFillColor(context_ref, 1.0, 1.0, 1.0, 1.0);
			CGContextSetFont( context_ref, font_ref );
			CGContextSetFontSize( context_ref, POINT_SIZE );
			CGContextShowGlyphs( context_ref, &glyph, count );
			CGFontRelease( font_ref );
			CGContextRelease( context_ref );
		}

		CGColorSpaceRelease( color_space );
	}

	return bitmap.valid();
}
    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;
    }
Beispiel #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_defaults3(&av_context,NULL);
    if (avcodec_open2(&av_context,codec,NULL)<0) {
        ms_error("jpeg2yuv: avcodec_open failed");
        return NULL;
    }
    av_init_packet(&pkt);
    pkt.data=jpgbuf;
    pkt.size=bufsize;

    memset(&orig, 0, sizeof(orig));
    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
}
bool
SourceSurfaceCG::InitFromData(unsigned char *aData,
                               const IntSize &aSize,
                               int32_t aStride,
                               SurfaceFormat aFormat)
{
  //XXX: we should avoid creating this colorspace everytime
  CGColorSpaceRef colorSpace = NULL;
  CGBitmapInfo bitinfo = 0;
  CGDataProviderRef dataProvider = NULL;
  int bitsPerComponent = 0;
  int bitsPerPixel = 0;

  switch (aFormat) {
    case B8G8R8A8:
      colorSpace = CGColorSpaceCreateDeviceRGB();
      bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
      bitsPerComponent = 8;
      bitsPerPixel = 32;
      break;

    case B8G8R8X8:
      colorSpace = CGColorSpaceCreateDeviceRGB();
      bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
      bitsPerComponent = 8;
      bitsPerPixel = 32;
      break;

    case A8:
      // XXX: why don't we set a colorspace here?
      bitsPerComponent = 8;
      bitsPerPixel = 8;
  };

  void *data = malloc(aStride * aSize.height);
  memcpy(aData, data, aStride * aSize.height);

  mFormat = aFormat;

  dataProvider = CGDataProviderCreateWithData (data,
                                               data,
					       aSize.height * aStride,
					       releaseCallback);

  if (aFormat == A8) {
    CGFloat decode[] = {1.0, 0.0};
    mImage = CGImageMaskCreate (aSize.width, aSize.height,
				bitsPerComponent,
				bitsPerPixel,
				aStride,
				dataProvider,
				decode,
				true);

  } else {
    mImage = CGImageCreate (aSize.width, aSize.height,
			    bitsPerComponent,
			    bitsPerPixel,
			    aStride,
			    colorSpace,
			    bitinfo,
			    dataProvider,
			    NULL,
			    true,
			    kCGRenderingIntentDefault);
  }

  CGDataProviderRelease(dataProvider);
  CGColorSpaceRelease (colorSpace);

  if (mImage) {
    return false;
  }

  return true;
}
CGColorSpaceRef colorSpaceFromPDFArray(CGPDFArrayRef colorSpaceArray){
	CGColorSpaceRef       cgColorSpace = NULL, alternateColorSpace = NULL;
	CGPDFStreamRef        stream;
	const char            *colorSpaceName = NULL, *alternateColorSpaceName = NULL;
	CGPDFInteger        numberOfComponents;
	CGPDFDictionaryRef    dict;
	bool                retrieved;
	CGFloat                *range;
	CGPDFArrayRef        rangeArray;
	
	if (CGPDFArrayGetName(colorSpaceArray, 0, &colorSpaceName)) {
		if (strcmp(colorSpaceName, "ICCBased") == 0) {
			if (CGPDFArrayGetStream(colorSpaceArray, 1, &stream)) {
				dict = CGPDFStreamGetDictionary(stream);
				
				// First obtain the alternate color space if present
				if (CGPDFDictionaryGetName(dict, "Alternate",  &alternateColorSpaceName)) {
					if (strcmp(alternateColorSpaceName, "DeviceRGB") == 0) {
						alternateColorSpace = CGColorSpaceCreateDeviceRGB();
					} else if (strcmp(alternateColorSpaceName, "DeviceGray") == 
							   0) {
						alternateColorSpace = CGColorSpaceCreateDeviceGray();
					} else if (strcmp(alternateColorSpaceName, "DeviceCMYK") == 
							   0) {
						alternateColorSpace = CGColorSpaceCreateDeviceCMYK();
					}
				}
				
				// Obtain the preferential color space
				CGPDFDataFormat        dataFormat;
				CFDataRef            colorSpaceDataPtr = 
				CGPDFStreamCopyData(stream, &dataFormat);
				
				if (dataFormat == CGPDFDataFormatRaw) {
					CGDataProviderRef    profile = 
					CGDataProviderCreateWithCFData(colorSpaceDataPtr);
					
					retrieved = CGPDFDictionaryGetInteger(dict, "N", 
														  &numberOfComponents);
					
					// Deduce an alternate color space if we don't have one 
					//already
					if (alternateColorSpace == NULL) {
						switch (numberOfComponents) {
							case 1:
								alternateColorSpace = CGColorSpaceCreateDeviceGray();
								break;
							case 3:
								alternateColorSpace = CGColorSpaceCreateDeviceRGB();
								break;
							case 4:
								alternateColorSpace = CGColorSpaceCreateDeviceCMYK();
								break;
							default:
								break;
						}
					}
					
					range = malloc(numberOfComponents * 2 * sizeof(CGFloat));
					if (!CGPDFDictionaryGetArray(dict, "Range", &rangeArray)) {
						int i = 0;
						for (; i < numberOfComponents * 2; i += 2) {
							range[i] = (i % 2 == 0) ? 0.0 : 1.0;
						}
					} else {
						size_t count = CGPDFArrayGetCount(rangeArray);
						int i = 0;
						for (; i < count; i++) {
							(void)CGPDFArrayGetNumber(rangeArray, i, &range[i]);
						}
						
					}
					
					
					cgColorSpace = CGColorSpaceCreateICCBased(numberOfComponents, range, profile, 
															  alternateColorSpace);
					CGDataProviderRelease(profile);
					free(range);
					if (cgColorSpace) {
						// Since we have a preferential color space, we no 
						//longer need the hang on to the alternate color space
						CGColorSpaceRelease(alternateColorSpace);
					} else {
						cgColorSpace = alternateColorSpace;
					}
					
				} else if (dataFormat == CGPDFDataFormatJPEGEncoded) {
					//
				} else if (dataFormat == CGPDFDataFormatJPEG2000) {
					//
				}
			}
		} else if (strcmp(colorSpaceName, "Indexed") == 0) {
			CGColorSpaceRef baseSpace;
			CGPDFArrayRef    base = NULL;
			CGPDFInteger    highValue = 0;
			CGPDFStreamRef    stream = NULL;
			CGPDFStringRef    string;
			const unsigned char *chars;
			const char        *namedColorSpaceName;
			
			if (CGPDFArrayGetArray(colorSpaceArray, 1, &base)) {
				baseSpace = colorSpaceFromPDFArray(base);
			} else if (CGPDFArrayGetName(colorSpaceArray, 1, 
										 &namedColorSpaceName)) {
				if (strcmp(namedColorSpaceName, "DeviceRGB") == 0) {
					baseSpace = CGColorSpaceCreateDeviceRGB();
				} else if (strcmp(namedColorSpaceName, "DeviceGray") == 0) {
					baseSpace = CGColorSpaceCreateDeviceGray();
				} else if (strcmp(namedColorSpaceName, "DeviceCMYK") == 0) {
					baseSpace = CGColorSpaceCreateDeviceCMYK();
				}
			}
			
			retrieved = CGPDFArrayGetInteger(colorSpaceArray, 2, &highValue);
			
			if (CGPDFArrayGetStream(colorSpaceArray, 3, &stream)) {
				chars = CFDataGetBytePtr(CGPDFStreamCopyData(stream, NULL));
			} else if (CGPDFArrayGetString(colorSpaceArray, 3, &string)) {
				chars = CGPDFStringGetBytePtr(string);
			} else {
				
				// TODO: Raise some error state?
			}
			
			cgColorSpace = CGColorSpaceCreateIndexed(baseSpace, highValue, 
													 chars);
		}
	}
	
	return (CGColorSpaceRef)CFMakeCollectable(cgColorSpace);
}
Beispiel #7
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
Beispiel #8
0
bool  ImageIOEncoder::write( const Mat& img, const vector<int>& params )
{
    int width = img.cols, height = img.rows;
    int _channels = img.channels();
    const uchar* data = img.data;
    int step = img.step;

    // Determine the appropriate UTI based on the filename extension
    CFStringRef imageUTI = FilenameToUTI( m_filename.c_str() );

    // Determine the Bytes Per Pixel
    int bpp = (_channels == 1) ? 1 : 4;

    // Write the data into a bitmap context
    CGContextRef context;
    CGColorSpaceRef colorSpace;
    uchar* bitmapData = NULL;

    if( bpp == 1 ) {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
        colorSpace = CGColorSpaceCreateDeviceGray();
#else
        colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericGray );
#endif
    }
    else if( bpp == 4 ) {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
        colorSpace = CGColorSpaceCreateDeviceRGB();
#else
        colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear );
#endif
    }
    if( !colorSpace )
        return false;

    bitmapData = (uchar*)malloc( bpp * height * width );
    if( !bitmapData )
    {
        CGColorSpaceRelease( colorSpace );
        return false;
    }

    context = CGBitmapContextCreate( bitmapData,
                                     width,
                                     height,
                                     8,
                                     bpp * width,
                                     colorSpace,
                                     (bpp == 1) ? kCGImageAlphaNone :
                                     kCGImageAlphaNoneSkipLast );
    CGColorSpaceRelease( colorSpace );
    if( !context )
    {
        free( bitmapData );
        return false;
    }

    // Copy pixel information from data into bitmapData
    if (bpp == 4)
    {
        int           bitmapIndex = 0;
        const uchar * base        = data;

        for (int y = 0; y < height; y++)
        {
            const uchar * line = base + y * step;

            for (int x = 0; x < width; x++)
            {
                // Blue channel
                bitmapData[bitmapIndex + 2] = line[0];
                // Green channel
                bitmapData[bitmapIndex + 1] = line[1];
                // Red channel
                bitmapData[bitmapIndex + 0] = line[2];

                line        += 3;
                bitmapIndex += bpp;
            }
        }
    }
    else if (bpp == 1)
    {
        for (int y = 0; y < height; y++)
            memcpy (bitmapData + y * width, data + y * step, width);
    }

    // Turn the bitmap context into an imageRef
    CGImageRef imageRef = CGBitmapContextCreateImage( context );
    CGContextRelease( context );
    if( !imageRef )
    {
        free( bitmapData );
        return false;
    }

    // Write the imageRef to a file based on the UTI
    CFURLRef imageURLRef = CFURLCreateFromFileSystemRepresentation( NULL,
        (const UInt8*)m_filename.c_str(), m_filename.size(), false );
    if( !imageURLRef )
    {
        CGImageRelease( imageRef );
        free( bitmapData );
        return false;
    }

    CGImageDestinationRef destRef = CGImageDestinationCreateWithURL( imageURLRef,
                                                                     imageUTI,
                                                                     1,
                                                                     NULL);
    CFRelease( imageURLRef );
    if( !destRef )
    {
        CGImageRelease( imageRef );
        free( bitmapData );
        fprintf(stderr, "!destRef\n");
        return false;
    }

    CGImageDestinationAddImage(destRef, imageRef, NULL);
    if( !CGImageDestinationFinalize(destRef) )
    {
        fprintf(stderr, "Finalize failed\n");
        return false;
    }

    CFRelease( destRef );
    CGImageRelease( imageRef );
    free( bitmapData );

    return true;
}
Beispiel #9
0
bool  ImageIODecoder::readData( Mat& img )
{
    uchar* data = img.data;
    int step = img.step;
    bool color = img.channels() > 1;
    int bpp; // Bytes per pixel
    int bit_depth = 8;

    // Get Height, Width, and color information
    if( !readHeader() )
        return false;

    CGContextRef     context = NULL; // The bitmap context
    CGColorSpaceRef  colorSpace = NULL;
    uchar*           bitmap = NULL;
    CGImageAlphaInfo alphaInfo;

    // CoreGraphics will take care of converting to grayscale and back as long as the
    // appropriate colorspace is set
    if( color == CV_LOAD_IMAGE_GRAYSCALE )
    {
        colorSpace = CGColorSpaceCreateDeviceGray();
        bpp = 1;
        alphaInfo = kCGImageAlphaNone;
    }
    else if( color == CV_LOAD_IMAGE_COLOR )
    {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
        colorSpace = CGColorSpaceCreateDeviceRGB();
#else
        colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear );
#endif
        bpp = 4; /* CG only has 8 and 32 bit color spaces, so we waste a byte */
        alphaInfo = kCGImageAlphaNoneSkipLast;
    }
    if( !colorSpace )
        return false;

    bitmap = (uchar*)malloc( bpp * m_height * m_width );
    if( !bitmap )
    {
        CGColorSpaceRelease( colorSpace );
        return false;
    }

    context = CGBitmapContextCreate( (void *)bitmap,
                                     m_width,        /* width */
                                     m_height,       /* height */
                                     bit_depth,    /* bit depth */
                                     bpp * m_width,  /* bytes per row */
                                     colorSpace,     /* color space */
                                     alphaInfo);

    CGColorSpaceRelease( colorSpace );
    if( !context )
    {
        free( bitmap );
        return false;
    }

    // Copy the image data into the bitmap region
    CGRect rect = {{0,0},{m_width,m_height}};
    CGContextDrawImage( context, rect, imageRef );

    uchar* bitdata = (uchar*)CGBitmapContextGetData( context );
    if( !bitdata )
    {
        free( bitmap);
        CGContextRelease( context );
        return false;
    }

    // Move the bitmap (in RGB) into data (in BGR)
    int bitmapIndex = 0;

    if( color == CV_LOAD_IMAGE_COLOR )
    {
        uchar * base = data;

        for (int y = 0; y < m_height; y++)
        {
            uchar * line = base + y * step;

            for (int x = 0; x < m_width; x++)
            {
                // Blue channel
                line[0] = bitdata[bitmapIndex + 2];
                // Green channel
                line[1] = bitdata[bitmapIndex + 1];
                // Red channel
                line[2] = bitdata[bitmapIndex + 0];

                line        += 3;
                bitmapIndex += bpp;
            }
        }
    }
    else if( color == CV_LOAD_IMAGE_GRAYSCALE )
    {
        for (int y = 0; y < m_height; y++)
            memcpy (data + y * step, bitmap + y * m_width, m_width);
    }

    free( bitmap );
    CGContextRelease( context );
    return true;
}
Beispiel #10
0
// -----------------------------------------------------------------------------
//	CreateCGImageWithQTFromFile
// -----------------------------------------------------------------------------
//
OSStatus
CreateCGImageWithQTFromFile(
	FSRef*						inFSRef,
	CGImageRef*					outImage )
{
	OSStatus					err;
	GraphicsImportComponent		importer;
	FSSpec						fileSpec;
	GWorldPtr					gWorld = NULL;
	Rect						bounds;
	CGDataProviderRef			provider;
	CGColorSpaceRef				colorspace;
	long						width;
	long						height;
	long						rowbytes;
	Ptr							dataPtr;

	// Make an FSRef into an FSSpec
	err = FSGetCatalogInfo( inFSRef, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL );
	require_noerr( err, CantMakeFSSpec );

	err = GetGraphicsImporterForFile( &fileSpec, &importer );
	require_noerr( err, CantGetImporter );
	
	err = GraphicsImportGetNaturalBounds( importer, &bounds );
	require_noerr( err, CantGetBounds );

	// Allocate the buffer
	width = RECT_WIDTH( bounds );
	height = RECT_HEIGHT( bounds );
	rowbytes = width * 4;
	dataPtr = NewPtr( height * rowbytes );
	require_action( dataPtr != NULL, CantAllocBuffer, err = memFullErr );
	
	err = NewGWorldFromPtr( &gWorld, 32, &bounds, NULL, NULL, NULL, dataPtr, rowbytes );
	require_noerr( err, CantCreateGWorld );

	err = GraphicsImportSetGWorld( importer, gWorld, GetGWorldDevice( gWorld) );
	require_noerr( err, CantSetGWorld );

	err = GraphicsImportDraw( importer );
	require_noerr( err, CantDraw );
	
	provider = CGDataProviderCreateWithData( NULL, dataPtr, height * rowbytes,
			GWorldImageBufferRelease );
	require_action( provider != NULL, CantCreateProvider, err = memFullErr );

	colorspace = CGColorSpaceCreateDeviceRGB();
	require_action( colorspace != NULL, CantCreateColorSpace, err = memFullErr );
	
	*outImage = CGImageCreate( width, height, 8, 32, rowbytes, colorspace,
			kCGImageAlphaPremultipliedFirst, provider, NULL, false, kCGRenderingIntentDefault );
	require_action( *outImage != NULL, CantCreateImage, err = memFullErr );
	
CantCreateImage:
	CGColorSpaceRelease( colorspace );

CantCreateColorSpace:
	CGDataProviderRelease( provider );

CantCreateProvider:
CantDraw:
CantSetGWorld:
	if ( gWorld != NULL )
		DisposeGWorld( gWorld );

CantCreateGWorld:
CantAllocBuffer:
CantGetBounds:
CantGetImporter:
CantMakeFSSpec:
	return err;
}
PsychError SCREENTestTexture(void) 
{
#if PSYCH_SYSTEM == PSYCH_OSX

    PsychWindowRecordType 	*winRec;
    CGContextRef			cgContext;
    unsigned int			memoryTotalSizeBytes, memoryRowSizeBytes;
    UInt32					*textureMemory;
    int						stringLength, totalTexels, i;
    GLuint					myTexture;
    CGColorSpaceRef			cgColorSpace;
    
    			
    //all subfunctions should have these two lines.  
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    
    //Get the window structure for the onscreen window.  It holds the onscreein GL context which we will need in the
    //final step when we copy the texture from system RAM onto the screen.
    PsychErrorExit(PsychCapNumInputArgs(1));   	
    PsychErrorExit(PsychRequireNumInputArgs(1)); 	
    PsychErrorExit(PsychCapNumOutputArgs(1));  
    PsychAllocInWindowRecordArg(1, TRUE, &winRec);
    if(!PsychIsOnscreenWindow(winRec))
        PsychErrorExitMsg(PsychError_user, "Onscreen window pointer required");
        
    //allocate memory for the surface
    memoryRowSizeBytes=sizeof(UInt32) * textureSizeX;
    memoryTotalSizeBytes= memoryRowSizeBytes * textureSizeY;
    textureMemory=(UInt32 *)malloc(memoryTotalSizeBytes);
    if(!textureMemory)
            PsychErrorExitMsg(PsychError_internal, "Failed to allocate surface memory\n");
    
    if(useQuartz){
        //Create the Core Graphics bitmap graphics context.  We have to be careful to specify arguments which will allow us to store the texture as an OpenGL texture. 
        //The choice of color space needs to be checked.  
        cgColorSpace=CGColorSpaceCreateDeviceRGB();
        cgContext= CGBitmapContextCreate(textureMemory, textureSizeX, textureSizeY, cg_RGBA_32_BitsPerComponent, memoryRowSizeBytes, cgColorSpace, cg_RGBA_32_AlphaOption);
        if(!cgContext){
            free((void *)textureMemory);
            PsychErrorExitMsg(PsychError_internal, "Failed to allocate CG Bimap Context\n");
        }
            
        //	Draw some text into the bitmap context.  We need to set font, size, pen (drawing mode), color, alpha, text position.
        
        //	There are two ways to select the font in a Core Graphics Quartz context depending on the type of font.
        //	1) CGContextSetFont() for Apple Type Services (ATS) font aka "The Right Way"
        //		A) call CGFontCreateWithPlatformFont() which returns a CGFontRef
        //		B) call CGContextSetFont() to set the font to be the drawing font within a context.
        //  2) CGContextSelectFont() for MacRoman aka "How We Do It"
        //
        //  Using MacRoman seems to mean that we just change the coding, though CGContextSelectFont().  For info on using ATS fonts see:
        // 	http://developer.apple.com/documentation/Carbon/Reference/ATS/
        CGContextSelectFont(cgContext, "Helvetica", (float)24, kCGEncodingMacRoman);		//set the font and its size.
        CGContextSetTextDrawingMode(cgContext, kCGTextFill);					//set the pen to be a filled pen
        CGContextSetRGBStrokeColor(cgContext, (float)0.5, (float)0.5, (float)0.0, (float)1.0);	//set the stroke color and alpha
        CGContextSetRGBFillColor(cgContext, (float)0.5, (float)0.5, (float)0.0, (float)1.0);	//set the fill color and alpha
        stringLength=strlen(textString);
        CGContextShowTextAtPoint(cgContext, (float)textPositionX, (float)textPositionY, textString, stringLength);	//draw at specified location.
        CGContextFlush(cgContext); 	//this might not be necessary but do it just in case.
    }else{
        //fill the texture memory by poking bits in the array which will be turned into a texture.
        totalTexels=textureSizeX * textureSizeY;
        for(i=0;i<totalTexels;i++)
            textureMemory[i]=	redFill << 24 | greenFill | 16 << blueFill << 8 | alphaFill;
     }       

    //Convert the CG graphics bitmap (Quartz surface) into a CG texture.  GL thinks we are loading the texture from memory we indicate to glTexImage2D, but really
    //we are just setting the texture to share the same memory as the Quartz surface.
    PsychSetGLContext(winRec); 
    glEnable(GL_TEXTURE_RECTANGLE_EXT);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glGenTextures(1, &myTexture);						//create an index "name" for our texture
    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, myTexture);			//instantiate a texture of type associated with the index and set it to be the target for subsequent gl texture operators.
    glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);			//tell gl how to unpack from our memory when creating a surface, namely don't really unpack it but use it for texture storage.
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	//specify interpolation scaling rule for copying from texture.  
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  //specify interpolation scaling rule from copying from texture.
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,  textureSizeX, textureSizeY, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, textureMemory);
    
    //Copy the texture to the display.  What are the s and  t indices  of the first pixel of the texture ? 0 or 1 ?
    //set the GL context to be the onscreen window
    glBegin(GL_QUADS);
        glTexCoord2d(0.0, 0.0);					glVertex2d(0.0, 0.0);
        glTexCoord2d(textureSizeX, 0.0 );			glVertex2d(textureSizeX, 0.0);
        glTexCoord2d(textureSizeX, textureSizeY);		glVertex2d(textureSizeX, textureSizeY);
        glTexCoord2d(0.0, textureSizeY);			glVertex2d(0.0, textureSizeY);
    glEnd();
    glFlush();	
    glDisable(GL_TEXTURE_RECTANGLE_EXT);

    //Close  up shop.  Unlike with normal textures is important to release the context before deallocating the memory which glTexImage2D() was given. 
    //First release the GL context, then the CG context, then free the memory.
    glDeleteTextures(1, &myTexture);	//Remove references from gl to the texture memory  & free gl's associated resources   
    if(useQuartz) CGContextRelease(cgContext);	//Remove references from Core Graphics to the texture memory & free Core Graphics' associated resources.
    free((void *)textureMemory);	//Free the memory
#endif
    return(PsychError_none);

}
        Q_UNUSED(aglPixelFormat);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
        GLint attributeCount = 2;
#else
        long attributeCount = 2;
#endif
        CGLPixelFormatAttribute pfa[attributeCount];
        pfa[0] = kCGLPFAWindow;
        pfa[1] = (CGLPixelFormatAttribute) 0;
        err = CGLChoosePixelFormat(pfa, &cglPixelFormat, &attributeCount);
        BACKEND_ASSERT3(err == noErr, "Could not create pixel format (OpenGL)", FATAL_ERROR, false)
    }

    CFTypeRef keys[] = { kQTVisualContextWorkingColorSpaceKey };
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CFDictionaryRef textureContextAttributes = CFDictionaryCreate(kCFAllocatorDefault,
        (const void **)keys,
        (const void **)&colorSpace, 1,
        &kCFTypeDictionaryKeyCallBacks,
        &kCFTypeDictionaryValueCallBacks);
        
	err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, cglContext,
        cglPixelFormat, textureContextAttributes, &m_visualContext);
    CFRelease(textureContextAttributes);
    BACKEND_ASSERT3(err == noErr, "Could not create visual context (OpenGL)", FATAL_ERROR, false)

    if (m_movieRef && m_visualContext)
        SetMovieVisualContext(m_movieRef, m_visualContext);
    return true;    
}
/* Create a CGImageRef from osg::Image.
 * Code adapted from
 * http://developer.apple.com/samplecode/OpenGLScreenSnapshot/listing2.html
 */
CGImageRef CreateCGImageFromOSGData(const osg::Image &osg_image)
{
    size_t image_width  = osg_image.s();
    size_t image_height = osg_image.t();
    /* From Apple's header for CGBitmapContextCreate()
     * Each row of the bitmap consists of `bytesPerRow' bytes, which must be at
     * least `(width * bitsPerComponent * number of components + 7)/8' bytes.
     */
    size_t target_bytes_per_row;

    CGColorSpaceRef color_space;
    CGBitmapInfo    bitmap_info;
    /* From what I can figure out so far...
     * We need to create a CGContext connected to the data we want to save
     * and then call CGBitmapContextCreateImage() on that context to get
     * a CGImageRef.
     * However, OS X only allows 4-component image formats (e.g. RGBA) and not
     * just RGB for the RGB-based CGContext. So for a 24-bit image coming in,
     * we need to expand the data to 32-bit.
     * The easiest and fastest way to do that is through the vImage framework
     * which is part of the Accelerate framework.
     * Also, the osg::Image data coming in is inverted from what we want, so
     * we need to invert the image too. Since the osg::Image is const,
     * we don't want to touch the data, so again we turn to the vImage framework
     * and invert the data.
     */
    vImage_Buffer vimage_buffer_in =
    {
        (void*)osg_image.data(), // need to override const, but we don't modify the data so it's safe
        image_height,
        image_width,
        osg_image.getRowSizeInBytes()
    };

    void          *out_image_data;
    vImage_Buffer vimage_buffer_out =
    {
        NULL, // will fill-in in switch
        image_height,
        image_width,
        0 // will fill-in in switch
    };
    vImage_Error vimage_error_flag;

    // FIXME: Do I want to use format, type, or internalFormat?
    switch (osg_image.getPixelFormat())
    {
    case GL_LUMINANCE:
    {
        bitmap_info          = kCGImageAlphaNone;
        target_bytes_per_row = (image_width * 8 + 7) / 8;
        // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
        color_space = CGColorSpaceCreateDeviceGray();
        if (NULL == color_space)
        {
            return NULL;
        }

        //    out_image_data = calloc(target_bytes_per_row, image_height);
        out_image_data = malloc(target_bytes_per_row * image_height);
        if (NULL == out_image_data)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl;
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        vimage_buffer_out.data     = out_image_data;
        vimage_buffer_out.rowBytes = target_bytes_per_row;

        // Now invert the image
        vimage_error_flag = vImageVerticalReflect_Planar8(
            &vimage_buffer_in,     // since the osg_image is const...
            &vimage_buffer_out,     // don't reuse the buffer
            kvImageNoFlags
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData for GL_LUMINANCE, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            CGColorSpaceRelease(color_space);
            return NULL;
        }


        break;
    }

    case GL_ALPHA:
    {
        bitmap_info          = kCGImageAlphaOnly;
        target_bytes_per_row = (image_width * 8 + 7) / 8;
        // According to:
        // http://developer.apple.com/qa/qa2001/qa1037.html
        // colorSpace=NULL is for alpha only
        color_space = NULL;

        //    out_image_data = calloc(target_bytes_per_row, image_height);
        out_image_data = malloc(target_bytes_per_row * image_height);
        if (NULL == out_image_data)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl;
            return NULL;
        }

        vimage_buffer_out.data     = out_image_data;
        vimage_buffer_out.rowBytes = target_bytes_per_row;

        // Now invert the image
        vimage_error_flag = vImageVerticalReflect_Planar8(
            &vimage_buffer_in,     // since the osg_image is const...
            &vimage_buffer_out,     // don't reuse the buffer
            kvImageNoFlags
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData for GL_ALPHA, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            return NULL;
        }


        break;
    }

/*
        case GL_LUMINANCE_ALPHA:
        {
            // I don't know if we can support this.
            // The qa1037 doesn't show both gray+alpha.
            break;
        }
 */
    case GL_RGB:
    {
        bitmap_info          = kCGImageAlphaNoneSkipFirst;
        target_bytes_per_row = (image_width * 8 * 4 + 7) / 8;
        // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        color_space = CGColorSpaceCreateDeviceRGB();
        if (NULL == color_space)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl;
            return NULL;
        }

        //    out_image_data = calloc(target_bytes_per_row, image_height);
        out_image_data = malloc(target_bytes_per_row * image_height);
        if (NULL == out_image_data)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl;
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        // Use vImage to get an RGB buffer into ARGB.
        vimage_buffer_out.data     = out_image_data;
        vimage_buffer_out.rowBytes = target_bytes_per_row;
        vimage_error_flag          = vImageConvert_RGB888toARGB8888(
            &vimage_buffer_in,
            NULL,     // we don't have a buffer containing alpha values
            255,     // The alpha value we want given to all pixels since we don't have a buffer
            &vimage_buffer_out,
            0,     // premultiply?
            kvImageNoFlags     // Only responds to kvImageDoNotTile, but I think we want tiling/threading
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, vImageConvert_RGB888toARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        // Now invert the image
        vimage_error_flag = vImageVerticalReflect_ARGB8888(
            &vimage_buffer_out,
            &vimage_buffer_out,     // reuse the same buffer
            kvImageNoFlags
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        break;
    }

    case GL_RGBA:
    {
        bitmap_info          = kCGImageAlphaPremultipliedLast;
        target_bytes_per_row = osg_image.getRowSizeInBytes();
        // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        color_space = CGColorSpaceCreateDeviceRGB();
        if (NULL == color_space)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl;
            return NULL;
        }

        //    out_image_data = calloc(target_bytes_per_row, image_height);
        out_image_data = malloc(target_bytes_per_row * image_height);
        if (NULL == out_image_data)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl;
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        vimage_buffer_out.data     = out_image_data;
        vimage_buffer_out.rowBytes = target_bytes_per_row;
        // Invert the image
        vimage_error_flag = vImageVerticalReflect_ARGB8888(
            &vimage_buffer_in,     // since the osg_image is const...
            &vimage_buffer_out,     // don't reuse the buffer
            kvImageNoFlags
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        break;
    }

    case GL_BGRA:
    {
        if (GL_UNSIGNED_INT_8_8_8_8_REV == osg_image.getDataType())
        {
#if __BIG_ENDIAN__
            bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big;     /* XRGB Big Endian */
#else
            bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;     /* XRGB Little Endian */
#endif
        }
        else
        {
            // FIXME: Don't know how to handle this case
            bitmap_info = kCGImageAlphaPremultipliedLast;
        }

        target_bytes_per_row = osg_image.getRowSizeInBytes();
        // color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        color_space = CGColorSpaceCreateDeviceRGB();
        if (NULL == color_space)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl;
            return NULL;
        }

        //    out_image_data = calloc(target_bytes_per_row, image_height);
        out_image_data = malloc(target_bytes_per_row * image_height);
        if (NULL == out_image_data)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl;
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        vimage_buffer_out.data     = out_image_data;
        vimage_buffer_out.rowBytes = target_bytes_per_row;
        // Invert the image
        vimage_error_flag = vImageVerticalReflect_ARGB8888(
            &vimage_buffer_in,                                                    // since the osg_image is const...
            &vimage_buffer_out,                                                    // don't reuse the buffer
            kvImageNoFlags
            );
        if (vimage_error_flag != kvImageNoError)
        {
            OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl;
            free(out_image_data);
            CGColorSpaceRelease(color_space);
            return NULL;
        }

        break;
    }

    // FIXME: Handle other cases.
    // Use vImagePermuteChannels_ARGB8888 to swizzle bytes
    default:
    {
        OSG_WARN << "In CreateCGImageFromOSGData: Sorry support for this format is not implemented." << std::endl;
        return NULL;
        break;
    }
    }

    CGContextRef bitmap_context = CGBitmapContextCreate(
        vimage_buffer_out.data,
        vimage_buffer_out.width,
        vimage_buffer_out.height,
        8,
        vimage_buffer_out.rowBytes,
        color_space,
        bitmap_info
        );
    /* Done with color space */
    CGColorSpaceRelease(color_space);

    if (NULL == bitmap_context)
    {
        free(out_image_data);
        return NULL;
    }


    /* Make an image out of our bitmap; does a cheap vm_copy of the bitmap */
    CGImageRef image_ref = CGBitmapContextCreateImage(bitmap_context);

    /* Done with data */
    free(out_image_data);

    /* Done with bitmap_context */
    CGContextRelease(bitmap_context);

    return image_ref;
}
static bool image_coregraphics_load (fs_file_t *f, image_t *im, int *error) {
  CGDataProviderRef provider = fs_data_provider_of_file(f);
  CGColorSpaceRef color_space = NULL;
  CGContextRef context = NULL;
  CGImageRef image = NULL;
  void *data = NULL;
  bool ok = false;

  for (unsigned i = 0; i < G_N_ELEMENTS(providers); i++) {
    if ((image = providers[i](provider, NULL, true, kCGRenderingIntentDefault))) {
      break;
    }
  }

  if (!image) {
    *error = IMAGE_ERROR_INVALID_FORMAT;
    goto error;
  }

  int width = CGImageGetWidth(image);
  int height = CGImageGetHeight(image);

  if (!image_dimensions_valid(width, header)) {
    *error = IMAGE_ERROR_INVALID_SIZE;
    goto error;
  }

  if (!(data = mem_alloc(image_mem_pool, width * height * 4))) {
    *error = IMAGE_ERROR_ALLOC_FAILED;
    goto error;
  }

  if (!(color_space = CGColorSpaceCreateDeviceRGB())) {
    *error = IMAGE_ERROR_INTERNAL;
    goto error;
  }

  context = CGBitmapContextCreate(data, width, height, 8, width * 4, color_space, kCGImageAlphaPremultipliedLast);

  if (!context) {
    *error = IMAGE_ERROR_INTERNAL;
    goto error;
  }

  CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);

  im->width = width;
  im->height = height;
  im->format = IMAGE_DATA_FORMAT_BGRA;
  im->data = data;

  // convert to bgra
  for (int i = 0; i < width * height; i++) {
    uint8_t r = im->data[(i << 2) + 0];
    im->data[(i << 2) + 0] = im->data[(i << 2) + 2];
    im->data[(i << 2) + 2] = r;
  }

  ok = true;

error:
  CGContextRelease(context);
  CGColorSpaceRelease(color_space);
  CGImageRelease(image);
  fs_data_provider_release(provider);

  if (!ok) {
    mem_free(data);
  }

  return ok;
}
void JBGSetUpJumballGraphics()
{
    CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
    
    // 白色
    CGFloat white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
    kJBGWhite = CGColorCreate(color_space, white);
    
    // 浅蓝 204 224 244
    CGFloat light_blue[4] = {204/255.0f, 224/255.0f, 244/255.0f, 1.0f};
    kJBGLightBlue = CGColorCreate(color_space, light_blue);
    
    // 蓝 29 156 215
    CGFloat blue[4] = {29/255.0f, 156/255.0f, 215/255.0f, 1.0f};
    kJBGBlue = CGColorCreate(color_space, blue);
    
    // 深蓝 0 50 126
    CGFloat dark_blue[4] = {0, 50/255.0f, 126/255.0f, 1.0f};
    kJBGDarkBlue = CGColorCreate(color_space, dark_blue);
    
    // 深红 Firebrick3 205 38 38
    CGFloat dark_red[4] = {205/255.0f, 38/255.0f, 38/255.0f, 1.0f};
    kJBGDarkRed = CGColorCreate(color_space, dark_red);
    
    // 红 Firebrick2 238 44 44
    CGFloat red[4] = {238/255.0f, 44/255.0f, 44/255.0f, 1.0f};
    kJBGRed = CGColorCreate(color_space, red);
    
    // 深金 DarkGoldenrod3 205 149 12
    CGFloat dark_gold[4] = {205/255.0f, 149/255.0f, 12/255.0f, 1.0f};
    kJBGDarkGold = CGColorCreate(color_space, dark_gold);
    
    // 金 DarkGoldenrod2	238 173 14 (原来选的是255 215 0)
    CGFloat gold[4] = {238/255.0f, 173.0f/255.0f, 14/255.0f, 1.0f};
    kJBGGold = CGColorCreate(color_space, gold);
    
    // 深绿 SpringGreen3 0 205 102
    CGFloat dark_green[4] = {0, 205/255.0f, 102/255.0f, 1.0f};
    kJBGDarkGreen = CGColorCreate(color_space, dark_green);
    
    // 绿 SpringGreen2 0 238 118
    CGFloat green[4] = {0, 238/255.0f, 118/255.0f, 1.0f};
    kJBGGreen = CGColorCreate(color_space, green);
    
    // 深紫  Purple3 125 38 205
    CGFloat dark_purple[4] = {125/255.0f, 38/255.0f, 205/255.0f, 1.0f};
    kJBGDarkPurple = CGColorCreate(color_space, dark_purple);
    
    // 紫 Purple2 145 44 238
    CGFloat purple[4] = {145/255.0f, 44/255.0f, 238/255.0f, 1.0f};
    kJBGPurple = CGColorCreate(color_space, purple);
    
    // 深粉红 Magenta3	205 0 205
    CGFloat dark_pink[4] = {205/255.0f, 0/255.0f, 205/255.0f, 1.0f};
    kJBGDarkPink = CGColorCreate(color_space, dark_pink);
    
    // 粉红 Magenta2	238 0 238
    CGFloat pink[4] = {238/255.0f, 0/255.0f, 238/255.0f, 1.0f};
    kJBGPink = CGColorCreate(color_space, pink);
    
    // 深黄 Yellow3	205 205 0
    CGFloat dark_yellow[4] = {205, 205/255.0f, 0/255.0f, 1.0f};
    kJBGDarkYellow = CGColorCreate(color_space, dark_yellow);
    
    // 黄 Yellow2	238 238 0
    CGFloat yellow[4] = {238, 238/255.0f, 0/255.0f, 1.0f};
    kJBGYellow = CGColorCreate(color_space, yellow);
    
    CGColorSpaceRelease(color_space);
}
Beispiel #16
0
void drawGraphic( CGContextRef context, float x, float y )
{
    static GWorldPtr imageGW = NULL;
    static CGImageRef imageRef = NULL;
    static CGDataProviderRef dataProviderRef = NULL;

    Rect bounds;
    static size_t width;
    static size_t height;
    size_t bitsPerComponent;
    size_t bitsPerPixel;
    size_t bytesPerRow;
    PixMapHandle pmh;    
    
    //	Load the image if we haven't already
    if ( NULL == imageGW )
    {
        //	Load and create the GWorld
        imageGW = OpenImage();
        
        if ( imageGW != NULL )
        {
            
            GetPortBounds( imageGW, &bounds );
            width = bounds.right - bounds.left;
            height = bounds.bottom - bounds.top;
            
            pmh = GetPortPixMap( imageGW );
            bitsPerComponent = (**pmh).cmpSize;
            bitsPerPixel = (**pmh).pixelSize;
            bytesPerRow = GetPixRowBytes( pmh );
            
            LockPixels( pmh );
            
            dataProviderRef = CGDataProviderCreateWithData( NULL, GetPixBaseAddr( pmh ), height * bytesPerRow, releaseData );
            
            
            //	Create the imageRef for that GWorld
            imageRef = CGImageCreate( width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedFirst/*kCGImageAlphaNone*/, dataProviderRef, NULL, 0, kCGRenderingIntentDefault );
        }
    }
    
    
    //	Draw the image at 0,0
    CGContextDrawImage( context, CGRectMake( x - 20, y, 40, 40 * height / width ), imageRef );
    
}
Beispiel #17
0
QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
{
    const glyph_metrics_t br = boundingBox(glyph);
    QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
    im.fill(0);

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    uint cgflags = kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
    if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
        cgflags |= kCGBitmapByteOrder32Host;
#endif
#else
    CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
#endif
    CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
                                             8, im.bytesPerLine(), colorspace,
                                             cgflags);
    CGColorSpaceRelease(colorspace);
    CGContextSetFontSize(ctx, fontDef.pixelSize);
    CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
    CGAffineTransformConcat(cgMatrix, oldTextMatrix);

    if (synthesisFlags & QFontEngine::SynthesizedItalic)
        cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));

    cgMatrix = CGAffineTransformConcat(cgMatrix, multiEngine->transform);

    CGContextSetTextMatrix(ctx, cgMatrix);
    CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
    CGContextSetTextDrawingMode(ctx, kCGTextFill);
    CGContextSetFont(ctx, cgFont);

    qreal pos_x = -br.x.toReal()+1, pos_y = im.height()+br.y.toReal();
    CGContextSetTextPosition(ctx, pos_x, pos_y);

    CGSize advance;
    advance.width = 0;
    advance.height = 0;
    CGGlyph cgGlyph = glyph;
    CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);

    if (synthesisFlags & QFontEngine::SynthesizedBold) {
        CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
        CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
    }

    CGContextRelease(ctx);

    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
    QVector<QRgb> colors(256);
    for (int i=0; i<256; ++i)
        colors[i] = qRgba(0, 0, 0, i);
    indexed.setColorTable(colors);

    for (int y=0; y<im.height(); ++y) {
        uint *src = (uint*) im.scanLine(y);
        uchar *dst = indexed.scanLine(y);
        for (int x=0; x<im.width(); ++x) {
            *dst = qGray(*src);
            ++dst;
            ++src;
        }
    }

    return indexed;
}
Beispiel #18
0
BOOL MacWidgetPainter::DrawProgressbar(const OpRect &drawrect, double percent, INT32 progress_when_total_unknown, OpWidgetString* string, const char *skin_empty, const char *skin_full)
{
	const char *full_skin  = skin_full && *skin_full ? skin_full : "Progress Full Skin";

	OpSkinElement *border_skin = g_skin_manager->GetSkinElement(full_skin);
	if(!g_skin_manager->GetCurrentSkin() || !border_skin || !border_skin->IsNative())
	{
		return IndpWidgetPainter::DrawProgressbar(drawrect, percent, progress_when_total_unknown, string, skin_empty, skin_full);
	}

	UINT32 full_color = g_op_ui_info->GetUICSSColor(CSS_VALUE_HighlightText);

	g_skin_manager->GetTextColor(full_skin, &full_color);
		
	CGRect r = {{0, 0}, {drawrect.width, drawrect.height}};
	
	CGContextRef context;
	OpBitmap* bitmap = NULL;

	int bmpwidth = drawrect.width;
	int bmpheight = drawrect.height;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
	const PixelScaler& scaler = vd->GetVPScale();
	bmpwidth = TO_DEVICE_PIXEL(scaler, bmpwidth);
	bmpheight = TO_DEVICE_PIXEL(scaler, bmpheight);
#endif // PIXEL_SCALE_RENDERING_SUPPORT

	if(OpStatus::IsSuccess(OpBitmap::Create(&bitmap, bmpwidth, bmpheight, FALSE, TRUE, 0, 0, TRUE)))
	{
		int w = bitmap->Width();
		int h = bitmap->Height();
		int bpl = bitmap->GetBytesPerLine();
		void *image_data = bitmap->GetPointer(OpBitmap::ACCESS_WRITEONLY);
		if (!image_data)
		{
			delete bitmap;
			return FALSE;
		}
		memset(image_data, 0, bpl*h);
		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
		CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal;
		context = CGBitmapContextCreate(image_data, w, h, 8, bpl, colorSpace, alpha);
		CGColorSpaceRelease(colorSpace);
		int win_height = drawrect.height;

		float scale = 1.0f;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
		scale = TO_DEVICE_PIXEL(scaler, scale);
#endif // PIXEL_SCALE_RENDERING_SUPPORT
		CGContextScaleCTM(context, scale, -scale);
		CGContextTranslateCTM(context, 0.0, -win_height);

		if (percent == 0 && progress_when_total_unknown)
		{
			HIThemeTrackDrawInfo drawInfo;
			
			SInt32 thickness = 0;
			SInt32 shadow = 0;
			if	(noErr == GetThemeMetric(kThemeMetricLargeProgressBarThickness, &thickness) &&
				(noErr == GetThemeMetric(kThemeMetricProgressBarShadowOutset, &shadow)))
			{
				SInt32 progressHeight = thickness + shadow;
				
				if((r.size.height) > progressHeight)
				{
					float f = (r.size.height - progressHeight); // / 2;
					r.origin.y += f;
					r.size.height -= f;
				}
			}
			else
			{
				float f = (r.size.height / 4) - 1;
				r.origin.y += f;
				r.size.height -= f;
			}

			drawInfo.version = 0;
			drawInfo.kind = kThemeIndeterminateBarLarge;
			drawInfo.bounds = r;
			drawInfo.min = 0;
			drawInfo.max = 100;
			drawInfo.value = 0;
			drawInfo.attributes = kThemeTrackHorizontal;
			drawInfo.enableState = widget->IsEnabled() ? kThemeTrackActive : kThemeTrackInactive;
			drawInfo.trackInfo.progress.phase = progress_when_total_unknown;
			
			HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal);		
		}
		else
		{
			HIThemeTrackDrawInfo drawInfo;
			
			SInt32 thickness = 0;
			SInt32 shadow = 0;
			if	(noErr == GetThemeMetric(kThemeMetricLargeProgressBarThickness, &thickness) &&
				(noErr == GetThemeMetric(kThemeMetricProgressBarShadowOutset, &shadow)))
			{
				SInt32 progressHeight = thickness + shadow;
				
				if((r.size.height) > progressHeight)
				{
					float f = (r.size.height - progressHeight); // / 2;
					r.origin.y += f;
					r.size.height -= f;
				}
			}
			else
			{
				float f = (r.size.height / 4) - 1;
				r.origin.y += f;
				r.size.height -= f;
			}

			drawInfo.version = 0;
			drawInfo.kind = kThemeProgressBarLarge;
			drawInfo.bounds = r;
			drawInfo.min = 0;
			drawInfo.max = 100;
			drawInfo.value = (SInt32)(percent);
			drawInfo.attributes = kThemeTrackHorizontal;
			drawInfo.enableState = widget->IsEnabled() ? kThemeTrackActive : kThemeTrackInactive;
			drawInfo.trackInfo.progress.phase = floorf(GetCurrentEventTime()*16);
			
			HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal);
		}
		
		CGContextRelease(context);
		bitmap->ReleasePointer();
		vd->BitmapOut(bitmap, OpRect(0, 0, bitmap->Width(), bitmap->Height()), drawrect);
		delete bitmap;
	}
	
	if (string)
	{
		widget->SetClipRect(drawrect);
		OpRect textRect = drawrect;
		textRect.y -= 1;
		string->Draw(textRect, vd, full_color);
		widget->RemoveClipRect();
	}
	
	return TRUE;
}
void myOperator_Do(CGPDFScannerRef s, void *info)
{
    // Check to see if this is an image or not.
    const char *name;
    CGPDFObjectRef xobject;
    CGPDFDictionaryRef dict;
    CGPDFStreamRef stream;
    CGPDFContentStreamRef cs = CGPDFScannerGetContentStream(s);
    
    // The Do operator takes a name. Pop the name off the
    // stack. If this fails then the argument to the 
    // Do operator is not a name and is therefore invalid!
    if(!CGPDFScannerPopName(s, &name)){
		fprintf(stderr, "Couldn't pop name off stack!\n"); 
		return;
    }
    // Get the resource with type "XObject" and the name
    // obtained from the stack.
    xobject = CGPDFContentStreamGetResource(cs, "XObject", name);
    if(!xobject){
		fprintf(stderr, "Couldn't get XObject with name %s\n", name);
		return;
    }

    // An XObject must be a stream so obtain the value from the xobject
    // as if it were a stream. If this fails, the PDF is malformed.
    if (!CGPDFObjectGetValue(xobject, kCGPDFObjectTypeStream, &stream)){
		fprintf(stderr, "XObject '%s' is not a stream!\n", name);
		return;
    }
    // Streams consist of a dictionary and the data associated
    // with the stream. This code only cares about the dictionary.
    dict = CGPDFStreamGetDictionary(stream);
    if(!dict){
		fprintf(stderr, 
			"Couldn't obtain dictionary from stream %s!\n", name);
		return;
    }
    // An XObject dict has a Subtype that indicates what kind it is.
    if(!CGPDFDictionaryGetName(dict, "Subtype", &name)){
		fprintf(stderr, "Couldn't get SubType of dictionary object!\n");
		return;
    }
	
	
    // This code is interested in the "Image" Subtype of an XObject.
    // Check whether this object has Subtype of "Image".
	printf("%s\n",name);
    if(strcmp(name, "Image") != 0){
		// The Subtype is not "Image" so this must be a form 
		// or other type of XObject.
		return;
    } else {
		CGPDFArrayRef colorSpaceArray;
		CGPDFDictionaryGetArray(dict,"ColorSpace" ,&colorSpaceArray);
		CGColorSpaceRef colorSpace=NULL;
		colorSpace=colorSpaceFromPDFArray(colorSpaceArray);
		
		CGPDFDataFormat format;
		const char *name = NULL, *colorSpaceName = NULL,*renderingIntentName = NULL;;
		CFDataRef data=CGPDFStreamCopyData(stream,&format);
		if (format == CGPDFDataFormatRaw){
			CGColorSpaceRef cgColorSpace;
			CGPDFInteger width, height, bps, spp;
			CGColorRenderingIntent renderingIntent;
			CGPDFBoolean interpolation = 0;
			CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);
			
			if (!CGPDFDictionaryGetInteger(dict, "Width", &width))
				return ;
			
			if (!CGPDFDictionaryGetInteger(dict, "Height", &height))
				return ;
			
			if (!CGPDFDictionaryGetInteger(dict, "BitsPerComponent", &bps))
				return ;
			
			if (!CGPDFDictionaryGetBoolean(dict, "Interpolate", &interpolation))
				interpolation = 0;
			
			if (!CGPDFDictionaryGetName(dict, "Intent", &renderingIntentName))
				renderingIntent = kCGRenderingIntentDefault;
			else{
				renderingIntent = kCGRenderingIntentDefault;
				//      renderingIntent = renderingIntentFromName(renderingIntentName);
			}
			
			if (CGPDFDictionaryGetArray(dict, "ColorSpace", &colorSpaceArray)) {
				cgColorSpace = CGColorSpaceCreateDeviceRGB();
				//      cgColorSpace = colorSpaceFromPDFArray(colorSpaceArray);
				spp = CGColorSpaceGetNumberOfComponents(cgColorSpace);
			} else if (CGPDFDictionaryGetName(dict, "ColorSpace", &colorSpaceName)) {
				if (strcmp(colorSpaceName, "DeviceRGB") == 0) {
					cgColorSpace = CGColorSpaceCreateDeviceRGB();
					//          CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
					spp = 3;
				} else if (strcmp(colorSpaceName, "DeviceCMYK") == 0) {     
					cgColorSpace = CGColorSpaceCreateDeviceCMYK();
					//          CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK);
					spp = 4;
				} else if (strcmp(colorSpaceName, "DeviceGray") == 0) {
					cgColorSpace = CGColorSpaceCreateDeviceGray();
					//          CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
					spp = 1;
				} else if (bps == 1) { // if there's no colorspace entry, there's still one we can infer from bps
					cgColorSpace = CGColorSpaceCreateDeviceGray();
					//          colorSpace = NSDeviceBlackColorSpace;
					spp = 1;
				}
			}
			 CGFloat *decodeValues = NULL;
			decodeValues = decodeValuesFromImageDictionary(dict, cgColorSpace, bps);
			
			int rowBits = bps * spp * width;
			int rowBytes = rowBits / 8;
			// pdf image row lengths are padded to byte-alignment
			if (rowBits % 8 != 0)
				++rowBytes;
			CGImageRef sourceImage = CGImageCreate(width, height, bps, bps * spp, rowBytes, cgColorSpace, 0, dataProvider, decodeValues, interpolation, renderingIntent);
			CGDataProviderRelease(dataProvider);
			
			
			CGDataProviderRef dataProvider2 = CGImageGetDataProvider(sourceImage);
			CFDataRef data = CGDataProviderCopyData(dataProvider2);
			int fd;
			findex;
			char file[256];
			memset(file,0,sizeof(file));
			sprintf(file,"%d.jpg",findex);	   
			fd=open(file, O_RDWR|O_CREAT);
			write(fd, CFDataGetBytePtr(data), CFDataGetLength(data));
			findex++;
			close(fd);
			
			//[[NSImage alloc] initWithCGImage:sourceImage size:NSMakeSize(0, 0)];
		}else {
			int fd;
			findex;
			char file[256];
			memset(file,0,sizeof(file));
			sprintf(file,"%d.jpg",findex);	   
			fd=open(file, O_RDWR|O_CREAT);
			write(fd, CFDataGetBytePtr(data), CFDataGetLength(data));
			findex++;
			close(fd);
		}


		
	}

    
    // This is an Image so figure out what variety of image it is.
    checkImageType(dict, (MyDataScan *)info);
    
}
Beispiel #20
0
BOOL MacWidgetPainter::DrawSlider(const OpRect& rect, BOOL horizontal, double min, double max, double pos, BOOL highlighted, BOOL pressed_knob, OpRect& out_knob_position, OpPoint& out_start_track, OpPoint& out_end_track)
{
	// Opera 11.50: We are going to use special skinned (non-toolkit) sliders for zoom sliders
	// so we are not drawing with our painter in that case
	if (!widget || widget->GetType() == OpTypedObject::WIDGET_TYPE_ZOOM_SLIDER)
		return FALSE;

	OpSkinElement *border_skin = widget->GetBorderSkin()->GetSkinElement();
	if(!g_skin_manager->GetCurrentSkin() || (border_skin && !border_skin->IsNative()))
	{
		return IndpWidgetPainter::DrawSlider(rect, horizontal, min, max, pos, highlighted, pressed_knob, out_knob_position, out_start_track, out_end_track);
	}
	
	CGRect r = {{0, 0}, {rect.width, rect.height}};
	
	CGContextRef context;
	OpBitmap* bitmap = NULL;

	int bmpwidth = rect.width;
	int bmpheight = rect.height;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
	const PixelScaler& scaler = vd->GetVPScale();
	bmpwidth = TO_DEVICE_PIXEL(scaler, bmpwidth);
	bmpheight = TO_DEVICE_PIXEL(scaler, bmpheight);
#endif // PIXEL_SCALE_RENDERING_SUPPORT

	if(OpStatus::IsSuccess(OpBitmap::Create(&bitmap, bmpwidth, bmpheight, FALSE, TRUE, 0, 0, TRUE)))
	{
		int w = bitmap->Width();
		int h = bitmap->Height();
		int bpl = bitmap->GetBytesPerLine();
		void *image_data = bitmap->GetPointer(OpBitmap::ACCESS_WRITEONLY);
		if (!image_data)
		{
			delete bitmap;
			return FALSE;
		}
		memset(image_data, 0, bpl*h);
		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
		CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal;
		context = CGBitmapContextCreate(image_data, w, h, 8, bpl, colorSpace, alpha);
		CGColorSpaceRelease(colorSpace);
		int win_height = rect.height;
		
		float scale = 1.0f;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
		scale = TO_DEVICE_PIXEL(scaler, scale);
#endif // PIXEL_SCALE_RENDERING_SUPPORT
		CGContextScaleCTM(context, scale, -scale);
		CGContextTranslateCTM(context, 0.0, -win_height);
		
		HIThemeTrackDrawInfo drawInfo;
		
		SInt32 thickness = 0;
		SInt32 shadow = 0;
		if	(noErr == GetThemeMetric(kThemeMetricLargeProgressBarThickness, &thickness) &&
			 (noErr == GetThemeMetric(kThemeMetricProgressBarShadowOutset, &shadow)))
		{
			SInt32 progressHeight = thickness + shadow;
			
			if (horizontal)
			{
				if((r.size.height) > progressHeight)
				{
					float f = (r.size.height - progressHeight);
					r.origin.y += f / 2;
					r.size.height -= f;
				}
			}
			else 
			{
				if((r.size.width) > progressHeight)
				{
					float f = (r.size.width - progressHeight);
					r.origin.x += f / 2;
					r.size.width -= f;
				}			
			}
		}
		else
		{
			if (horizontal)
			{
				float f = (r.size.height / 4) - 1;
				r.origin.y += f / 2;
				r.size.height -= f;
			}
			else
			{
				float f = (r.size.width / 4) - 1;
				r.origin.x += f / 2;
				r.size.width -= f;			
			}
		}
		
		drawInfo.version = 0;
		drawInfo.kind = kThemeSliderSmall;
		drawInfo.bounds = r;
		drawInfo.min = 0;
		drawInfo.max = NUMBER_OF_STEPS;
		if (widget->GetRTL())
			drawInfo.value = (max - pos) / (max - min) * NUMBER_OF_STEPS;
		else
			drawInfo.value = (pos - min) / (max - min) * NUMBER_OF_STEPS;
		drawInfo.attributes = kThemeTrackShowThumb;
		if (horizontal)
		{
			drawInfo.attributes |= kThemeTrackHorizontal;
		}
		else
		{
			drawInfo.attributes |= kThemeTrackRightToLeft;
		}
		drawInfo.enableState = widget->IsEnabled() ? kThemeTrackActive : kThemeTrackInactive;
		drawInfo.trackInfo.slider.thumbDir = kThemeThumbPlain;
		drawInfo.trackInfo.slider.pressState = 0;
		
		if (highlighted)
			drawInfo.attributes |= kThemeTrackHasFocus;

		HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal);
		
		HIShapeRef thumb_shape;
		HIRect thumb_bounds, track_bounds;
		HIThemeGetTrackThumbShape(&drawInfo, &thumb_shape);
		HIShapeGetBounds(thumb_shape, &thumb_bounds);
		HIThemeGetTrackBounds(&drawInfo, &track_bounds);
		CFRelease(thumb_shape);
		
		out_knob_position.Set(thumb_bounds.origin.x, thumb_bounds.origin.y, thumb_bounds.size.width, thumb_bounds.size.height);
		out_start_track.Set(track_bounds.origin.x, track_bounds.origin.y);
		out_end_track.Set(track_bounds.origin.x+track_bounds.size.width, track_bounds.origin.y+track_bounds.size.height);
		
		CGContextRelease(context);
		bitmap->ReleasePointer();
		vd->BitmapOut(bitmap, OpRect(0, 0, bitmap->Width(), bitmap->Height()), rect);
		delete bitmap;
	}
	
	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
}
Beispiel #22
0
BOOL MacWidgetPainter::DrawScrollbar(const OpRect &drawrect)
{
	HIThemeTrackDrawInfo 	drawInfo;
	ThemeTrackPressState 	pressState = 0;
	OpScrollbar 			*scroll = (OpScrollbar*)widget;
	HIShapeRef				thumbRgn;
	OpRect					opBounds = scroll->GetBounds();
		
	CGRect bounds = {{-drawrect.x, -drawrect.y}, {opBounds.width, opBounds.height}};
	
	pressState = (ThemeTrackPressState)scroll->GetHitPart();
	
	// hack to draw correctly, for some reason DrawThemeTrack needs this.
	if(pressState == kThemeTopInsideArrowPressed)
		pressState = kThemeBottomInsideArrowPressed;
	else if(pressState == kThemeBottomInsideArrowPressed)
		pressState = kThemeTopInsideArrowPressed;

	if(scroll->horizontal)
	{
		bounds.size.width++;
	}
	else
	{
		bounds.size.height++;
	}

	OpWindow *rootWindow;
	BOOL inActiveWindow = FALSE;
	if (vd->GetView())
	{
		rootWindow = vd->GetView()->GetContainer()->GetOpView()->GetRootWindow();
		inActiveWindow = rootWindow->IsActiveTopmostWindow() || rootWindow->GetStyle() == OpWindow::STYLE_POPUP;
	}

	drawInfo.version = 0;
	drawInfo.kind = kThemeMediumScrollBar;
	drawInfo.enableState = (scroll->IsEnabled() && inActiveWindow) ? kThemeTrackActive : kThemeTrackInactive;
	drawInfo.attributes = kThemeTrackShowThumb | (scroll->horizontal ? kThemeTrackHorizontal : 0);
	drawInfo.bounds = bounds;
	drawInfo.min = scroll->limit_min;
	drawInfo.max = scroll->limit_max;
	drawInfo.value = scroll->value;
	drawInfo.trackInfo.scrollbar.viewsize = scroll->limit_visible;
	drawInfo.trackInfo.scrollbar.pressState = pressState;
	
	int minSize = g_op_ui_info->GetHorizontalScrollbarHeight();
	if (GetOSVersion() >= 0x1070)
	{
		minSize = 0;
	}
	else if (GetInfo()->GetScrollbarArrowStyle() == ARROWS_AT_BOTTOM_AND_TOP)
	{
		minSize *= 6;
		minSize -= 4;
	}
	else
	{
		minSize *= 4;
	}
	
	// Bail out if smaller than minSize
	if(scroll->horizontal)
	{
		if((bounds.size.width) < minSize)
		{
			return FALSE;
		}
	}
	else
	{
		if((bounds.size.height) < minSize)
		{
			return FALSE;
		}
	}
	
	// Ok, the thumb(knob) could have been changed, let's update
	if(noErr == HIThemeGetTrackThumbShape(&drawInfo, &thumbRgn))
	{
		HIRect thumbRect;
		OpRect thumbOpRect;
		HIShapeGetBounds(thumbRgn, &thumbRect);
		CFRelease(thumbRgn);
		
		thumbOpRect.x = thumbRect.origin.x - bounds.origin.x;
		thumbOpRect.y = thumbRect.origin.y - bounds.origin.y;
		thumbOpRect.width = thumbRect.size.width;
		thumbOpRect.height = thumbRect.size.height;
		
		scroll->SetKnobRect(thumbOpRect);
	}
	
	if (OpStatus::IsError(MacCachedObjectFactory<MacWidgetBitmap, MacWidgetBitmapTraits>::Init()))
		return FALSE;

	int bmpwidth = drawrect.width;
	int bmpheight = drawrect.height;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
	const PixelScaler& scaler = vd->GetVPScale();
	bmpwidth = TO_DEVICE_PIXEL(scaler, bmpwidth);
	bmpheight = TO_DEVICE_PIXEL(scaler, bmpheight);
#endif // PIXEL_SCALE_RENDERING_SUPPORT

	MacWidgetBitmap* bitmap = MacCachedObjectFactory<MacWidgetBitmap, MacWidgetBitmapTraits>::CreateObject(MacWidgetBitmapTraits::CreateParam(bmpwidth, bmpheight));

	if (!bitmap)
		return FALSE;

	// Set clip and draw
	widget->SetClipRect(drawrect);
	OpBitmap* bmp = bitmap->GetOpBitmap();
	void* image_data = bmp->GetPointer(OpBitmap::ACCESS_WRITEONLY);
	if (!image_data)
	{
		bitmap->DecRef();
		widget->RemoveClipRect();
		return FALSE;
	}
	bitmap->Lock();
	const int bpl = bmp->GetBytesPerLine();
	memset(image_data, 0, bpl * bmp->Height());

	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal;
	// create the context at size of drawrect instead of bitmap itself.
	// we cache the bitmap to prevent create-destroy cycle and reallocation.
	// since we need the bitmap's memory only, we can create a much smaller context within that buffer.
	CGContextRef context = CGBitmapContextCreate(image_data, bmpwidth, bmpheight, 8, bpl, colorSpace, alpha);
	CGColorSpaceRelease(colorSpace);
	if (!context)
	{
		bitmap->DecRef();
		bmp->ReleasePointer(FALSE);
		widget->RemoveClipRect();
		bitmap->Unlock();
		return FALSE;
	}

	const int win_height = drawrect.height;

	CGFloat scale = 1.0f;
#ifdef PIXEL_SCALE_RENDERING_SUPPORT
	scale = CGFloat(scaler.GetScale()) / 100.0f;
#endif // PIXEL_SCALE_RENDERING_SUPPORT
	CGContextScaleCTM(context, scale, -scale);
	CGContextTranslateCTM(context, 0.0f, -win_height);
	
	HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal);

	bmp->ReleasePointer();
	vd->BitmapOut(bmp, OpRect(0, 0, bmp->Width(), bmp->Height()), drawrect);
	CGContextRelease(context);

	widget->RemoveClipRect();
	bitmap->Unlock();
	bitmap->DecRef();

	return TRUE;
}
Beispiel #23
0
/* Once we have our image (CGImageRef), we need to get it into an osg::Image */
osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref)
{
    /* This code is adapted from Apple's Documentation found here:
     * http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/index.html
     * Listing 9-4Using a Quartz image as a texture source.
     * Unfortunately, this guide doesn't show what to do about
     * non-RGBA image formats so I'm making the rest up
     * (and it's probably all wrong).
     */

    size_t the_width = CGImageGetWidth(image_ref);
    size_t the_height = CGImageGetHeight(image_ref);
    CGRect the_rect = {{0.0f, 0.0f}, {static_cast<CGFloat>(the_width), static_cast<CGFloat>(the_height)}};

    size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref);
    size_t bytes_per_row = CGImageGetBytesPerRow(image_ref);
//    size_t bits_per_component = CGImageGetBitsPerComponent(image_ref);
    size_t bits_per_component = 8;

    CGImageAlphaInfo alpha_info = CGImageGetAlphaInfo(image_ref);

    GLint internal_format;
    GLenum pixel_format;
    GLenum data_type;

    void* image_data = calloc(the_width * 4, the_height);

    CGColorSpaceRef color_space;
    CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref);

    switch(bits_per_pixel)
    {
        // Drat, if 8-bit, how do you distinguish
        // between a 256 color GIF, a LUMINANCE map
        // or an ALPHA map?
        case 8:
        {
            // I probably did the formats all wrong for this case,
            // especially the ALPHA case.
            if(kCGImageAlphaNone == alpha_info)
            {
                /*
                 internal_format = GL_LUMINANCE;
                 pixel_format = GL_LUMINANCE;
                 */
                internal_format = GL_RGBA8;
                pixel_format = GL_BGRA_EXT;
                data_type = GL_UNSIGNED_INT_8_8_8_8_REV;

                bytes_per_row = the_width*4;
//                color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
                color_space = CGColorSpaceCreateDeviceRGB();
//                bitmap_info = kCGImageAlphaPremultipliedFirst;
#if __BIG_ENDIAN__
                bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */
#else
                bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */
#endif
            }
            else
            {
                internal_format = GL_ALPHA;
                pixel_format = GL_ALPHA;
                data_type = GL_UNSIGNED_BYTE;
                //            bytes_per_row = the_width;
//                color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
                color_space = CGColorSpaceCreateDeviceGray();
            }

            break;
        }
        case 24:
        {
            internal_format = GL_RGBA8;
            pixel_format = GL_BGRA_EXT;
            data_type = GL_UNSIGNED_INT_8_8_8_8_REV;
            bytes_per_row = the_width*4;
//            color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
            color_space = CGColorSpaceCreateDeviceRGB();
//            bitmap_info = kCGImageAlphaNone;
#if __BIG_ENDIAN__
            bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */
#else
            bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */
#endif
            break;
        }
        //
        // Tatsuhiro Nishioka
        // 16 bpp grayscale (8 bit white and 8 bit alpha) causes invalid argument combination
        // in CGBitmapContextCreate.
        // I guess it is safer to handle 16 bit grayscale image as 32-bit RGBA image.
        // It works at least on FlightGear
        //
        case 16:
        case 32:
        case 48:
        case 64:
        {

            internal_format = GL_RGBA8;
            pixel_format = GL_BGRA_EXT;
            data_type = GL_UNSIGNED_INT_8_8_8_8_REV;

            bytes_per_row = the_width*4;
//            color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
            color_space = CGColorSpaceCreateDeviceRGB();
//            bitmap_info = kCGImageAlphaPremultipliedFirst;

#if __BIG_ENDIAN__
            bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */
#else
            bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */
#endif
            break;
        }
        default:
        {
            // OSG_WARN << "Unknown file type in " << fileName.c_str() << " with " << origDepth << std::endl;
            return NULL;
            break;
        }

    }


    // Sets up a context to be drawn to with image_data as the area to be drawn to
    CGContextRef bitmap_context = CGBitmapContextCreate(
        image_data,
        the_width,
        the_height,
        bits_per_component,
        bytes_per_row,
        color_space,
        bitmap_info
    );

    CGContextTranslateCTM(bitmap_context, 0, the_height);
    CGContextScaleCTM(bitmap_context, 1.0, -1.0);
    // Draws the image into the context's image_data
    CGContextDrawImage(bitmap_context, the_rect, image_ref);

    CGContextRelease(bitmap_context);

    if (!image_data)
        return NULL;

    // alpha is premultiplied with rgba, undo it

    vImage_Buffer vb;
    vb.data = image_data;
    vb.height = the_height;
    vb.width = the_width;
    vb.rowBytes = the_width * 4;
    vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0);

    // changing it to GL_UNSIGNED_BYTE seems working, but I'm not sure if this is a right way.
    //
    data_type = GL_UNSIGNED_BYTE;
    osg::Image* osg_image = new osg::Image;

    osg_image->setImage(
        the_width,
        the_height,
        1,
        internal_format,
        pixel_format,
        data_type,
        (unsigned char*)image_data,
        osg::Image::USE_MALLOC_FREE // Assumption: osg_image takes ownership of image_data and will free
    );

    return osg_image;



}
Beispiel #24
0
void ContentLayerChromium::updateContents()
{
    RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
    if (!backing || backing->paintingGoesToWindow())
        return;

    ASSERT(drawsContent());

    ASSERT(layerRenderer());

    // FIXME: Remove this test when tiled layers are implemented.
    m_skipsDraw = false;
    if (!layerRenderer()->checkTextureSize(m_bounds)) {
        m_skipsDraw = true;
        return;
    }

    void* pixels = 0;
    IntRect dirtyRect(m_dirtyRect);
    IntSize requiredTextureSize;
    IntSize bitmapSize;

    requiredTextureSize = m_bounds;
    IntRect boundsRect(IntPoint(0, 0), m_bounds);

    // If the texture needs to be reallocated then we must redraw the entire
    // contents of the layer.
    if (requiredTextureSize != m_allocatedTextureSize)
        dirtyRect = boundsRect;
    else {
        // Clip the dirtyRect to the size of the layer to avoid drawing outside
        // the bounds of the backing texture.
        dirtyRect.intersect(boundsRect);
    }

#if PLATFORM(SKIA)
    const SkBitmap* skiaBitmap = 0;
    OwnPtr<skia::PlatformCanvas> canvas;
    OwnPtr<PlatformContextSkia> skiaContext;
    OwnPtr<GraphicsContext> graphicsContext;

    canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
    skiaContext.set(new PlatformContextSkia(canvas.get()));

    // This is needed to get text to show up correctly.
    // FIXME: Does this take us down a very slow text rendering path?
    skiaContext->setDrawingToImageBuffer(true);

    graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));

    // Bring the canvas into the coordinate system of the paint rect.
    canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));

    m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
    skiaBitmap = &bitmap;
    ASSERT(skiaBitmap);

    SkAutoLockPixels lock(*skiaBitmap);
    SkBitmap::Config skiaConfig = skiaBitmap->config();
    // FIXME: do we need to support more image configurations?
    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
        pixels = skiaBitmap->getPixels();
        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
    }
#elif PLATFORM(CG)
    Vector<uint8_t> tempVector;
    int rowBytes = 4 * dirtyRect.width();
    tempVector.resize(rowBytes * dirtyRect.height());
    memset(tempVector.data(), 0, tempVector.size());
    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
                                                                     dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
                                                                     colorSpace.get(),
                                                                     kCGImageAlphaPremultipliedLast));
    CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height());
    CGContextScaleCTM(contextCG.get(), 1, -1);

    GraphicsContext graphicsContext(contextCG.get());

    // Translate the graphics context into the coordinate system of the dirty rect.
    graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());

    m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);

    pixels = tempVector.data();
    bitmapSize = dirtyRect.size();
#else
#error "Need to implement for your platform."
#endif

    unsigned textureId = m_contentsTexture;
    if (!textureId)
        textureId = layerRenderer()->createLayerTexture();

    if (pixels)
        updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
}