Implement CGColorSpaceRef support for cairo quartz image

Submitted by Fred Bca on Aug. 26, 2019, 12:54 p.m.

Details

Message ID CAKTSDKb334M5bRoe02YmFcWQLrDMD34Vwo0ciuVrgHG0gUziOA@mail.gmail.com
State New
Headers show
Series "Implement CGColorSpaceRef support for cairo quartz image" ( rev: 1 ) in Cairo

Not browsing as part of any series.

Commit Message

Fred Bca Aug. 26, 2019, 12:54 p.m.
Hi,

on recent versions of Mac OS, Core Graphics performs color space
conversions when the source and target are using different color
spaces (which typically happens when drawing an image loaded from file
on screen). The performance hit is not negligible (around 20%).

Here is a patch proposal to let you specify an optional color space
when creating a quartz image surface (instead of using the default RGB
color space). It changes the API, but it could also be implemented as
a separate function if preferred. The patch also ensures that the
appropriate color space is used when creating a similar surface.

Would you please consider incorporating this change to cairo?

 _cairo_quartz_image_surface_create_similar (void *asurface,
      cairo_content_t content,
@@ -64,7 +73,7 @@
 {
     cairo_surface_t *isurf =
  _cairo_image_surface_create_with_content (content, width, height);
-    cairo_surface_t *result = cairo_quartz_image_surface_create (isurf);
+    cairo_surface_t *result = cairo_quartz_image_surface_create
(isurf,_cairo_quartz_image_surface_get_color_space(asurface));
     cairo_surface_destroy (isurf);

     return result;
@@ -77,7 +86,7 @@
    int height)
 {
     cairo_surface_t *isurf = cairo_image_surface_create (format,
width, height);
-    cairo_surface_t *result = cairo_quartz_image_surface_create (isurf);
+    cairo_surface_t *result = cairo_quartz_image_surface_create
(isurf,_cairo_quartz_image_surface_get_color_space(asurface));
     cairo_surface_destroy (isurf);

     return result;
@@ -147,10 +156,13 @@
     cairo_quartz_image_surface_t *surface =
(cairo_quartz_image_surface_t *) asurface;
     CGImageRef oldImage = surface->image;
     CGImageRef newImage = NULL;
-
+    CGColorSpaceRef colorSpace = NULL;
+
     if (flags)
  return CAIRO_STATUS_SUCCESS;

+    if(oldImage)
+        colorSpace=CGImageGetColorSpace(oldImage);
     /* XXX only flush if the image has been modified. */

     /* To be released by the ReleaseCallback */
@@ -162,7 +174,7 @@
  surface->imageSurface->stride,
  surface->imageSurface->data,
  TRUE,
- NULL,
+ colorSpace,
  DataProviderReleaseCallback,
  surface->imageSurface);

@@ -286,6 +298,7 @@
 /**
  * cairo_quartz_image_surface_create:
  * @image_surface: a cairo image surface to wrap with a quartz image surface
+ * @colorSpace: an optional CGColorSpaceRef to define the color space
used by the CGImageRef
  *
  * Creates a Quartz surface backed by a CGImageRef that references the
  * given image surface. The resulting surface can be rendered quickly
@@ -299,7 +312,7 @@
  * Since: 1.6
  **/
 cairo_surface_t *
-cairo_quartz_image_surface_create (cairo_surface_t *surface)
+cairo_quartz_image_surface_create (cairo_surface_t
*surface,CGColorSpaceRef colorSpace)
 {
     cairo_quartz_image_surface_t *qisurf;

@@ -349,7 +362,7 @@
        stride,
        data,
        TRUE,
-       NULL,
+       colorSpace,
        DataProviderReleaseCallback,
        image_surface);

Patch hide | download patch | download mbox

Index: cairo-quartz-image.h
===================================================================
--- cairo-quartz-image.h (cairo 14.12)
+++ cairo-quartz-image.h (fix)
@@ -45,7 +45,7 @@ 
 CAIRO_BEGIN_DECLS

 cairo_public cairo_surface_t *
-cairo_quartz_image_surface_create (cairo_surface_t *image_surface);
+cairo_quartz_image_surface_create (cairo_surface_t
*image_surface,CGColorSpaceRef colorSpace);

 cairo_public cairo_surface_t *
 cairo_quartz_image_surface_get_image (cairo_surface_t *surface);
Index: cairo-quartz-image-surface.c
===================================================================
--- cairo-quartz-image-surface.c (cairo 14.12)
+++ cairo-quartz-image-surface.c (fix)
@@ -56,6 +56,15 @@ 
     cairo_surface_destroy (surface);
 }

+static CGColorSpaceRef
_cairo_quartz_image_surface_get_color_space(void *asurface)
+{
+    cairo_quartz_image_surface_t *surface =
(cairo_quartz_image_surface_t *) asurface;
+    CGColorSpaceRef colorSpace=NULL;
+    if(surface->image!=NULL)
+        colorSpace=CGImageGetColorSpace(surface->image);
+    return colorSpace;
+}
+
 static cairo_surface_t *