1 /* Darwin support via Quartz Display Services */
4 #include <ApplicationServices/ApplicationServices.h>
8 http://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage-cocoa-touch-or-cgimage-core-graphics
13 imss_darwin(i_img_dim left, i_img_dim top, i_img_dim right, i_img_dim bottom) {
15 CGDirectDisplayID disp = CGMainDisplayID();
17 i_push_error(0, "No main display");
21 /* for now, only interested in the first display */
22 CGRect rect = CGDisplayBounds(disp);
23 i_img_dim screen_width = rect.size.width;
24 i_img_dim screen_height = rect.size.height;
26 /* adjust negative/zero values to window size */
32 right += screen_width;
34 bottom += screen_height;
39 if (right > screen_width)
43 if (bottom > screen_height)
44 bottom = screen_height;
47 if (right <= left || bottom <= top) {
48 i_push_error(0, "image would be empty");
52 i_img_dim width = right - left;
53 i_img_dim height = bottom - top;
56 cap_rect.origin.x = left;
57 cap_rect.origin.y = top; /* flipped relative to I::S API */
58 cap_rect.size.width = width;
59 cap_rect.size.height = height;
61 CGImageRef image = CGDisplayCreateImageForRect(disp, cap_rect);
63 i_push_error(0, "CGDisplayCreateImageForRect failed");
67 int channels = CGImageGetAlphaInfo(image) == kCGImageAlphaNone ? 3 : 4;
68 i_img *result = i_img_8_new(width, height, channels);
70 CGImageRelease(image);
74 /* bytes per row - round up to the closest 16 byte boundary */
75 size_t bytes_per_row = channels * width;
76 bytes_per_row = (bytes_per_row + 15) & ~15U;
78 unsigned char *data = mymalloc(bytes_per_row * height);
79 CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
81 CGContextRef context = CGBitmapContextCreate
82 (data, width, height, 8, bytes_per_row, color_space,
83 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
84 CGColorSpaceRelease(color_space);
86 CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
87 CGContextRelease(context);
89 CGImageRelease(image);
91 const unsigned char *p = data;
93 for (y = 0; y < height; ++y) {
94 i_psamp(result, 0, width, y, p, NULL, channels);
99 i_tags_setn(&result->tags, "ss_window_width", width);
100 i_tags_setn(&result->tags, "ss_window_height", height);
101 i_tags_set(&result->tags, "ss_type", "Darwin", 6);
102 i_tags_set(&result->tags, "ss_variant", "11+", 3);
103 i_tags_setn(&result->tags, "ss_left", left);
104 i_tags_setn(&result->tags, "ss_top", top);