/* 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(); }
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; }
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()); }
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 }
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()); }
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; }
/* 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(); }
/*********************************************************************** * 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; }
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 }
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 }
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 }
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; }
//============================================================================ // 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); }
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); }
/*********************************************************************** * 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; }
/*********************************************************************** * 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; }
// 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