/* static */
already_AddRefed<NativeFontResourceMac>
NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength)
{
  // copy font data
  CFDataRef data = CFDataCreate(kCFAllocatorDefault, aFontData, aDataLength);
  if (!data) {
    return nullptr;
  }

  // create a provider
  CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);

  // release our reference to the CFData, provider keeps it alive
  CFRelease(data);

  // create the font object
  CGFontRef fontRef = CGFontCreateWithDataProvider(provider);

  // release our reference, font will keep it alive as long as needed
  CGDataProviderRelease(provider);

  if (!fontRef) {
    return nullptr;
  }

  // passes ownership of fontRef to the NativeFontResourceMac instance
  RefPtr<NativeFontResourceMac> fontResource =
    new NativeFontResourceMac(fontRef);

  return fontResource.forget();
}
Example #2
0
static bool MCAlphaToCGImage(uindex_t p_width, uindex_t p_height, uint8_t* p_data, uindex_t p_stride, CGImageRef &r_image)
{
	bool t_success = true;
	
	CGImageRef t_image = nil;
	CGColorSpaceRef t_colorspace = nil;
	CFDataRef t_data = nil;
	CGDataProviderRef t_dp = nil;
	
	if (t_success)
		t_success = nil != (t_data = CFDataCreate(kCFAllocatorDefault, (uint8_t*)p_data, p_stride * p_height));
	
	if (t_success)
		t_success = nil != (t_dp = CGDataProviderCreateWithCFData(t_data));
	
	if (t_success)
		t_success = nil != (t_colorspace = CGColorSpaceCreateDeviceGray());
	
	if (t_success)
		t_success = nil != (t_image = CGImageCreate(p_width, p_height, 8, 8, p_stride, t_colorspace, kCGImageAlphaNone, t_dp, nil, false, kCGRenderingIntentDefault));
	
	CGColorSpaceRelease(t_colorspace);
	CGDataProviderRelease(t_dp);
	CFRelease(t_data);
	
	if (t_success)
		r_image = t_image;
	
	return t_success;
}
Example #3
0
unsigned char* os_image_load_from_file(const char* filename, int* outWidth, int* outHeight, int* outChannels, int unused) {
  const int fileHandle = open(filename, O_RDONLY);
  struct stat statBuffer;
  fstat(fileHandle, &statBuffer);
  const size_t bytesInFile = (size_t)(statBuffer.st_size);
  uint8_t* fileData = (uint8_t*)(mmap(NULL, bytesInFile, PROT_READ, MAP_SHARED, fileHandle, 0));
  if (fileData == MAP_FAILED) {
    fprintf(stderr, "Couldn't open file '%s' with mmap\n", filename);
    return NULL;
  }
  CFDataRef fileDataRef = CFDataCreateWithBytesNoCopy(NULL, fileData, bytesInFile, kCFAllocatorNull);
  CGDataProviderRef imageProvider = CGDataProviderCreateWithCFData(fileDataRef);

  const char* suffix = strrchr(filename, '.');
  if (!suffix || suffix == filename) {
    suffix = "";
  }
  CGImageRef image;
  if (strcasecmp(suffix, ".png") == 0) {
    image = CGImageCreateWithPNGDataProvider(imageProvider, NULL, true, kCGRenderingIntentDefault);
  } else if ((strcasecmp(suffix, ".jpg") == 0) ||
    (strcasecmp(suffix, ".jpeg") == 0)) {
    image = CGImageCreateWithJPEGDataProvider(imageProvider, NULL, true, kCGRenderingIntentDefault);
  } else {
    munmap(fileData, bytesInFile);
    close(fileHandle);
    CFRelease(imageProvider);
    CFRelease(fileDataRef);
    fprintf(stderr, "Unknown suffix for file '%s'\n", filename);
    return NULL;
  }

  const int width = (int)CGImageGetWidth(image);
  const int height = (int)CGImageGetHeight(image);
  const int channels = 4;
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  const int bytesPerRow = (width * channels);
  const int bytesInImage = (bytesPerRow * height);
  uint8_t* result = (uint8_t*)(malloc(bytesInImage));
  const int bitsPerComponent = 8;
  CGContextRef context = CGBitmapContextCreate(result, width, height,
    bitsPerComponent, bytesPerRow, colorSpace,
    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
  CGColorSpaceRelease(colorSpace);
  CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
  CGContextRelease(context);
  CFRelease(image);

  munmap(fileData, bytesInFile);
  close(fileHandle);
  CFRelease(imageProvider);
  CFRelease(fileDataRef);

  *outWidth = width;
  *outHeight = height;
  *outChannels = channels;

  return result;
}
void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point)
{
    // FIXME: Creating CFData is non-optimal, but needed to avoid crashing when printing.  Ideally we should 
    // make a custom CGDataProvider that controls the WindowsBitmap lifetime.  see <rdar://6394455>
    RetainPtr<CFDataRef> imageData = adoptCF(CFDataCreate(kCFAllocatorDefault, image->buffer(), image->bufferLength()));
    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(imageData.get()));
    RetainPtr<CGImageRef> cgImage = adoptCF(CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGBColorSpaceRef(),
                                                         kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault));
    CGContextDrawImage(m_data->m_cgContext.get(), CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get());   
}
Example #5
0
static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile)
{
    RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(colorProfile.data()), colorProfile.size()));
#ifndef TARGETING_LEOPARD
    return CGColorSpaceCreateWithICCProfile(data.get());
#else
    RetainPtr<CGDataProviderRef> profileDataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
    CGFloat ranges[] = {0.0, 255.0, 0.0, 255.0, 0.0, 255.0};
    return CGColorSpaceCreateICCBased(3, ranges, profileDataProvider.get(), deviceRGBColorSpaceRef());
#endif
}
Example #6
0
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

    ATSFontContainerRef containerRef = 0;
    ATSFontRef fontRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
    
    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
#ifndef BUILDING_ON_TIGER
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
#endif
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)

    return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef());
}
Example #7
0
CGImageRef NZCGImageCreateUsingWebPData(CFDataRef webPData)
{
	uint8 *y = NULL, *u = NULL, *v = NULL;
	int32_t width, height;
	
	if (CFDataGetLength(webPData) > INT_MAX)	// highly unlikely to happen; just checking anyway
		return NULL;
	
	// Step 1: Decode the data.
	if (WebPDecode(CFDataGetBytePtr(webPData), (int)CFDataGetLength(webPData), &y, &u, &v, &width, &height) == webp_success)
	{
		const int32_t depth = 32;
		const int wordsPerLine = (width*depth+31)/32;
		size_t pixelBytesLength = 4*height*wordsPerLine;	// Google's documentation is incorrect here; the length has to be quadrupled or we'll have an overrun
		uint32 *pixelBytes = malloc(pixelBytesLength);
		CFDataRef pixelData;
		CGDataProviderRef dataProvider;
		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
		CGImageRef theImage;
		
		// Step 2: Convert the YUV data into RGB.
		YUV420toRGBA(y, u, v, wordsPerLine, width, height, pixelBytes);
		
		// Step 3: Convert the RGB data into a CGImageRef.
		pixelData = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)pixelBytes, pixelBytesLength, NULL);
		dataProvider = CGDataProviderCreateWithCFData(pixelData);
		theImage = CGImageCreate(width,
								 height,
								 8,		// each component is one byte or 8 bits large
								 32,	// our data has four components
								 wordsPerLine*4,	// there are 32 bits or 4 bytes in a word
								 colorSpace,
								 kCGBitmapByteOrder32Host,	// our data is in host-endian format
								 dataProvider,
								 NULL,	// we don't care about decode arrays
								 true,	// sure, why not interpolate?
								 kCGRenderingIntentDefault);
		
		// Finally, clean up memory.
		CGColorSpaceRelease(colorSpace);
		CGDataProviderRelease(dataProvider);
		CFRelease(pixelData);
		free(y);
		return theImage;
	}
	fprintf(stderr, "NZCGWebPFunctions: The data provided is not in WebP format.\n");
	return NULL;
}
Example #8
0
/* static */
already_AddRefed<NativeFontResourceMac>
NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength,
                              uint32_t aVariationCount,
                              const ScaledFont::VariationSetting* aVariations)
{
  // copy font data
  CFDataRef data = CFDataCreate(kCFAllocatorDefault, aFontData, aDataLength);
  if (!data) {
    return nullptr;
  }

  // create a provider
  CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);

  // release our reference to the CFData, provider keeps it alive
  CFRelease(data);

  // create the font object
  CGFontRef fontRef = CGFontCreateWithDataProvider(provider);

  // release our reference, font will keep it alive as long as needed
  CGDataProviderRelease(provider);

  if (!fontRef) {
    return nullptr;
  }

  if (aVariationCount > 0) {
    MOZ_ASSERT(aVariations);
    AutoRelease<CFDictionaryRef>
      varDict(CreateVariationDictionaryOrNull(fontRef, aVariationCount,
                                              aVariations));
    if (varDict) {
      CGFontRef varFont = CGFontCreateCopyWithVariations(fontRef, varDict);
      if (varFont) {
        CFRelease(fontRef);
        fontRef = varFont;
      }
    }
  }

  // passes ownership of fontRef to the NativeFontResourceMac instance
  RefPtr<NativeFontResourceMac> fontResource =
    new NativeFontResourceMac(fontRef);

  return fontResource.forget();
}
Example #9
0
/***********************************************************************
 *              create_surface_image
 *
 * Caller must hold the surface lock.  On input, *rect is the requested
 * image rect, relative to the window whole_rect, a.k.a. visible_rect.
 * On output, it's been intersected with that part backed by the surface
 * and is the actual size of the returned image.  copy_data indicates if
 * the caller will keep the returned image beyond the point where the
 * surface bits can be guaranteed to remain valid and unchanged.  If so,
 * the bits are copied instead of merely referenced by the image.
 *
 * IMPORTANT: This function is called from non-Wine threads, so it
 *            must not use Win32 or Wine functions, including debug
 *            logging.
 */
CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data)
{
    CGImageRef cgimage = NULL;
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    int width, height;

    width  = surface->header.rect.right - surface->header.rect.left;
    height = surface->header.rect.bottom - surface->header.rect.top;
    *rect = CGRectIntersection(cgrect_from_rect(surface->header.rect), *rect);
    if (!CGRectIsEmpty(*rect))
    {
        CGRect visrect;
        CGColorSpaceRef colorspace;
        CGDataProviderRef provider;
        int bytes_per_row, offset, size;
        CGImageAlphaInfo alphaInfo;

        visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top);

        colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        bytes_per_row = get_dib_stride(width, 32);
        offset = CGRectGetMinX(visrect) * 4 + (height - CGRectGetMaxY(visrect)) * bytes_per_row;
        size = min(CGRectGetHeight(visrect) * bytes_per_row,
                   surface->info.bmiHeader.biSizeImage - offset);

        if (copy_data)
        {
            CFDataRef data = CFDataCreate(NULL, (UInt8*)surface->bits + offset, size);
            provider = CGDataProviderCreateWithCFData(data);
            CFRelease(data);
        }
        else
            provider = CGDataProviderCreateWithData(NULL, surface->bits + offset, size, NULL);

        alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
        cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect),
                                8, 32, bytes_per_row, colorspace,
                                alphaInfo | kCGBitmapByteOrder32Little,
                                provider, NULL, FALSE, kCGRenderingIntentDefault);
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorspace);
    }

    return cgimage;
}
Example #10
0
bool PDFDocumentImage::dataChanged(bool allDataReceived)
{
    if (allDataReceived && !m_document) {
#if PLATFORM(MAC)
        // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
        // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
        RetainPtr<CFDataRef> data(AdoptCF, this->data()->createCFData());
#else
        // If no NSData is available, then we know SharedBuffer will always just be a vector.  That means no secret changes can occur to it behind the
        // scenes.  We use CFDataCreateWithBytesNoCopy in that case.
        RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(this->data()->data()), this->data()->size(), kCFAllocatorNull));
#endif
        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
        m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
        setCurrentPage(0);
    }
    return m_document; // return true if size is available
}
Example #11
0
bool PDFDocumentImage::dataChanged(bool allDataReceived)
{
    if (allDataReceived && !m_document) {
#if PLATFORM(MAC)
        // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
        // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
        RetainPtr<CFDataRef> data(AdoptCF, this->data()->createCFData());
        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
#else
        // Create a CGDataProvider to wrap the SharedBuffer.
        // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
        // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
        // is a requirement for using the GetBytePointer callback.
        CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 };
        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks));
#endif
        m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
        setCurrentPage(0);
    }
    return m_document; // return true if size is available
}
Example #12
0
void os_image_save_to_file(const char* filename, unsigned char* data, int width, int height, int channels) {
  assert((channels == 3) || (channels == 4));

  const int bytesPerRow = (width * channels);
  const int bytesPerImage = (bytesPerRow * height);
  const int bitsPerChannel = 8;
  const int bitsPerPixel = (bitsPerChannel * channels);

  CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
  CFDataRef rgbData = CFDataCreate(NULL, data, bytesPerImage);
  CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
  CGImageRef imageRef = CGImageCreate(
    width,
    height,
    bitsPerChannel,
    bitsPerPixel,
    bytesPerRow,
    colorspace,
    kCGBitmapByteOrderDefault,
    provider,
    NULL,
    true,
    kCGRenderingIntentDefault);
  CFRelease(rgbData);
  CGDataProviderRelease(provider);
  CGColorSpaceRelease(colorspace);

  CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const uint8_t*)filename, (CFIndex)strlen(filename), false);
  CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
  CGImageDestinationAddImage(destination, imageRef, nil);

  if (!CGImageDestinationFinalize(destination)) {
    fprintf(stderr, "Failed to write image to %s\n", filename);
  }

  CFRelease(destination);
  CFRelease(url);
  CGImageRelease(imageRef);
}
std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
{
    RetainPtr<CFDataRef> bufferData = buffer.createCFData();

#if CORETEXT_WEB_FONTS
    RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontManagerCreateFontDescriptorFromData(bufferData.get()));
    if (!fontDescriptor)
        return nullptr;

    return std::make_unique<FontCustomPlatformData>(fontDescriptor.get());

#else

    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(bufferData.get()));

    RetainPtr<CGFontRef> cgFontRef = adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return nullptr;

    return std::make_unique<FontCustomPlatformData>(cgFontRef.get());
#endif
}
Example #14
0
CGImageRef CGImageMaskCreateWithImageRef(CGImageRef imageRef) {
  size_t maskWidth = CGImageGetWidth(imageRef);
  size_t maskHeight = CGImageGetHeight(imageRef);
  size_t bytesPerRow = maskWidth;
  size_t bufferSize = maskWidth * maskHeight;

  CFMutableDataRef dataBuffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
  CFDataSetLength(dataBuffer, bufferSize);

  CGColorSpaceRef greyColorSpaceRef = CGColorSpaceCreateDeviceGray();
  CGContextRef ctx = CGBitmapContextCreate(CFDataGetMutableBytePtr(dataBuffer),
                                           maskWidth,
                                           maskHeight,
                                           8,
                                           bytesPerRow,
                                           greyColorSpaceRef,
                                           kCGImageAlphaNone);

  CGContextDrawImage(ctx, CGRectMake(0, 0, maskWidth, maskHeight), imageRef);
  CGContextRelease(ctx);

  CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataBuffer);
  CGImageRef maskImageRef = CGImageMaskCreate(maskWidth,
                                              maskHeight,
                                              8,
                                              8,
                                              bytesPerRow,
                                              dataProvider,
                                              NULL,
                                              FALSE);

  CGDataProviderRelease(dataProvider);
  CGColorSpaceRelease(greyColorSpaceRef);
  CFRelease(dataBuffer);

  return maskImageRef;
}
Example #15
0
//============================================================================
//		NCGImage::GetObject : Get the object.
//----------------------------------------------------------------------------
NCFObject NCGImage::GetObject(bool cloneData) const
{	NCFObject			cgDataProvider, theObject;
	CGBitmapInfo		bitmapInfo;
	NCFData				theData;



	// Get the state we need
	bitmapInfo = GetBitmapInfo(GetFormat());
	theData    = GetData();



	// Prepare the data
	if (cloneData)
		cgDataProvider.SetObject(CGDataProviderCreateWithCFData(theData.GetObject()));
	else
		cgDataProvider.SetObject(CGDataProviderCreateWithData(NULL, theData.GetData(), theData.GetSize(), NULL));

	if (!cgDataProvider.IsValid())
		return(theObject);



	// Get the object
	theObject.SetObject(CGImageCreate(	GetWidth(),
										GetHeight(),
										GetBitsPerComponent(),
										GetBitsPerPixel(),
										GetBytesPerRow(),
										NCGColor::GetDeviceRGB(),
										bitmapInfo, cgDataProvider,
										NULL, false, kCGRenderingIntentDefault));

	return(theObject);
}
Example #16
0
void PDFDocumentImage::createPDFDocument()
{
    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(data()->createCFData().get()));
    m_document = adoptCF(CGPDFDocumentCreateWithProvider(dataProvider.get()));
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

#if ENABLE(OPENTYPE_SANITIZER)
    OpenTypeSanitizer sanitizer(buffer);
    RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
    if (!transcodeBuffer)
        return 0; // validation failed.
    buffer = transcodeBuffer.get();
#endif

    ATSFontContainerRef containerRef = 0;
    ATSFontRef fontRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
    
    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
#ifndef BUILDING_ON_TIGER
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
#endif
	
#if PLATFORM(APOLLO)
	// On Leopard the CGFontGetNumberOfGlyphs call is necessary to reject invalid fonts
	// On Snow Leopard this happens at ATSFontActivateFromMemory
	if (isOsLeopardOrGreater()) {
		static _CGFontGetNumberOfGlyphsFunc CGFontGetNumberOfGlyphsFunc = getCGFontGetNumberOfGlyphsFunc();
		
		if (CGFontGetNumberOfGlyphsFunc && cgFontRef && !CGFontGetNumberOfGlyphsFunc(cgFontRef.get())) {
			cgFontRef = 0;
		}
	}
#endif
	
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)

    return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef());
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

#if USE(OPENTYPE_SANITIZER)
    OpenTypeSanitizer sanitizer(buffer);
    RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
    if (!transcodeBuffer)
        return 0; // validation failed.
    buffer = transcodeBuffer.get();
#else
    RefPtr<SharedBuffer> sfntBuffer;
    if (isWOFF(buffer)) {
        Vector<char> sfnt;
        if (!convertWOFFToSfnt(buffer, sfnt))
            return 0;

        sfntBuffer = SharedBuffer::adoptVector(sfnt);
        buffer = sfntBuffer.get();
    }
#endif

    ATSFontContainerRef containerRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#ifndef BUILDING_ON_LEOPARD
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));

    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontRef fontRef = 0;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_LEOPARD)

    FontCustomPlatformData* fontCustomPlatformData = new FontCustomPlatformData(containerRef, cgFontRef.releaseRef());
#if USE(SKIA_ON_MAC_CHROMIUM)
    RemoteFontStream* stream = new RemoteFontStream(buffer);
    fontCustomPlatformData->m_typeface = SkTypeface::CreateFromStream(stream);
    stream->unref();
#endif
    return fontCustomPlatformData;
}
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);
}
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);
    
}
Example #21
0
/***********************************************************************
 *              create_cgimage_from_icon_bitmaps
 */
CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP hbmColor,
                                            unsigned char *color_bits, int color_size, HBITMAP hbmMask,
                                            unsigned char *mask_bits, int mask_size, int width,
                                            int height, int istep)
{
    int i, has_alpha = FALSE;
    DWORD *ptr;
    CGBitmapInfo alpha_format;
    CGColorSpaceRef colorspace;
    CFDataRef data;
    CGDataProviderRef provider;
    CGImageRef cgimage;

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

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

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

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

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

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

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

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

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

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

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

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

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

    return cgimage;
}
Example #22
0
/***********************************************************************
 *              create_app_icon_images
 */
CFArrayRef create_app_icon_images(void)
{
    HRSRC res_info;
    HGLOBAL res_data;
    GRPICONDIR *icon_dir;
    CFMutableArrayRef images = NULL;
    int i;

    TRACE("()\n");

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

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

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

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

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

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

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

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

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

        if (found_better_bpp) continue;

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

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

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

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

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

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

        FreeResource(icon_res_data);
    }

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

    return images;
}
Example #23
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