[cairo-commit] 4 commits - configure.ac perf/micro src/cairo-debug.c src/cairo.h src/cairo-image-compositor.c src/cairo-image-source.c src/cairo-image-surface.c src/cairoint.h src/cairo-png.c src/cairo-script-surface.c src/cairo-xlib-display.c test/any2ppm.c test/map-to-image.c test/png.c util/cairo-script util/cairo-trace

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 8 03:15:20 UTC 2019


 configure.ac                               |    2 
 perf/micro/fill-clip.c                     |    2 
 perf/micro/pixel.c                         |    2 
 src/cairo-debug.c                          |    6 +
 src/cairo-image-compositor.c               |    4 
 src/cairo-image-source.c                   |   27 ++++
 src/cairo-image-surface.c                  |   16 ++
 src/cairo-png.c                            |  174 ++++++++++++++++++++++++++---
 src/cairo-script-surface.c                 |   20 +++
 src/cairo-xlib-display.c                   |   12 ++
 src/cairo.h                                |    6 -
 src/cairoint.h                             |    2 
 test/any2ppm.c                             |    2 
 test/map-to-image.c                        |    2 
 test/png.c                                 |    2 
 util/cairo-script/cairo-script-operators.c |   12 ++
 util/cairo-trace/trace.c                   |   37 ++----
 17 files changed, 287 insertions(+), 41 deletions(-)

New commits:
commit d061570a70c12ebf43e9aa914a9cbb87b616a979
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Mon Dec 3 15:13:42 2018 +0100

    png: Add support for 16 bpc png reading as floating point format
    
    Similar to writing png, don't squash 16 bpc to 8 bpc and create
    a float surface to contain the image.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Reviewed-by: Bryce Harrington <bryce at bryceharrington.org>

diff --git a/src/cairo-png.c b/src/cairo-png.c
index 2e0520ae8..0037dd531 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -142,6 +142,33 @@ unpremultiply_float (float *f, uint16_t *d16, unsigned width)
     }
 }
 
+static void
+premultiply_float (float *f, const uint16_t *d16, unsigned int width)
+{
+    unsigned int i = width;
+
+    /* Convert d16 in place back to float */
+    while (i--) {
+	float a = d16[i * 4 + 3] / 65535.f;
+
+	f[i * 4 + 3] = a;
+	f[i * 4 + 2] = (float)d16[i * 4 + 2] / 65535.f * a;
+	f[i * 4 + 1] = (float)d16[i * 4 + 1] / 65535.f * a;
+	f[i * 4] = (float)d16[i * 4] / 65535.f * a;
+    }
+}
+
+static void convert_u16_to_float (float *f, const uint16_t *d16, unsigned int width)
+{
+    /* Convert d16 in place back to float */
+    unsigned int i = width;
+
+    while (i--) {
+	f[i * 3 + 2] = (float)d16[i * 4 + 2] / 65535.f;
+	f[i * 3 + 1] = (float)d16[i * 4 + 1] / 65535.f;
+	f[i * 3] = (float)d16[i * 4] / 65535.f;
+    }
+}
 
 static void
 convert_float_to_u16 (float *f, uint16_t *d16, unsigned int width)
@@ -700,9 +727,6 @@ read_png (struct png_read_closure_t *png_closure)
     if (png_get_valid (png, info, PNG_INFO_tRNS))
         png_set_tRNS_to_alpha (png);
 
-    if (depth == 16)
-        png_set_strip_16 (png);
-
     if (depth < 8)
         png_set_packing (png);
 
@@ -723,7 +747,7 @@ read_png (struct png_read_closure_t *png_closure)
     png_get_IHDR (png, info,
                   &png_width, &png_height, &depth,
                   &color_type, &interlace, NULL, NULL);
-    if (depth != 8 ||
+    if ((depth != 8 && depth != 16) ||
 	! (color_type == PNG_COLOR_TYPE_RGB ||
 	   color_type == PNG_COLOR_TYPE_RGB_ALPHA))
     {
@@ -737,13 +761,21 @@ read_png (struct png_read_closure_t *png_closure)
 	    /* fall-through just in case ;-) */
 
 	case PNG_COLOR_TYPE_RGB_ALPHA:
-	    format = CAIRO_FORMAT_ARGB32;
-	    png_set_read_user_transform_fn (png, premultiply_data);
+	    if (depth == 8) {
+		format = CAIRO_FORMAT_ARGB32;
+		png_set_read_user_transform_fn (png, premultiply_data);
+	    } else {
+		format = CAIRO_FORMAT_RGBA128F;
+	    }
 	    break;
 
 	case PNG_COLOR_TYPE_RGB:
-	    format = CAIRO_FORMAT_RGB24;
-	    png_set_read_user_transform_fn (png, convert_bytes_to_data);
+	    if (depth == 8) {
+		format = CAIRO_FORMAT_RGB24;
+		png_set_read_user_transform_fn (png, convert_bytes_to_data);
+	    } else {
+		format = CAIRO_FORMAT_RGB96F;
+	    }
 	    break;
     }
 
@@ -776,6 +808,26 @@ read_png (struct png_read_closure_t *png_closure)
 	goto BAIL;
     }
 
+    if (format == CAIRO_FORMAT_RGBA128F) {
+	i = png_height;
+
+	while (i--) {
+	    float *float_line = (float *)row_pointers[i];
+	    uint16_t *u16_line = (uint16_t *)row_pointers[i];
+
+	    premultiply_float (float_line, u16_line, png_width);
+	}
+    } else if (format == CAIRO_FORMAT_RGB96F) {
+	i = png_height;
+
+	while (i--) {
+	    float *float_line = (float *)row_pointers[i];
+	    uint16_t *u16_line = (uint16_t *)row_pointers[i];
+
+	    convert_u16_to_float (float_line, u16_line, png_width);
+	}
+    }
+
     surface = cairo_image_surface_create_for_data (data, format,
 						   png_width, png_height,
 						   stride);
commit 1df0a68460ed0c9e16089919002d8c58faccdab5
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Mon Dec 3 15:13:41 2018 +0100

    png: Add support for writing new floating point formats as 16 bpc png.
    
    _cairo_image_surface_coerce will round down the image to a lower
    bpp when using one of the floating point formats, so don't coerce those.
    This makes the code actually work for those formats.
    
    Because a float takes more storage than u16, we have to convert float
    to u16 before calling png_write_image, because png_write
    doesn't give us back the original row data, but an in-place copy.
    
    With these changes we can dump floating point files with the highest
    possible accuracy, with floats clamped between 0 and 1.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Reviewed-by: Bryce Harrington <bryce at bryceharrington.org>

diff --git a/src/cairo-png.c b/src/cairo-png.c
index b9fc9160a..2e0520ae8 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -105,6 +105,57 @@ unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
     }
 }
 
+static uint16_t f_to_u16(float val)
+{
+    if (val < 0)
+	return 0;
+    else if (val > 1)
+	return 65535;
+    else
+	return (uint16_t)(val * 65535.f);
+}
+
+static void
+unpremultiply_float (float *f, uint16_t *d16, unsigned width)
+{
+    unsigned int i;
+
+    for (i = 0; i < width; i++) {
+	float r, g, b, a;
+
+	r = *f++;
+	g = *f++;
+	b = *f++;
+	a = *f++;
+
+	if (a > 0) {
+	    *d16++ = f_to_u16(r / a);
+	    *d16++ = f_to_u16(g / a);
+	    *d16++ = f_to_u16(b / a);
+	    *d16++ = f_to_u16(a);
+	} else {
+	    *d16++ = 0;
+	    *d16++ = 0;
+	    *d16++ = 0;
+	    *d16++ = 0;
+	}
+    }
+}
+
+
+static void
+convert_float_to_u16 (float *f, uint16_t *d16, unsigned int width)
+{
+    unsigned int i;
+
+    for (i = 0; i < width; i++) {
+	*d16++ = f_to_u16(*f++);
+	*d16++ = f_to_u16(*f++);
+	*d16++ = f_to_u16(*f++);
+	*d16++ = 0;
+    }
+}
+
 /* Converts native endian xRGB => RGBx bytes */
 static void
 convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
@@ -182,6 +233,7 @@ write_png (cairo_surface_t	*surface,
     png_color_16 white;
     int png_color_type;
     int bpc;
+    unsigned char *volatile u16_copy = NULL;
 
     status = _cairo_surface_acquire_source_image (surface,
 						  &image,
@@ -198,11 +250,22 @@ write_png (cairo_surface_t	*surface,
 	goto BAIL1;
     }
 
-    /* Handle the various fallback formats (e.g. low bit-depth XServers)
-     * by coercing them to a simpler format using pixman.
-     */
-    clone = _cairo_image_surface_coerce (image);
-    status = clone->base.status;
+    /* Don't coerce to a lower resolution format */
+    if (image->format == CAIRO_FORMAT_RGB96F ||
+        image->format == CAIRO_FORMAT_RGBA128F) {
+	u16_copy = _cairo_malloc_ab (image->width * 8, image->height);
+	if (!u16_copy) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto BAIL1;
+	}
+	clone = (cairo_image_surface_t *)cairo_surface_reference (&image->base);
+    } else {
+	  /* Handle the various fallback formats (e.g. low bit-depth XServers)
+	  * by coercing them to a simpler format using pixman.
+	  */
+	  clone = _cairo_image_surface_coerce (image);
+	  status = clone->base.status;
+    }
     if (unlikely (status))
         goto BAIL1;
 
@@ -212,8 +275,22 @@ write_png (cairo_surface_t	*surface,
 	goto BAIL2;
     }
 
-    for (i = 0; i < clone->height; i++)
-	rows[i] = (png_byte *) clone->data + i * clone->stride;
+    if (!u16_copy) {
+	for (i = 0; i < clone->height; i++)
+	    rows[i] = (png_byte *)clone->data + i * clone->stride;
+    } else {
+	for (i = 0; i < clone->height; i++) {
+	    float *float_line = (float *)&clone->data[i * clone->stride];
+	    uint16_t *u16_line = (uint16_t *)&u16_copy[i * clone->width * 8];
+
+	    if (image->format == CAIRO_FORMAT_RGBA128F)
+		unpremultiply_float (float_line, u16_line, clone->width);
+	    else
+		convert_float_to_u16 (float_line, u16_line, clone->width);
+
+	    rows[i] = (png_byte *)u16_line;
+	}
+    }
 
     png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
 	                           png_simple_error_callback,
@@ -263,10 +340,16 @@ write_png (cairo_surface_t	*surface,
 	png_set_packswap (png);
 #endif
 	break;
-    case CAIRO_FORMAT_INVALID:
-    case CAIRO_FORMAT_RGB16_565:
     case CAIRO_FORMAT_RGB96F:
+	bpc = 16;
+	png_color_type = PNG_COLOR_TYPE_RGB;
+	break;
     case CAIRO_FORMAT_RGBA128F:
+	bpc = 16;
+	png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+	break;
+    case CAIRO_FORMAT_INVALID:
+    case CAIRO_FORMAT_RGB16_565:
     default:
 	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
 	goto BAIL4;
@@ -298,9 +381,11 @@ write_png (cairo_surface_t	*surface,
     png_write_info (png, info);
 
     if (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-	png_set_write_user_transform_fn (png, unpremultiply_data);
+	if (clone->format != CAIRO_FORMAT_RGBA128F)
+	    png_set_write_user_transform_fn (png, unpremultiply_data);
     } else if (png_color_type == PNG_COLOR_TYPE_RGB) {
-	png_set_write_user_transform_fn (png, convert_data_to_bytes);
+	if (clone->format != CAIRO_FORMAT_RGB96F)
+	    png_set_write_user_transform_fn (png, convert_data_to_bytes);
 	png_set_filler (png, 0, PNG_FILLER_AFTER);
     }
 
@@ -313,6 +398,7 @@ BAIL3:
     free (rows);
 BAIL2:
     cairo_surface_destroy (&clone->base);
+    free (u16_copy);
 BAIL1:
     _cairo_surface_release_source_image (surface, image, image_extra);
 
commit a34cb719cd9cb4f0c5b78be80b80ab0ae22464a6
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Mon Dec 3 15:13:40 2018 +0100

    Add support for RGBA128F and RGB96F formats.
    
    IGT wants to add support for planes with a bit depth >10, which
    requires a higher precision format than we have currently.
    
    I'm using RGBA as format, because of its existence in OpenGL.
    With the new formats we can directly convert our bytes to half float,
    or multiply a colro vector with a matrix to go to the Y'CbCr colorspace.
    
    This requires pixman 0.36.0, so bump the version requirement.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Reviewed-by: Bryce Harrington <bryce at bryceharrington.org>

diff --git a/configure.ac b/configure.ac
index 5e33c96ea..2f3eed746 100644
--- a/configure.ac
+++ b/configure.ac
@@ -685,7 +685,7 @@ CAIRO_ENABLE(test_surfaces, test surfaces, no)
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [
-  pixman_REQUIRES="pixman-1 >= 0.30.0"
+  pixman_REQUIRES="pixman-1 >= 0.36.0"
   PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, ,
     [use_image="no (requires $pixman_REQUIRES https://cairographics.org/releases/)"])
   image_REQUIRES=$pixman_REQUIRES
diff --git a/perf/micro/fill-clip.c b/perf/micro/fill-clip.c
index 2d014aca8..f9802705f 100644
--- a/perf/micro/fill-clip.c
+++ b/perf/micro/fill-clip.c
@@ -92,6 +92,8 @@ direct (cairo_t *cr, int width, int height, int loops)
     case CAIRO_FORMAT_RGB24:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32: bpp = 32; break;
+    case CAIRO_FORMAT_RGB96F: bpp = 96; break;
+    case CAIRO_FORMAT_RGBA128F: bpp = 128; break;
     }
 
     cairo_perf_timer_start ();
diff --git a/perf/micro/pixel.c b/perf/micro/pixel.c
index b600b5170..85a42e442 100644
--- a/perf/micro/pixel.c
+++ b/perf/micro/pixel.c
@@ -51,6 +51,8 @@ pixel_direct (cairo_t *cr, int width, int height, int loops)
     case CAIRO_FORMAT_RGB24:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32: bpp = 32; break;
+    case CAIRO_FORMAT_RGB96F: bpp = 96; break;
+    case CAIRO_FORMAT_RGBA128F: bpp = 128; break;
     }
 
     cairo_perf_timer_start ();
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index 6005060d4..760f092e3 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -131,6 +131,12 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
     case CAIRO_FORMAT_ARGB32:
 	width = image->width*4;
 	break;
+    case CAIRO_FORMAT_RGB96F:
+	width = image->width*12;
+	break;
+    case CAIRO_FORMAT_RGBA128F:
+	width = image->width*16;
+	break;
     case CAIRO_FORMAT_INVALID:
     default:
 	/* XXX compute width from pixman bpp */
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index bbf4cf228..434f67e59 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -2845,6 +2845,8 @@ inplace_renderer_init (cairo_image_span_renderer_t	*r,
 		case CAIRO_FORMAT_A1:
 		case CAIRO_FORMAT_RGB16_565:
 		case CAIRO_FORMAT_RGB30:
+		case CAIRO_FORMAT_RGB96F:
+		case CAIRO_FORMAT_RGBA128F:
 		case CAIRO_FORMAT_INVALID:
 		default: break;
 		}
@@ -2860,6 +2862,8 @@ inplace_renderer_init (cairo_image_span_renderer_t	*r,
 		case CAIRO_FORMAT_A1:
 		case CAIRO_FORMAT_RGB16_565:
 		case CAIRO_FORMAT_RGB30:
+		case CAIRO_FORMAT_RGB96F:
+		case CAIRO_FORMAT_RGBA128F:
 		case CAIRO_FORMAT_INVALID:
 		default: break;
 		}
diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index 0b50afcad..c56845ab2 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -455,6 +455,7 @@ static pixman_image_t *
 _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
 {
     uint32_t pixel;
+    float *rgba;
     pixman_color_t color;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -523,6 +524,32 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
 	color.green = (pixel >> 8 & 0xff) | (pixel & 0xff00);
 	color.blue = (pixel & 0xff) | (pixel << 8 & 0xff00);
 	return pixman_image_create_solid_fill (&color);
+
+    case CAIRO_FORMAT_RGB96F:
+    case CAIRO_FORMAT_RGBA128F:
+	if (image->format == CAIRO_FORMAT_RGBA128F)
+	{
+	    rgba = (float *)&image->data[y * image->stride + 16 * x];
+	    color.alpha = 65535.f * rgba[3];
+
+	    if (color.alpha == 0)
+		return _pixman_transparent_image ();
+	}
+	else
+	{
+	    rgba = (float *)&image->data[y * image->stride + 12 * x];
+	    color.alpha = 0xffff;
+	}
+
+	if (color.alpha == 0xffff && rgba[0] == 0.f && rgba[1] == 0.f && rgba[2] == 0.f)
+	    return _pixman_black_image ();
+	if (color.alpha == 0xffff && rgba[0] == 1.f && rgba[1] == 1.f && rgba[2] == 1.f)
+	    return _pixman_white_image ();
+
+	color.red = rgba[0] * 65535.f;
+	color.green = rgba[1] * 65535.f;
+	color.blue = rgba[2] * 65535.f;
+	return pixman_image_create_solid_fill (&color);
     }
 }
 
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 2ee1cad42..0e17f3a16 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -93,6 +93,10 @@ cairo_format_t
 _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
 {
     switch (pixman_format) {
+    case PIXMAN_rgba_float:
+	return CAIRO_FORMAT_RGBA128F;
+    case PIXMAN_rgb_float:
+	return CAIRO_FORMAT_RGB96F;
     case PIXMAN_a8r8g8b8:
 	return CAIRO_FORMAT_ARGB32;
     case PIXMAN_x2r10g10b10:
@@ -322,6 +326,12 @@ _cairo_format_to_pixman_format_code (cairo_format_t format)
     case CAIRO_FORMAT_RGB16_565:
 	ret = PIXMAN_r5g6b5;
 	break;
+    case CAIRO_FORMAT_RGB96F:
+	ret = PIXMAN_rgb_float;
+	break;
+    case CAIRO_FORMAT_RGBA128F:
+	ret = PIXMAN_rgba_float;
+	break;
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_FORMAT_INVALID:
     default:
@@ -693,8 +703,10 @@ _cairo_format_from_content (cairo_content_t content)
 _cairo_content_from_format (cairo_format_t format)
 {
     switch (format) {
+    case CAIRO_FORMAT_RGBA128F:
     case CAIRO_FORMAT_ARGB32:
 	return CAIRO_CONTENT_COLOR_ALPHA;
+    case CAIRO_FORMAT_RGB96F:
     case CAIRO_FORMAT_RGB30:
 	return CAIRO_CONTENT_COLOR;
     case CAIRO_FORMAT_RGB24:
@@ -716,6 +728,10 @@ _cairo_content_from_format (cairo_format_t format)
 _cairo_format_bits_per_pixel (cairo_format_t format)
 {
     switch (format) {
+    case CAIRO_FORMAT_RGBA128F:
+	return 128;
+    case CAIRO_FORMAT_RGB96F:
+	return 96;
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_RGB24:
diff --git a/src/cairo-png.c b/src/cairo-png.c
index ab0b9d0c5..b9fc9160a 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -265,6 +265,8 @@ write_png (cairo_surface_t	*surface,
 	break;
     case CAIRO_FORMAT_INVALID:
     case CAIRO_FORMAT_RGB16_565:
+    case CAIRO_FORMAT_RGB96F:
+    case CAIRO_FORMAT_RGBA128F:
     default:
 	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
 	goto BAIL4;
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 7db7dc5b0..0e6bc5e89 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -871,6 +871,8 @@ static const char *
 _format_to_string (cairo_format_t format)
 {
     switch (format) {
+    case CAIRO_FORMAT_RGBA128F: return "RGBA128F";
+    case CAIRO_FORMAT_RGB96F: return "RGB96F";
     case CAIRO_FORMAT_ARGB32:  return "ARGB32";
     case CAIRO_FORMAT_RGB30:   return "RGB30";
     case CAIRO_FORMAT_RGB24:   return "RGB24";
@@ -1315,6 +1317,18 @@ _write_image_surface (cairo_output_stream_t *output,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_RGB96F:
+	for (row = image->height; row--; ) {
+	    _cairo_output_stream_write (output, data, 12*width);
+	    data += stride;
+	}
+	break;
+    case CAIRO_FORMAT_RGBA128F:
+	for (row = image->height; row--; ) {
+	    _cairo_output_stream_write (output, data, 16*width);
+	    data += stride;
+	}
+	break;
     case CAIRO_FORMAT_INVALID:
     default:
 	ASSERT_NOT_REACHED;
@@ -1421,6 +1435,12 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	case CAIRO_FORMAT_ARGB32:
 	    len = clone->width * 4;
 	    break;
+	case CAIRO_FORMAT_RGB96F:
+	    len = clone->width * 12;
+	    break;
+	case CAIRO_FORMAT_RGBA128F:
+	    len = clone->width * 16;
+	    break;
 	case CAIRO_FORMAT_INVALID:
 	default:
 	    ASSERT_NOT_REACHED;
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index add42299b..108897e92 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -383,6 +383,10 @@ _cairo_xlib_display_get_xrender_format_for_pixman(cairo_xlib_display_t *display,
     XRenderPictFormat tmpl;
     int mask;
 
+    /* No equivalent in X11 yet. */
+    if (format == PIXMAN_rgba_float || format == PIXMAN_rgb_float)
+	return NULL;
+
 #define MASK(x) ((1<<(x))-1)
 
     tmpl.depth = PIXMAN_FORMAT_DEPTH(format);
@@ -510,6 +514,14 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	    xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
 									       PIXMAN_x2r10g10b10);
 	    break;
+	case CAIRO_FORMAT_RGBA128F:
+	    xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
+									       PIXMAN_rgba_float);
+	    break;
+	case CAIRO_FORMAT_RGB96F:
+	    xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
+									       PIXMAN_rgb_float);
+	    break;
 	case CAIRO_FORMAT_INVALID:
 	default:
 	    ASSERT_NOT_REACHED;
diff --git a/src/cairo.h b/src/cairo.h
index 3492bdc6b..079defd88 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -405,6 +405,8 @@ typedef enum _cairo_content {
  *   with red in the upper 5 bits, then green in the middle
  *   6 bits, and blue in the lower 5 bits. (Since 1.2)
  * @CAIRO_FORMAT_RGB30: like RGB24 but with 10bpc. (Since 1.12)
+ * @CAIRO_FORMAT_RGB96F: 3 floats, R, G, B. (Since 1.16)
+ * @CAIRO_FORMAT_RGBA128F: 4 floats, R, G, B, A. (Since 1.16)
  *
  * #cairo_format_t is used to identify the memory format of
  * image data.
@@ -420,7 +422,9 @@ typedef enum _cairo_format {
     CAIRO_FORMAT_A8        = 2,
     CAIRO_FORMAT_A1        = 3,
     CAIRO_FORMAT_RGB16_565 = 4,
-    CAIRO_FORMAT_RGB30     = 5
+    CAIRO_FORMAT_RGB30     = 5,
+    CAIRO_FORMAT_RGB96F    = 6,
+    CAIRO_FORMAT_RGBA128F  = 7
 } cairo_format_t;
 
 
diff --git a/src/cairoint.h b/src/cairoint.h
index cfae18cf9..331ab5357 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1536,7 +1536,7 @@ _cairo_surface_release_device_reference (cairo_surface_t *surface);
  * in cairo-xlib-surface.c--again see -Wswitch-enum).
  */
 #define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 &&		\
-                                    (format) <= CAIRO_FORMAT_RGB30)
+                                    (format) <= CAIRO_FORMAT_RGBA128F)
 
 /* pixman-required stride alignment in bytes. */
 #define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
diff --git a/test/any2ppm.c b/test/any2ppm.c
index a92412d08..7eb582c04 100644
--- a/test/any2ppm.c
+++ b/test/any2ppm.c
@@ -201,6 +201,8 @@ write_ppm (cairo_surface_t *surface, int fd)
     case CAIRO_FORMAT_A1:
     case CAIRO_FORMAT_RGB16_565:
     case CAIRO_FORMAT_RGB30:
+    case CAIRO_FORMAT_RGB96F:
+    case CAIRO_FORMAT_RGBA128F:
     case CAIRO_FORMAT_INVALID:
     default:
 	return "unhandled image format";
diff --git a/test/map-to-image.c b/test/map-to-image.c
index 0262245a8..2b1799f71 100644
--- a/test/map-to-image.c
+++ b/test/map-to-image.c
@@ -45,6 +45,8 @@ set_pixel_black(uint8_t *data, int stride,
     case CAIRO_FORMAT_RGB16_565:
 	*(uint16_t *)(data + y * stride + 2*x) = black_pixel;
 	break;
+    case CAIRO_FORMAT_RGBA128F:
+    case CAIRO_FORMAT_RGB96F:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_A8:
     case CAIRO_FORMAT_A1:
diff --git a/test/png.c b/test/png.c
index cd11fd0d1..a199d4867 100644
--- a/test/png.c
+++ b/test/png.c
@@ -60,6 +60,8 @@ format_to_string (cairo_format_t format)
     case CAIRO_FORMAT_RGB24:  return "rgb24";
     case CAIRO_FORMAT_RGB30:  return "rgb30";
     case CAIRO_FORMAT_ARGB32: return "argb32";
+    case CAIRO_FORMAT_RGB96F: return "rgb96f";
+    case CAIRO_FORMAT_RGBA128F: return "rgba128f";
     case CAIRO_FORMAT_INVALID:
     default: return "???";
     }
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index e493311e7..7cdb5afb6 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -2967,6 +2967,12 @@ _image_read_raw (csi_t *ctx,
     case CAIRO_FORMAT_ARGB32:
 	instride = rowlen = 4 * width;
 	break;
+    case CAIRO_FORMAT_RGB96F:
+	instride = rowlen = 12 * width;
+	break;
+    case CAIRO_FORMAT_RGBA128F:
+	instride = rowlen = 16 * width;
+	break;
     }
     len = rowlen * height;
 
@@ -3066,6 +3072,8 @@ err_decompress:
 #endif
 		    }
 		    break;
+		case CAIRO_FORMAT_RGB96F:
+		case CAIRO_FORMAT_RGBA128F:
 		case CAIRO_FORMAT_RGB30:
 		case CAIRO_FORMAT_INVALID:
 		case CAIRO_FORMAT_ARGB32:
@@ -3155,6 +3163,8 @@ err_decompress:
 #endif
 		}
 		break;
+	    case CAIRO_FORMAT_RGBA128F:
+	    case CAIRO_FORMAT_RGB96F:
 	    case CAIRO_FORMAT_RGB30:
 	    case CAIRO_FORMAT_INVALID:
 	    case CAIRO_FORMAT_ARGB32:
@@ -3191,6 +3201,8 @@ err_decompress:
 	    case CAIRO_FORMAT_A8:
 		break;
 
+	    case CAIRO_FORMAT_RGBA128F:
+	    case CAIRO_FORMAT_RGB96F:
 	    case CAIRO_FORMAT_RGB30:
 	    case CAIRO_FORMAT_RGB24:
 	    case CAIRO_FORMAT_INVALID:
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 7ce903b11..28ec11941 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -1510,6 +1510,8 @@ _format_to_string (cairo_format_t format)
 #define f(name) case CAIRO_FORMAT_ ## name: return #name
     switch (format) {
 	f(INVALID);
+	f(RGBA128F);
+	f(RGB96F);
 	f(ARGB32);
 	f(RGB30);
 	f(RGB24);
@@ -1527,8 +1529,10 @@ _format_to_content_string (cairo_format_t format)
     switch (format) {
     case CAIRO_FORMAT_INVALID:
 	return "INVALID";
+    case CAIRO_FORMAT_RGBA128F:
     case CAIRO_FORMAT_ARGB32:
 	return "COLOR_ALPHA";
+    case CAIRO_FORMAT_RGB96F:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_RGB24:
     case CAIRO_FORMAT_RGB16_565:
@@ -1673,6 +1677,8 @@ _emit_image (cairo_surface_t *image,
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_INVALID:
     case CAIRO_FORMAT_ARGB32: len = 4*width; break;
+    case CAIRO_FORMAT_RGB96F: len = 12*width; break;
+    case CAIRO_FORMAT_RGBA128F: len = 16*width; break;
     }
 
     _trace_printf ("  /source ");
@@ -1696,6 +1702,8 @@ _emit_image (cairo_surface_t *image,
     case CAIRO_FORMAT_RGB16_565:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
+    case CAIRO_FORMAT_RGB96F:
+    case CAIRO_FORMAT_RGBA128F:
 	for (row = height; row--; ) {
 	    _write_data (&stream, data, len);
 	    data += stride;
@@ -1754,6 +1762,8 @@ _emit_image (cairo_surface_t *image,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_RGB96F:
+    case CAIRO_FORMAT_RGBA128F:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	for (row = height; row--; ) {
@@ -1766,7 +1776,7 @@ _emit_image (cairo_surface_t *image,
 	    data += stride;
 	}
 	break;
-    case CAIRO_FORMAT_INVALID:
+   case CAIRO_FORMAT_INVALID:
     default:
 	break;
     }
commit 87c1c19197a6a3cdae955b320386f5449e17b286
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Mon Dec 3 15:13:39 2018 +0100

    cairo-trace: Simplify bigendian case in emit_image.
    
    All the cases are the same, except len is different.
    Use the already calculated len parameter to handle all
    cases except RGB24 the same.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Suggested-by: Bryce Harrington <bryce at bryceharrington.org>
    Reviewed-by: Bryce Harrington <bryce at bryceharrington.org>

diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 1fe130bba..7ce903b11 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -1680,24 +1680,6 @@ _emit_image (cairo_surface_t *image,
 
 #ifdef WORDS_BIGENDIAN
     switch (format) {
-    case CAIRO_FORMAT_A1:
-	for (row = height; row--; ) {
-	    _write_data (&stream, data, (width+7)/8);
-	    data += stride;
-	}
-	break;
-    case CAIRO_FORMAT_A8:
-	for (row = height; row--; ) {
-	    _write_data (&stream, data, width);
-	    data += stride;
-	}
-	break;
-    case CAIRO_FORMAT_RGB16_565:
-	for (row = height; row--; ) {
-	    _write_data (&stream, data, 2*width);
-	    data += stride;
-	}
-	break;
     case CAIRO_FORMAT_RGB24:
 	for (row = height; row--; ) {
 	    int col;
@@ -1709,10 +1691,13 @@ _emit_image (cairo_surface_t *image,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_A1:
+    case CAIRO_FORMAT_A8:
+    case CAIRO_FORMAT_RGB16_565:
     case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	for (row = height; row--; ) {
-	    _write_data (&stream, data, 4*width);
+	    _write_data (&stream, data, len);
 	    data += stride;
 	}
 	break;
@@ -1777,7 +1762,7 @@ _emit_image (cairo_surface_t *image,
 	    int col;
 	    for (col = 0; col < width; col++)
 		dst[col] = bswap_32 (src[col]);
-	    _write_data (&stream, rowdata, 4*width);
+	    _write_data (&stream, rowdata, len);
 	    data += stride;
 	}
 	break;


More information about the cairo-commit mailing list