Skip to content

Commit

Permalink
fixing too much memory consumption in MacOSGrabber
Browse files Browse the repository at this point in the history
  • Loading branch information
timsat committed Nov 8, 2013
1 parent 1378bea commit c879c2c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 15 deletions.
45 changes: 32 additions & 13 deletions Software/grab/MacOSGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,21 @@
MacOSGrabber::MacOSGrabber(QObject *parent, QList<QRgb> *grabResult, QList<GrabWidget *> *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()
Expand All @@ -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;
}
Expand Down
13 changes: 11 additions & 2 deletions Software/grab/include/MacOSGrabber.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@

#include "TimeredGrabber.hpp"

struct CGImage;
typedef CGImage *CGImageRef;
#include <CoreGraphics/CGColorSpace.h>
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGImage.h>


class MacOSGrabber : public TimeredGrabber
{
Expand All @@ -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

0 comments on commit c879c2c

Please sign in to comment.