aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-03-26 14:42:10 +0900
committerYAMAMOTO Mitsuharu2019-03-26 14:42:10 +0900
commit75b7b2cf7cfd39dd595fa27ddeef859ed85861bb (patch)
tree8f37cd68d617760fd93b2f266ed9b3e661daa178 /src/image.c
parent568af1e5822086f2457b6e98a22624b8138aa72f (diff)
downloademacs-75b7b2cf7cfd39dd595fa27ddeef859ed85861bb.tar.gz
emacs-75b7b2cf7cfd39dd595fa27ddeef859ed85861bb.zip
Simplify cairo image surface creation and destruction
* src/dispextern.h (struct image) [USE_CAIRO]: Remove member cr_data2. * src/image.c (set_cairo_image_surface): New function split from original create_cairo_image_surface. Call cairo_surface_mark_dirty. (create_cairo_image_surface): Just create image surface and return it. (x_clear_image): Don't free cr_data2. (xpm_load, pbm_load, png_load_body, jpeg_load_body, tiff_load) (gif_load, imagemagick_load_image, svg_load_image) [USE_CAIRO]: Use new create_cairo_image_surface and cairo_image_surface_get_data instead of xmalloc. Use set_cairo_image_surface instead of old create_cairo_image_surface. (pbm_load) [USE_CAIRO]: Call cairo_surface_destroy for surface instead of xfree for data. (gif_load) [USE_CAIRO]: Multiply y-coordinate value by width instead of subimg_width.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c99
1 files changed, 48 insertions, 51 deletions
diff --git a/src/image.c b/src/image.c
index 854fbe40f75..16c5978db6e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1157,24 +1157,22 @@ get_spec_bg_or_alpha_as_argb (struct image *img,
1157 return bgcolor; 1157 return bgcolor;
1158} 1158}
1159 1159
1160static void 1160static cairo_surface_t *
1161create_cairo_image_surface (struct image *img, 1161create_cairo_image_surface (int width, int height)
1162 unsigned char *data,
1163 int width,
1164 int height)
1165{ 1162{
1166 cairo_surface_t *surface;
1167 cairo_format_t format = CAIRO_FORMAT_ARGB32; 1163 cairo_format_t format = CAIRO_FORMAT_ARGB32;
1168 int stride = cairo_format_stride_for_width (format, width); 1164 eassert (cairo_format_stride_for_width (format, width) == width * 4);
1169 surface = cairo_image_surface_create_for_data (data, 1165
1170 format, 1166 return cairo_image_surface_create (format, width, height);
1171 width, 1167}
1172 height, 1168
1173 stride); 1169static void
1174 img->width = width; 1170set_cairo_image_surface (struct image *img, cairo_surface_t *surface)
1175 img->height = height; 1171{
1172 cairo_surface_mark_dirty (surface);
1173 img->width = cairo_image_surface_get_width (surface);
1174 img->height = cairo_image_surface_get_height (surface);
1176 img->cr_data = surface; 1175 img->cr_data = surface;
1177 img->cr_data2 = data;
1178 img->pixmap = 0; 1176 img->pixmap = 0;
1179} 1177}
1180#endif 1178#endif
@@ -1404,7 +1402,6 @@ x_clear_image (struct frame *f, struct image *img)
1404#ifdef USE_CAIRO 1402#ifdef USE_CAIRO
1405 if (img->cr_data) 1403 if (img->cr_data)
1406 cairo_surface_destroy ((cairo_surface_t *)img->cr_data); 1404 cairo_surface_destroy ((cairo_surface_t *)img->cr_data);
1407 if (img->cr_data2) xfree (img->cr_data2);
1408#endif 1405#endif
1409 x_clear_image_1 (f, img, 1406 x_clear_image_1 (f, img,
1410 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS); 1407 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
@@ -3967,9 +3964,9 @@ xpm_load (struct frame *f, struct image *img)
3967 { 3964 {
3968 int width = img->ximg->width; 3965 int width = img->ximg->width;
3969 int height = img->ximg->height; 3966 int height = img->ximg->height;
3970 void *data = xmalloc (width * height * 4); 3967 cairo_surface_t *surface = create_cairo_image_surface (width, height);
3971 int i; 3968 int i;
3972 uint32_t *od = data; 3969 uint32_t *od = (uint32_t *) cairo_image_surface_get_data (surface);
3973 uint32_t *id = (uint32_t *) img->ximg->data; 3970 uint32_t *id = (uint32_t *) img->ximg->data;
3974 char *mid = img->mask_img ? img->mask_img->data : 0; 3971 char *mid = img->mask_img ? img->mask_img->data : 0;
3975 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); 3972 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
@@ -3988,7 +3985,7 @@ xpm_load (struct frame *f, struct image *img)
3988 } 3985 }
3989 } 3986 }
3990 3987
3991 create_cairo_image_surface (img, data, width, height); 3988 set_cairo_image_surface (img, surface);
3992 } 3989 }
3993 else 3990 else
3994 { 3991 {
@@ -5625,8 +5622,8 @@ pbm_load (struct frame *f, struct image *img)
5625 height = pbm_scan_number (&p, end); 5622 height = pbm_scan_number (&p, end);
5626 5623
5627#ifdef USE_CAIRO 5624#ifdef USE_CAIRO
5628 void *data = xmalloc (width * height * 4); 5625 cairo_surface_t *surface = create_cairo_image_surface (width, height);
5629 uint32_t *dataptr = data; 5626 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
5630#endif 5627#endif
5631 5628
5632 if (type != PBM_MONO) 5629 if (type != PBM_MONO)
@@ -5710,7 +5707,7 @@ pbm_load (struct frame *f, struct image *img)
5710 if (p >= end) 5707 if (p >= end)
5711 { 5708 {
5712#ifdef USE_CAIRO 5709#ifdef USE_CAIRO
5713 xfree (data); 5710 cairo_surface_destroy (surface);
5714#else 5711#else
5715 x_destroy_x_image (ximg); 5712 x_destroy_x_image (ximg);
5716#endif 5713#endif
@@ -5756,7 +5753,7 @@ pbm_load (struct frame *f, struct image *img)
5756 if (raw_p && p + expected_size > end) 5753 if (raw_p && p + expected_size > end)
5757 { 5754 {
5758#ifdef USE_CAIRO 5755#ifdef USE_CAIRO
5759 xfree (data); 5756 cairo_surface_destroy (surface);
5760#else 5757#else
5761 x_destroy_x_image (ximg); 5758 x_destroy_x_image (ximg);
5762#endif 5759#endif
@@ -5790,7 +5787,7 @@ pbm_load (struct frame *f, struct image *img)
5790 if (r < 0 || g < 0 || b < 0) 5787 if (r < 0 || g < 0 || b < 0)
5791 { 5788 {
5792#ifdef USE_CAIRO 5789#ifdef USE_CAIRO
5793 xfree (data); 5790 cairo_surface_destroy (surface);
5794#else 5791#else
5795 x_destroy_x_image (ximg); 5792 x_destroy_x_image (ximg);
5796#endif 5793#endif
@@ -5827,7 +5824,7 @@ pbm_load (struct frame *f, struct image *img)
5827 /* Maybe fill in the background field while we have ximg handy. */ 5824 /* Maybe fill in the background field while we have ximg handy. */
5828 5825
5829#ifdef USE_CAIRO 5826#ifdef USE_CAIRO
5830 create_cairo_image_surface (img, data, width, height); 5827 set_cairo_image_surface (img, surface);
5831#else 5828#else
5832 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 5829 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5833 /* Casting avoids a GCC warning. */ 5830 /* Casting avoids a GCC warning. */
@@ -6173,7 +6170,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6173 ptrdiff_t nbytes; 6170 ptrdiff_t nbytes;
6174 6171
6175#ifdef USE_CAIRO 6172#ifdef USE_CAIRO
6176 unsigned char *data = 0; 6173 cairo_surface_t *surface;
6177 uint32_t *dataptr; 6174 uint32_t *dataptr;
6178#else 6175#else
6179 XImagePtr ximg, mask_img = NULL; 6176 XImagePtr ximg, mask_img = NULL;
@@ -6388,8 +6385,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6388 } 6385 }
6389 6386
6390#ifdef USE_CAIRO 6387#ifdef USE_CAIRO
6391 data = (unsigned char *) xmalloc (width * height * 4); 6388 surface = create_cairo_image_surface (width, height);
6392 dataptr = (uint32_t *) data; 6389 dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
6393#else 6390#else
6394 /* Create an image and pixmap serving as mask if the PNG image 6391 /* Create an image and pixmap serving as mask if the PNG image
6395 contains an alpha channel. */ 6392 contains an alpha channel. */
@@ -6480,7 +6477,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6480 img->height = height; 6477 img->height = height;
6481 6478
6482#ifdef USE_CAIRO 6479#ifdef USE_CAIRO
6483 create_cairo_image_surface (img, data, width, height); 6480 set_cairo_image_surface (img, surface);
6484#else 6481#else
6485 /* Maybe fill in the background field while we have ximg handy. 6482 /* Maybe fill in the background field while we have ximg handy.
6486 Casting avoids a GCC warning. */ 6483 Casting avoids a GCC warning. */
@@ -7084,8 +7081,8 @@ jpeg_load_body (struct frame *f, struct image *img,
7084 JPOOL_IMAGE, row_stride, 1); 7081 JPOOL_IMAGE, row_stride, 1);
7085#ifdef USE_CAIRO 7082#ifdef USE_CAIRO
7086 { 7083 {
7087 unsigned char *data = (unsigned char *) xmalloc (width*height*4); 7084 cairo_surface_t *surface = create_cairo_image_surface (width, height);
7088 uint32_t *dataptr = (uint32_t *) data; 7085 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
7089 int r, g, b; 7086 int r, g, b;
7090 7087
7091 for (y = 0; y < height; ++y) 7088 for (y = 0; y < height; ++y)
@@ -7102,7 +7099,7 @@ jpeg_load_body (struct frame *f, struct image *img,
7102 } 7099 }
7103 } 7100 }
7104 7101
7105 create_cairo_image_surface (img, data, width, height); 7102 set_cairo_image_surface (img, surface);
7106 } 7103 }
7107#else 7104#else
7108 for (y = 0; y < height; ++y) 7105 for (y = 0; y < height; ++y)
@@ -7564,8 +7561,8 @@ tiff_load (struct frame *f, struct image *img)
7564 7561
7565#ifdef USE_CAIRO 7562#ifdef USE_CAIRO
7566 { 7563 {
7567 unsigned char *data = (unsigned char *) xmalloc (width*height*4); 7564 cairo_surface_t *surface = create_cairo_image_surface (width, height);
7568 uint32_t *dataptr = (uint32_t *) data; 7565 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
7569 7566
7570 for (y = 0; y < height; ++y) 7567 for (y = 0; y < height; ++y)
7571 { 7568 {
@@ -7581,7 +7578,7 @@ tiff_load (struct frame *f, struct image *img)
7581 } 7578 }
7582 } 7579 }
7583 7580
7584 create_cairo_image_surface (img, data, width, height); 7581 set_cairo_image_surface (img, surface);
7585 } 7582 }
7586#else 7583#else
7587 /* Initialize the color table. */ 7584 /* Initialize the color table. */
@@ -8020,9 +8017,8 @@ gif_load (struct frame *f, struct image *img)
8020 } 8017 }
8021 8018
8022#ifdef USE_CAIRO 8019#ifdef USE_CAIRO
8023 /* xzalloc so data is zero => transparent */ 8020 cairo_surface_t *surface = create_cairo_image_surface (width, height);
8024 void *data = xzalloc (width * height * 4); 8021 uint32_t *data32 = (uint32_t *) cairo_image_surface_get_data (surface);
8025 uint32_t *data32 = data;
8026 if (STRINGP (specified_bg)) 8022 if (STRINGP (specified_bg))
8027 { 8023 {
8028 XColor color; 8024 XColor color;
@@ -8169,7 +8165,7 @@ gif_load (struct frame *f, struct image *img)
8169 { 8165 {
8170#ifdef USE_CAIRO 8166#ifdef USE_CAIRO
8171 uint32_t *dataptr = 8167 uint32_t *dataptr =
8172 (data32 + ((row + subimg_top) * subimg_width 8168 (data32 + ((row + subimg_top) * width
8173 + x + subimg_left)); 8169 + x + subimg_left));
8174 int r = gif_color_map->Colors[c].Red; 8170 int r = gif_color_map->Colors[c].Red;
8175 int g = gif_color_map->Colors[c].Green; 8171 int g = gif_color_map->Colors[c].Green;
@@ -8181,7 +8177,7 @@ gif_load (struct frame *f, struct image *img)
8181 XPutPixel (ximg, x + subimg_left, row + subimg_top, 8177 XPutPixel (ximg, x + subimg_left, row + subimg_top,
8182 pixel_colors[c]); 8178 pixel_colors[c]);
8183#endif 8179#endif
8184 } 8180 }
8185 } 8181 }
8186 } 8182 }
8187 } 8183 }
@@ -8195,7 +8191,7 @@ gif_load (struct frame *f, struct image *img)
8195 { 8191 {
8196#ifdef USE_CAIRO 8192#ifdef USE_CAIRO
8197 uint32_t *dataptr = 8193 uint32_t *dataptr =
8198 (data32 + ((y + subimg_top) * subimg_width 8194 (data32 + ((y + subimg_top) * width
8199 + x + subimg_left)); 8195 + x + subimg_left));
8200 int r = gif_color_map->Colors[c].Red; 8196 int r = gif_color_map->Colors[c].Red;
8201 int g = gif_color_map->Colors[c].Green; 8197 int g = gif_color_map->Colors[c].Green;
@@ -8265,7 +8261,7 @@ gif_load (struct frame *f, struct image *img)
8265 } 8261 }
8266 8262
8267#ifdef USE_CAIRO 8263#ifdef USE_CAIRO
8268 create_cairo_image_surface (img, data, width, height); 8264 set_cairo_image_surface (img, surface);
8269#else 8265#else
8270 /* Maybe fill in the background field while we have ximg handy. */ 8266 /* Maybe fill in the background field while we have ximg handy. */
8271 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 8267 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -8693,7 +8689,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8693 char hint_buffer[MaxTextExtent]; 8689 char hint_buffer[MaxTextExtent];
8694 char *filename_hint = NULL; 8690 char *filename_hint = NULL;
8695#ifdef USE_CAIRO 8691#ifdef USE_CAIRO
8696 void *data = NULL; 8692 cairo_surface_t *surface;
8697#endif 8693#endif
8698 8694
8699 /* Initialize the ImageMagick environment. */ 8695 /* Initialize the ImageMagick environment. */
@@ -8905,9 +8901,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
8905 ad-hoc and needs to be more researched. */ 8901 ad-hoc and needs to be more researched. */
8906 void *dataptr; 8902 void *dataptr;
8907#ifdef USE_CAIRO 8903#ifdef USE_CAIRO
8908 data = xmalloc (width * height * 4); 8904 surface = create_cairo_image_surface (width, height);
8909 const char *exportdepth = "BGRA"; 8905 const char *exportdepth = "BGRA";
8910 dataptr = data; 8906 dataptr = cairo_image_surface_get_data (surface);
8911#else 8907#else
8912 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ 8908 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
8913 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ 8909 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
@@ -8954,7 +8950,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
8954 double quantum_range = QuantumRange; 8950 double quantum_range = QuantumRange;
8955 MagickRealType color_scale = 65535.0 / quantum_range; 8951 MagickRealType color_scale = 65535.0 / quantum_range;
8956#ifdef USE_CAIRO 8952#ifdef USE_CAIRO
8957 data = xmalloc (width * height * 4); 8953 surface = create_cairo_image_surface (width, height);
8954 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
8958 color_scale /= 256; 8955 color_scale /= 256;
8959#else 8956#else
8960 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 8957 /* Try to create a x pixmap to hold the imagemagick pixmap. */
@@ -8999,7 +8996,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8999 { 8996 {
9000 PixelGetMagickColor (pixels[x], &pixel); 8997 PixelGetMagickColor (pixels[x], &pixel);
9001#ifdef USE_CAIRO 8998#ifdef USE_CAIRO
9002 ((uint32_t *)data)[width * y + x] = 8999 dataptr[width * y + x] =
9003 lookup_rgb_color (f, 9000 lookup_rgb_color (f,
9004 color_scale * pixel.red, 9001 color_scale * pixel.red,
9005 color_scale * pixel.green, 9002 color_scale * pixel.green,
@@ -9017,7 +9014,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
9017 } 9014 }
9018 9015
9019#ifdef USE_CAIRO 9016#ifdef USE_CAIRO
9020 create_cairo_image_surface (img, data, width, height); 9017 set_cairo_image_surface (img, surface);
9021#else 9018#else
9022#ifdef COLOR_TABLE_SUPPORT 9019#ifdef COLOR_TABLE_SUPPORT
9023 /* Remember colors allocated for this image. */ 9020 /* Remember colors allocated for this image. */
@@ -9480,13 +9477,13 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9480 9477
9481 { 9478 {
9482#ifdef USE_CAIRO 9479#ifdef USE_CAIRO
9483 unsigned char *data = (unsigned char *) xmalloc (width*height*4); 9480 cairo_surface_t *surface = create_cairo_image_surface (width, height);
9481 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
9484 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); 9482 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
9485 9483
9486 for (int y = 0; y < height; ++y) 9484 for (int y = 0; y < height; ++y)
9487 { 9485 {
9488 const guchar *iconptr = pixels + y * rowstride; 9486 const guchar *iconptr = pixels + y * rowstride;
9489 uint32_t *dataptr = (uint32_t *) (data + y * rowstride);
9490 9487
9491 for (int x = 0; x < width; ++x) 9488 for (int x = 0; x < width; ++x)
9492 { 9489 {
@@ -9503,7 +9500,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9503 } 9500 }
9504 } 9501 }
9505 9502
9506 create_cairo_image_surface (img, data, width, height); 9503 set_cairo_image_surface (img, surface);
9507 g_object_unref (pixbuf); 9504 g_object_unref (pixbuf);
9508#else 9505#else
9509 /* Try to create a x pixmap to hold the svg pixmap. */ 9506 /* Try to create a x pixmap to hold the svg pixmap. */