diff options
-rw-r--r-- | vncviewer/Surface.h | 1 | ||||
-rw-r--r-- | vncviewer/Surface_OSX.cxx | 81 |
2 files changed, 46 insertions, 36 deletions
diff --git a/vncviewer/Surface.h b/vncviewer/Surface.h index 032889b4..1cb87f50 100644 --- a/vncviewer/Surface.h +++ b/vncviewer/Surface.h @@ -60,7 +60,6 @@ protected: HBITMAP bitmap; #elif defined(__APPLE__) unsigned char* data; - CGImageRef image; #else Pixmap pixmap; Picture picture; diff --git a/vncviewer/Surface_OSX.cxx b/vncviewer/Surface_OSX.cxx index 668187bc..10d1e3e2 100644 --- a/vncviewer/Surface_OSX.cxx +++ b/vncviewer/Surface_OSX.cxx @@ -28,13 +28,47 @@ #include "Surface.h" -static void render(CGContextRef gc, CGImageRef image, +static CGImageRef create_image(const unsigned char* data, + int w, int h) +{ + CGColorSpaceRef lut; + CGDataProviderRef provider; + + CGImageRef image; + + lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay); + if (!lut) { + lut = CGColorSpaceCreateDeviceRGB(); + if (!lut) + throw rdr::Exception("CGColorSpaceCreateDeviceRGB"); + } + + provider = CGDataProviderCreateWithData(NULL, data, + w * h * 4, NULL); + if (!provider) + throw rdr::Exception("CGDataProviderCreateWithData"); + + image = CGImageCreate(w, h, 8, 32, w * 4, lut, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, + provider, NULL, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(provider); + if (!image) + throw rdr::Exception("CGImageCreate"); + + return image; +} + +static void render(CGContextRef gc, + const unsigned char* data, CGBlendMode mode, CGFloat alpha, - int src_x, int src_y, + int src_x, int src_y, int src_w, int src_h, int x, int y, int w, int h) { CGRect rect; - CGImageRef subimage; + CGImageRef image, subimage; + + image = create_image(data, src_w, src_h); rect.origin.x = src_x; rect.origin.y = src_y; @@ -60,6 +94,7 @@ static void render(CGContextRef gc, CGImageRef image, CGContextRestoreGState(gc); CGImageRelease(subimage); + CGImageRelease(image); } static CGContextRef make_bitmap(int width, int height, unsigned char* data) @@ -114,8 +149,8 @@ void Surface::draw(int src_x, int src_y, int x, int y, int w, int h) // macOS Coordinates are from bottom left, not top left y = Fl_Window::current()->h() - (y + h); - render(fl_gc, image, kCGBlendModeCopy, 1.0, - src_x, src_y, x, y, w, h); + render(fl_gc, data, kCGBlendModeCopy, 1.0, + src_x, src_y, width(), height(), x, y, w, h); CGContextRestoreGState(fl_gc); } @@ -129,8 +164,8 @@ void Surface::draw(Surface* dst, int src_x, int src_y, int x, int y, int w, int // macOS Coordinates are from bottom left, not top left y = dst->height() - (y + h); - render(bitmap, image, kCGBlendModeCopy, 1.0, - src_x, src_y, x, y, w, h); + render(bitmap, data, kCGBlendModeCopy, 1.0, + src_x, src_y, width(), height(), x, y, w, h); CGContextRelease(bitmap); } @@ -146,8 +181,8 @@ void Surface::blend(int src_x, int src_y, int x, int y, int w, int h, int a) // macOS Coordinates are from bottom left, not top left y = Fl_Window::current()->h() - (y + h); - render(fl_gc, image, kCGBlendModeNormal, (CGFloat)a/255.0, - src_x, src_y, x, y, w, h); + render(fl_gc, data, kCGBlendModeNormal, (CGFloat)a/255.0, + src_x, src_y, width(), height(), x, y, w, h); CGContextRestoreGState(fl_gc); } @@ -161,43 +196,19 @@ void Surface::blend(Surface* dst, int src_x, int src_y, int x, int y, int w, int // macOS Coordinates are from bottom left, not top left y = dst->height() - (y + h); - render(bitmap, image, kCGBlendModeNormal, (CGFloat)a/255.0, - src_x, src_y, x, y, w, h); + render(bitmap, data, kCGBlendModeNormal, (CGFloat)a/255.0, + src_x, src_y, width(), height(), x, y, w, h); CGContextRelease(bitmap); } void Surface::alloc() { - CGColorSpaceRef lut; - CGDataProviderRef provider; - data = new unsigned char[width() * height() * 4]; - - lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay); - if (!lut) { - lut = CGColorSpaceCreateDeviceRGB(); - if (!lut) - throw rdr::Exception("CGColorSpaceCreateDeviceRGB"); - } - - provider = CGDataProviderCreateWithData(NULL, data, - width() * height() * 4, NULL); - if (!provider) - throw rdr::Exception("CGDataProviderCreateWithData"); - - image = CGImageCreate(width(), height(), 8, 32, width() * 4, lut, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, - provider, NULL, false, kCGRenderingIntentDefault); - CGColorSpaceRelease(lut); - CGDataProviderRelease(provider); - if (!image) - throw rdr::Exception("CGImageCreate"); } void Surface::dealloc() { - CGImageRelease(image); delete [] data; } |