diff --git a/Software/grab/MacOSGrabber.cpp b/Software/grab/MacOSGrabber.cpp index ba5bd903..87d6f80b 100644 --- a/Software/grab/MacOSGrabber.cpp +++ b/Software/grab/MacOSGrabber.cpp @@ -34,10 +34,21 @@ MacOSGrabber::MacOSGrabber(QObject *parent, QList *grabResult, QList *grabAreasGeometry): TimeredGrabber(parent, grabResult, grabAreasGeometry) { + _imageBuf = NULL; + _imageBufSize = 0; + _colorSpace = CGColorSpaceCreateDeviceRGB(); + _context = NULL; + _contextHeight = 0; + _contextWidth = 0; } MacOSGrabber::~MacOSGrabber() { + CGColorSpaceRelease(_colorSpace); + if(_imageBuf) + free(_imageBuf); + if(_context) + CGContextRelease(_context); } const char * MacOSGrabber::getName() @@ -50,28 +61,36 @@ void MacOSGrabber::updateGrabMonitor(QWidget *widget) Q_UNUSED(widget); } -void imageCleanup(void *data) { - free(data); -} - QImage * MacOSGrabber::toImage(CGImageRef imageRef) { size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char)); + size_t new_buf_size = height * width * 4; + if (new_buf_size > _imageBufSize) { + DEBUG_LOW_LEVEL << Q_FUNC_INFO << "new width = " << width << " new height = " << height; + if (_imageBuf) + free(_imageBuf); + _imageBuf = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char)); + _imageBufSize = new_buf_size; + } + size_t bytesPerPixel = 4; size_t bytesPerRow = bytesPerPixel * width; size_t bitsPerComponent = 8; - CGContextRef context = CGBitmapContextCreate(rawData, width, height, - bitsPerComponent, bytesPerRow, colorSpace, - kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - CGColorSpaceRelease(colorSpace); + if (width != _contextWidth || height != _contextHeight) { + if(_context) + CGContextRelease(_context); + + _context = CGBitmapContextCreate(_imageBuf, width, height, + bitsPerComponent, bytesPerRow, _colorSpace, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); + _contextWidth = width; + _contextHeight = height; + } - CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); - CGContextRelease(context); + CGContextDrawImage(_context, CGRectMake(0, 0, _contextWidth, _contextHeight), imageRef); - QImage * result = new QImage(rawData, width, height, QImage::Format_ARGB32, imageCleanup); + QImage * result = new QImage(_imageBuf, _contextWidth, _contextHeight, QImage::Format_RGB32); return result; } diff --git a/Software/grab/include/MacOSGrabber.hpp b/Software/grab/include/MacOSGrabber.hpp index d4053820..9a92413f 100644 --- a/Software/grab/include/MacOSGrabber.hpp +++ b/Software/grab/include/MacOSGrabber.hpp @@ -31,8 +31,10 @@ #include "TimeredGrabber.hpp" -struct CGImage; -typedef CGImage *CGImageRef; +#include +#include +#include + class MacOSGrabber : public TimeredGrabber { @@ -53,6 +55,13 @@ public slots: QRgb getColor(QImage * image, const QWidget * grabme); QRgb getColor(QImage * image, int x, int y, int width, int height); QImage * toImage(CGImageRef); + + unsigned char *_imageBuf; + size_t _imageBufSize; + size_t _contextWidth; + size_t _contextHeight; + CGColorSpaceRef _colorSpace; + CGContextRef _context; }; #endif // MAC_OS_CG_GRAB_SUPPORT