commit libgdiplus0 for openSUSE:Factory
Hello community, here is the log from the commit of package libgdiplus0 for openSUSE:Factory checked in at Fri Nov 5 14:33:35 CET 2010. -------- --- libgdiplus0/libgdiplus0.changes 2010-04-28 00:57:48.000000000 +0200 +++ libgdiplus0/libgdiplus0.changes 2010-10-12 19:41:54.000000000 +0200 @@ -1,0 +2,6 @@ +Tue Oct 12 17:38:27 UTC 2010 - ajorgensen@novell.com + +- Update to 2.8 + * http://www.go-mono.com/archive/2.8 + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- libgdiplus-2.6.4.tar.bz2 New: ---- libgdiplus-2.8.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libgdiplus0.spec ++++++ --- /var/tmp/diff_new_pack.1zR774/_old 2010-11-05 14:33:10.000000000 +0100 +++ /var/tmp/diff_new_pack.1zR774/_new 2010-11-05 14:33:10.000000000 +0100 @@ -1,5 +1,5 @@ # -# spec file for package libgdiplus0 (Version 2.6.4) +# spec file for package libgdiplus0 (Version 2.8) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -22,7 +22,7 @@ %define system_cairo 0 Name: libgdiplus0 -Version: 2.6.4 +Version: 2.8 Release: 1 License: LGPLv2.1 ; MPL ; MIT License (or similar) Url: http://go-mono.org/ ++++++ libgdiplus-2.6.4.tar.bz2 -> libgdiplus-2.8.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/configure new/libgdiplus-2.8/configure --- old/libgdiplus-2.6.4/configure 2010-04-13 13:30:18.000000000 +0200 +++ new/libgdiplus-2.8/configure 2010-09-16 19:30:53.000000000 +0200 @@ -2560,7 +2560,7 @@ # Define the identity of the package. PACKAGE=libgdiplus - VERSION=2.6.4 + VERSION=2.8 cat >>confdefs.h <<_ACEOF diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/configure.in new/libgdiplus-2.8/configure.in --- old/libgdiplus-2.6.4/configure.in 2010-04-06 00:08:25.000000000 +0200 +++ new/libgdiplus-2.8/configure.in 2010-09-16 19:26:25.000000000 +0200 @@ -1,7 +1,7 @@ AC_INIT(README) AC_CANONICAL_SYSTEM AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libgdiplus,2.6.4) +AM_INIT_AUTOMAKE(libgdiplus,2.8) AM_MAINTAINER_MODE AM_PROG_LIBTOOL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/libgdiplus0.spec.in new/libgdiplus-2.8/libgdiplus0.spec.in --- old/libgdiplus-2.6.4/libgdiplus0.spec.in 2009-09-25 17:06:53.000000000 +0200 +++ new/libgdiplus-2.8/libgdiplus0.spec.in 2010-09-16 19:26:25.000000000 +0200 @@ -1,9 +1,11 @@ %define real_name libgdiplus +# There may be strange bugs when using the system cairo +%define system_cairo 0 Name: libgdiplus0 Version: @VERSION@ Release: 0 -License: LGPL v2.1 only; MOZILLA PUBLIC LICENSE (MPL/NPL); X11/MIT +License: LGPL v2.1 only ; MPL ; MIT License (or similar) Url: http://go-mono.org/ Source0: %{real_name}-%{version}.tar.bz2 Summary: Open Source Implementation of the GDI+ API @@ -13,52 +15,23 @@ Provides: libgdiplus-devel Obsoletes: libgdiplus Provides: libgdiplus -#### suse #### -%if 0%{?suse_version} -# Common requires for suse distros -BuildRequires: fontconfig-devel freetype2-devel glib2-devel libexif libjpeg-devel libpng-devel libtiff-devel -%if %suse_version >= 1030 -BuildRequires: giflib-devel libexif-devel xorg-x11-libSM-devel xorg-x11-libXrender-devel -%endif -%if %suse_version == 1020 -BuildRequires: giflib-devel xorg-x11-libSM-devel xorg-x11-libXrender-devel -%endif -%if %sles_version == 10 -BuildRequires: giflib-devel xorg-x11-devel -%endif -%if %suse_version == 1010 -BuildRequires: giflib-devel xorg-x11-devel -%endif -%if %sles_version == 9 -BuildRequires: XFree86-devel libungif pkgconfig -%endif -%endif -#### fedora #### -%if 0%{?fedora_version} -# All fedora distros have the same names, requirements -BuildRequires: fontconfig-devel glib2-devel libXrender-devel libXt-devel libexif-devel libjpeg-devel libpng-devel libtiff-devel libungif-devel -%endif -%if 0%{?rhel_version} -BuildRequires: fontconfig-devel glib2-devel libexif-devel libjpeg-devel libpng-devel libtiff-devel libungif-devel -%if %{rhel_version} >= 500 -BuildRequires: libXrender-devel libXt-devel -%endif +%if %system_cairo +BuildRequires: cairo-devel >= 1.6.4 %endif +BuildRequires: fontconfig-devel +BuildRequires: freetype2-devel +BuildRequires: giflib-devel +BuildRequires: glib2-devel +BuildRequires: libexif-devel +BuildRequires: libjpeg-devel +BuildRequires: libpng-devel +BuildRequires: libtiff-devel +BuildRequires: xorg-x11-libXrender-devel %description This is part of the Mono project. It is required when using Windows.Forms. - - -Authors: --------- - Alexandre Pigolkine - Duncan Mak - Jordi Mas - Miguel de Icaza - Ravindra Kumar - %files %defattr(-, root, root) %_libdir/libgdiplus.so* @@ -69,12 +42,6 @@ %setup -q -n %{real_name}-%{version} %build -# Set PKG_CONFIG_PATH for sles9 -%if 0%{?sles_version} -%if %sles_version == 9 -export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/gnome/%_lib/pkgconfig -%endif -%endif export CFLAGS="$RPM_OPT_FLAGS" %configure make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/ChangeLog new/libgdiplus-2.8/src/ChangeLog --- old/libgdiplus-2.6.4/src/ChangeLog 2010-04-13 02:56:07.000000000 +0200 +++ new/libgdiplus-2.8/src/ChangeLog 2010-09-16 19:26:25.000000000 +0200 @@ -1,8 +1,37 @@ +2010-07-20 Sebastien Pouliot <sebastien@ximian.com> + + * image.c: Use DPI from source image when creating a Graphics + instance from it. Fix bug #556181 + +2010-07-14 Sebastien Pouliot <sebastien@ximian.com> + + * lineargradientbrush.c: Do not accept empty (width/height) + rectangles to create a linear brush. Fix bug #537396 + +2010-07-07 Sebastien Pouliot <sebastien@ximian.com> + + * pngcodec.c: security fix in libpng 1.2 broke the define + +2010-06-16 Sebastien Pouliot <sebastien@ximian.com> + + * image.c: Fix #529887 for drawing a part of image with scaling. + Patch provided by Dan Parnham + +2010-05-17 Tom Hindle <tom_hindle@sil.org> + + * image.c: perform calculated transformation. Fix #606412 + +2010-05-04 Miguel de Icaza <miguel@novell.com> + + * Apply patch from Matthew Metnetsky which fixes Bug #590286 + Passing -1 (to indicate null terminated string) for the string + lengths for GdipDrawString and GdipMeasureString causes the + program to seg-fault. + 2010-04-12 Sebastien Pouliot <sebastien@ximian.com> * pngcodec.c: SuSE provided patch for newer libpng (1.4.x). Made to be backward compatible with 1.2.x - [Backport r155275] 2010-03-26 Miguel de Icaza <miguel@novell.com> @@ -12,7 +41,6 @@ 2010-01-13 Sebastien Pouliot <sebastien@ximian.com> * tiffcodec.c: Don't call TIFFClose with a NULL value. Fix #569940 - [Backport r149475] 2009-08-19 Jeffrey Stedfast <fejj@novell.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/adjustablearrowcap.c new/libgdiplus-2.8/src/adjustablearrowcap.c --- old/libgdiplus-2.6.4/src/adjustablearrowcap.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/adjustablearrowcap.c 2010-09-16 19:26:25.000000000 +0200 @@ -23,10 +23,12 @@ */ #include "adjustablearrowcap-private.h" +#include "graphics-private.h" static GpStatus gdip_adjust_arrowcap_setup (GpGraphics *graphics, GpCustomLineCap *cap); static GpStatus gdip_adjust_arrowcap_clone_cap (GpCustomLineCap *cap, GpCustomLineCap **clonedCap); static GpStatus gdip_adjust_arrowcap_destroy (GpCustomLineCap *cap); +static GpStatus gdip_adjust_arrowcap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *Cap, float x, float y, float otherend_x, float otherend_y); /* * we have a single copy of vtable for @@ -36,7 +38,8 @@ static CapClass vtable = { CustomLineCapTypeAdjustableArrow, gdip_adjust_arrowcap_setup, gdip_adjust_arrowcap_clone_cap, - gdip_adjust_arrowcap_destroy }; + gdip_adjust_arrowcap_destroy, + gdip_adjust_arrowcap_draw }; static void gdip_adjust_arrowcap_init (GpAdjustableArrowCap *arrow) @@ -44,6 +47,8 @@ gdip_custom_linecap_init (&arrow->base, &vtable); arrow->fill_state = TRUE; arrow->middle_inset = 0.0; + arrow->width = 0.0; + arrow->height = 0.0; } static GpAdjustableArrowCap* @@ -96,6 +101,59 @@ return NotImplemented; } +GpStatus +gdip_adjust_arrowcap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *customCap, float x, float y, float otherend_x, float otherend_y) +{ + double angle; + GpAdjustableArrowCap *arrowcap; + float w; + float h; + float penwidth; + + if (!graphics || !customCap) + return InvalidParameter; + + penwidth = pen->width; + if (penwidth < 2.0) { + /* Seems to be a minimum */ + penwidth = 2.0; + } + + arrowcap = (GpAdjustableArrowCap *)customCap; + w = arrowcap->width / 2; + h = arrowcap->height; + + /* Vertical lines need some assistance to point the arrowhead correctly */ + if ((x == otherend_x) && + (y < otherend_y)) { + h = -h; + } + + angle = gdip_custom_linecap_angle (x, y, otherend_x, otherend_y); + + cairo_save (graphics->ct); + + /* FIXME: handle base_inset (including set/get!) */ + cairo_translate (graphics->ct, x, y); + cairo_rotate (graphics->ct, angle); + + gdip_cairo_move_to (graphics, 0, 0, TRUE, TRUE); + gdip_cairo_line_to (graphics, -w * penwidth, -h * penwidth, TRUE, TRUE); + gdip_cairo_line_to (graphics, w * penwidth, -h * penwidth, TRUE, TRUE); + gdip_cairo_line_to (graphics, 0, 0, TRUE, TRUE); + + if (arrowcap->fill_state) { + /* FIXME: handle middle_inset */ + cairo_fill_preserve (graphics->ct); + } + + cairo_stroke (graphics->ct); + + cairo_restore (graphics->ct); + + return Ok; +} + /* AdjustableArrowCap functions */ // coverity[+alloc : arg-*3] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/bmpcodec.c new/libgdiplus-2.8/src/bmpcodec.c --- old/libgdiplus-2.6.4/src/bmpcodec.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/bmpcodec.c 2010-09-16 19:26:25.000000000 +0200 @@ -781,7 +781,6 @@ int colours; BOOL os2format = FALSE; BOOL upsidedown = TRUE; - int size; int size_read; BYTE *data_read = NULL; int line; @@ -793,6 +792,7 @@ ARGB green_mask = 0; ARGB blue_mask = 0; int red_shift = 0; + unsigned long long int size; status = gdip_read_BITMAPINFOHEADER (pointer, &bmi, source, &os2format, &upsidedown); if (status != Ok) @@ -860,23 +860,30 @@ result->active_bitmap->width = bmi.biWidth; result->active_bitmap->height = bmi.biHeight; + /* biWidth and biHeight are LONG (32 bits signed integer) */ + size = bmi.biWidth; + switch (result->active_bitmap->pixel_format) { case PixelFormat1bppIndexed: - result->active_bitmap->stride = (result->active_bitmap->width + 7) / 8; + result->active_bitmap->stride = (size + 7) / 8; break; case PixelFormat4bppIndexed: - result->active_bitmap->stride = (result->active_bitmap->width + 1) / 2; + result->active_bitmap->stride = (size + 1) / 2; break; case PixelFormat8bppIndexed: - result->active_bitmap->stride = result->active_bitmap->width; - break; - case PixelFormat24bppRGB: - result->active_bitmap->stride = result->active_bitmap->width * 4; + result->active_bitmap->stride = size; break; default: /* For other types, we assume 32 bit and translate into 32 bit from source format */ result->active_bitmap->pixel_format = PixelFormat32bppRGB; - result->active_bitmap->stride = result->active_bitmap->width * 4; + /* fall-thru */ + case PixelFormat24bppRGB: + /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc + * this effectively limits 'width' to 536870911 pixels */ + size *= 4; + if (size > G_MAXINT32) + goto error; + result->active_bitmap->stride = size; break; } @@ -922,7 +929,14 @@ data_read = NULL; } - pixels = GdipAlloc (result->active_bitmap->stride * result->active_bitmap->height); + size = result->active_bitmap->stride; + /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ + size *= result->active_bitmap->height; + if (size > G_MAXINT32) { + status = OutOfMemory; + goto error; + } + pixels = GdipAlloc (size); if (pixels == NULL) { status = OutOfMemory; goto error; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/customlinecap-private.h new/libgdiplus-2.8/src/customlinecap-private.h --- old/libgdiplus-2.6.4/src/customlinecap-private.h 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/customlinecap-private.h 2010-09-16 19:26:25.000000000 +0200 @@ -42,6 +42,7 @@ GpStatus (*setup) (GpGraphics *graphics, GpCustomLineCap *cap); GpStatus (*clone_cap) (GpCustomLineCap *cap, GpCustomLineCap **clonedCap); GpStatus (*destroy) (GpCustomLineCap *cap); + GpStatus (*draw) (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *cap, float x, float y, float otherend_x, float otherend_y); } CapClass; typedef struct _CustomLineCap { @@ -58,6 +59,8 @@ void gdip_custom_linecap_init (GpCustomLineCap *cap, CapClass *vt) GDIP_INTERNAL; GpStatus gdip_linecap_setup (GpGraphics *graphics, GpCustomLineCap *customCap) GDIP_INTERNAL; +GpStatus gdip_linecap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *customCap, float x, float y, float otherend_x, float otherend_y) GDIP_INTERNAL; +double gdip_custom_linecap_angle (float x, float y, float otherend_x, float otherend_y); #include "customlinecap.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/customlinecap.c new/libgdiplus-2.8/src/customlinecap.c --- old/libgdiplus-2.6.4/src/customlinecap.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/customlinecap.c 2010-09-16 19:26:25.000000000 +0200 @@ -25,10 +25,14 @@ */ #include "customlinecap-private.h" +#include "graphics-path-private.h" +#include "graphics-private.h" +#include "graphics-cairo-private.h" static GpStatus gdip_custom_linecap_setup (GpGraphics *graphics, GpCustomLineCap *cap); static GpStatus gdip_custom_linecap_clone_cap (GpCustomLineCap *cap, GpCustomLineCap **clonedCap); static GpStatus gdip_custom_linecap_destroy (GpCustomLineCap *cap); +static GpStatus gdip_custom_linecap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *cap, float x, float y, float otherend_x, float otherend_y); /* * we have a single copy of vtable for @@ -38,7 +42,8 @@ static CapClass vtable = { CustomLineCapTypeDefault, gdip_custom_linecap_setup, gdip_custom_linecap_clone_cap, - gdip_custom_linecap_destroy }; + gdip_custom_linecap_destroy, + gdip_custom_linecap_draw }; void gdip_custom_linecap_init (GpCustomLineCap *cap, CapClass *vt) @@ -51,6 +56,8 @@ cap->base_inset = 0.0; /* LAMESPEC: Default value is documented as 1.0, but actually it is 0.0 */ cap->width_scale = 0.0; + cap->fill_path = NULL; + cap->stroke_path = NULL; } static GpCustomLineCap* @@ -68,6 +75,7 @@ gdip_custom_linecap_clone_cap (GpCustomLineCap *cap, GpCustomLineCap **clonedCap) { GpCustomLineCap *newcap; + GpPath *fillpath = NULL, *strokepath = NULL; if (!cap || !clonedCap) return InvalidParameter; @@ -84,6 +92,27 @@ newcap->base_inset = cap->base_inset; newcap->width_scale = cap->width_scale; + if (cap->fill_path) { + if (GdipClonePath (cap->fill_path, &fillpath) != Ok) { + if (fillpath != NULL) + GdipFree (fillpath); + GdipFree (newcap); + return OutOfMemory; + } + } + newcap->fill_path = fillpath; + + if (cap->stroke_path) { + if (GdipClonePath (cap->stroke_path, &strokepath) != Ok) { + if (strokepath != NULL) + GdipFree (strokepath); + GdipFree (fillpath); + GdipFree (newcap); + return OutOfMemory; + } + } + newcap->stroke_path = strokepath; + *clonedCap = newcap; return Ok; @@ -95,6 +124,14 @@ if (!cap) return InvalidParameter; + if (cap->fill_path) { + GdipDeletePath (cap->fill_path); + cap->fill_path = NULL; + } + if (cap->stroke_path) { + GdipDeletePath (cap->stroke_path); + cap->stroke_path = NULL; + } GdipFree (cap); return Ok; @@ -110,6 +147,105 @@ return NotImplemented; } +double +gdip_custom_linecap_angle (float x, float y, float otherend_x, float otherend_y) +{ + float slope; + double angle; + + if (y < otherend_y) { + slope = (otherend_y - y) / (otherend_x - x); + if (x < otherend_x) { + angle = PI/2; + } else { + angle = PI/-2; + } + } else { + slope = (otherend_x - x) / (y - otherend_y); + angle = 0; + } + angle += atan (slope); + + return angle; +} + +GpStatus +gdip_custom_linecap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *customCap, float x, float y, float otherend_x, float otherend_y) +{ + double angle; + int points; + int i, idx = 0; + float penwidth; + + if (!graphics || !pen || !customCap) + return InvalidParameter; + + penwidth = pen->width; + angle = gdip_custom_linecap_angle (x, y, otherend_x, otherend_y); + + cairo_save (graphics->ct); + + /* FIXME: handle base_inset (including set/get!) */ + cairo_translate (graphics->ct, x, y); + cairo_rotate (graphics->ct, angle); + + if (customCap->stroke_path) { + GpPath *path = customCap->stroke_path; + points = path->count; + + for (i = 0; i < points; i++) { + /* Adapted from gdip_plot_path() */ + GpPointF point = g_array_index (path->points, GpPointF, i); + BYTE type = g_array_index (path->types, BYTE, i); + GpPointF pts [3]; + + /* mask the bits so that we get only the type value not the other flags */ + switch (type & PathPointTypePathTypeMask) { + case PathPointTypeStart: + gdip_cairo_move_to (graphics, point.X * penwidth, point.Y * penwidth, TRUE, TRUE); + break; + + case PathPointTypeLine: + gdip_cairo_line_to (graphics, point.X * penwidth, point.Y * penwidth, TRUE, TRUE); + break; + + case PathPointTypeBezier: + /* make sure we only add at most 3 points to pts */ + if (idx < 3) { + pts [idx] = point; + idx ++; + } + + /* once we've added 3 pts, we can draw the curve */ + if (idx == 3) { + gdip_cairo_curve_to (graphics, pts[0].X * penwidth, pts[0].Y * penwidth, pts[1].X * penwidth, pts[1].Y * penwidth, pts[2].X * penwidth, pts[2].Y * penwidth, TRUE, TRUE); + idx = 0; + } + break; + + default: + g_warning ("Unknown PathPointType %d", type); + return NotImplemented; + } + + /* close the subpath */ + if (type & PathPointTypeCloseSubpath) { + cairo_close_path (graphics->ct); + } + } + + gdip_pen_setup (graphics, pen); + cairo_stroke (graphics->ct); + cairo_set_matrix (graphics->ct, graphics->copy_of_ctm); + } + + /* FIXME: handle fill_path */ + + cairo_restore (graphics->ct); + + return gdip_get_status (cairo_status (graphics->ct)); +} + /* this setup function gets called from pen */ GpStatus @@ -121,6 +257,17 @@ return customCap->vtable->setup (graphics, customCap); } +/* this draw function gets called from pen */ + +GpStatus +gdip_linecap_draw (GpGraphics *graphics, GpPen *pen, GpCustomLineCap *customCap, float x, float y, float otherend_x, float otherend_y) +{ + if (!graphics || !pen || !customCap) + return InvalidParameter; + + return customCap->vtable->draw (graphics, pen, customCap, x, y, otherend_x, otherend_y); +} + /* CustomLineCap functions */ // coverity[+alloc : arg-*4] @@ -128,6 +275,7 @@ GdipCreateCustomLineCap (GpPath *fillPath, GpPath *strokePath, GpLineCap baseCap, float baseInset, GpCustomLineCap **customCap) { GpCustomLineCap *cap; + GpPath *fillpath_clone = NULL, *strokepath_clone = NULL; if ((!fillPath && !strokePath) || !customCap) return InvalidParameter; @@ -136,8 +284,27 @@ if (!cap) return OutOfMemory; - cap->fill_path = fillPath; - cap->stroke_path = strokePath; + if (fillPath) { + if (GdipClonePath (fillPath, &fillpath_clone) != Ok) { + if (fillpath_clone != NULL) + GdipFree (fillpath_clone); + GdipFree (cap); + return OutOfMemory; + } + } + cap->fill_path = fillpath_clone; + + if (strokePath) { + if (GdipClonePath (strokePath, &strokepath_clone) != Ok) { + if (strokepath_clone != NULL) + GdipFree (strokepath_clone); + GdipFree (fillpath_clone); + GdipFree (cap); + return OutOfMemory; + } + } + cap->stroke_path = strokepath_clone; + cap->base_cap = baseCap; cap->base_inset = baseInset; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/graphics-cairo.c new/libgdiplus-2.8/src/graphics-cairo.c --- old/libgdiplus-2.6.4/src/graphics-cairo.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/graphics-cairo.c 2010-09-16 19:26:25.000000000 +0200 @@ -485,41 +485,74 @@ GpStatus cairo_DrawLine (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2) { + GpStatus ret; + /* We use graphics->copy_of_ctm matrix for path creation. We should have it set already. */ gdip_cairo_move_to (graphics, x1, y1, TRUE, TRUE); gdip_cairo_line_to (graphics, x2, y2, TRUE, TRUE); - return stroke_graphics_with_pen (graphics, pen); + ret = stroke_graphics_with_pen (graphics, pen); + + gdip_pen_draw_custom_start_cap (graphics, pen, x1, y1, x2, y2); + gdip_pen_draw_custom_end_cap (graphics, pen, x2, y2, x1, y1); + + return ret; } GpStatus cairo_DrawLines (GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points, int count) { int i; + float last_x, last_y, prev_x, prev_y; + GpStatus ret; /* We use graphics->copy_of_ctm matrix for path creation. We should have it set already. */ gdip_cairo_move_to (graphics, points [0].X, points [0].Y, TRUE, TRUE); for (i = 1; i < count; i++) { gdip_cairo_line_to (graphics, points [i].X, points [i].Y, TRUE, TRUE); + prev_x = points [i - 1].X; + prev_y = points [i - 1].Y; + last_x = points [i].X; + last_y = points [i].Y; + } + + ret = stroke_graphics_with_pen (graphics, pen); + + if (count > 1) { + gdip_pen_draw_custom_start_cap (graphics, pen, points [0].X, points [0].Y, points [1].X, points [1].Y); + gdip_pen_draw_custom_end_cap (graphics, pen, last_x, last_y, prev_x, prev_y); } - return stroke_graphics_with_pen (graphics, pen); + return ret; } GpStatus cairo_DrawLinesI (GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points, int count) { int i; + float last_x, last_y, prev_x, prev_y; + GpStatus ret; /* We use graphics->copy_of_ctm matrix for path creation. We should have it set already. */ gdip_cairo_move_to (graphics, points [0].X, points [0].Y, TRUE, TRUE); for (i = 1; i < count; i++) { gdip_cairo_line_to (graphics, points [i].X, points [i].Y, TRUE, TRUE); + prev_x = points [i - 1].X; + prev_y = points [i - 1].Y; + last_x = points [i].X; + last_y = points [i].Y; + } + + ret = stroke_graphics_with_pen (graphics, pen); + + if (count > 1) { + gdip_pen_draw_custom_start_cap (graphics, pen, points [0].X, points [0].Y, points [1].X, points [1].Y); + gdip_pen_draw_custom_end_cap (graphics, pen, last_x, last_y, prev_x, prev_y); } - return stroke_graphics_with_pen (graphics, pen); + return ret; } GpStatus @@ -574,12 +607,41 @@ GpStatus cairo_DrawPath (GpGraphics *graphics, GpPen *pen, GpPath *path) { + GpStatus ret; + int count; + GpPointF *points; + /* We use graphics->copy_of_ctm matrix for path creation. We should have it set already. */ GpStatus status = gdip_plot_path (graphics, path, TRUE); if (status != Ok) return status; - return stroke_graphics_with_pen (graphics, pen); + ret = stroke_graphics_with_pen (graphics, pen); + + /* Draw any custom pen end caps */ + + status = GdipGetPointCount (path, &count); + + /* To know the angle of the end cap, we need the penultimate point. + Unfortunately there's no way of getting it without getting all + the points :-( + */ + if (status == Ok && count > 1) { + points = gdip_calloc (count, sizeof(GpPointF)); + if (points == NULL) { + return OutOfMemory; + } + status = GdipGetPathPoints (path, points, count); + + if (status == Ok) { + gdip_pen_draw_custom_start_cap (graphics, pen, points [0].X, points [0].Y, points [1].X, points [1].Y); + gdip_pen_draw_custom_end_cap (graphics, pen, points [count - 1].X, points [count - 1].Y, points [count - 2].X, points [count - 2].Y); + } + + GdipFree (points); + } + + return ret; } /* FIXME - this doesn't match MS behaviour when we use really complex paths with internal intersections */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/graphics-path.c new/libgdiplus-2.8/src/graphics-path.c --- old/libgdiplus-2.6.4/src/graphics-path.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/graphics-path.c 2010-09-16 19:26:25.000000000 +0200 @@ -1352,7 +1352,7 @@ GdipAddPathCurve2I (GpPath *path, const GpPoint *points, int count, float tension) { GpPointF *pt; - Status s; + GpStatus s; if (!points) return InvalidParameter; @@ -1373,7 +1373,7 @@ int count, int offset, int numberOfSegments, float tension) { GpPointF *pt; - Status s; + GpStatus s; if (!points) return InvalidParameter; @@ -1398,7 +1398,7 @@ GdipAddPathClosedCurve2I (GpPath *path, const GpPoint *points, int count, float tension) { GpPointF *pt; - Status s; + GpStatus s; if (!path || !points) return InvalidParameter; @@ -1788,7 +1788,7 @@ { PointF *points; int count; - Status s; + GpStatus s; if (!path) return InvalidParameter; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/graphics.c new/libgdiplus-2.8/src/graphics.c --- old/libgdiplus-2.6.4/src/graphics.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/graphics.c 2010-09-16 19:26:25.000000000 +0200 @@ -619,7 +619,7 @@ GpStatus GdipMultiplyWorldTransform (GpGraphics *graphics, GpMatrix *matrix, GpMatrixOrder order) { - Status s; + GpStatus s; BOOL invertible; GpMatrix inverted; @@ -2082,7 +2082,7 @@ GdipGetClipBoundsI (GpGraphics *graphics, GpRect *rect) { GpRectF rectF; - Status status; + GpStatus status; if (!graphics || !rect) return InvalidParameter; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/image.c new/libgdiplus-2.8/src/image.c --- old/libgdiplus-2.6.4/src/image.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/image.c 2010-09-16 19:26:25.000000000 +0200 @@ -313,7 +313,8 @@ image->active_bitmap->width, image->active_bitmap->height, image->active_bitmap->stride); gfx = gdip_graphics_new (surface); - gfx->dpi_x = gfx->dpi_y = gdip_get_display_dpi (); + gfx->dpi_x = image->active_bitmap->dpi_horz <= 0 ? gdip_get_display_dpi () : image->active_bitmap->dpi_horz; + gfx->dpi_y = image->active_bitmap->dpi_vert <= 0 ? gdip_get_display_dpi () : image->active_bitmap->dpi_vert; cairo_surface_destroy (surface); gfx->image = image; @@ -710,8 +711,9 @@ } } + cairo_matrix_translate (&mat, srcx, srcy); cairo_matrix_scale (&mat, srcwidth / dstwidth, srcheight / dstheight); - cairo_matrix_translate (&mat, srcx - (dstx + posx), srcy - (dsty + posy)); + cairo_matrix_translate (&mat, - (dstx + posx), - (dsty + posy)); pattern = cairo_pattern_create_for_surface(cur_image->surface); cairo_pattern_set_matrix (pattern, &mat); @@ -760,10 +762,12 @@ filter = cairo_pattern_create_for_surface (image->surface); cairo_pattern_set_filter (filter, gdip_get_cairo_filter (graphics->interpolation)); + cairo_matrix_translate (&mat, srcx, srcy); + if (!gdip_near_zero(srcwidth - dstwidth) || !gdip_near_zero(srcheight - dstheight)) cairo_matrix_scale (&mat, srcwidth / dstwidth, srcheight / dstheight); - cairo_matrix_translate (&mat, srcx - dstx, srcy - dsty); + cairo_matrix_translate (&mat, -dstx, -dsty); pattern = cairo_pattern_create_for_surface(image->surface); cairo_pattern_set_matrix (pattern, &mat); @@ -818,6 +822,7 @@ GpRectF rect; GpStatus status; GpMatrix *matrix = NULL; + cairo_matrix_t orig_matrix; if (!graphics || !image || !points || (count < 3)) return InvalidParameter; @@ -837,8 +842,11 @@ status = GdipCreateMatrix3 (&rect, points, &matrix); if (status == Ok) { + cairo_get_matrix (graphics->ct, &orig_matrix); + cairo_set_matrix (graphics->ct, matrix); status = GdipDrawImageRectRect (graphics, image, rect.X, rect.Y, rect.Width, rect.Height, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback, callbackData); + cairo_set_matrix (graphics->ct, &orig_matrix); } if (matrix) GdipDeleteMatrix (matrix); @@ -1547,7 +1555,7 @@ int target_y_offset = target_starts_at_bottom ? (target_height - 1) * target_stride : 0; int target_y_offset_delta = target_starts_at_bottom ? -target_stride : +target_stride; - Status status = gdip_init_pixel_stream (&stream, image->active_bitmap, 0, 0, image->active_bitmap->width, image->active_bitmap->height); + GpStatus status = gdip_init_pixel_stream (&stream, image->active_bitmap, 0, 0, image->active_bitmap->width, image->active_bitmap->height); if (status != Ok) { GdipFree (rotated); @@ -1602,7 +1610,7 @@ scan_valid[i] = ((scan_index >= 0) && (scan_index < source_height)); if (scan_valid[i]) { - Status status = gdip_init_pixel_stream (&scan[i], image->active_bitmap, 0, scan_index, source_width, 1); + GpStatus status = gdip_init_pixel_stream (&scan[i], image->active_bitmap, 0, scan_index, source_width, 1); if (status != Ok) { GdipFree (rotated); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/jpegcodec.c new/libgdiplus-2.8/src/jpegcodec.c --- old/libgdiplus-2.6.4/src/jpegcodec.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/jpegcodec.c 2010-09-16 19:26:25.000000000 +0200 @@ -282,6 +282,7 @@ BYTE *lines[4] = {NULL, NULL, NULL, NULL}; GpStatus status; int stride; + unsigned long long int size; destbuf = NULL; result = NULL; @@ -323,20 +324,21 @@ if (cinfo.num_components == 1) { result->cairo_format = CAIRO_FORMAT_A8; - result->active_bitmap->stride = cinfo.image_width; result->active_bitmap->pixel_format = PixelFormat8bppIndexed; + size = 1; } else if (cinfo.num_components == 3) { /* libjpeg gives us RGB for many formats and * we convert to RGB format when needed. JPEG * does not support alpha (transparency). */ result->cairo_format = CAIRO_FORMAT_ARGB32; - result->active_bitmap->stride = 4 * cinfo.image_width; result->active_bitmap->pixel_format = PixelFormat24bppRGB; + size = 4; } else if (cinfo.num_components == 4) { result->cairo_format = CAIRO_FORMAT_ARGB32; - result->active_bitmap->stride = 4 * cinfo.image_width; result->active_bitmap->pixel_format = PixelFormat32bppRGB; - } + size = 4; + } else + goto error; switch (cinfo.jpeg_color_space) { case JCS_GRAYSCALE: @@ -360,7 +362,12 @@ break; } - stride = result->active_bitmap->stride; + size *= cinfo.image_width; + /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc + * this effectively limits 'width' to 536870911 pixels */ + if (size > G_MAXINT32) + goto error; + stride = result->active_bitmap->stride = size; /* Request cairo-compat output */ /* libjpeg can do only following conversions, @@ -397,7 +404,13 @@ jpeg_start_decompress (&cinfo); - destbuf = GdipAlloc (stride * cinfo.output_height); + /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ + size *= cinfo.output_height; + if (size > G_MAXINT32) { + status = OutOfMemory; + goto error; + } + destbuf = GdipAlloc (size); if (destbuf == NULL) { status = OutOfMemory; goto error; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/lineargradientbrush.c new/libgdiplus-2.8/src/lineargradientbrush.c --- old/libgdiplus-2.6.4/src/lineargradientbrush.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/lineargradientbrush.c 2010-09-16 19:26:25.000000000 +0200 @@ -600,9 +600,8 @@ GdipCreateLineBrushFromRectWithAngle (GDIPCONST GpRectF *rect, ARGB color1, ARGB color2, float angle, BOOL isAngleScalable, GpWrapMode wrapMode, GpLineGradient **lineGradient) { GpLineGradient *linear; - GpRectF *rectf; - if (!rect || !lineGradient) + if (!rect || !lineGradient || rect->Width == 0.0 || rect->Height == 0.0) return InvalidParameter; linear = gdip_linear_gradient_new (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/pen-private.h new/libgdiplus-2.8/src/pen-private.h --- old/libgdiplus-2.6.4/src/pen-private.h 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/pen-private.h 2010-09-16 19:26:25.000000000 +0200 @@ -59,9 +59,13 @@ GpUnit unit; /* Always set to UnitWorld. */ cairo_matrix_t matrix; BOOL changed; /* flag to mark if pen is changed and needs setup */ + GpCustomLineCap *custom_start_cap; + GpCustomLineCap *custom_end_cap; }; GpStatus gdip_pen_setup (GpGraphics *graphics, GpPen *pen) GDIP_INTERNAL; +GpStatus gdip_pen_draw_custom_start_cap (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2); +GpStatus gdip_pen_draw_custom_end_cap (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2); #include "pen.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/pen.c new/libgdiplus-2.8/src/pen.c --- old/libgdiplus-2.6.4/src/pen.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/pen.c 2010-09-16 19:26:25.000000000 +0200 @@ -30,6 +30,7 @@ #include "solidbrush-private.h" #include "matrix-private.h" #include "graphics-private.h" +#include "customlinecap-private.h" static void gdip_pen_init (GpPen *pen) @@ -53,6 +54,8 @@ pen->compound_array = NULL; pen->unit = UnitWorld; pen->changed = TRUE; + pen->custom_start_cap = NULL; + pen->custom_end_cap = NULL; cairo_matrix_init_identity (&pen->matrix); } @@ -204,6 +207,34 @@ return gdip_get_status (cairo_status (graphics->ct)); } +GpStatus +gdip_pen_draw_custom_start_cap (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2) +{ + if (!graphics || !pen) + return InvalidParameter; + + if (pen->custom_start_cap) { + /* Draw the end cap */ + gdip_linecap_draw (graphics, pen, pen->custom_start_cap, x1, y1, x2, y2); + } + + return gdip_get_status (cairo_status (graphics->ct)); +} + +GpStatus +gdip_pen_draw_custom_end_cap (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2) +{ + if (!graphics || !pen) + return InvalidParameter; + + if (pen->custom_end_cap) { + /* Draw the end cap */ + gdip_linecap_draw (graphics, pen, pen->custom_end_cap, x1, y1, x2, y2); + } + + return gdip_get_status (cairo_status (graphics->ct)); +} + // coverity[+alloc : arg-*3] GpStatus GdipCreatePen1 (ARGB argb, float width, GpUnit unit, GpPen **pen) @@ -319,6 +350,8 @@ GpPen *result; float *dashes; /* copy off pen->dash_array */ float *compound_array = NULL; /* copy off pen->compound_array */ + GpCustomLineCap *custom_start_cap = NULL; + GpCustomLineCap *custom_end_cap = NULL; if (!pen || !clonepen) return InvalidParameter; @@ -345,6 +378,34 @@ clone_dash_array (compound_array, pen->compound_array, pen->compound_count); } + if (pen->custom_start_cap != NULL) { + GpStatus status = GdipCloneCustomLineCap (pen->custom_start_cap, &custom_start_cap); + if (status != Ok) { + if (custom_start_cap) + GdipDeleteCustomLineCap (custom_start_cap); + if (compound_array != NULL) + GdipFree (compound_array); + if (pen->dash_count > 0) + GdipFree (dashes); + return OutOfMemory; + } + } + + if (pen->custom_end_cap != NULL) { + GpStatus status = GdipCloneCustomLineCap (pen->custom_end_cap, &custom_end_cap); + if (status != Ok) { + if (custom_end_cap) + GdipDeleteCustomLineCap (custom_end_cap); + if (custom_start_cap) + GdipDeleteCustomLineCap (custom_start_cap); + if (compound_array != NULL) + GdipFree (compound_array); + if (pen->dash_count > 0) + GdipFree (dashes); + return OutOfMemory; + } + } + result = gdip_pen_new (); if (result == NULL) { if (pen->dash_count > 0) @@ -382,6 +443,8 @@ result->unit = pen->unit; gdip_cairo_matrix_copy (&result->matrix, &pen->matrix); result->changed = pen->changed; + result->custom_start_cap = custom_start_cap; + result->custom_end_cap = custom_end_cap; *clonepen = result; @@ -411,6 +474,16 @@ pen->compound_count = 0; } + if (pen->custom_start_cap != NULL) { + GdipDeleteCustomLineCap (pen->custom_start_cap); + pen->custom_start_cap = NULL; + } + + if (pen->custom_end_cap != NULL) { + GdipDeleteCustomLineCap (pen->custom_end_cap); + pen->custom_end_cap = NULL; + } + GdipFree (pen); return Ok; } @@ -1004,52 +1077,38 @@ return Ok; } -/* MonoTODO - not implemented */ GpStatus GdipSetPenCustomStartCap (GpPen *pen, GpCustomLineCap *customCap) { - static BOOL called = FALSE; - if (!called) { - g_warning ("GdipSetPenCustomStartCap isn't implemented"); - called = TRUE; - } - return Ok; + if (!pen) + return InvalidParameter; + + return GdipCloneCustomLineCap (customCap, &pen->custom_start_cap); } -/* MonoTODO - not implemented */ GpStatus GdipGetPenCustomStartCap (GpPen *pen, GpCustomLineCap **customCap) { - static BOOL called = FALSE; - if (!called) { - g_warning ("GdipGetPenCustomStartCap isn't implemented"); - called = TRUE; - } - *customCap = NULL; - return Ok; + if (!pen || !customCap) + return InvalidParameter; + + return GdipCloneCustomLineCap (pen->custom_start_cap, customCap); } -/* MonoTODO - not implemented */ GpStatus GdipSetPenCustomEndCap (GpPen *pen, GpCustomLineCap *customCap) { - static BOOL called = FALSE; - if (!called) { - g_warning ("GdipSetPenCustomEndCap isn't implemented"); - called = TRUE; - } - return Ok; + if (!pen) + return InvalidParameter; + + return GdipCloneCustomLineCap (customCap, &pen->custom_end_cap); } -/* MonoTODO - not implemented */ GpStatus GdipGetPenCustomEndCap (GpPen *pen, GpCustomLineCap **customCap) { - static BOOL called = FALSE; - if (!called) { - g_warning ("GdipGetPenCustomEndCap isn't implemented"); - called = TRUE; - } - *customCap = NULL; - return Ok; + if (!pen || !customCap) + return InvalidParameter; + + return GdipCloneCustomLineCap (pen->custom_end_cap, customCap); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/pngcodec.c new/libgdiplus-2.8/src/pngcodec.c --- old/libgdiplus-2.6.4/src/pngcodec.c 2010-04-13 13:30:06.000000000 +0200 +++ new/libgdiplus-2.8/src/pngcodec.c 2010-09-16 19:26:25.000000000 +0200 @@ -352,7 +352,7 @@ info_ptr->palette[i].blue, info_ptr->palette[i].green, info_ptr->palette[i].red, -#if PNG_LIBPNG_VER > 10243 +#if PNG_LIBPNG_VER > 10399 info_ptr->trans_alpha [i]); /* alpha */ #else info_ptr->trans[i]); /* alpha */ @@ -422,7 +422,7 @@ } if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) { -#if PNG_LIBPNG_VER > 10243 +#if PNG_LIBPNG_VER > 10399 png_set_expand_gray_1_2_4_to_8 (png_ptr); #else png_set_gray_1_2_4_to_8(png_ptr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/text.c new/libgdiplus-2.8/src/text.c --- old/libgdiplus-2.6.4/src/text.c 2009-09-25 17:06:51.000000000 +0200 +++ new/libgdiplus-2.8/src/text.c 2010-09-16 19:26:25.000000000 +0200 @@ -43,8 +43,18 @@ GdipDrawString (GpGraphics *graphics, GDIPCONST WCHAR *string, int length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GpBrush *brush) { - if (length == 0) + GDIPCONST WCHAR *ptr = NULL; + + if (length == 0) { return Ok; + } else if (length == -1) { + ptr = string; + length = 0; + while (*ptr != 0) { + length++; + ptr++; + } + } if (!graphics || !string || !font || !layoutRect) return InvalidParameter; @@ -63,6 +73,8 @@ GdipMeasureString (GpGraphics *graphics, GDIPCONST WCHAR *string, int length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, RectF *boundingBox, int *codepointsFitted, int *linesFilled) { + GDIPCONST WCHAR *ptr = NULL; + if (length == 0) { if (boundingBox) { if (layoutRect) { @@ -82,6 +94,13 @@ *codepointsFitted = 0; } return Ok; + } else if (length == -1) { + ptr = string; + length = 0; + while (*ptr != 0) { + length++; + ptr++; + } } if (!graphics || !string || !font || !layoutRect) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgdiplus-2.6.4/src/tiffcodec.c new/libgdiplus-2.8/src/tiffcodec.c --- old/libgdiplus-2.6.4/src/tiffcodec.c 2010-01-13 16:45:05.000000000 +0100 +++ new/libgdiplus-2.8/src/tiffcodec.c 2010-09-16 19:26:25.000000000 +0200 @@ -1104,6 +1104,8 @@ frame = gdip_frame_add(result, &gdip_image_frameDimension_page_guid); for (page = 0; page < num_of_pages; page++) { + unsigned long long int size; + bitmap_data = gdip_frame_add_bitmapdata(frame); if (bitmap_data == NULL) { goto error; @@ -1139,14 +1141,25 @@ bitmap_data->image_flags |= ImageFlagsHasRealDPI; } - bitmap_data->stride = tiff_image.width * 4; + /* width and height are uint32, but TIFF uses 32 bits offsets (so it's real size limit is 4GB), + * however libtiff uses signed int (int32 not uint32) as offsets so we limit ourselves to 2GB */ + size = tiff_image.width; + /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc + * this effectively limits 'width' to 536870911 pixels */ + size *= sizeof (guint32); + if (size > G_MAXINT32) + goto error; + bitmap_data->stride = size; bitmap_data->width = tiff_image.width; bitmap_data->height = tiff_image.height; bitmap_data->reserved = GBD_OWN_SCAN0; bitmap_data->image_flags |= ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly; - num_of_pixels = tiff_image.width * tiff_image.height; - pixbuf = GdipAlloc(num_of_pixels * sizeof(guint32)); + /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ + size *= tiff_image.height; + if (size > G_MAXINT32) + goto error; + pixbuf = GdipAlloc (size); if (pixbuf == NULL) { goto error; } @@ -1168,9 +1181,9 @@ memcpy(pixbuf + (bitmap_data->stride * (tiff_image.height - i - 1)), pixbuf_row, bitmap_data->stride); } - /* Now flip from ARGB to ABGR */ + /* Now flip from ARGB to ABGR processing one pixel (4 bytes) at the time */ pixbuf_ptr = (guint32 *)pixbuf; - for (i = 0; i < num_of_pixels; i++) { + for (i = 0; i < (size >> 2); i++) { *pixbuf_ptr = (*pixbuf_ptr & 0xff000000) | ((*pixbuf_ptr & 0x00ff0000) >> 16) | (*pixbuf_ptr & 0x0000ff00) | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de