void TIPGradientAxialFillPath( CGContextRef theContext, TIPGradientRef theGradient, CGPathRef thePath, float angle) { CGRect boundingRect = CGPathGetBoundingBox(thePath); CGPoint startPoint; CGPoint endPoint; TIPGradientFindEndpointsForRotation(boundingRect,angle,&startPoint,&endPoint); // CoreGraphics Calls CGContextSaveGState(theContext); CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGShadingRef myCGShading = CGShadingCreateAxial(colorSpace,startPoint,endPoint,theGradient->gradientFunction,FALSE,FALSE); CGContextAddPath(theContext,thePath); CGContextClip(theContext); CGContextDrawShading(theContext,myCGShading); CGShadingRelease(myCGShading); CGColorSpaceRelease(colorSpace); CGContextRestoreGState(theContext); }
void CanvasRenderingContext2D::applyShadow() { GraphicsContext* c = drawingContext(); if (!c) return; // FIXME: Do this through platform-independent GraphicsContext API. #if PLATFORM(CG) RGBA32 rgba = state().m_shadowColor.isEmpty() ? 0 : CSSParser::parseColor(state().m_shadowColor); const CGFloat components[4] = { ((rgba >> 16) & 0xFF) / 255.0f, ((rgba >> 8) & 0xFF) / 255.0f, (rgba & 0xFF) / 255.0f, ((rgba >> 24) & 0xFF) / 255.0f }; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorRef color = CGColorCreate(colorSpace, components); CGColorSpaceRelease(colorSpace); CGContextSetShadowWithColor(c->platformContext(), state().m_shadowOffset, state().m_shadowBlur, color); CGColorRelease(color); #endif }
/** * Converts a QPixmap to a CGImage. * * @returns CGImageRef for the new image. (Remember to release it when finished with it.) * @param aPixmap Pointer to the QPixmap instance to convert. */ CGImageRef darwinToCGImageRef(const QImage *pImage) { QImage *imageCopy = new QImage(*pImage); /** @todo this code assumes 32-bit image input, the lazy bird convert image to 32-bit method is anything but optimal... */ if (imageCopy->format() != QImage::Format_ARGB32) *imageCopy = imageCopy->convertToFormat(QImage::Format_ARGB32); Assert(!imageCopy->isNull()); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGDataProviderRef dp = CGDataProviderCreateWithData(imageCopy, pImage->bits(), pImage->numBytes(), darwinDataProviderReleaseQImage); CGBitmapInfo bmpInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; CGImageRef ir = CGImageCreate(imageCopy->width(), imageCopy->height(), 8, 32, imageCopy->bytesPerLine(), cs, bmpInfo, dp, 0 /*decode */, 0 /* shouldInterpolate */, kCGRenderingIntentDefault); CGColorSpaceRelease(cs); CGDataProviderRelease(dp); Assert(ir); return ir; }
void QuartzWindow::close() { if (!is_open()) return; CGrafPtr gp = GetWindowPort(my_window()); if (gp != NULL) // already closed by std handler QDEndCGContext( gp, &myContext ); CGColorRelease((CGColorRef) _red); CGColorRelease((CGColorRef) _yellow); CGColorRelease((CGColorRef) _black); CGColorRelease((CGColorRef) _gray); CGColorRelease((CGColorRef) _white); CGColorSpaceRelease(_color_space); WindowSet::rm_window(my_window()); if (gp != NULL) DisposeWindow(my_window()); _is_open = false; DisposeEventHandlerUPP(_my_event_handler_upp); DisposeEventHandlerUPP(_my_spy_event_handler_upp); _my_event_handler = NULL; _my_spy_event_handler = NULL; _quartz_win = NULL; }
CGShadingRef CanvasGradient::platformShading() { if (m_shading) return m_shading; const CGFloat intervalRanges[2] = { 0, 1 }; const CGFloat colorComponentRanges[4 * 2] = { 0, 1, 0, 1, 0, 1, 0, 1 }; const CGFunctionCallbacks gradientCallbacks = { 0, gradientCallback, 0 }; CGFunctionRef colorFunction = CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if (m_radial) m_shading = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction, true, true); else m_shading = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction, true, true); CGColorSpaceRelease(colorSpace); CGFunctionRelease(colorFunction); return m_shading; }
CGImageRef CGimageResize(CGImageRef image, CGSize maxSize) { // calcualte size CGFloat ratio = MAX(CGImageGetWidth(image)/maxSize.width,CGImageGetHeight(image)/maxSize.height); size_t width = CGImageGetWidth(image)/ratio; size_t height = CGImageGetHeight(image)/ratio; // resize CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width*4, colorspace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorspace); if(context == NULL) return nil; // draw image to context (resizing it) CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); // extract resulting image from context CGImageRef imgRef = CGBitmapContextCreateImage(context); CGContextRelease(context); return imgRef; }
static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) { if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { return NULL; } CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; if (pBitmap->HasAlpha()) { bitmapInfo |= kCGImageAlphaPremultipliedFirst; } else { bitmapInfo |= kCGImageAlphaNoneSkipFirst; } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8, pBitmap->GetPitch(), colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); return context; }
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); }
bool GiCanvasIosImpl::createBufferBitmap(float width, float height) { width *= _scale; // 点数宽度转为像素宽度 height *= _scale; if (width < 4 || height < 4 || width > 2049 || height > 2049) { return false; } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); _buffctx = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); // 坐标系改为Y朝下,原点在左上角,这样除了放大倍数为1外,其余就与 _context 坐标系一致 if (_buffctx) { CGContextTranslateCTM(_buffctx, 0, height); CGContextScaleCTM(_buffctx, _scale, - _scale); } return !!_buffctx; }
bool nglImageCGCodec::Feed(nglIStream* pIStream) { if (!mpCGImage) { mpCGImage = ReadInfo(pIStream); ///< shall allocate the buffer } if (!mpCGImage) return false; mpIStream = pIStream; // Use the generic RGB color space. CGColorSpaceRef pCGColors = CGColorSpaceCreateDeviceRGB(); if (pCGColors == NULL) { NGL_OUT(_T("nglImageCGCodec::Feed Error allocating color space\n")); return false; } nglImageInfo info; mpImage->GetInfo(info); NGL_ASSERT(info.mpBuffer); // Create the bitmap context. // The image will be converted to the format specified here by CGBitmapContextCreate. CGContextRef pCGContext = CGBitmapContextCreate(info.mpBuffer, info.mWidth, info.mHeight, info.mBitDepth/4, info.mBytesPerLine, pCGColors, kCGImageAlphaPremultipliedLast);//kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(pCGColors); CGRect rect = { {0,0}, {info.mWidth, info.mHeight} }; CGContextClearRect(pCGContext, rect); CGContextDrawImage(pCGContext, rect, mpCGImage); CGContextRelease(pCGContext); SendData(1.0f); return (pIStream->GetState()==eStreamWait) || (pIStream->GetState()==eStreamReady);; }
CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, CGColorSpaceRef colorSpace) { size_t bitsPerComponent SK_INIT_TO_AVOID_WARNING; CGBitmapInfo info SK_INIT_TO_AVOID_WARNING; SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info); if (NULL == bitmap) { return NULL; } const int w = bitmap->width(); const int h = bitmap->height(); const size_t s = bitmap->getSize(); // our provider "owns" the bitmap*, and will take care of deleting it // we initially lock it, so we can access the pixels. The bitmap will be deleted in the release // proc, which will in turn unlock the pixels bitmap->lockPixels(); CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s, SkBitmap_ReleaseInfo); bool releaseColorSpace = false; if (NULL == colorSpace) { colorSpace = CGColorSpaceCreateDeviceRGB(); releaseColorSpace = true; } CGImageRef ref = CGImageCreate(w, h, bitsPerComponent, bitmap->bytesPerPixel() * 8, bitmap->rowBytes(), colorSpace, info, dataRef, NULL, false, kCGRenderingIntentDefault); if (releaseColorSpace) { CGColorSpaceRelease(colorSpace); } CGDataProviderRelease(dataRef); return ref; }
int main(int argc, const char * argv[]) { size_t width = 2000; size_t height = 2000; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(nullptr, width, height, 8, width * 4, colorSpace, kCGImageAlphaNoneSkipLast); CGColorSpaceRelease(colorSpace); const std::vector<uint8_t> fontVector = generateFont(); std::ofstream outputFile("/Volumes/Data/home/mmaxfield/tmp/output.otf", std::ios::out | std::ios::binary); for (uint8_t b : fontVector) outputFile << b; outputFile.close(); CFDataRef fontData = CFDataCreate(kCFAllocatorDefault, fontVector.data(), fontVector.size()); CTFontDescriptorRef fontDescriptor = CTFontManagerCreateFontDescriptorFromData(fontData); CFRelease(fontData); CFTypeRef featureValues[] = { CFSTR("liga"), CFSTR("clig"), CFSTR("dlig"), CFSTR("hlig"), CFSTR("calt"), CFSTR("subs"), CFSTR("sups"), CFSTR("smcp"), CFSTR("c2sc"), CFSTR("pcap"), CFSTR("c2pc"), CFSTR("unic"), CFSTR("titl"), CFSTR("onum"), CFSTR("pnum"), CFSTR("tnum"), CFSTR("frac"), CFSTR("afrc"), CFSTR("ordn"), CFSTR("zero"), CFSTR("hist"), CFSTR("jp78"), CFSTR("jp83"), CFSTR("jp90"), CFSTR("jp04"), CFSTR("smpl"), CFSTR("trad"), CFSTR("fwid"), CFSTR("pwid"), CFSTR("ruby") }; CFArrayRef features = CFArrayCreate(kCFAllocatorDefault, featureValues, 30, &kCFTypeArrayCallBacks); for (CFIndex i = 0; i < CFArrayGetCount(features); ++i) { drawTextWithFeature(context, fontDescriptor, static_cast<CFStringRef>(CFArrayGetValueAtIndex(features, i)), 1, CGPointMake(25, 1950 - 50 * i)); drawTextWithFeature(context, fontDescriptor, static_cast<CFStringRef>(CFArrayGetValueAtIndex(features, i)), 0, CGPointMake(25, 1925 - 50 * i)); } CFRelease(features); CFRelease(fontDescriptor); CGImageRef image = CGBitmapContextCreateImage(context); CGContextRelease(context); CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/Volumes/Data/home/mmaxfield/tmp/output.png"), kCFURLPOSIXPathStyle, FALSE); CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, nullptr); CFRelease(url); CGImageDestinationAddImage(imageDestination, image, nullptr); CGImageRelease(image); CGImageDestinationFinalize(imageDestination); CFRelease(imageDestination); return 0; }
static CGContextRef CGContextWithHDC(HDC hdc, bool hasAlpha) { HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); BITMAP info; GetObject(bitmap, sizeof(info), &info); ASSERT(info.bmBitsPixel == 32); CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | (hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8, info.bmWidthBytes, deviceRGB, bitmapInfo); CGColorSpaceRelease(deviceRGB); // Flip coords CGContextTranslateCTM(context, 0, info.bmHeight); CGContextScaleCTM(context, 1, -1); // Put the HDC In advanced mode so it will honor affine transforms. SetGraphicsMode(hdc, GM_ADVANCED); return context; }
HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef) { BitmapInfo bmpInfo = BitmapInfo::create(size); LPVOID bits; HBITMAP hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0); if (!targetRef) return hbmp; CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); CGContextRef bitmapContext = CGBitmapContextCreate(bits, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, 8, bmpInfo.bmiHeader.biWidth * 4, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst); CGColorSpaceRelease(deviceRGB); if (!bitmapContext) { DeleteObject(hbmp); return 0; } *targetRef = bitmapContext; return hbmp; }
OpBitmap* CreateOpBitmapFromIcon(IconRef iconin, int cx, int cy) { if (iconin) { OpBitmap* bm; if (OpStatus::IsSuccess(OpBitmap::Create(&bm, cx, cy, FALSE, TRUE, 0, 0, TRUE))) { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); void* p = bm->GetPointer(OpBitmap::ACCESS_WRITEONLY); memset(p, 0, bm->Height()*bm->GetBytesPerLine()); CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal; CGContextRef ctx = CGBitmapContextCreate(p, bm->Width(), bm->Height(), 8, bm->GetBytesPerLine(), colorSpace, alpha); CGColorSpaceRelease(colorSpace); CGRect cgrect = CGRectMake(0,0,cx,cy); PlotIconRefInContext(ctx, &cgrect, kAlignAbsoluteCenter, kTransformNone, NULL, kPlotIconRefNormalFlags, iconin); CGContextFlush(ctx); CGContextRelease(ctx); bm->ReleasePointer(); return bm; } } return NULL; }
void CanvasRenderingContext2D::applyStrokePattern() { GraphicsContext* c = drawingContext(); if (!c) return; #if PLATFORM(CG) // Check for case where the pattern is already set. CGAffineTransform m = CGContextGetCTM(c->platformContext()); if (state().m_appliedStrokePattern && CGAffineTransformEqualToTransform(m, state().m_strokeStylePatternTransform)) return; CanvasPattern* pattern = state().m_strokeStyle->pattern(); if (!pattern) return; CGPatternRef platformPattern = pattern->createPattern(m); if (!platformPattern) return; CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0); CGContextSetStrokeColorSpace(c->platformContext(), patternSpace); CGColorSpaceRelease(patternSpace); const CGFloat patternAlpha = 1; CGContextSetStrokePattern(c->platformContext(), platformPattern, &patternAlpha); CGPatternRelease(platformPattern); state().m_strokeStylePatternTransform = m; #elif PLATFORM(QT) fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyStrokePattern\n"); #elif PLATFORM(CAIRO) notImplemented(); #endif state().m_appliedStrokePattern = true; }
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; }
GLuint load_texure(const char *filename) { GLuint texid; // ImageIO loader CFStringRef path = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8); CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0); CGImageSourceRef imagesource = CGImageSourceCreateWithURL(url, NULL); CGImageRef image = CGImageSourceCreateImageAtIndex (imagesource, 0, NULL); size_t width = CGImageGetWidth(image); size_t height = CGImageGetHeight(image); CGRect rect = {{0, 0}, {width, height}}; void * data = malloc(width * height * 4); CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGContextRef myBitmapContext = CGBitmapContextCreate (data, width, height, 8, width*4, space, kCGImageAlphaPremultipliedFirst); CGContextDrawImage(myBitmapContext, rect, image); CGContextRelease(myBitmapContext); CGColorSpaceRelease(space); CGImageRelease(image); CFRelease(imagesource); CFRelease(url); CFRelease(path); glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); free(data); return texid; }
/* Create a CGImageRef from osg::Image. * Code adapted from * http://developer.apple.com/samplecode/OpenGLScreenSnapshot/listing2.html */ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) { size_t image_width = osg_image.s(); size_t image_height = osg_image.t(); /* From Apple's header for CGBitmapContextCreate() * Each row of the bitmap consists of `bytesPerRow' bytes, which must be at * least `(width * bitsPerComponent * number of components + 7)/8' bytes. */ size_t target_bytes_per_row; CGColorSpaceRef color_space; CGBitmapInfo bitmap_info; /* From what I can figure out so far... * We need to create a CGContext connected to the data we want to save * and then call CGBitmapContextCreateImage() on that context to get * a CGImageRef. * However, OS X only allows 4-component image formats (e.g. RGBA) and not * just RGB for the RGB-based CGContext. So for a 24-bit image coming in, * we need to expand the data to 32-bit. * The easiest and fastest way to do that is through the vImage framework * which is part of the Accelerate framework. * Also, the osg::Image data coming in is inverted from what we want, so * we need to invert the image too. Since the osg::Image is const, * we don't want to touch the data, so again we turn to the vImage framework * and invert the data. */ vImage_Buffer vimage_buffer_in = { (void*)osg_image.data(), // need to override const, but we don't modify the data so it's safe image_height, image_width, osg_image.getRowSizeInBytes() }; void* out_image_data; vImage_Buffer vimage_buffer_out = { NULL, // will fill-in in switch image_height, image_width, 0 // will fill-in in switch }; vImage_Error vimage_error_flag; // FIXME: Do I want to use format, type, or internalFormat? switch(osg_image.getPixelFormat()) { case GL_LUMINANCE: { bitmap_info = kCGImageAlphaNone; target_bytes_per_row = (image_width * 8 + 7)/8; //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); color_space = CGColorSpaceCreateDeviceGray(); if(NULL == color_space) { return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image vimage_error_flag = vImageVerticalReflect_Planar8( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_LUMINANCE, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_ALPHA: { bitmap_info = kCGImageAlphaOnly; target_bytes_per_row = (image_width * 8 + 7)/8; // According to: // http://developer.apple.com/qa/qa2001/qa1037.html // colorSpace=NULL is for alpha only color_space = NULL; // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image vimage_error_flag = vImageVerticalReflect_Planar8( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_ALPHA, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); return NULL; } break; } /* case GL_LUMINANCE_ALPHA: { // I don't know if we can support this. // The qa1037 doesn't show both gray+alpha. break; } */ case GL_RGB: { bitmap_info = kCGImageAlphaNoneSkipFirst; target_bytes_per_row = (image_width * 8 * 4 + 7)/8; //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } // Use vImage to get an RGB buffer into ARGB. vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; vimage_error_flag = vImageConvert_RGB888toARGB8888( &vimage_buffer_in, NULL, // we don't have a buffer containing alpha values 255, // The alpha value we want given to all pixels since we don't have a buffer &vimage_buffer_out, 0, // premultiply? kvImageNoFlags // Only responds to kvImageDoNotTile, but I think we want tiling/threading ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageConvert_RGB888toARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } // Now invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_out, &vimage_buffer_out, // reuse the same buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_RGBA: { bitmap_info = kCGImageAlphaPremultipliedLast; target_bytes_per_row = osg_image.getRowSizeInBytes(); //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } case GL_BGRA: { if(GL_UNSIGNED_INT_8_8_8_8_REV == osg_image.getDataType()) { #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif } else { // FIXME: Don't know how to handle this case bitmap_info = kCGImageAlphaPremultipliedLast; } target_bytes_per_row = osg_image.getRowSizeInBytes(); //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } // out_image_data = calloc(target_bytes_per_row, image_height); out_image_data = malloc(target_bytes_per_row * image_height); if(NULL == out_image_data) { OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } vimage_buffer_out.data = out_image_data; vimage_buffer_out.rowBytes = target_bytes_per_row; // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... &vimage_buffer_out, // don't reuse the buffer kvImageNoFlags ); if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; } // FIXME: Handle other cases. // Use vImagePermuteChannels_ARGB8888 to swizzle bytes default: { OSG_WARN << "In CreateCGImageFromOSGData: Sorry support for this format is not implemented." << std::endl; return NULL; break; } } CGContextRef bitmap_context = CGBitmapContextCreate( vimage_buffer_out.data, vimage_buffer_out.width, vimage_buffer_out.height, 8, vimage_buffer_out.rowBytes, color_space, bitmap_info ); /* Done with color space */ CGColorSpaceRelease(color_space); if(NULL == bitmap_context) { free(out_image_data); return NULL; } /* Make an image out of our bitmap; does a cheap vm_copy of the bitmap */ CGImageRef image_ref = CGBitmapContextCreateImage(bitmap_context); /* Done with data */ free(out_image_data); /* Done with bitmap_context */ CGContextRelease(bitmap_context); return image_ref; }
bool sdl_osd_interface::font_get_bitmap(osd_font font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) { UniChar uni_char; CGGlyph glyph; CTFontRef ct_font = (CTFontRef)font; const CFIndex count = 1; CGRect bounding_rect, success_rect; CGContextRef context_ref; if( chnum == ' ' ) { uni_char = 'n'; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); uni_char = chnum; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); } else { uni_char = chnum; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); } if( CGRectEqualToRect( success_rect, CGRectNull ) == false ) { size_t bitmap_width; size_t bitmap_height; bitmap_width = ceilf(bounding_rect.size.width * EXTRA_WIDTH); bitmap_width = bitmap_width == 0 ? 1 : bitmap_width; bitmap_height = ceilf( (CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font)) * EXTRA_HEIGHT); xoffs = yoffs = 0; width = bitmap_width; size_t bits_per_component; CGColorSpaceRef color_space; CGBitmapInfo bitmap_info = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; color_space = CGColorSpaceCreateDeviceRGB(); bits_per_component = 8; bitmap.allocate(bitmap_width, bitmap_height); context_ref = CGBitmapContextCreate( bitmap.raw_pixptr(0), bitmap_width, bitmap_height, bits_per_component, bitmap.rowpixels()*4, color_space, bitmap_info ); if( context_ref != NULL ) { CGFontRef font_ref; font_ref = CTFontCopyGraphicsFont( ct_font, NULL ); CGContextSetTextPosition(context_ref, -bounding_rect.origin.x*EXTRA_WIDTH, CTFontGetDescent(ct_font)+CTFontGetLeading(ct_font) ); CGContextSetRGBFillColor(context_ref, 1.0, 1.0, 1.0, 1.0); CGContextSetFont( context_ref, font_ref ); CGContextSetFontSize( context_ref, POINT_SIZE ); CGContextShowGlyphs( context_ref, &glyph, count ); CGFontRelease( font_ref ); CGContextRelease( context_ref ); } CGColorSpaceRelease( color_space ); } return bitmap.valid(); }
block_t *screen_Capture(demux_t *p_demux) { demux_sys_t *p_sys = p_demux->p_sys; screen_data_t *p_data = (screen_data_t *)p_sys->p_data; block_t *p_block; CGRect capture_rect; CGImageRef image; /* forward cursor location */ CGPoint cursor_pos; CGEventRef event = CGEventCreate(NULL); cursor_pos = CGEventGetLocation(event); CFRelease(event); cursor_pos.x -= p_data->screen_left; cursor_pos.y -= p_data->screen_top; if (p_sys->b_follow_mouse) FollowMouse(p_sys, cursor_pos.x, cursor_pos.y); capture_rect.origin.x = p_sys->i_left; capture_rect.origin.y = p_sys->i_top; capture_rect.size.width = p_data->width; capture_rect.size.height = p_data->height; /* fetch image data */ image = CGDisplayCreateImageForRect(p_data->display_id, capture_rect); if (!image) { msg_Warn(p_demux, "no image!"); return NULL; } /* create offscreen context */ if (!p_data->offscreen_context) { CGColorSpaceRef colorspace; colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); p_data->offscreen_bitmap_size = p_sys->fmt.video.i_width * p_sys->fmt.video.i_height * 4; p_data->offscreen_bitmap = calloc(1, p_data->offscreen_bitmap_size); if (p_data->offscreen_bitmap == NULL) { msg_Warn(p_demux, "can't allocate offscreen bitmap"); CFRelease(image); return NULL; } p_data->offscreen_context = CGBitmapContextCreate(p_data->offscreen_bitmap, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height, 8, p_sys->fmt.video.i_width * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); if (!p_data->offscreen_context) { msg_Warn(p_demux, "can't create offscreen bitmap context"); CFRelease(image); return NULL; } CGColorSpaceRelease(colorspace); p_data->offscreen_rect = CGRectMake(0, 0, p_sys->fmt.video.i_width, p_sys->fmt.video.i_height); } /* fetch cursor image */ CGImageRef cursor_image; int cid = CGSMainConnectionID(); CGPoint outHotSpot; cursor_image = CGSCreateRegisteredCursorImage(cid, (char *)"com.apple.coregraphics.GlobalCurrent", &outHotSpot); /* draw screen image and cursor image */ CGRect cursor_rect; cursor_rect.size.width = CGImageGetWidth(cursor_image); cursor_rect.size.height = CGImageGetHeight(cursor_image); cursor_rect.origin.x = cursor_pos.x - p_sys->i_left - outHotSpot.x; cursor_rect.origin.y = p_data->offscreen_rect.size.height - (cursor_pos.y + cursor_rect.size.height - p_sys->i_top - outHotSpot.y); CGContextDrawImage(p_data->offscreen_context, p_data->offscreen_rect, image); CGContextDrawImage(p_data->offscreen_context, cursor_rect, cursor_image); /* build block */ p_block = block_Alloc(p_data->offscreen_bitmap_size); if (!p_block) { msg_Warn(p_demux, "can't get block"); CFRelease(image); return NULL; } memmove(p_block->p_buffer, p_data->offscreen_bitmap, p_data->offscreen_bitmap_size); CFRelease(image); return p_block; }
CGImageRef CreateCGImage(CGDataProviderReleaseDataCallback aCallback, void *aInfo, const void *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { //XXX: we should avoid creating this colorspace everytime CGColorSpaceRef colorSpace = nullptr; CGBitmapInfo bitinfo = 0; int bitsPerComponent = 0; int bitsPerPixel = 0; switch (aFormat) { case SurfaceFormat::B8G8R8A8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case SurfaceFormat::B8G8R8X8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case SurfaceFormat::A8: // XXX: why don't we set a colorspace here? bitsPerComponent = 8; bitsPerPixel = 8; break; default: MOZ_CRASH(); } size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height); if (bufLen == 0) { return nullptr; } CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo, aData, bufLen, aCallback); CGImageRef image; if (aFormat == SurfaceFormat::A8) { CGFloat decode[] = {1.0, 0.0}; image = CGImageMaskCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, dataProvider, decode, true); } else { image = CGImageCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, colorSpace, bitinfo, dataProvider, nullptr, true, kCGRenderingIntentDefault); } CGDataProviderRelease(dataProvider); CGColorSpaceRelease(colorSpace); return image; }
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight) { if (URIUtils::GetExtension(texturePath).Equals(".dds")) { // special case for DDS images CDDSImage image; if (image.ReadFile(texturePath)) { Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false); return true; } return false; } #if defined(__APPLE__) && defined(__arm__) XFILE::CFile file; UInt8 *imageBuff = NULL; int64_t imageBuffSize = 0; //open path and read data to buffer //this handles advancedsettings.xml pathsubstitution //and resulting networking if (file.Open(texturePath, 0)) { imageBuffSize =file.GetLength(); imageBuff = new UInt8[imageBuffSize]; imageBuffSize = file.Read(imageBuff, imageBuffSize); file.Close(); } else { CLog::Log(LOGERROR, "Texture manager unable to open file %s", texturePath.c_str()); return false; } if (imageBuffSize <= 0) { CLog::Log(LOGERROR, "Texture manager read texture file failed."); delete [] imageBuff; return false; } // create the image from buffer; CGImageSourceRef imageSource; // create a CFDataRef using CFDataCreateWithBytesNoCopy and kCFAllocatorNull for deallocator. // this allows us to do a nocopy reference and we handle the free of imageBuff CFDataRef cfdata = CFDataCreateWithBytesNoCopy(NULL, imageBuff, imageBuffSize, kCFAllocatorNull); imageSource = CGImageSourceCreateWithData(cfdata, NULL); if (imageSource == nil) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CSpecialProtocol::TranslatePath(texturePath).c_str()); CFRelease(cfdata); delete [] imageBuff; return false; } CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); int rotate = 0; if (autoRotate) { // get the orientation of the image for displaying it correctly CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource,0, NULL); if (imagePropertiesDictionary != nil) { CFNumberRef orientation = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyOrientation); if (orientation != nil) { int value = 0; CFNumberGetValue(orientation, kCFNumberIntType, &value); if (value) rotate = value - 1; } CFRelease(imagePropertiesDictionary); } } CFRelease(imageSource); unsigned int width = CGImageGetWidth(image); unsigned int height = CGImageGetHeight(image); m_hasAlpha = (CGImageGetAlphaInfo(image) != kCGImageAlphaNone); if (originalWidth) *originalWidth = width; if (originalHeight) *originalHeight = height; // check texture size limits and limit to screen size - preserving aspectratio of image if ( width > g_Windowing.GetMaxTextureSize() || height > g_Windowing.GetMaxTextureSize() ) { float aspect; if ( width > height ) { aspect = (float)width / (float)height; width = g_Windowing.GetWidth(); height = (float)width / (float)aspect; } else { aspect = (float)height / (float)width; height = g_Windowing.GetHeight(); width = (float)height / (float)aspect; } CLog::Log(LOGDEBUG, "Texture manager texture clamp:new texture size: %i x %i", width, height); } // use RGBA to skip swizzling Allocate(width, height, XB_FMT_RGBA8); m_orientation = rotate; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // hw convert jmpeg to RGBA CGContextRef context = CGBitmapContextCreate(m_pixels, width, height, 8, GetPitch(), colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); // Flip so that it isn't upside-down //CGContextTranslateCTM(context, 0, height); //CGContextScaleCTM(context, 1.0f, -1.0f); #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 CGContextClearRect(context, CGRectMake(0, 0, width, height)); #else #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 // (just a way of checking whether we're running in 10.5 or later) if (CGContextDrawLinearGradient == 0) CGContextClearRect(context, CGRectMake(0, 0, width, height)); else #endif CGContextSetBlendMode(context, kCGBlendModeCopy); #endif //CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); CGContextRelease(context); CGImageRelease(image); CFRelease(cfdata); delete [] imageBuff; #else DllImageLib dll; if (!dll.Load()) return false; ImageInfo image; memset(&image, 0, sizeof(image)); unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); if(!dll.LoadImage(texturePath.c_str(), width, height, &image)) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str()); return false; } m_hasAlpha = NULL != image.alpha; Allocate(image.width, image.height, XB_FMT_A8R8G8B8); if (autoRotate && image.exifInfo.Orientation) m_orientation = image.exifInfo.Orientation - 1; if (originalWidth) *originalWidth = image.originalwidth; if (originalHeight) *originalHeight = image.originalheight; unsigned int dstPitch = GetPitch(); unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes unsigned char *dst = m_pixels; unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3) { dst2[0] = src2[0]; dst2[1] = src2[1]; dst2[2] = src2[2]; dst2[3] = 0xff; } src -= srcPitch; dst += dstPitch; } if(image.alpha) { dst = m_pixels + 3; src = image.alpha + (m_imageHeight - 1) * m_imageWidth; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2+=4, src2++) *dst2 = *src2; src -= m_imageWidth; dst += dstPitch; } } dll.ReleaseImage(&image); #endif ClampToEdge(); return true; }
bool GCPVideoRenderer::OnWindowRefresh(FB::RefreshEvent* pEvt) { FB::CoreGraphicsDraw* pCgDrawEvt(static_cast<FB::CoreGraphicsDraw*>(pEvt)); CGContextRef pContext = pCgDrawEvt->context; boost::mutex::scoped_lock winLock(m_winMutex); const int stride = m_width*4; const int frameBufferSize = m_height*stride; static SInt32 osMajorVersion = 0; static SInt32 osMinorVersion = 0; static CGInterpolationQuality interpolationMode = kCGInterpolationNone; if(0 == osMajorVersion || 0 == osMinorVersion) { if(noErr != Gestalt(gestaltSystemVersionMajor, &osMajorVersion)) { osMajorVersion = 10; } if(noErr != Gestalt(gestaltSystemVersionMinor, &osMinorVersion)) { osMinorVersion = 6; } if(10 <= osMajorVersion && 7 <= osMinorVersion) { interpolationMode = kCGInterpolationDefault; } } if(NULL == pContext || NULL == m_pFrameBuffer.get()) { return false; } int winWidth = pCgDrawEvt->bounds.right - pCgDrawEvt->bounds.left; int winHeight = pCgDrawEvt->bounds.bottom - pCgDrawEvt->bounds.top; if(winWidth<=1 || winHeight<=1) return false; CGContextSaveGState(pContext); CGContextSetShouldAntialias(pContext, true); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGImageRef cgImage = CGImageCreate(m_width, m_height, 8, 32, stride, colorSpace, kCGImageAlphaNoneSkipLast, CGDataProviderCreateWithData(NULL, m_pFrameBuffer.get(), frameBufferSize, NULL), NULL, false, kCGRenderingIntentDefault); if(NULL == cgImage) { CGColorSpaceRelease(colorSpace); CGContextRestoreGState(pContext); return false; } CGContextSetInterpolationQuality(pContext, interpolationMode); CGContextTranslateCTM(pContext, 0, winHeight); CGContextScaleCTM(pContext, 1, -1); CGContextDrawImage(pContext, CGRectMake(0, 0, winWidth, winHeight), cgImage); CGImageRelease(cgImage); CGColorSpaceRelease(colorSpace); CGContextRestoreGState(pContext); return true; }
static IconRef CreateIconRefFromImage (CGImageRef srcImage, CGRect srcRect) { OSStatus err; CGContextRef cctx, actx; CGColorSpaceRef color; CGRect dstRect; IconRef iconRef; IconFamilyHandle icns; Handle hdl; SInt32 size; UInt32 rgb[kIconSize * kIconSize]; UInt8 alp[kIconSize * kIconSize]; srcRect.origin.y = CGImageGetHeight(srcImage) - srcRect.origin.y - kIconSize; color = CGColorSpaceCreateDeviceRGB(); if (color) { cctx = CGBitmapContextCreate(rgb, kIconSize, kIconSize, 8, kIconSize * 4, color, kCGImageAlphaNoneSkipFirst); if (cctx) { dstRect = CGRectMake(0, 0, kIconSize, kIconSize); DrawSubCGImage(cctx, srcImage, srcRect, dstRect); actx = CGBitmapContextCreate(alp, kIconSize, kIconSize, 8, kIconSize, NULL, kCGImageAlphaOnly); if (actx) { DrawSubCGImage(actx, srcImage, srcRect, dstRect); CGContextRelease(actx); } CGContextRelease(cctx); } CGColorSpaceRelease(color); } iconRef = NULL; size = sizeof(OSType) + sizeof(SInt32); icns = (IconFamilyHandle) NewHandle(size); if (icns) { // Big-endian: Panther is for PowerPC only (*icns)->resourceType = kIconFamilyType; (*icns)->resourceSize = size; err = PtrToHand(rgb, &hdl, sizeof(rgb)); if (err == noErr) { err = SetIconFamilyData(icns, kSmall32BitData, hdl); DisposeHandle(hdl); if (err == noErr) { err = PtrToHand(alp, &hdl, sizeof(alp)); if (err == noErr) { err = SetIconFamilyData(icns, kSmall8BitMask, hdl); DisposeHandle(hdl); } } } if (err == noErr) err = GetIconRefFromIconFamilyPtr(*icns, GetHandleSize((Handle) icns), &iconRef); DisposeHandle((Handle) icns); } return (iconRef); }
void CreateIconImages (void) { CGDataProviderRef prov; CGImageRef image; CFURLRef url; image = NULL; memset(macIconImage, 0, sizeof(macIconImage)); #ifdef MAC_PANTHER_SUPPORT if (systemVersion < 0x1040) memset(macIconRef, 0, sizeof(macIconRef)); #endif url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("icons"), CFSTR("png"), NULL); if (url) { prov = CGDataProviderCreateWithURL(url); if (prov) { image = CGImageCreateWithPNGDataProvider(prov, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(prov); } CFRelease(url); } if (image) { int x, y, v = 0, n = 0; macPadIconIndex = n; for (y = 0; y < 8; y++) { for (x = 0; x < 12; x++) SetIconImage(image, CGRectMake(x * kIconSize, v, kIconSize, kIconSize), n++); v += kIconSize; } macLegendIconIndex = n; for (x = 0; x < 2; x++) SetIconImage(image, CGRectMake(x * kIconSize, v, kIconSize, kIconSize), n++); v += kIconSize; macMusicBoxIconIndex = n; for (x = 0; x < 3; x++) SetIconImage(image, CGRectMake(x * kIconSize, v, kIconSize, kIconSize), n++); v += kIconSize; macFunctionIconIndex = n; for (x = 0; x < 17; x++) SetIconImage(image, CGRectMake(x * kIconSize, v, kIconSize, kIconSize), n++); CGImageRelease(image); #ifdef MAC_PANTHER_SUPPORT if (systemVersion < 0x1040) { CGColorSpaceRef color; CGContextRef ctx; CGRect rct; static UInt32 data[2][kIconSize * kIconSize]; rct = CGRectMake(0, 0, kIconSize, kIconSize); color = CGColorSpaceCreateDeviceRGB(); if (color) { for (int i = 0; i < 2; i++) { ctx = CGBitmapContextCreate(data[i], kIconSize, kIconSize, 8, kIconSize * 4, color, kCGImageAlphaNoneSkipFirst); if (ctx) { PlotIconRefInContext(ctx, &rct, kAlignNone, kTransformNone, NULL, kPlotIconRefNormalFlags, macIconRef[macLegendIconIndex + i]); CGContextRelease(ctx); prov = CGDataProviderCreateWithData(NULL, data[i], kIconSize * kIconSize * 4, NULL); if (prov) { macIconImage[macLegendIconIndex + i] = CGImageCreate(kIconSize, kIconSize, 8, 32, kIconSize * 4, color, kCGImageAlphaNoneSkipFirst, prov, NULL, 1, kCGRenderingIntentDefault); CGDataProviderRelease(prov); } } } CGColorSpaceRelease(color); } } #endif } }
void VPictureData_MacPicture::_CreateTransparent(VPictureDrawSettings* inSet)const { CGImageRef result = 0; if (fTrans) return; VPictureDrawSettings set(inSet); if (GetWidth() && GetHeight()) { if (fMetaFile) { CGContextRef context = NULL; CGColorSpaceRef colorSpace; void * bitmapData; int bitmapByteCount; int bitmapBytesPerRow; sLONG width, height; CGRect cgr = QDPictGetBounds(fMetaFile); width = cgr.size.width; height = cgr.size.height; bitmapBytesPerRow = (4 * width + 15) & ~15; bitmapByteCount = (bitmapBytesPerRow * height); bitmapData = malloc(bitmapByteCount); if (bitmapData) { colorSpace = CGColorSpaceCreateDeviceRGB();//CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); memset(bitmapData, 0, bitmapByteCount); context = CGBitmapContextCreate(bitmapData, width, height, 8, // bits per component bitmapBytesPerRow, colorSpace, kCGImageAlphaNoneSkipLast); if (context) { CGRect vr; vr.origin.x = 0; vr.origin.y = 0; vr.size.width = width; vr.size.height = height; VRect pictrect(0, 0, width, height); set.SetScaleMode(PM_SCALE_TO_FIT); set.SetYAxisSwap(height, true); set.SetPictureMatrix(VAffineTransform()); CGContextSaveGState(context); CGContextSetRGBFillColor(context, 1, 1, 1, 1); CGContextFillRect(context, vr); xDraw(fMetaFile, context, pictrect, &set); CGContextRestoreGState(context); CGDataProviderRef dataprov = xV4DPicture_MemoryDataProvider::CGDataProviderCreate((char*) bitmapData, bitmapByteCount, true); result = CGImageCreate(width, height, 8, 32, bitmapBytesPerRow, colorSpace, kCGImageAlphaNoneSkipLast, dataprov, 0, 0, kCGRenderingIntentDefault); CGContextRelease(context); CGDataProviderRelease(dataprov); if (set.GetDrawingMode() == 1) { const VColor& col = set.GetTransparentColor(); CGFloat MaskingColors[6]; MaskingColors[0] = col.GetRed(); MaskingColors[1] = col.GetGreen(); MaskingColors[2] = col.GetBlue(); MaskingColors[3] = col.GetRed(); MaskingColors[4] = col.GetGreen(); MaskingColors[5] = col.GetBlue(); CGImageRef trans = CGImageCreateWithMaskingColors(result, MaskingColors); if (trans) { CFRelease(result); fTrans = trans; } } } CGColorSpaceRelease(colorSpace); } free(bitmapData); } } }
bool ImageIODecoder::readData( Mat& img ) { uchar* data = img.data; int step = img.step; bool color = img.channels() > 1; int bpp; // Bytes per pixel int bit_depth = 8; // Get Height, Width, and color information if( !readHeader() ) return false; CGContextRef context = NULL; // The bitmap context CGColorSpaceRef colorSpace = NULL; uchar* bitmap = NULL; CGImageAlphaInfo alphaInfo; // CoreGraphics will take care of converting to grayscale and back as long as the // appropriate colorspace is set if( color == CV_LOAD_IMAGE_GRAYSCALE ) { colorSpace = CGColorSpaceCreateDeviceGray(); bpp = 1; alphaInfo = kCGImageAlphaNone; } else if( color == CV_LOAD_IMAGE_COLOR ) { colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear ); bpp = 4; /* CG only has 8 and 32 bit color spaces, so we waste a byte */ alphaInfo = kCGImageAlphaNoneSkipLast; } if( !colorSpace ) return false; bitmap = (uchar*)malloc( bpp * m_height * m_width ); if( !bitmap ) { CGColorSpaceRelease( colorSpace ); return false; } context = CGBitmapContextCreate( (void *)bitmap, m_width, /* width */ m_height, /* height */ bit_depth, /* bit depth */ bpp * m_width, /* bytes per row */ colorSpace, /* color space */ alphaInfo); CGColorSpaceRelease( colorSpace ); if( !context ) { free( bitmap ); return false; } // Copy the image data into the bitmap region CGRect rect = {{0,0},{m_width,m_height}}; CGContextDrawImage( context, rect, imageRef ); uchar* bitdata = (uchar*)CGBitmapContextGetData( context ); if( !bitdata ) { free( bitmap); CGContextRelease( context ); return false; } // Move the bitmap (in RGB) into data (in BGR) int bitmapIndex = 0; if( color == CV_LOAD_IMAGE_COLOR ) { uchar * base = data; for (int y = 0; y < m_height; y++) { uchar * line = base + y * step; for (int x = 0; x < m_width; x++) { // Blue channel line[0] = bitdata[bitmapIndex + 2]; // Green channel line[1] = bitdata[bitmapIndex + 1]; // Red channel line[2] = bitdata[bitmapIndex + 0]; line += 3; bitmapIndex += bpp; } } } else if( color == CV_LOAD_IMAGE_GRAYSCALE ) { for (int y = 0; y < m_height; y++) memcpy (data + y * step, bitmap + y * m_width, m_width); } free( bitmap ); CGContextRelease( context ); return true; }
static void quartzgen_begin_page(GVJ_t *job) { CGRect bounds = CGRectMake(0.0, 0.0, job->width, job->height); if (!job->context) { switch (job->device.id) { case FORMAT_PDF: { /* create the auxiliary info for PDF content, author and title */ CFStringRef auxiliaryKeys[] = { kCGPDFContextCreator, kCGPDFContextTitle }; CFStringRef auxiliaryValues[] = { CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s %s"), job->common->info[0], job->common->info[1]), job->obj->type == ROOTGRAPH_OBJTYPE ? CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)job->obj->u.g->name, strlen(job->obj->u.g->name), kCFStringEncodingUTF8, false, kCFAllocatorNull) : CFSTR("") }; CFDictionaryRef auxiliaryInfo = CFDictionaryCreate( kCFAllocatorDefault, (const void **)&auxiliaryKeys, (const void **)&auxiliaryValues, sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); /* create a PDF for drawing into */ CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks); job->context = CGPDFContextCreate(data_consumer, &bounds, auxiliaryInfo); /* clean up */ CGDataConsumerRelease(data_consumer); CFRelease(auxiliaryInfo); int i; for (i = 0; i < sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]); ++i) CFRelease(auxiliaryValues[i]); } break; default: /* bitmap formats */ { size_t bytes_per_row = (job->width * BYTES_PER_PIXEL + BYTE_ALIGN) & ~BYTE_ALIGN; void* buffer = NULL; #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 20000 /* iPhoneOS has no swap files for memory, so if we're short of memory we need to make our own temp scratch file to back it */ size_t buffer_size = job->height * bytes_per_row; mach_msg_type_number_t vm_info_size = HOST_VM_INFO_COUNT; vm_statistics_data_t vm_info; if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_info, &vm_info_size) != KERN_SUCCESS || buffer_size * 2 > vm_info.free_count * vm_page_size) { FILE* temp_file = tmpfile(); if (temp_file) { int temp_file_descriptor = fileno(temp_file); if (temp_file_descriptor >= 0 && ftruncate(temp_file_descriptor, buffer_size) == 0) { buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, temp_file_descriptor, 0); if (buffer == (void*)-1) buffer = NULL; } fclose(temp_file); } } if (!buffer) buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_ANON| MAP_SHARED, -1, 0); #endif /* create a true color bitmap for drawing into */ CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); job->context = CGBitmapContextCreate( buffer, /* data: MacOSX lets system allocate, iPhoneOS use manual memory mapping */ job->width, /* width in pixels */ job->height, /* height in pixels */ BITS_PER_COMPONENT, /* bits per component */ bytes_per_row, /* bytes per row: align to 16 byte boundary */ color_space, /* color space: device RGB */ kCGImageAlphaPremultipliedFirst /* bitmap info: premul ARGB has best support in OS X */ ); job->imagedata = CGBitmapContextGetData((CGContextRef)job->context); /* clean up */ CGColorSpaceRelease(color_space); } break; } } /* start the page (if this is a paged context) and graphics state */ CGContextRef context = (CGContextRef)job->context; CGContextBeginPage(context, &bounds); CGContextSaveGState(context); CGContextSetMiterLimit(context, 1.0); CGContextSetLineJoin(context, kCGLineJoinRound); /* set up the context transformation */ CGContextScaleCTM(context, job->scale.x, job->scale.y); CGContextRotateCTM(context, -job->rotation * M_PI / 180.0); CGContextTranslateCTM(context, job->translation.x, job->translation.y); }
bool ImageIOEncoder::write( const Mat& img, const vector<int>& params ) { int width = img.cols, height = img.rows; int _channels = img.channels(); const uchar* data = img.data; int step = img.step; // Determine the appropriate UTI based on the filename extension CFStringRef imageUTI = FilenameToUTI( m_filename.c_str() ); // Determine the Bytes Per Pixel int bpp = (_channels == 1) ? 1 : 4; // Write the data into a bitmap context CGContextRef context; CGColorSpaceRef colorSpace; uchar* bitmapData = NULL; if( bpp == 1 ) colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericGray ); else if( bpp == 4 ) colorSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGBLinear ); if( !colorSpace ) return false; bitmapData = (uchar*)malloc( bpp * height * width ); if( !bitmapData ) { CGColorSpaceRelease( colorSpace ); return false; } context = CGBitmapContextCreate( bitmapData, width, height, 8, bpp * width, colorSpace, (bpp == 1) ? kCGImageAlphaNone : kCGImageAlphaNoneSkipLast ); CGColorSpaceRelease( colorSpace ); if( !context ) { free( bitmapData ); return false; } // Copy pixel information from data into bitmapData if (bpp == 4) { int bitmapIndex = 0; const uchar * base = data; for (int y = 0; y < height; y++) { const uchar * line = base + y * step; for (int x = 0; x < width; x++) { // Blue channel bitmapData[bitmapIndex + 2] = line[0]; // Green channel bitmapData[bitmapIndex + 1] = line[1]; // Red channel bitmapData[bitmapIndex + 0] = line[2]; line += 3; bitmapIndex += bpp; } } } else if (bpp == 1) { for (int y = 0; y < height; y++) memcpy (bitmapData + y * width, data + y * step, width); } // Turn the bitmap context into an imageRef CGImageRef imageRef = CGBitmapContextCreateImage( context ); CGContextRelease( context ); if( !imageRef ) { free( bitmapData ); return false; } // Write the imageRef to a file based on the UTI CFURLRef imageURLRef = CFURLCreateFromFileSystemRepresentation( NULL, (const UInt8*)m_filename.c_str(), m_filename.size(), false ); if( !imageURLRef ) { CGImageRelease( imageRef ); free( bitmapData ); return false; } CGImageDestinationRef destRef = CGImageDestinationCreateWithURL( imageURLRef, imageUTI, 1, NULL); CFRelease( imageURLRef ); if( !destRef ) { CGImageRelease( imageRef ); free( bitmapData ); fprintf(stderr, "!destRef\n"); return false; } CGImageDestinationAddImage(destRef, imageRef, NULL); if( !CGImageDestinationFinalize(destRef) ) { fprintf(stderr, "Finalize failed\n"); return false; } CFRelease( destRef ); CGImageRelease( imageRef ); free( bitmapData ); return true; }