From ec07e5377383b36a9fe714a1ad15b70b5df8a4a3 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Wed, 25 Oct 2017 12:10:24 +0100 Subject: Fix multithreaded crash with tiled regions. Michael has found a crash when scrolling quickly through pages with gsview. 2 Threads are redrawing at the same time from a display list. The problem comes when both threads happen to be trying to draw the same tile from the cache at the same time. The current code alters the ->{x,y} values of the pixmap from the cache as it tiles. If 2 threads are using the same tile at the same time, this causes a race condition which can upset the clipping calculations and we can access out of range. The solution is to make a new 'wrapper' fz_pixmap around the same data, and to alter the x/y values there instead. We therefore introduce a (hopefully generally useful) function fz_new_pixmap_from_pixmap, and use that. --- include/mupdf/fitz/pixmap.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h index a7bb4354..fcf9d8b3 100644 --- a/include/mupdf/fitz/pixmap.h +++ b/include/mupdf/fitz/pixmap.h @@ -135,6 +135,19 @@ fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, i */ fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *rect, fz_separations *seps, int alpha, unsigned char *samples); +/* + fz_new_pixmap_from_pixmap: Create a new pixmap that represents + a subarea of the specified pixmap. A reference is taken to his + pixmap that will be dropped on destruction. + + The supplied rectangle must be wholly contained within the original + pixmap. + + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, const fz_irect *rect); + /* fz_keep_pixmap: Take a reference to a pixmap. @@ -319,8 +332,6 @@ fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *cs_ Bit 0: If set, draw the image with linear interpolation. Bit 1: If set, free the samples buffer when the pixmap is destroyed. - Bit 2: If set, all separations are enabled (ignore the - fields in the seps structure). stride: The byte offset from the data for any given pixel to the data for the same pixel on the row below. @@ -351,12 +362,13 @@ struct fz_pixmap_s int xres, yres; fz_colorspace *colorspace; unsigned char *samples; + fz_pixmap *underlying; }; enum { FZ_PIXMAP_FLAG_INTERPOLATE = 1, - FZ_PIXMAP_FLAG_FREE_SAMPLES = 2, + FZ_PIXMAP_FLAG_FREE_SAMPLES = 2 }; void fz_drop_pixmap_imp(fz_context *ctx, fz_storable *pix); -- cgit v1.2.3