Пример #1
0
static UncompressedImage
CGImageToUncompressedImage(CGImageRef image)
{
  if (image == nullptr)
    return UncompressedImage();
  
  size_t width = CGImageGetWidth(image);
  size_t height = CGImageGetHeight(image);
  
  if ((0 == width) || (0 == height))
    return UncompressedImage();
  
  size_t bits_per_pixel = CGImageGetBitsPerPixel(image);
  size_t bits_per_component = CGImageGetBitsPerComponent(image);
  CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
  
  size_t row_size;
  UncompressedImage::Format format;
  CGColorSpaceRef bitmap_colorspace;
  CGBitmapInfo bitmap_info;
  
  if ((8 == bits_per_pixel) &&
      (8 == bits_per_component) &&
      (CGColorSpaceGetModel(colorspace) == kCGColorSpaceModelMonochrome)) {
    row_size = width;
    format = UncompressedImage::Format::GRAY;
    static CGColorSpaceRef grey_colorspace = CGColorSpaceCreateDeviceGray();
    bitmap_colorspace = grey_colorspace;
    bitmap_info = 0;
  } else {
    static CGColorSpaceRef rgb_colorspace = CGColorSpaceCreateDeviceRGB();
    bitmap_colorspace = rgb_colorspace;
    if ((24 == bits_per_pixel) && (8 == bits_per_component)) {
      row_size = width * 3;
      format = UncompressedImage::Format::RGB;
      bitmap_info = kCGBitmapByteOrder32Big;
    } else {
      row_size = width * 4;
      format = UncompressedImage::Format::RGBA;
      bitmap_info = kCGImageAlphaPremultipliedLast |
                    kCGBitmapByteOrder32Big;
    }
  }
  
  std::unique_ptr<uint8_t[]> uncompressed(new uint8_t[height * row_size]);
  
  CGContextRef bitmap = CGBitmapContextCreate(uncompressed.get(), width, height,
                                              8, row_size, bitmap_colorspace,
                                              bitmap_info);
  if (nullptr == bitmap) {
    return UncompressedImage();
  }

  AtScopeExit(bitmap) { CFRelease(bitmap); };

  CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), image);
  
  return UncompressedImage(format, row_size, width, height,
                           std::move(uncompressed));
}
Пример #2
0
void pop_img_props (CGImageRef source_image, img_prop im_props) {
	
	// Populate the remaining image property struct values
	im_props->image_w = CGImageGetWidth (source_image);
	im_props->image_h = CGImageGetHeight (source_image);
	im_props->bits_ppixel = CGImageGetBitsPerPixel (source_image);
	im_props->bytes_row = CGImageGetBytesPerRow (source_image);
} // pop_img_props 
Пример #3
0
// Ok, a bit freaky coz we want non-premultipied alpha!
//
BBDataBuffer *BBLoadImageData( BBDataBuffer *buf,String path,Array<int> info ) {

    path=String( "data/" )+path;
    NSString *nspath=path.ToNSString();

    //This was apparently buggy in iOS2.x, but NO MORE?
    UIImage *uiimage=[ UIImage imageNamed:nspath ];
    if( !uiimage ) return 0;

    CGImageRef cgimage=uiimage.CGImage;

    int width=CGImageGetWidth( cgimage );
    int height=CGImageGetHeight( cgimage );
    int pitch=CGImageGetBytesPerRow( cgimage );
    int bpp=CGImageGetBitsPerPixel( cgimage );

    if( bpp!=24 && bpp!=32 ) return 0;

    CFDataRef cfdata=CGDataProviderCopyData( CGImageGetDataProvider( cgimage ) );
    unsigned char *src=(unsigned char*)CFDataGetBytePtr( cfdata );
    int srclen=(int)CFDataGetLength( cfdata );

    if( !buf->_New( width*height*4 ) ) return 0;

    unsigned char *dst=(unsigned char*)buf->WritePointer();

    int y;

    switch( bpp ) {
    case 24:
        for( y=0; y<height; ++y ) {
            for( int x=0; x<width; ++x ) {
                *dst++=*src++;
                *dst++=*src++;
                *dst++=*src++;
                *dst++=255;
            }
            src+=pitch-width*3;
        }
        break;
    case 32:
        for( y=0; y<height; ++y ) {
            memcpy( dst,src,width*4 );
            dst+=width*4;
            src+=pitch;
        }
        break;
    }

    if( info.Length()>0 ) info[0]=width;
    if( info.Length()>1 ) info[1]=height;

    CFRelease( cfdata );

    return buf;
}
Пример #4
0
cv::Mat &osx_cv::toMat(
        const CGImageRef &image,
        cv::Mat &out,
        osx::disp::RGBType destType
        ) {
    cv::Mat temp;

    size_t w = CGImageGetWidth(image), h = CGImageGetHeight(image);

    if (CGImageGetBitsPerPixel(image) != 32) {
        throw invalid_argument("`image` must be 32 bits per pixel");
    }

    temp.create(int(h), int(w), CV_8UC4);

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image);

    CGContextRef context = CGBitmapContextCreate(
            temp.data,
            w,
            h,
            CGImageGetBitsPerComponent(image),
            CGImageGetBytesPerRow(image),
            colorSpace,
            CGImageGetAlphaInfo(image)
    );

    CGContextDrawImage(
            context,
            CGRectMake(0, 0, (CGFloat)w, (CGFloat)h),
            image
            );

    _cvtRGBColor(temp, out, CGImageGetAlphaInfo(image), destType);

    CGContextRelease(context);

    return out;
}
Пример #5
0
Screenshot* ScreenShooter::take_screenshot(const CFStringRef format, float compression) {
  CGImageRef* images = new CGImageRef[_dsp_count];
   
  /* Grab the images */
  for (unsigned int i = 0; i < _dsp_count; i++) {
     images[i] = CGDisplayCreateImage(_displays[i]);
  }

  /* Calculate size of image to produce */
  CGSize finalSize = CGSizeMake(_top_right.x - _bottom_left.x, _bottom_left.y - _top_right.y);

  /* Round out the bitmap size information */
  size_t bytesPerRow = finalSize.width * CGImageGetBitsPerPixel(images[0]) / 8;

  /* Create context around bitmap */
  CGContextRef context = CGBitmapContextCreate(
    NULL, finalSize.width, finalSize.height,
    CGImageGetBitsPerComponent(images[0]), bytesPerRow,
    CGImageGetColorSpace(images[0]), CGImageGetBitmapInfo(images[0])
  );

  /* Draw images into the bitmap */
  for (unsigned int i = 0; i < _dsp_count; i++)
  {
      /* Adjust the positions to account for coordinate system shifts
         (displays origin is at top left; image origin is at bottom left) */
      CGRect adjustedPoint = CGRectMake(_display_bounds[i].origin.x - _bottom_left.x,
                                        _bottom_left.y - _display_bounds[i].size.height - _display_bounds[i].origin.y,
                                        _display_bounds[i].size.width,
                                        _display_bounds[i].size.height);
      CGContextDrawImage(context, adjustedPoint, images[i]);
  }
  
  delete [] images;

  return new Screenshot(context, format, compression);
}
Пример #6
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-4††Using a Quartz image as a texture source.
     * Unfortunately, this guide doesn't show what to do about
     * non-RGBA image formats so I'm making the rest up
     * (and it's probably all wrong).
     */

    size_t the_width = CGImageGetWidth(image_ref);
    size_t the_height = CGImageGetHeight(image_ref);
    CGRect the_rect = {{0, 0}, {the_width, the_height}};

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

    CGImageAlphaInfo alpha_info = CGImageGetAlphaInfo(image_ref);

    GLint internal_format;
    GLenum pixel_format;
    GLenum data_type;

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

    CGColorSpaceRef color_space;
    CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref);

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

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

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

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

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

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

    }
    

    // Sets up a context to be drawn to with image_data as the area to be drawn to
    CGContextRef bitmap_context = CGBitmapContextCreate(
        image_data,
        the_width,
        the_height,
        bits_per_component,
        bytes_per_row,
        color_space,
        bitmap_info
    );
    
    CGContextTranslateCTM(bitmap_context, 0, the_height);
    CGContextScaleCTM(bitmap_context, 1.0, -1.0);
    // Draws the image into the context's image_data
    CGContextDrawImage(bitmap_context, the_rect, image_ref);

    CGContextRelease(bitmap_context);
    
    if (!image_data)
        return NULL;

    // alpha is premultiplied with rgba, undo it
    
    vImage_Buffer vb;
    vb.data = image_data;
    vb.height = the_height;
    vb.width = the_width;
    vb.rowBytes = the_width * 4;
    vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0);
    
    // changing it to GL_UNSIGNED_BYTE seems working, but I'm not sure if this is a right way.
    //
    data_type = GL_UNSIGNED_BYTE;
    osg::Image* osg_image = new osg::Image;

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

    return osg_image;



}
Пример #7
0
//============================================================================
//		NCGImage::SetObject : Set the object.
//----------------------------------------------------------------------------
bool NCGImage::SetObject(CGImageRef cfObject, bool takeOwnership)
{	size_t				theWidth, theHeight, bitsPerPixel, bitsPerComponent;
	NCFObject			theObject(cfObject, takeOwnership);
	NCFObject			cgColorSpace, cgContext;
	CGBitmapInfo		bitmapInfo;
	NImageFormat		theFormat;
	NImage				theImage;
	bool				isValid;



	// Get the state we need
	theWidth         = CGImageGetWidth(           cfObject);
	theHeight        = CGImageGetHeight(          cfObject);
	bitsPerPixel     = CGImageGetBitsPerPixel(    cfObject);
	bitsPerComponent = CGImageGetBitsPerComponent(cfObject);



	// Select the image format
	if (bitsPerPixel == 8 && bitsPerComponent == 8)
		{
		// Convert indexed images to 32bpp without alpha
		theFormat    = kNImageFormat_RGBX_8888;
		bitmapInfo   = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipLast;
		cgColorSpace = NCGColor::GetDeviceRGB();
		}

	else if (bitsPerPixel == 24 && bitsPerComponent == 8)
		{
		// Convert 24bpp images to 32bpp without alpha
		theFormat    = kNImageFormat_RGBX_8888;
		bitmapInfo   = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipLast;
		cgColorSpace = NCGColor::GetDeviceRGB();
		}

	else if (bitsPerPixel == 32 && bitsPerComponent == 8)
		{
		// Convert 32bpp images to 32bpp with alpha
		theFormat    = kNImageFormat_RGBA_8888;
		bitmapInfo   = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
		cgColorSpace = NCGColor::GetDeviceRGB();
		}

	else
		{
		NN_LOG("Unknown image format: %d/%d", bitsPerPixel, bitsPerComponent);
		theFormat  = kNImageFormatNone;
		bitmapInfo = kCGImageAlphaNone;
		}

	if (!cgColorSpace.IsValid())
		return(false);



	// Set the object
	theImage = NImage(NSize(theWidth, theHeight), theFormat);
	isValid  = cgContext.SetObject(CGBitmapContextCreate(	theImage.GetPixels(),
															theWidth,
															theHeight,
															bitsPerComponent,
															theImage.GetBytesPerRow(),
															cgColorSpace,
															bitmapInfo));

	if (isValid)
		{
		CGContextDrawImage(cgContext, ToCG(theImage.GetBounds()), cfObject);
		*this = theImage;
		}

	return(isValid);
}
/* read image file */
int BIReadFile(
	const char			*fileName,
	BIFileType			fileType,
	BIPadMode			padMode,
	unsigned			padSize,
	BIImageInfo			*imageInfo,		/* RETURNED */
	unsigned char		**bitmap)		/* mallocd and RETURNED; caller must free */
{
	CFURLRef fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, 
		(unsigned char*)fileName, strlen(fileName), FALSE);
	if(fileURL == NULL) {
		fprintf(stderr, "***BIReadFile: Error on CFURLCreateFromFileSystemRepresentation\n");
		return -1;
	}

	CFStringRef keys[1] = {kCGImageSourceTypeIdentifierHint};
	CFStringRef values[1] = {BIGetUTI(fileURL, fileType)};
	
	if(values[0] == NULL) {
		return -1;
	}
	
	CFDictionaryRef		optionsDict = NULL;
	CGImageSourceRef	imageSourceRef = NULL;
	CGImageRef			imageRef = NULL;
	CGColorSpaceRef		rgbColorSpaceRef = NULL;
	CGContextRef		bitmapContextRef = NULL;
	CGBitmapInfo		bitmapInfo = 0;
	CGImageAlphaInfo	alpha;
	unsigned			bytesPerPixel = 4;
	
	optionsDict = CFDictionaryCreate( kCFAllocatorDefault, 
		(const void **)keys, (const void **)values, 1,  
		&kCFTypeDictionaryKeyCallBacks,  &kCFTypeDictionaryValueCallBacks );
	/* subsequent errors to errOut: */
	
	int ourRtn = 0;
	
	/* source file --> CGImageRef */
	imageSourceRef = CGImageSourceCreateWithURL(fileURL, optionsDict);
	if(imageSourceRef == NULL) {
		fprintf(stderr, "***BIReadFile: Error on CGImageSourceCreateWithURL\n");
		ourRtn = 1;
		goto errOut;
	}
	CFRELEASE(fileURL);
	imageRef = CGImageSourceCreateImageAtIndex(imageSourceRef, 0, optionsDict );
	if(imageRef == NULL) {
		fprintf(stderr, "***BIReadFile: Error on CGImageSourceCreateImageAtIndex\n");
		ourRtn = 1;
		goto errOut;
	}
	
	imageInfo->imageWidth			= CGImageGetWidth(imageRef);
	imageInfo->imageHeight			= CGImageGetHeight(imageRef);
	imageInfo->bitsPerComponent		= CGImageGetBitsPerComponent(imageRef);
	imageInfo->bitsPerPixel			= CGImageGetBitsPerPixel(imageRef);
	
	if(imageInfo->bitsPerPixel == 8) {
		/* the image is gray */
		rgbColorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
		imageInfo->bytesPerRow = imageInfo->imageWidth; 
		alpha = kCGImageAlphaNone;
		bitmapInfo = CGImageGetBitmapInfo(imageRef);
		bytesPerPixel = 1;
	}
	else {
        rgbColorSpaceRef = CGColorSpaceCreateDeviceRGB();
		imageInfo->bytesPerRow = imageInfo->imageWidth * 4;
		alpha = kCGImageAlphaPremultipliedLast;
		bitmapInfo = kCGBitmapByteOrder32Big | alpha;
	}
	if(rgbColorSpaceRef == NULL) {
		fprintf(stderr, "***BIReadFile: Error on CGColorSpaceCreateWithName\n");
		ourRtn = 1;
		goto errOut;
	}
	
	/* optionally pad */
	imageInfo->effectHeight = imageInfo->imageHeight;
	if(padMode != PM_None) {
		if(padSize == 0) {
			fprintf(stderr, "***Pad size of 0 invalid\n");
			ourRtn = 1;
			goto errOut;
		}
		unsigned padSizeBytes = padSize;
		if(padMode == PM_Pixels) {
			padSizeBytes *= bytesPerPixel;
		}
		imageInfo->bytesPerRow = ROUND_TO(imageInfo->bytesPerRow, padSizeBytes);
		/* also round up row count */
		imageInfo->effectHeight = ROUND_TO(imageInfo->imageHeight, padSize);
	}

	*bitmap = (unsigned char *)malloc(imageInfo->bytesPerRow * imageInfo->effectHeight);
	
	bitmapContextRef = CGBitmapContextCreate(*bitmap, 
		imageInfo->imageWidth, imageInfo->imageHeight, 
		imageInfo->bitsPerComponent, imageInfo->bytesPerRow, 
		rgbColorSpaceRef, 
		bitmapInfo);
	if(bitmapContextRef == NULL) {
		fprintf(stderr, "***BIReadFile: Error creating CGBitmapContext\n");
		ourRtn = 1;
		goto errOut;
	}

	/* enable high quality interpolation */
	CGContextSetInterpolationQuality(bitmapContextRef, kCGInterpolationHigh);

	/* Draw into the context */
	CGContextDrawImage(bitmapContextRef, CGRectMake(0, 0, imageInfo->imageWidth, imageInfo->imageHeight), 
		imageRef);

errOut:
	CFRELEASE(optionsDict);
	CFRELEASE(imageSourceRef);
	CFRELEASE(imageRef);
	CFRELEASE(rgbColorSpaceRef);
	CFRELEASE(bitmapContextRef);
	if(ourRtn) {
		if(*bitmap) {
			free(*bitmap);
			*bitmap = NULL;
		}
	}
	return ourRtn;
}
Пример #9
0
bool GraphicsContext3D::getImageData(Image* image,
                                     unsigned int format,
                                     unsigned int type,
                                     bool premultiplyAlpha,
                                     Vector<uint8_t>& outputVector)
{
    if (!image)
        return false;
    CGImageRef cgImage;
    RetainPtr<CGImageRef> decodedImage;
    if (image->data()) {
        ImageSource decoder(false);
        decoder.setData(image->data(), true);
        if (!decoder.frameCount())
            return false;
        decodedImage = decoder.createFrameAtIndex(0);
        cgImage = decodedImage.get();
    } else
        cgImage = image->nativeImageForCurrentFrame();
    if (!cgImage)
        return false;
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    if (!width || !height)
        return false;
    size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
    if (bitsPerComponent != 8 && bitsPerComponent != 16)
        return false;
    if (bitsPerPixel % bitsPerComponent)
        return false;
    size_t componentsPerPixel = bitsPerPixel / bitsPerComponent;
    SourceDataFormat srcDataFormat = kSourceFormatRGBA8;
    AlphaOp neededAlphaOp = kAlphaDoNothing;
    switch (CGImageGetAlphaInfo(cgImage)) {
    case kCGImageAlphaPremultipliedFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        // This is a special case for texImage2D with HTMLCanvasElement input,
        // in which case image->data() should be null.
        ASSERT(!image->data());
        if (!premultiplyAlpha)
            neededAlphaOp = kAlphaDoUnmultiply;
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        if (premultiplyAlpha)
            neededAlphaOp = kAlphaDoPremultiply;
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatA8;
            else
                srcDataFormat = kSourceFormatA16;
            break;
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNoneSkipFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaPremultipliedLast:
        // This is a special case for texImage2D with HTMLCanvasElement input,
        // in which case image->data() should be null.
        ASSERT(!image->data());
        if (!premultiplyAlpha)
            neededAlphaOp = kAlphaDoUnmultiply;
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaLast:
        if (premultiplyAlpha)
            neededAlphaOp = kAlphaDoPremultiply;
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatA8;
            else
                srcDataFormat = kSourceFormatA16;
            break;
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNoneSkipLast:
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNone:
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatR8;
            else
                srcDataFormat = kSourceFormatR16;
            break;
        case 3:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGB8;
            else
                srcDataFormat = kSourceFormatRGB16;
            break;
        default:
            return false;
        }
        break;
    default:
        return false;
    }
    RetainPtr<CFDataRef> pixelData;
    pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage)));
    if (!pixelData)
        return false;
    const UInt8* rgba = CFDataGetBytePtr(pixelData.get());
    outputVector.resize(width * height * 4);
    unsigned int srcUnpackAlignment = 0;
    size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
    unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width;
    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }
    bool rt = packPixels(rgba, srcDataFormat, width, height, srcUnpackAlignment,
                         format, type, neededAlphaOp, outputVector.data());
    return rt;
}
Пример #10
0
void CGImageLuminanceSource::init (CGImageRef cgimage, int left, int top, int width, int height) {
    data_ = 0;
    image_ = cgimage;
    left_ = left;
    top_ = top;
    width_ = width;
    height_ = height;
    dataWidth_ = (int)CGImageGetWidth(image_);
    dataHeight_ = (int)CGImageGetHeight(image_);

    if (left_ + width_ > dataWidth_ ||
        top_ + height_ > dataHeight_ ||
        top_ < 0 ||
        left_ < 0) {
        throw IllegalArgumentException("Crop rectangle does not fit within image data.");
    }

    CGColorSpaceRef space = CGImageGetColorSpace(image_);
    CGColorSpaceModel model = CGColorSpaceGetModel(space);

    if (model != kCGColorSpaceModelMonochrome || CGImageGetBitsPerComponent(image_) != 8 || CGImageGetBitsPerPixel(image_) != 8) {
        CGColorSpaceRef gray = CGColorSpaceCreateDeviceGray();
        
        CGContextRef ctx = CGBitmapContextCreate(0, width, height, 8, width, gray, kCGImageAlphaNone);
        
        CGColorSpaceRelease(gray);

        if (top || left) {
            CGContextClipToRect(ctx, CGRectMake(0, 0, width, height));
        }

        CGContextDrawImage(ctx, CGRectMake(-left, -top, width, height), image_);
    
        image_ = CGBitmapContextCreateImage(ctx);

        bytesPerRow_ = width;
        top_ = 0;
        left_ = 0;
        dataWidth_ = width;
        dataHeight_ = height;

        CGContextRelease(ctx);
    } else {
        CGImageRetain(image_);
    }

    CGDataProviderRef provider = CGImageGetDataProvider(image_);
    data_ = CGDataProviderCopyData(provider);
}
Пример #11
0
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect)
{
#if defined(IS_MACOSX)

	size_t bytewidth;
	uint8_t bitsPerPixel, bytesPerPixel;
	uint8_t *buffer;

	CGDirectDisplayID displayID = CGMainDisplayID();

	//Replacement for CGDisplayBitsPerPixel. 
	CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID);
	size_t depth = 0;
	
	CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
	if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 32;
	else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 16;
	else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 8;

	bitsPerPixel = (uint8_t) depth; 
	bytesPerPixel = bitsPerPixel / 8;
	/* Align width to padding. */
	bytewidth = ADD_PADDING(rect.size.width * bytesPerPixel);

	/* Convert Quartz point to postscript point. */
	rect.origin.y = CGDisplayPixelsHigh(displayID) - rect.origin.y - rect.size.height;

	CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));

    // Request access to the raw pixel data via the image's DataProvider.
    CGDataProviderRef provider = CGImageGetDataProvider(image);
    CFDataRef data = CGDataProviderCopyData(provider);

    size_t width, height;    
    width = CGImageGetWidth(image);
    height = CGImageGetHeight(image); 
    size_t bpp = CGImageGetBitsPerPixel(image) / 8;

    uint8 *pixels = malloc(width * height * bpp);
    memcpy(pixels, CFDataGetBytePtr(data), width * height * bpp);
    CFRelease(data); 
   	CGImageRelease(image); 

	return createMMBitmap(pixels, rect.size.width, rect.size.height, bytewidth,
	                      bitsPerPixel, bytesPerPixel);
#elif defined(USE_X11)
	MMBitmapRef bitmap;

	Display *display = XOpenDisplay(NULL);
	XImage *image = XGetImage(display,
	                          XDefaultRootWindow(display),
	                          (int)rect.origin.x,
	                          (int)rect.origin.y,
	                          (unsigned int)rect.size.width,
	                          (unsigned int)rect.size.height,
	                          AllPlanes, ZPixmap);
	XCloseDisplay(display);
	if (image == NULL) return NULL;

	bitmap = createMMBitmap((uint8_t *)image->data,
	                        rect.size.width,
	                        rect.size.height,
	                        (size_t)image->bytes_per_line,
	                        (uint8_t)image->bits_per_pixel,
	                        (uint8_t)image->bits_per_pixel / 8);
	image->data = NULL; /* Steal ownership of bitmap data so we don't have to
	                     * copy it. */
	XDestroyImage(image);

	return bitmap;
#elif defined(IS_WINDOWS)
	MMBitmapRef bitmap;
	void *data;
	HDC screen = NULL, screenMem = NULL;
	HBITMAP dib;
	BITMAPINFO bi;

	/* Initialize bitmap info. */
	bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
   	bi.bmiHeader.biWidth = (long)rect.size.width;
   	bi.bmiHeader.biHeight = -(long)rect.size.height; /* Non-cartesian, please */
   	bi.bmiHeader.biPlanes = 1;
   	bi.bmiHeader.biBitCount = 32;
   	bi.bmiHeader.biCompression = BI_RGB;
   	bi.bmiHeader.biSizeImage = (DWORD)(4 * rect.size.width * rect.size.height);
	bi.bmiHeader.biXPelsPerMeter = 0;
	bi.bmiHeader.biYPelsPerMeter = 0;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;

	screen = GetDC(NULL); /* Get entire screen */
	if (screen == NULL) return NULL;

	/* Get screen data in display device context. */
   	dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0);

	/* Copy the data into a bitmap struct. */
	if ((screenMem = CreateCompatibleDC(screen)) == NULL ||
	    SelectObject(screenMem, dib) == NULL ||
	    !BitBlt(screenMem, 
	            (int)rect.origin.x, 
	            (int)rect.origin.y, 
	            (int)rect.size.width,
	            (int)rect.size.height, screen, 0, 0, SRCCOPY)) {
		/* Error copying data. */
		ReleaseDC(NULL, screen);
		DeleteObject(dib);
		if (screenMem != NULL) DeleteDC(screenMem);

		return NULL;
	}

	bitmap = createMMBitmap(NULL,
	                        rect.size.width,
	                        rect.size.height,
	                        4 * rect.size.width,
	                        (uint8_t)bi.bmiHeader.biBitCount, 
	                        4);

	/* Copy the data to our pixel buffer. */
	if (bitmap != NULL) {
		bitmap->imageBuffer = malloc(bitmap->bytewidth * bitmap->height);
		memcpy(bitmap->imageBuffer, data, bitmap->bytewidth * bitmap->height);
	}

	ReleaseDC(NULL, screen);
	DeleteObject(dib);
	DeleteDC(screenMem);

	return bitmap;
#endif
}