diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e631c69 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libgxps-0.3.0.tar.xz diff --git a/.libgxps.metadata b/.libgxps.metadata new file mode 100644 index 0000000..0ac1c04 --- /dev/null +++ b/.libgxps.metadata @@ -0,0 +1 @@ +3e30b03543bdc4529815eb97261041d152f7785a SOURCES/libgxps-0.3.0.tar.xz diff --git a/SOURCES/libgxps-0.2.4-GXPSImage.patch b/SOURCES/libgxps-0.2.4-GXPSImage.patch new file mode 100644 index 0000000..77de9a4 --- /dev/null +++ b/SOURCES/libgxps-0.2.4-GXPSImage.patch @@ -0,0 +1,472 @@ +--- libgxps-0.3.0/libgxps/gxps-brush.c ++++ libgxps-0.3.0/libgxps/gxps-brush.c +@@ -965,7 +965,7 @@ brush_end_element (GMarkupParseContext + g_markup_parse_context_pop (context); + } else if (strcmp (element_name, "ImageBrush") == 0) { + GXPSBrushImage *brush_image; +- GXPSImage *image; ++ cairo_surface_t *image; + GError *err = NULL; + + brush_image = g_markup_parse_context_pop (context); +@@ -976,14 +976,20 @@ brush_end_element (GMarkupParseContext + cairo_matrix_t matrix; + gdouble x_scale, y_scale; + cairo_surface_t *clip_surface; ++ double *res_x, *res_y; + +- /* viewbox units is 1/96 inch, convert to pixels */ +- brush_image->viewbox.x *= image->res_x / 96; +- brush_image->viewbox.y *= image->res_y / 96; +- brush_image->viewbox.width *= image->res_x / 96; +- brush_image->viewbox.height *= image->res_y / 96; ++ res_x = cairo_surface_get_user_data (image, (const cairo_user_data_key_t *) 0x1); ++ res_y = cairo_surface_get_user_data (image, (const cairo_user_data_key_t *) 0x2); + +- clip_surface = cairo_surface_create_for_rectangle (image->surface, ++ if (res_x != NULL && res_y != NULL) { ++ /* viewbox units is 1/96 inch, convert to pixels */ ++ brush_image->viewbox.x *= *res_x / 96; ++ brush_image->viewbox.y *= *res_y / 96; ++ brush_image->viewbox.width *= *res_x / 96; ++ brush_image->viewbox.height *= *res_y / 96; ++ } ++ ++ clip_surface = cairo_surface_create_for_rectangle (image, + brush_image->viewbox.x, + brush_image->viewbox.y, + brush_image->viewbox.width, +--- libgxps-0.3.0/libgxps/gxps-images.c ++++ libgxps-0.3.0/libgxps/gxps-images.c +@@ -88,6 +88,45 @@ multiply_alpha (int alpha, int color) + return ((temp + (temp >> 8)) >> 8); + } + ++static void ++image_set_res_x (cairo_surface_t *image, ++ double res_x) ++{ ++ double *x; ++ ++ x = g_new (double, 1); ++ *x = res_x; ++ ++ cairo_surface_set_user_data (image, ++ (const cairo_user_data_key_t *) 0x1, ++ x, ++ (cairo_destroy_func_t) g_free); ++} ++ ++static void ++image_set_res_y (cairo_surface_t *image, ++ double res_y) ++{ ++ double *y; ++ ++ y = g_new (double, 1); ++ *y = res_y; ++ ++ cairo_surface_set_user_data (image, ++ (const cairo_user_data_key_t *) 0x2, ++ y, ++ (cairo_destroy_func_t) g_free); ++} ++ ++static void ++image_set_res (cairo_surface_t *image, ++ double res_x, ++ double res_y) ++{ ++ image_set_res_x (image, res_x); ++ image_set_res_y (image, res_y); ++} ++ + /* Premultiplies data and converts RGBA bytes => native endian + * From cairo's cairo-png.c */ + static void +@@ -163,14 +202,14 @@ fill_png_error (GError **error, + + /* Adapted from cairo's read_png in cairo-png.c + * http://cairographics.org/ */ +-static GXPSImage * ++static cairo_surface_t * + gxps_images_create_from_png (GXPSArchive *zip, + const gchar *image_uri, + GError **error) + { + #ifdef HAVE_LIBPNG + GInputStream *stream; +- GXPSImage *image = NULL; ++ cairo_surface_t *image = NULL; + char *png_err_msg = NULL; + png_struct *png; + png_info *info; +@@ -181,6 +220,7 @@ gxps_images_create_from_png (GXPSArchive + unsigned int i; + cairo_format_t format; + cairo_status_t status; ++ double res_x, res_y; + + stream = gxps_archive_open (zip, image_uri); + if (!stream) { +@@ -217,7 +257,7 @@ gxps_images_create_from_png (GXPSArchive + g_free (png_err_msg); + g_object_unref (stream); + png_destroy_read_struct (&png, &info, NULL); +- gxps_image_free (image); ++ cairo_surface_destroy (image); + g_free (row_pointers); + g_free (data); + return NULL; +@@ -295,13 +335,12 @@ gxps_images_create_from_png (GXPSArchive + return NULL; + } + +- image = g_slice_new0 (GXPSImage); +- image->res_x = png_get_x_pixels_per_meter (png, info) * METERS_PER_INCH; +- if (image->res_x == 0) +- image->res_x = 96; +- image->res_y = png_get_y_pixels_per_meter (png, info) * METERS_PER_INCH; +- if (image->res_y == 0) +- image->res_y = 96; ++ res_x = png_get_x_pixels_per_meter (png, info) * METERS_PER_INCH; ++ if (res_x == 0) ++ res_x = 96; ++ res_y = png_get_y_pixels_per_meter (png, info) * METERS_PER_INCH; ++ if (res_y == 0) ++ res_y = 96; + + data = g_malloc (png_height * stride); + row_pointers = g_new (png_byte *, png_height); +@@ -315,23 +354,25 @@ gxps_images_create_from_png (GXPSArchive + g_object_unref (stream); + g_free (row_pointers); + +- image->surface = cairo_image_surface_create_for_data (data, format, +- png_width, png_height, +- stride); +- if (cairo_surface_status (image->surface)) { ++ image = cairo_image_surface_create_for_data (data, format, ++ png_width, png_height, ++ stride); ++ if (cairo_surface_status (image)) { + fill_png_error (error, image_uri, NULL); +- gxps_image_free (image); ++ cairo_surface_destroy (image); + g_free (data); + return NULL; + } + +- status = cairo_surface_set_user_data (image->surface, ++ image_set_res (image, res_x, res_y); ++ ++ status = cairo_surface_set_user_data (image, + &image_data_cairo_key, + data, + (cairo_destroy_func_t) g_free); + if (status) { + fill_png_error (error, image_uri, NULL); +- gxps_image_free (image); ++ cairo_surface_destroy (image); + g_free (data); + return NULL; + } +@@ -423,7 +463,7 @@ _jpeg_error_exit (j_common_ptr error) + } + #endif /* HAVE_LIBJPEG */ + +-static GXPSImage * ++static cairo_surface_t * + gxps_images_create_from_jpeg (GXPSArchive *zip, + const gchar *image_uri, + GError **error) +@@ -433,7 +473,7 @@ gxps_images_create_from_jpeg (GXPSArchiv + struct jpeg_error_mgr error_mgr; + struct jpeg_decompress_struct cinfo; + struct _jpeg_src_mgr src; +- GXPSImage *image; ++ cairo_surface_t *image; + guchar *data; + gint stride; + JSAMPARRAY lines; +@@ -484,28 +524,26 @@ gxps_images_create_from_jpeg (GXPSArchiv + cinfo.do_fancy_upsampling = FALSE; + jpeg_start_decompress (&cinfo); + +- image = g_slice_new (GXPSImage); +- image->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, +- cinfo.output_width, +- cinfo.output_height); +- image->res_x = 96; +- image->res_y = 96; +- if (cairo_surface_status (image->surface)) { ++ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, ++ cinfo.output_width, ++ cinfo.output_height); ++ image_set_res (image, 96, 96); ++ if (cairo_surface_status (image)) { + g_set_error (error, + GXPS_ERROR, + GXPS_ERROR_IMAGE, + "Error loading JPEG image %s: %s", + image_uri, +- cairo_status_to_string (cairo_surface_status (image->surface))); ++ cairo_status_to_string (cairo_surface_status (image))); + jpeg_destroy_decompress (&cinfo); +- gxps_image_free (image); ++ cairo_surface_destroy (image); + g_object_unref (stream); + + return NULL; + } + +- data = cairo_image_surface_get_data (image->surface); +- stride = cairo_image_surface_get_stride (image->surface); ++ data = cairo_image_surface_get_data (image); ++ stride = cairo_image_surface_get_stride (image); + jpeg_stride = cinfo.output_width * cinfo.out_color_components; + lines = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, jpeg_stride, 4); + +@@ -535,7 +573,7 @@ gxps_images_create_from_jpeg (GXPSArchiv + GXPS_DEBUG (g_message ("Unsupported jpeg color space %s", + _jpeg_color_space_name (cinfo.out_color_space))); + +- gxps_image_free (image); ++ cairo_surface_destroy (image); + jpeg_destroy_decompress (&cinfo); + g_object_unref (stream); + return NULL; +@@ -549,27 +587,25 @@ gxps_images_create_from_jpeg (GXPSArchiv + } + + if (cinfo.density_unit == 1) { /* dots/inch */ +- image->res_x = cinfo.X_density; +- image->res_y = cinfo.Y_density; ++ image_set_res (image, cinfo.X_density, cinfo.Y_density); + } else if (cinfo.density_unit == 2) { /* dots/cm */ +- image->res_x = cinfo.X_density * CENTIMETERS_PER_INCH; +- image->res_y = cinfo.Y_density * CENTIMETERS_PER_INCH; ++ image_set_res (image, cinfo.X_density * CENTIMETERS_PER_INCH, cinfo.Y_density * CENTIMETERS_PER_INCH); + } + + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + g_object_unref (stream); + +- cairo_surface_mark_dirty (image->surface); ++ cairo_surface_mark_dirty (image); + +- if (cairo_surface_status (image->surface)) { ++ if (cairo_surface_status (image)) { + g_set_error (error, + GXPS_ERROR, + GXPS_ERROR_IMAGE, + "Error loading JPEG image %s: %s", + image_uri, +- cairo_status_to_string (cairo_surface_status (image->surface))); +- gxps_image_free (image); ++ cairo_status_to_string (cairo_surface_status (image))); ++ cairo_surface_destroy (image); + + return NULL; + } +@@ -728,7 +764,7 @@ _tiff_unmap_file (thandle_t handle, + } + #endif /* #ifdef HAVE_LIBTIFF */ + +-static GXPSImage * ++static cairo_surface_t * + gxps_images_create_from_tiff (GXPSArchive *zip, + const gchar *image_uri, + GError **error) +@@ -736,7 +772,7 @@ gxps_images_create_from_tiff (GXPSArchiv + #ifdef HAVE_LIBTIFF + TIFF *tiff; + TiffBuffer buffer; +- GXPSImage *image; ++ cairo_surface_t *image; + gint width, height; + guint16 res_unit; + float res_x, res_y; +@@ -802,49 +838,47 @@ gxps_images_create_from_tiff (GXPSArchiv + return NULL; + } + +- image = g_slice_new (GXPSImage); +- image->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, +- width, height); +- image->res_x = 96; +- image->res_y = 96; ++ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, ++ width, height); ++ image_set_res (image, 96, 96); + + if (!TIFFGetField (tiff, TIFFTAG_RESOLUTIONUNIT, &res_unit)) + res_unit = 0; + if (TIFFGetField (tiff, TIFFTAG_XRESOLUTION, &res_x)) { + if (res_unit == 2) { /* inches */ +- image->res_x = res_x; ++ image_set_res_x (image, res_x); + } else if (res_unit == 3) { /* centimeters */ +- image->res_x = res_x * CENTIMETERS_PER_INCH; ++ image_set_res_x (image, res_x * CENTIMETERS_PER_INCH); + } + } + if (TIFFGetField (tiff, TIFFTAG_YRESOLUTION, &res_y)) { + if (res_unit == 2) { /* inches */ +- image->res_y = res_y; ++ image_set_res_y (image, res_y); + } else if (res_unit == 3) { /* centimeters */ +- image->res_y = res_y * CENTIMETERS_PER_INCH; ++ image_set_res_y (image, res_y * CENTIMETERS_PER_INCH); + } + } + +- if (cairo_surface_status (image->surface)) { ++ if (cairo_surface_status (image)) { + g_set_error (error, + GXPS_ERROR, + GXPS_ERROR_IMAGE, + "Error loading TIFF image %s: %s", + image_uri, +- cairo_status_to_string (cairo_surface_status (image->surface))); +- gxps_image_free (image); ++ cairo_status_to_string (cairo_surface_status (image))); ++ cairo_surface_destroy (image); + TIFFClose (tiff); + _tiff_pop_handlers (); + g_free (buffer.buffer); + return NULL; + } + +- data = cairo_image_surface_get_data (image->surface); ++ data = cairo_image_surface_get_data (image); + if (!TIFFReadRGBAImageOriented (tiff, width, height, + (uint32 *)data, + ORIENTATION_TOPLEFT, 1) || _tiff_error) { + fill_tiff_error (error, image_uri); +- gxps_image_free (image); ++ cairo_surface_destroy (image); + TIFFClose (tiff); + _tiff_pop_handlers (); + g_free (buffer.buffer); +@@ -855,7 +889,7 @@ gxps_images_create_from_tiff (GXPSArchiv + _tiff_pop_handlers (); + g_free (buffer.buffer); + +- stride = cairo_image_surface_get_stride (image->surface); ++ stride = cairo_image_surface_get_stride (image); + p = data; + while (p < data + (height * stride)) { + guint32 *pixel = (guint32 *)p; +@@ -869,7 +903,7 @@ gxps_images_create_from_tiff (GXPSArchiv + p += 4; + } + +- cairo_surface_mark_dirty (image->surface); ++ cairo_surface_mark_dirty (image); + + return image; + #else +@@ -897,12 +931,12 @@ gxps_images_guess_content_type (GXPSArch + return mime_type; + } + +-GXPSImage * ++cairo_surface_t * + gxps_images_get_image (GXPSArchive *zip, + const gchar *image_uri, + GError **error) + { +- GXPSImage *image = NULL; ++ cairo_surface_t *image = NULL; + gchar *image_uri_lower; + + /* First try with extensions, +@@ -942,15 +976,3 @@ gxps_images_get_image (GXPSArchive *zip, + + return image; + } +- +-void +-gxps_image_free (GXPSImage *image) +-{ +- if (G_UNLIKELY (!image)) +- return; +- +- if (G_LIKELY (image->surface)) +- cairo_surface_destroy (image->surface); +- +- g_slice_free (GXPSImage, image); +-} +--- libgxps-0.3.0/libgxps/gxps-images.h ++++ libgxps-0.3.0/libgxps/gxps-images.h +@@ -25,18 +25,9 @@ + + G_BEGIN_DECLS + +-typedef struct _GXPSImage GXPSImage; +- +-struct _GXPSImage { +- cairo_surface_t *surface; +- double res_x; +- double res_y; +-}; +- +-GXPSImage *gxps_images_get_image (GXPSArchive *zip, +- const gchar *image_uri, +- GError **error); +-void gxps_image_free (GXPSImage *image); ++cairo_surface_t *gxps_images_get_image (GXPSArchive *zip, ++ const gchar *image_uri, ++ GError **error); + + G_END_DECLS + +--- libgxps-0.3.0/libgxps/gxps-page.c ++++ libgxps-0.3.0/libgxps/gxps-page.c +@@ -77,12 +77,12 @@ gxps_page_error_quark (void) + } + + /* Images */ +-GXPSImage * ++cairo_surface_t * + gxps_page_get_image (GXPSPage *page, + const gchar *image_uri, + GError **error) + { +- GXPSImage *image; ++ cairo_surface_t *image; + + if (page->priv->image_cache) { + image = g_hash_table_lookup (page->priv->image_cache, +@@ -99,12 +99,12 @@ gxps_page_get_image (GXPSPage *page, + page->priv->image_cache = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, +- (GDestroyNotify)gxps_image_free); ++ (GDestroyNotify)cairo_surface_destroy); + } + + g_hash_table_insert (page->priv->image_cache, + g_strdup (image_uri), +- image); ++ cairo_surface_reference (image)); + return image; + } + +--- libgxps-0.3.0/libgxps/gxps-page-private.h ++++ libgxps-0.3.0/libgxps/gxps-page-private.h +@@ -58,9 +58,9 @@ struct _GXPSRenderContext { + GXPSBrushVisual *visual; + }; + +-GXPSImage *gxps_page_get_image (GXPSPage *page, +- const gchar *image_uri, +- GError **error); ++cairo_surface_t *gxps_page_get_image (GXPSPage *page, ++ const gchar *image_uri, ++ GError **error); + void gxps_page_render_parser_push (GMarkupParseContext *context, + GXPSRenderContext *ctx); + diff --git a/SOURCES/libgxps-0.2.5-private-methods.patch b/SOURCES/libgxps-0.2.5-private-methods.patch new file mode 100644 index 0000000..202fda4 --- /dev/null +++ b/SOURCES/libgxps-0.2.5-private-methods.patch @@ -0,0 +1,192 @@ +--- libgxps-0.3.0/libgxps/gxps-archive.h ++++ libgxps-0.3.0/libgxps/gxps-archive.h +@@ -38,14 +38,20 @@ G_BEGIN_DECLS + typedef struct _GXPSArchive GXPSArchive; + typedef struct _GXPSArchiveClass GXPSArchiveClass; + ++GXPS_AVAILABLE_IN_ALL + GType gxps_archive_get_type (void) G_GNUC_CONST; ++GXPS_AVAILABLE_IN_ALL + GXPSArchive *gxps_archive_new (GFile *filename, + GError **error); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_archive_has_entry (GXPSArchive *archive, + const gchar *path); ++GXPS_AVAILABLE_IN_ALL + GXPSResources *gxps_archive_get_resources (GXPSArchive *archive); ++GXPS_AVAILABLE_IN_ALL + GInputStream *gxps_archive_open (GXPSArchive *archive, + const gchar *path); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_archive_read_entry (GXPSArchive *archive, + const gchar *path, + guchar **buffer, +--- libgxps-0.2.5/libgxps/gxps-brush.h ++++ libgxps-0.2.5/libgxps/gxps-brush.h +@@ -33,12 +33,16 @@ struct _GXPSBrush { + gdouble opacity; + }; + ++GXPS_AVAILABLE_IN_ALL + GXPSBrush *gxps_brush_new (GXPSRenderContext *ctx); ++GXPS_AVAILABLE_IN_ALL + void gxps_brush_free (GXPSBrush *brush); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_brush_solid_color_parse (const gchar *data, + GXPSArchive *zip, + gdouble alpha, + cairo_pattern_t **pattern); ++GXPS_AVAILABLE_IN_ALL + void gxps_brush_parser_push (GMarkupParseContext *context, + GXPSBrush *brush); + +--- libgxps-0.2.5/libgxps/gxps-color.h ++++ libgxps-0.2.5/libgxps/gxps-color.h +@@ -34,6 +34,7 @@ typedef struct _GXPSColor { + gdouble blue; + } GXPSColor; + ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_color_new_for_icc (GXPSArchive *zip, + const gchar *icc_profile_uri, + gdouble *values, +--- libgxps-0.2.5/libgxps/gxps-fonts.h ++++ libgxps-0.2.5/libgxps/gxps-fonts.h +@@ -25,6 +25,7 @@ + + G_BEGIN_DECLS + ++GXPS_AVAILABLE_IN_ALL + cairo_font_face_t *gxps_fonts_get_font (GXPSArchive *zip, + const gchar *font_uri, + GError **error); +--- libgxps-0.2.5/libgxps/gxps-glyphs.h ++++ libgxps-0.2.5/libgxps/gxps-glyphs.h +@@ -45,12 +45,15 @@ struct _GXPSGlyphs { + guint italic : 1; + }; + ++GXPS_AVAILABLE_IN_ALL + GXPSGlyphs *gxps_glyphs_new (GXPSRenderContext *ctx, + gchar *font_uri, + gdouble font_size, + gdouble origin_x, + gdouble origin_y); ++GXPS_AVAILABLE_IN_ALL + void gxps_glyphs_free (GXPSGlyphs *glyphs); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_glyphs_to_cairo_glyphs (GXPSGlyphs *gxps_glyphs, + cairo_scaled_font_t *scaled_font, + const gchar *utf8, +@@ -59,6 +62,7 @@ gboolean gxps_glyphs_to_cairo_glyphs + cairo_text_cluster_t **clusters, + int *num_clusters, + GError **error); ++GXPS_AVAILABLE_IN_ALL + void gxps_glyphs_parser_push (GMarkupParseContext *context, + GXPSGlyphs *glyphs); + +--- libgxps-0.2.5/libgxps/gxps-images.h ++++ libgxps-0.2.5/libgxps/gxps-images.h +@@ -25,6 +25,7 @@ + + G_BEGIN_DECLS + ++GXPS_AVAILABLE_IN_ALL + cairo_surface_t *gxps_images_get_image (GXPSArchive *zip, + const gchar *image_uri, + GError **error); +--- libgxps-0.2.5/libgxps/gxps-matrix.h ++++ libgxps-0.2.5/libgxps/gxps-matrix.h +@@ -32,10 +32,14 @@ struct _GXPSMatrix { + cairo_matrix_t matrix; + }; + ++GXPS_AVAILABLE_IN_ALL + GXPSMatrix *gxps_matrix_new (GXPSRenderContext *ctx); ++GXPS_AVAILABLE_IN_ALL + void gxps_matrix_free (GXPSMatrix *matrix); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_matrix_parse (const gchar *data, + cairo_matrix_t *matrix); ++GXPS_AVAILABLE_IN_ALL + void gxps_matrix_parser_push (GMarkupParseContext *context, + GXPSMatrix *matrix); + +--- libgxps-0.2.5/libgxps/gxps-page-private.h ++++ libgxps-0.2.5/libgxps/gxps-page-private.h +@@ -58,9 +58,11 @@ struct _GXPSRenderContext { + GXPSBrushVisual *visual; + }; + ++GXPS_AVAILABLE_IN_ALL + cairo_surface_t *gxps_page_get_image (GXPSPage *page, + const gchar *image_uri, + GError **error); ++GXPS_AVAILABLE_IN_ALL + void gxps_page_render_parser_push (GMarkupParseContext *context, + GXPSRenderContext *ctx); + +--- libgxps-0.2.5/libgxps/gxps-parse-utils.h ++++ libgxps-0.2.5/libgxps/gxps-parse-utils.h +@@ -24,9 +24,11 @@ + + G_BEGIN_DECLS + ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_parse_stream (GMarkupParseContext *context, + GInputStream *stream, + GError **error); ++GXPS_AVAILABLE_IN_ALL + void gxps_parse_error (GMarkupParseContext *context, + const gchar *source, + GMarkupError error_type, +@@ -34,21 +36,29 @@ void gxps_parse_error + const gchar *attribute_name, + const gchar *content, + GError **error); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_value_get_int (const gchar *value, + gint *int_value); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_value_get_double (const gchar *value, + gdouble *double_value); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_value_get_double_positive (const gchar *value, + gdouble *double_value); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_value_get_double_non_negative (const gchar *value, + gdouble *double_value); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_value_get_boolean (const gchar *value, + gboolean *boolean_value); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_point_parse (const gchar *point, + gdouble *x, + gdouble *y); ++GXPS_AVAILABLE_IN_ALL + void gxps_parse_skip_number (gchar **iter, + const gchar *end); ++GXPS_AVAILABLE_IN_ALL + gchar *gxps_resolve_relative_path (const gchar *source, + const gchar *target); + +--- libgxps-0.2.5/libgxps/gxps-path.h ++++ libgxps-0.2.5/libgxps/gxps-path.h +@@ -50,12 +50,16 @@ struct _GXPSPath { + gboolean is_closed : 1; + }; + ++GXPS_AVAILABLE_IN_ALL + GXPSPath *gxps_path_new (GXPSRenderContext *ctx); ++GXPS_AVAILABLE_IN_ALL + void gxps_path_free (GXPSPath *path); ++GXPS_AVAILABLE_IN_ALL + gboolean gxps_path_parse (const gchar *data, + cairo_t *cr, + GError **error); + ++GXPS_AVAILABLE_IN_ALL + void gxps_path_parser_push (GMarkupParseContext *context, + GXPSPath *path); + diff --git a/SOURCES/libgxps-0.3.0-archive-fill-error.patch b/SOURCES/libgxps-0.3.0-archive-fill-error.patch new file mode 100644 index 0000000..202b423 --- /dev/null +++ b/SOURCES/libgxps-0.3.0-archive-fill-error.patch @@ -0,0 +1,106 @@ +From b458226e162fe1ffe7acb4230c114a52ada5131b Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Sat, 5 May 2018 12:01:24 +0200 +Subject: gxps-archive: Ensure gxps_archive_read_entry() fills the GError in + case of failure + +And fix the callers to not overwrite the GError. + +diff --git a/libgxps/gxps-archive.c b/libgxps/gxps-archive.c +index e763773..346ba73 100644 +--- a/libgxps/gxps-archive.c ++++ b/libgxps/gxps-archive.c +@@ -406,9 +406,13 @@ gxps_archive_read_entry (GXPSArchive *archive, + gboolean retval; + + stream = gxps_archive_open (archive, path); +- if (!stream) +- /* TODO: Error */ ++ if (!stream) { ++ g_set_error (error, ++ G_IO_ERROR, ++ G_IO_ERROR_NOT_FOUND, ++ "The entry '%s' was not found in archive", path); + return FALSE; ++ } + + entry_size = archive_entry_size (GXPS_ARCHIVE_INPUT_STREAM (stream)->entry); + if (entry_size <= 0) { +@@ -423,7 +427,7 @@ gxps_archive_read_entry (GXPSArchive *archive, + *buffer = g_malloc (buffer_size); + do { + bytes = g_input_stream_read (stream, &buf, BUFFER_SIZE, NULL, error); +- if (*error != NULL) { ++ if (bytes < 0) { + g_free (*buffer); + g_object_unref (stream); + +@@ -441,7 +445,10 @@ gxps_archive_read_entry (GXPSArchive *archive, + g_object_unref (stream); + + if (*bytes_read == 0) { +- /* TODO: Error */ ++ g_set_error (error, ++ G_IO_ERROR, ++ G_IO_ERROR_INVALID_DATA, ++ "The entry '%s' is empty in archive", path); + g_free (*buffer); + return FALSE; + } +diff --git a/libgxps/gxps-fonts.c b/libgxps/gxps-fonts.c +index 882157d..8d02ffc 100644 +--- a/libgxps/gxps-fonts.c ++++ b/libgxps/gxps-fonts.c +@@ -220,19 +220,12 @@ gxps_fonts_new_font_face (GXPSArchive *zip, + cairo_font_face_t *font_face; + guchar *font_data; + gsize font_data_len; +- gboolean res; + +- res = gxps_archive_read_entry (zip, font_uri, +- &font_data, &font_data_len, +- error); +- if (!res) { +- g_set_error (error, +- GXPS_ERROR, +- GXPS_ERROR_SOURCE_NOT_FOUND, +- "Font source %s not found in archive", +- font_uri); +- return NULL; +- } ++ if (!gxps_archive_read_entry (zip, font_uri, ++ &font_data, &font_data_len, ++ error)) { ++ return NULL; ++ } + + ft_face.font_data = font_data; + ft_face.font_data_len = (gssize)font_data_len; +diff --git a/libgxps/gxps-images.c b/libgxps/gxps-images.c +index 4dcf9e2..50f899f 100644 +--- a/libgxps/gxps-images.c ++++ b/libgxps/gxps-images.c +@@ -742,17 +742,12 @@ gxps_images_create_from_tiff (GXPSArchive *zip, + guchar *data; + guchar *p; + +- if (!gxps_archive_read_entry (zip, image_uri, +- &buffer.buffer, +- &buffer.buffer_len, +- error)) { +- g_set_error (error, +- GXPS_ERROR, +- GXPS_ERROR_SOURCE_NOT_FOUND, +- "Image source %s not found in archive", +- image_uri); +- return NULL; +- } ++ if (!gxps_archive_read_entry (zip, image_uri, ++ &buffer.buffer, ++ &buffer.buffer_len, ++ error)) { ++ return NULL; ++ } + + buffer.pos = 0; + diff --git a/SOURCES/libgxps-0.3.0-archive-handle-error.patch b/SOURCES/libgxps-0.3.0-archive-handle-error.patch new file mode 100644 index 0000000..f563d4b --- /dev/null +++ b/SOURCES/libgxps-0.3.0-archive-handle-error.patch @@ -0,0 +1,24 @@ +From 133fe2a96e020d4ca65c6f64fb28a404050ebbfd Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Sat, 5 May 2018 12:02:36 +0200 +Subject: gxps-archive: Handle errors returned by archive_read_data + + +diff --git a/libgxps/gxps-archive.c b/libgxps/gxps-archive.c +index 346ba73..1bae729 100644 +--- a/libgxps/gxps-archive.c ++++ b/libgxps/gxps-archive.c +@@ -520,6 +520,13 @@ gxps_archive_input_stream_read (GInputStream *stream, + return -1; + + bytes_read = archive_read_data (istream->zip->archive, buffer, count); ++ if (bytes_read < 0) { ++ g_set_error_literal (error, ++ G_IO_ERROR, ++ g_io_error_from_errno (archive_errno (istream->zip->archive)), ++ archive_error_string (istream->zip->archive)); ++ return -1; ++ } + if (bytes_read == 0 && istream->is_interleaved && !gxps_archive_input_stream_is_last_piece (istream)) { + /* Read next piece */ + gxps_archive_input_stream_next_piece (istream); diff --git a/SOURCES/libgxps-0.3.0-clear-error.patch b/SOURCES/libgxps-0.3.0-clear-error.patch new file mode 100644 index 0000000..89123c6 --- /dev/null +++ b/SOURCES/libgxps-0.3.0-clear-error.patch @@ -0,0 +1,30 @@ +From 672c65ea8cbd2bcfd82a6b6498a4f1eb9daf5ec5 Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Fri, 8 Dec 2017 11:20:25 +0100 +Subject: [PATCH 2/2] gxps-images: clear the error before trying to load an + image again + +In gxps_images_get_image() we first try with the image file extension, +and if that fails then we try guessing the content type. If the image +load failed the first time, the GError might be filled already, so we +need to clear it before passing it to create functions again. +--- + libgxps/gxps-images.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libgxps/gxps-images.c b/libgxps/gxps-images.c +index 19cb1c0..4dcf9e2 100644 +--- a/libgxps/gxps-images.c ++++ b/libgxps/gxps-images.c +@@ -925,6 +925,8 @@ gxps_images_get_image (GXPSArchive *zip, + if (!image) { + gchar *mime_type; + ++ g_clear_error(error); ++ + mime_type = gxps_images_guess_content_type (zip, image_uri); + if (g_strcmp0 (mime_type, "image/png") == 0) { + image = gxps_images_create_from_png (zip, image_uri, error); +-- +2.17.1 + diff --git a/SOURCES/libgxps-0.3.0-integer-overflow.patch b/SOURCES/libgxps-0.3.0-integer-overflow.patch new file mode 100644 index 0000000..bbb6485 --- /dev/null +++ b/SOURCES/libgxps-0.3.0-integer-overflow.patch @@ -0,0 +1,25 @@ +From 123dd99c6a1ae2ef6fcb5547e51fa58e8c954b51 Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Fri, 8 Dec 2017 11:11:38 +0100 +Subject: [PATCH 1/2] gxps-images: fix integer overflow in png decoder + +--- + libgxps/gxps-images.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libgxps/gxps-images.c b/libgxps/gxps-images.c +index 98c7052..19cb1c0 100644 +--- a/libgxps/gxps-images.c ++++ b/libgxps/gxps-images.c +@@ -286,7 +286,7 @@ gxps_images_create_from_png (GXPSArchive *zip, + } + + stride = cairo_format_stride_for_width (format, png_width); +- if (stride < 0) { ++ if (stride < 0 || png_height >= INT_MAX / stride) { + fill_png_error (error, image_uri, NULL); + g_object_unref (stream); + png_destroy_read_struct (&png, &info, NULL); +-- +2.17.1 + diff --git a/SPECS/libgxps.spec b/SPECS/libgxps.spec new file mode 100644 index 0000000..fbb8f88 --- /dev/null +++ b/SPECS/libgxps.spec @@ -0,0 +1,179 @@ +Name: libgxps +Version: 0.3.0 +Release: 4%{?dist} +Summary: GObject based library for handling and rendering XPS documents +Group: System Environment/Libraries + +License: LGPLv2+ +URL: https://wiki.gnome.org/Projects/libgxps +Source0: https://ftp.gnome.org/pub/gnome/sources/%{name}/0.3/%{name}-%{version}.tar.xz + +Patch0: libgxps-0.2.4-GXPSImage.patch +Patch1: libgxps-0.2.5-private-methods.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1574844 +Patch2: libgxps-0.3.0-archive-fill-error.patch +Patch3: libgxps-0.3.0-archive-handle-error.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1591133 +Patch4: libgxps-0.3.0-integer-overflow.patch +Patch5: libgxps-0.3.0-clear-error.patch + +BuildRequires: meson +BuildRequires: gcc +BuildRequires: gtk3-devel +BuildRequires: glib2-devel +BuildRequires: gobject-introspection-devel +BuildRequires: gtk-doc +BuildRequires: cairo-devel +BuildRequires: libarchive-devel +BuildRequires: freetype-devel +BuildRequires: libjpeg-devel +BuildRequires: libtiff-devel +BuildRequires: lcms2-devel + +%description +libgxps is a GObject based library for handling and rendering XPS +documents. + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%package tools +Summary: Command-line utility programs for manipulating XPS files +Group: Applications/Text +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tools +The %{name}-tools contains command-line programs for manipulating XPS format +documents using the %{name} library. + + +%prep +%autosetup -p1 + + +%build +%meson -Denable-gtk-doc=true -Denable-man=true +%meson_build + + +%install +%meson_install + + +%post -p /sbin/ldconfig + + +%postun -p /sbin/ldconfig + + +%files +%doc AUTHORS MAINTAINERS NEWS README TODO +%license COPYING +%{_libdir}/*.so.* +%{_libdir}/girepository-1.0/*.typelib + + +%files devel +%{_includedir}/* +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_datadir}/gir-1.0/*.gir +%{_datadir}/gtk-doc/html/libgxps + + +%files tools +%{_bindir}/xpsto* +%{_mandir}/man1/xpsto*.1.gz + + +%changelog +* Thu Jun 21 2018 Marek Kasik - 0.3.0-4 +- Fix integer overflow in png decoder +- Resolves: #1591133 + +* Fri Jun 01 2018 Marek Kasik - 0.3.0-3 +- Fix crash in loading of png image +- Resolves: #1575188 + +* Fri Jun 01 2018 Marek Kasik - 0.3.0-2 +- Ensure gxps_archive_read_entry() fills the GError in case of failure +- Handle errors returned by archive_read_data() +- Resolves: #1574844 + +* Thu May 31 2018 Marek Kasik - 0.3.0-1 +- Update to 0.3.0 +- Resolves: #1569731 + +* Tue Feb 28 2017 Marek Kasik - 0.2.5-1 +- Update to newly released 0.2.5 +- Preserve ABI by exporting the same set of methods as before +- Resolves: #1384959 + +* Fri Feb 17 2017 Marek Kasik - 0.2.4-1 +- Update to 0.2.4 +- Backport several important patches from current master +- Revert addition of GXPSImage (it would change ABI) +- Resolves: #1384959 + +* Fri Jan 24 2014 Daniel Mach - 0.2.2-9 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 0.2.2-8 +- Mass rebuild 2013-12-27 + +* Tue Mar 26 2013 Daniel Mach - 0.2.2-7.1 +- Rebuild for libarchive + +* Thu Feb 14 2013 Fedora Release Engineering - 0.2.2-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Jan 18 2013 Adam Tkac - 0.2.2-6 +- rebuild due to "jpeg8-ABI" feature drop + +* Thu Jan 17 2013 Tomas Bzatek - 0.2.2-5 +- Rebuilt for new libarchive + +* Fri Dec 21 2012 Adam Tkac - 0.2.2-4 +- rebuild against new libjpeg + +* Thu Jul 19 2012 Fedora Release Engineering - 0.2.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun May 6 2012 Tom Hughes - 0.2.2-2 +- Rebuilt for new libtiff. + +* Mon Mar 19 2012 Tom Hughes - 0.2.2-1 +- Update to 0.2.2 upstream release. + +* Thu Jan 26 2012 Tomas Bzatek - 0.2.1-4 +- Rebuilt for new libarchive + +* Thu Jan 26 2012 Tom Hughes - 0.2.1-3 +- Correct summary and description for tools package. + +* Thu Jan 26 2012 Tom Hughes - 0.2.1-2 +- Rebuild for libarchive soname bump. + +* Sat Jan 21 2012 Tom Hughes - 0.2.1-1 +- Update to 0.2.1 upstream release. + +* Wed Jan 4 2012 Tom Hughes - 0.2.0-2 +- Rebuilt for gcc 4.7 mass rebuild. +- Run autoreconf to update libtool. + +* Thu Dec 1 2011 Tom Hughes - 0.2.0-1 +- Update to 0.2.0 upstream release. + +* Sat Nov 5 2011 Tom Hughes - 0.1.0-2 +- Fix base package dependency in devel package. + +* Fri Nov 4 2011 Tom Hughes - 0.1.0-1 +- Initial build.