2016-06-25 15:27:29 -05:00
|
|
|
// 25 june 2016
|
|
|
|
#import "uipriv_darwin.h"
|
|
|
|
|
|
|
|
struct uiImage {
|
|
|
|
NSImage *i;
|
|
|
|
NSSize size;
|
|
|
|
};
|
|
|
|
|
|
|
|
uiImage *uiNewImage(double width, double height)
|
|
|
|
{
|
|
|
|
uiImage *i;
|
|
|
|
|
2018-04-15 15:05:24 -05:00
|
|
|
i = uiprivNew(uiImage);
|
2016-06-25 15:27:29 -05:00
|
|
|
i->size = NSMakeSize(width, height);
|
|
|
|
i->i = [[NSImage alloc] initWithSize:i->size];
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2018-07-08 20:20:42 -05:00
|
|
|
void uiFreeImage(uiImage *i)
|
2016-06-25 15:27:29 -05:00
|
|
|
{
|
|
|
|
[i->i release];
|
2018-04-15 15:05:24 -05:00
|
|
|
uiprivFree(i);
|
2016-06-25 15:27:29 -05:00
|
|
|
}
|
|
|
|
|
2018-08-05 17:39:29 -05:00
|
|
|
void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int byteStride)
|
2016-06-25 15:27:29 -05:00
|
|
|
{
|
|
|
|
NSBitmapImageRep *repCalibrated, *repsRGB;
|
2018-08-06 03:54:19 -05:00
|
|
|
int x, y;
|
2018-08-29 19:32:12 -05:00
|
|
|
uint8_t *pix, *data;
|
|
|
|
NSInteger realStride;
|
2016-06-25 15:27:29 -05:00
|
|
|
|
2018-08-29 19:32:12 -05:00
|
|
|
repCalibrated = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
2016-06-25 15:27:29 -05:00
|
|
|
pixelsWide:pixelWidth
|
|
|
|
pixelsHigh:pixelHeight
|
|
|
|
bitsPerSample:8
|
|
|
|
samplesPerPixel:4
|
|
|
|
hasAlpha:YES
|
|
|
|
isPlanar:NO
|
|
|
|
colorSpaceName:NSCalibratedRGBColorSpace
|
|
|
|
bitmapFormat:0
|
2018-08-29 19:32:12 -05:00
|
|
|
bytesPerRow:0
|
2016-06-25 15:27:29 -05:00
|
|
|
bitsPerPixel:32];
|
2018-08-29 19:32:12 -05:00
|
|
|
|
|
|
|
// Apple doesn't explicitly document this, but we apparently need to use native system endian for the data :|
|
|
|
|
// TODO split this into a utility routine?
|
|
|
|
// TODO find proper documentation
|
2018-08-29 19:36:18 -05:00
|
|
|
// TODO test this on a big-endian system somehow; I have a feeling the above comment is wrong about the diagnosis since the order we are specifying is now 0xAABBGGRR
|
2018-08-29 19:32:12 -05:00
|
|
|
pix = (uint8_t *) pixels;
|
|
|
|
data = (uint8_t *) [repCalibrated bitmapData];
|
|
|
|
realStride = [repCalibrated bytesPerRow];
|
|
|
|
for (y = 0; y < pixelHeight; y++) {
|
|
|
|
for (x = 0; x < pixelWidth * 4; x += 4) {
|
|
|
|
union {
|
|
|
|
uint32_t v32;
|
|
|
|
uint8_t v8[4];
|
|
|
|
} v;
|
|
|
|
|
|
|
|
v.v32 = ((uint32_t) (pix[x + 3])) << 24;
|
|
|
|
v.v32 |= ((uint32_t) (pix[x + 2])) << 16;
|
|
|
|
v.v32 |= ((uint32_t) (pix[x + 1])) << 8;
|
|
|
|
v.v32 |= ((uint32_t) (pix[x]));
|
|
|
|
data[x] = v.v8[0];
|
|
|
|
data[x + 1] = v.v8[1];
|
|
|
|
data[x + 2] = v.v8[2];
|
|
|
|
data[x + 3] = v.v8[3];
|
|
|
|
}
|
|
|
|
pix += byteStride;
|
|
|
|
data += realStride;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we can't call the constructor with this, but we can retag (NOT convert)
|
2016-06-25 15:27:29 -05:00
|
|
|
repsRGB = [repCalibrated bitmapImageRepByRetaggingWithColorSpace:[NSColorSpace sRGBColorSpace]];
|
|
|
|
|
|
|
|
[i->i addRepresentation:repsRGB];
|
|
|
|
[repsRGB setSize:i->size];
|
2018-07-29 12:25:53 -05:00
|
|
|
// don't release repsRGB; it may be equivalent to repCalibrated
|
|
|
|
// do release repCalibrated though; NSImage has a ref to either it or to repsRGB
|
|
|
|
[repCalibrated release];
|
2016-06-25 15:27:29 -05:00
|
|
|
}
|
2016-06-25 18:18:25 -05:00
|
|
|
|
2018-05-05 20:28:13 -05:00
|
|
|
NSImage *uiprivImageNSImage(uiImage *i)
|
2016-06-25 18:18:25 -05:00
|
|
|
{
|
|
|
|
return i->i;
|
|
|
|
}
|