+XImage *
+jwxyz_png_to_ximage (Display *dpy, Visual *visual,
+ const unsigned char *png_data, unsigned long data_size)
+{
+ NSImage *img = [[NSImage alloc] initWithData:
+ [NSData dataWithBytes:png_data
+ length:data_size]];
+#ifndef USE_IPHONE
+ NSBitmapImageRep *bm = [NSBitmapImageRep
+ imageRepWithData:
+ [NSBitmapImageRep
+ TIFFRepresentationOfImageRepsInArray:
+ [img representations]]];
+ int width = [img size].width;
+ int height = [img size].height;
+ size_t ibpp = [bm bitsPerPixel];
+ size_t ibpl = [bm bytesPerRow];
+ const unsigned char *data = [bm bitmapData];
+ convert_mode_t mode = (([bm bitmapFormat] & NSAlphaFirstBitmapFormat)
+ ? CONVERT_MODE_ROTATE_MASK
+ : 0);
+#else // USE_IPHONE
+ CGImageRef cgi = [img CGImage];
+ int width = CGImageGetWidth (cgi);
+ int height = CGImageGetHeight (cgi);
+ size_t ibpp = 32;
+ size_t ibpl = ibpp/4 * width;
+ unsigned char *data = (unsigned char *) calloc (ibpl, height);
+ const CGBitmapInfo bitmap_info =
+ kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
+ CGContextRef cgc =
+ CGBitmapContextCreate (data, width, height,
+ 8, /* bits per component */
+ ibpl, dpy->colorspace,
+ bitmap_info);
+ CGContextDrawImage (cgc, CGRectMake (0, 0, width, height), cgi);
+
+ convert_mode_t mode = convert_mode_to_rgba (bitmap_info);
+
+#endif // USE_IPHONE
+
+ XImage *image = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0,
+ width, height, 8, 0);
+ image->data = (char *) malloc (image->height * image->bytes_per_line);
+
+ // data points at (x,y) with ibpl rowstride.
+
+ int obpl = image->bytes_per_line;
+ const unsigned char *iline = data;
+ unsigned char *oline = (unsigned char *) image->data;
+ int yy;
+ for (yy = 0; yy < height; yy++) {
+ convert_row ((uint32_t *)oline, iline, width, mode, ibpp);
+ oline += obpl;
+ iline += ibpl;
+ }
+
+ [img release];
+
+#ifndef USE_IPHONE
+ // [bm release];
+# else
+ CGContextRelease (cgc);
+ free (data);
+# endif
+
+ return image;
+}
+