diff options
Diffstat (limited to 'lib/pixman')
48 files changed, 2299 insertions, 266 deletions
diff --git a/lib/pixman/Makefile.am b/lib/pixman/Makefile.am index 0bf8206c0..a117af643 100644 --- a/lib/pixman/Makefile.am +++ b/lib/pixman/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = pixman +SUBDIRS = pixman test pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=pixman-1.pc @@ -31,33 +31,33 @@ EXTRA_DIST = \ $(NULL) tar_gz = $(PACKAGE)-$(VERSION).tar.gz -tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 +tar_xz = $(PACKAGE)-$(VERSION).tar.xz -sha1_tgz = $(tar_gz).sha1 -md5_tgz = $(tar_gz).md5 +sha512_tgz = $(tar_gz).sha512 +sha256_tgz = $(tar_gz).sha256 -sha1_tbz2 = $(tar_bz2).sha1 -md5_tbz2 = $(tar_bz2).md5 +sha512_txz = $(tar_xz).sha512 +sha256_txz = $(tar_xz).sha256 -gpg_file = $(sha1_tgz).asc +gpg_file = $(sha512_tgz).asc -$(sha1_tgz): $(tar_gz) - sha1sum $^ > $@ +$(sha512_tgz): $(tar_gz) + sha512sum $^ > $@ -$(md5_tgz): $(tar_gz) - md5sum $^ > $@ +$(sha256_tgz): $(tar_gz) + sha256sum $^ > $@ -$(sha1_tbz2): $(tar_bz2) - sha1sum $^ > $@ +$(sha512_txz): $(tar_xz) + sha512sum $^ > $@ -$(md5_tbz2): $(tar_bz2) - md5sum $^ > $@ +$(sha256_txz): $(tar_xz) + sha256sum $^ > $@ -$(gpg_file): $(sha1_tgz) +$(gpg_file): $(sha512_tgz) @echo "Please enter your GPG password to sign the checksum." gpg --armor --sign $^ -HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2) +HASHFILES = $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(sha256_txz) release-verify-newer: @echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..." @@ -72,7 +72,7 @@ release-verify-newer: @echo "Good." release-remove-old: - $(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file) + $(RM) $(tar_gz) $(tar_xz) $(HASHFILES) $(gpg_file) ensure-prev: @if [[ "$(PREV)" == "" ]]; then \ @@ -91,9 +91,9 @@ release-check: ensure-prev release-verify-newer release-remove-old distcheck release-tag: git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION) -release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(gpg_file) - scp $(tar_gz) $(sha1_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) - scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) +release-upload: release-check $(tar_gz) $(tar_xz) $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(gpg_file) + scp $(tar_gz) $(sha512_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) + scp $(tar_gz) $(tar_xz) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)" RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi) @@ -111,18 +111,18 @@ release-publish-message: $(HASHFILES) ensure-prev @echo " $(RELEASE_CAIRO_URL)/$(tar_gz)" @echo " $(RELEASE_XORG_URL)/$(tar_gz)" @echo "" - @echo "tar.bz2:" - @echo " $(RELEASE_XORG_URL)/$(tar_bz2)" + @echo "tar.xz:" + @echo " $(RELEASE_XORG_URL)/$(tar_xz)" @echo "" @echo "Hashes:" - @echo -n " MD5: " - @cat $(md5_tgz) - @echo -n " MD5: " - @cat $(md5_tbz2) - @echo -n " SHA1: " - @cat $(sha1_tgz) - @echo -n " SHA1: " - @cat $(sha1_tbz2) + @echo -n " SHA256: " + @cat $(sha256_tgz) + @echo -n " SHA256: " + @cat $(sha256_txz) + @echo -n " SHA512: " + @cat $(sha512_tgz) + @echo -n " SHA512: " + @cat $(sha512_txz) @echo "" @echo "GPG signature:" @echo " $(RELEASE_CAIRO_URL)/$(gpg_file)" diff --git a/lib/pixman/Makefile.bsd-wrapper b/lib/pixman/Makefile.bsd-wrapper index 77ade5fee..40305de5c 100644 --- a/lib/pixman/Makefile.bsd-wrapper +++ b/lib/pixman/Makefile.bsd-wrapper @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.25 2019/05/11 07:46:06 matthieu Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.26 2021/07/25 15:16:31 matthieu Exp $ .include <bsd.own.mk> -SHARED_LIBS= pixman-1 38.4 +SHARED_LIBS= pixman-1 40.0 .if ${MACHINE_ARCH} == arm CONFIGURE_ARGS += --disable-arm-simd --disable-arm-neon diff --git a/lib/pixman/Makefile.in b/lib/pixman/Makefile.in index 3e619b1c2..3060cb465 100644 --- a/lib/pixman/Makefile.in +++ b/lib/pixman/Makefile.in @@ -166,9 +166,9 @@ am__relativize = \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz GZIP_ENV = --best -DIST_TARGETS = dist-bzip2 dist-gzip +DIST_TARGETS = dist-xz dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -313,6 +313,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -321,7 +322,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = pixman +SUBDIRS = pixman test pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pixman-1.pc GPGKEY = 3892336E @@ -344,13 +345,13 @@ EXTRA_DIST = \ $(NULL) tar_gz = $(PACKAGE)-$(VERSION).tar.gz -tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 -sha1_tgz = $(tar_gz).sha1 -md5_tgz = $(tar_gz).md5 -sha1_tbz2 = $(tar_bz2).sha1 -md5_tbz2 = $(tar_bz2).md5 -gpg_file = $(sha1_tgz).asc -HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2) +tar_xz = $(PACKAGE)-$(VERSION).tar.xz +sha512_tgz = $(tar_gz).sha512 +sha256_tgz = $(tar_gz).sha256 +sha512_txz = $(tar_xz).sha512 +sha256_txz = $(tar_xz).sha256 +gpg_file = $(sha512_tgz).asc +HASHFILES = $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(sha256_txz) RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -643,6 +644,7 @@ distdir: $(DISTFILES) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) + dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) @@ -650,7 +652,6 @@ dist-bzip2: distdir dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) - dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) @@ -894,19 +895,19 @@ snapshot: test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \ $(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist -$(sha1_tgz): $(tar_gz) - sha1sum $^ > $@ +$(sha512_tgz): $(tar_gz) + sha512sum $^ > $@ -$(md5_tgz): $(tar_gz) - md5sum $^ > $@ +$(sha256_tgz): $(tar_gz) + sha256sum $^ > $@ -$(sha1_tbz2): $(tar_bz2) - sha1sum $^ > $@ +$(sha512_txz): $(tar_xz) + sha512sum $^ > $@ -$(md5_tbz2): $(tar_bz2) - md5sum $^ > $@ +$(sha256_txz): $(tar_xz) + sha256sum $^ > $@ -$(gpg_file): $(sha1_tgz) +$(gpg_file): $(sha512_tgz) @echo "Please enter your GPG password to sign the checksum." gpg --armor --sign $^ @@ -923,7 +924,7 @@ release-verify-newer: @echo "Good." release-remove-old: - $(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file) + $(RM) $(tar_gz) $(tar_xz) $(HASHFILES) $(gpg_file) ensure-prev: @if [[ "$(PREV)" == "" ]]; then \ @@ -942,9 +943,9 @@ release-check: ensure-prev release-verify-newer release-remove-old distcheck release-tag: git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION) -release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(gpg_file) - scp $(tar_gz) $(sha1_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) - scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) +release-upload: release-check $(tar_gz) $(tar_xz) $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(gpg_file) + scp $(tar_gz) $(sha512_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) + scp $(tar_gz) $(tar_xz) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)" release-publish-message: $(HASHFILES) ensure-prev @@ -960,18 +961,18 @@ release-publish-message: $(HASHFILES) ensure-prev @echo " $(RELEASE_CAIRO_URL)/$(tar_gz)" @echo " $(RELEASE_XORG_URL)/$(tar_gz)" @echo "" - @echo "tar.bz2:" - @echo " $(RELEASE_XORG_URL)/$(tar_bz2)" + @echo "tar.xz:" + @echo " $(RELEASE_XORG_URL)/$(tar_xz)" @echo "" @echo "Hashes:" - @echo -n " MD5: " - @cat $(md5_tgz) - @echo -n " MD5: " - @cat $(md5_tbz2) - @echo -n " SHA1: " - @cat $(sha1_tgz) - @echo -n " SHA1: " - @cat $(sha1_tbz2) + @echo -n " SHA256: " + @cat $(sha256_tgz) + @echo -n " SHA256: " + @cat $(sha256_txz) + @echo -n " SHA512: " + @cat $(sha512_tgz) + @echo -n " SHA512: " + @cat $(sha512_txz) @echo "" @echo "GPG signature:" @echo " $(RELEASE_CAIRO_URL)/$(gpg_file)" diff --git a/lib/pixman/aclocal.m4 b/lib/pixman/aclocal.m4 index 09f4aa5dc..22ebcb61c 100644 --- a/lib/pixman/aclocal.m4 +++ b/lib/pixman/aclocal.m4 @@ -8606,9 +8606,9 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl @@ -8649,7 +8649,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -8750,7 +8750,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -8760,11 +8760,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -8781,7 +8781,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full diff --git a/lib/pixman/configure b/lib/pixman/configure index 2b0cc8308..5fd3185c8 100644 --- a/lib/pixman/configure +++ b/lib/pixman/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pixman 0.38.4. +# Generated by GNU Autoconf 2.69 for pixman 0.40.0. # # Report bugs to <pixman@lists.freedesktop.org>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pixman' PACKAGE_TARNAME='pixman' -PACKAGE_VERSION='0.38.4' -PACKAGE_STRING='pixman 0.38.4' +PACKAGE_VERSION='0.40.0' +PACKAGE_STRING='pixman 0.40.0' PACKAGE_BUGREPORT='pixman@lists.freedesktop.org' PACKAGE_URL='' @@ -788,6 +788,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -894,6 +895,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1146,6 +1148,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1283,7 +1294,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1396,7 +1407,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures pixman 0.38.4 to adapt to many kinds of systems. +\`configure' configures pixman 0.40.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1436,6 +1447,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1466,7 +1478,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pixman 0.38.4:";; + short | recursive ) echo "Configuration of pixman 0.40.0:";; esac cat <<\_ACEOF @@ -1606,7 +1618,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pixman configure 0.38.4 +pixman configure 0.40.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2204,7 +2216,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by pixman $as_me 0.38.4, which was +It was created by pixman $as_me 0.40.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3028,7 +3040,7 @@ fi # Define the identity of the package. PACKAGE='pixman' - VERSION='0.38.4' + VERSION='0.40.0' cat >>confdefs.h <<_ACEOF @@ -12236,13 +12248,13 @@ fi -LT_VERSION_INFO="38:4:38" +LT_VERSION_INFO="40:0:40" PIXMAN_VERSION_MAJOR=0 -PIXMAN_VERSION_MINOR=38 +PIXMAN_VERSION_MINOR=40 -PIXMAN_VERSION_MICRO=4 +PIXMAN_VERSION_MICRO=0 @@ -12751,7 +12763,7 @@ $as_echo "$_yesno" >&6; } if test "x$LS_CFLAGS" = "x" ; then - LS_CFLAGS="-march=loongson2f" + LS_CFLAGS="-mloongson-mmi" fi have_loongson_mmi=no @@ -13713,8 +13725,8 @@ fi pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 -$as_echo_n "checking for GTK... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.16 pixman-1" >&5 +$as_echo_n "checking for gtk+-2.0 >= 2.16 pixman-1... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" @@ -13754,7 +13766,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -13781,7 +13793,7 @@ Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -13852,8 +13864,8 @@ fi if test $enable_gtk = auto ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 -$as_echo_n "checking for GTK... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.16 pixman-1" >&5 +$as_echo_n "checking for gtk+-2.0 >= 2.16 pixman-1... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" @@ -13893,7 +13905,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -13911,7 +13923,7 @@ fi enable_gtk=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_gtk=no else @@ -14601,8 +14613,8 @@ fi case x$have_libpng in xyes) pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG" >&5 -$as_echo_n "checking for PNG... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpng" >&5 +$as_echo_n "checking for libpng... " >&6; } if test -n "$PNG_CFLAGS"; then pkg_cv_PNG_CFLAGS="$PNG_CFLAGS" @@ -14642,7 +14654,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -14669,7 +14681,7 @@ Alternatively, you may set the environment variables PNG_CFLAGS and PNG_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -14693,8 +14705,8 @@ fi ;; xno) ;; *) pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG" >&5 -$as_echo_n "checking for PNG... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpng" >&5 +$as_echo_n "checking for libpng... " >&6; } if test -n "$PNG_CFLAGS"; then pkg_cv_PNG_CFLAGS="$PNG_CFLAGS" @@ -14734,7 +14746,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -14752,7 +14764,7 @@ fi have_libpng=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_libpng=no else @@ -15357,7 +15369,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by pixman $as_me 0.38.4, which was +This file was extended by pixman $as_me 0.40.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15423,7 +15435,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -pixman config.status 0.38.4 +pixman config.status 0.40.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/lib/pixman/configure.ac b/lib/pixman/configure.ac index 150023c9b..eea731cc2 100644 --- a/lib/pixman/configure.ac +++ b/lib/pixman/configure.ac @@ -53,13 +53,13 @@ AC_PREREQ([2.57]) # m4_define([pixman_major], 0) -m4_define([pixman_minor], 38) -m4_define([pixman_micro], 4) +m4_define([pixman_minor], 40) +m4_define([pixman_micro], 0) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) AC_INIT(pixman, pixman_version, [pixman@lists.freedesktop.org], pixman) -AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_INIT_AUTOMAKE([foreign dist-xz]) AM_MAINTAINER_MODE @@ -279,7 +279,7 @@ dnl =========================================================================== dnl Check for Loongson Multimedia Instructions if test "x$LS_CFLAGS" = "x" ; then - LS_CFLAGS="-march=loongson2f" + LS_CFLAGS="-mloongson-mmi" fi have_loongson_mmi=no diff --git a/lib/pixman/demos/Makefile.am b/lib/pixman/demos/Makefile.am index 44a555304..c58e35967 100644 --- a/lib/pixman/demos/Makefile.am +++ b/lib/pixman/demos/Makefile.am @@ -2,6 +2,7 @@ EXTRA_DIST = \ parrot.c \ parrot.jpg \ scale.ui \ + dither.ui \ meson.build \ $(NULL) @@ -33,7 +34,8 @@ DEMOS = \ checkerboard \ srgb-trap-test \ srgb-test \ - scale + scale \ + dither gradient_test_SOURCES = gradient-test.c $(GTK_UTILS) alpha_test_SOURCES = alpha-test.c $(GTK_UTILS) @@ -51,6 +53,7 @@ checkerboard_SOURCES = checkerboard.c $(GTK_UTILS) srgb_test_SOURCES = srgb-test.c $(GTK_UTILS) srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS) scale_SOURCES = scale.c $(GTK_UTILS) +dither_SOURCES = dither.c $(GTK_UTILS) noinst_PROGRAMS = $(DEMOS) diff --git a/lib/pixman/demos/Makefile.in b/lib/pixman/demos/Makefile.in index 836ac2e33..74fc160ac 100644 --- a/lib/pixman/demos/Makefile.in +++ b/lib/pixman/demos/Makefile.in @@ -70,7 +70,7 @@ CONFIG_CLEAN_VPATH_FILES = @HAVE_GTK_TRUE@ trap-test$(EXEEXT) tri-test$(EXEEXT) \ @HAVE_GTK_TRUE@ quad2quad$(EXEEXT) checkerboard$(EXEEXT) \ @HAVE_GTK_TRUE@ srgb-trap-test$(EXEEXT) srgb-test$(EXEEXT) \ -@HAVE_GTK_TRUE@ scale$(EXEEXT) +@HAVE_GTK_TRUE@ scale$(EXEEXT) dither$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__alpha_test_SOURCES_DIST = alpha-test.c gtk-utils.c gtk-utils.h \ ../test/utils.c ../test/utils.h ../test/utils-prng.c \ @@ -148,6 +148,15 @@ convolution_test_LDADD = $(LDADD) @HAVE_GTK_TRUE@convolution_test_DEPENDENCIES = \ @HAVE_GTK_TRUE@ $(top_builddir)/pixman/libpixman-1.la \ @HAVE_GTK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__dither_SOURCES_DIST = dither.c gtk-utils.c gtk-utils.h \ + ../test/utils.c ../test/utils.h ../test/utils-prng.c \ + ../test/utils-prng.h +@HAVE_GTK_TRUE@am_dither_OBJECTS = dither.$(OBJEXT) $(am__objects_1) +dither_OBJECTS = $(am_dither_OBJECTS) +dither_LDADD = $(LDADD) +@HAVE_GTK_TRUE@dither_DEPENDENCIES = \ +@HAVE_GTK_TRUE@ $(top_builddir)/pixman/libpixman-1.la \ +@HAVE_GTK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__gradient_test_SOURCES_DIST = gradient-test.c gtk-utils.c \ gtk-utils.h ../test/utils.c ../test/utils.h \ ../test/utils-prng.c ../test/utils-prng.h @@ -280,9 +289,10 @@ am__v_CCLD_1 = SOURCES = $(alpha_test_SOURCES) $(checkerboard_SOURCES) \ $(clip_in_SOURCES) $(clip_test_SOURCES) \ $(composite_test_SOURCES) $(conical_test_SOURCES) \ - $(convolution_test_SOURCES) $(gradient_test_SOURCES) \ - $(linear_gradient_SOURCES) quad2quad.c $(radial_test_SOURCES) \ - $(scale_SOURCES) $(screen_test_SOURCES) $(srgb_test_SOURCES) \ + $(convolution_test_SOURCES) $(dither_SOURCES) \ + $(gradient_test_SOURCES) $(linear_gradient_SOURCES) \ + quad2quad.c $(radial_test_SOURCES) $(scale_SOURCES) \ + $(screen_test_SOURCES) $(srgb_test_SOURCES) \ $(srgb_trap_test_SOURCES) $(trap_test_SOURCES) \ $(tri_test_SOURCES) DIST_SOURCES = $(am__alpha_test_SOURCES_DIST) \ @@ -291,7 +301,7 @@ DIST_SOURCES = $(am__alpha_test_SOURCES_DIST) \ $(am__composite_test_SOURCES_DIST) \ $(am__conical_test_SOURCES_DIST) \ $(am__convolution_test_SOURCES_DIST) \ - $(am__gradient_test_SOURCES_DIST) \ + $(am__dither_SOURCES_DIST) $(am__gradient_test_SOURCES_DIST) \ $(am__linear_gradient_SOURCES_DIST) quad2quad.c \ $(am__radial_test_SOURCES_DIST) $(am__scale_SOURCES_DIST) \ $(am__screen_test_SOURCES_DIST) $(am__srgb_test_SOURCES_DIST) \ @@ -445,6 +455,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -457,6 +468,7 @@ EXTRA_DIST = \ parrot.c \ parrot.jpg \ scale.ui \ + dither.ui \ meson.build \ $(NULL) @@ -484,7 +496,8 @@ EXTRA_DIST = \ @HAVE_GTK_TRUE@ checkerboard \ @HAVE_GTK_TRUE@ srgb-trap-test \ @HAVE_GTK_TRUE@ srgb-test \ -@HAVE_GTK_TRUE@ scale +@HAVE_GTK_TRUE@ scale \ +@HAVE_GTK_TRUE@ dither @HAVE_GTK_TRUE@gradient_test_SOURCES = gradient-test.c $(GTK_UTILS) @HAVE_GTK_TRUE@alpha_test_SOURCES = alpha-test.c $(GTK_UTILS) @@ -502,6 +515,7 @@ EXTRA_DIST = \ @HAVE_GTK_TRUE@srgb_test_SOURCES = srgb-test.c $(GTK_UTILS) @HAVE_GTK_TRUE@srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS) @HAVE_GTK_TRUE@scale_SOURCES = scale.c $(GTK_UTILS) +@HAVE_GTK_TRUE@dither_SOURCES = dither.c $(GTK_UTILS) all: all-am .SUFFIXES: @@ -566,6 +580,9 @@ conical-test$(EXEEXT): $(conical_test_OBJECTS) $(conical_test_DEPENDENCIES) $(EX convolution-test$(EXEEXT): $(convolution_test_OBJECTS) $(convolution_test_DEPENDENCIES) $(EXTRA_convolution_test_DEPENDENCIES) @rm -f convolution-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(convolution_test_OBJECTS) $(convolution_test_LDADD) $(LIBS) +dither$(EXEEXT): $(dither_OBJECTS) $(dither_DEPENDENCIES) $(EXTRA_dither_DEPENDENCIES) + @rm -f dither$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dither_OBJECTS) $(dither_LDADD) $(LIBS) gradient-test$(EXEEXT): $(gradient_test_OBJECTS) $(gradient_test_DEPENDENCIES) $(EXTRA_gradient_test_DEPENDENCIES) @rm -f gradient-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gradient_test_OBJECTS) $(gradient_test_LDADD) $(LIBS) @@ -610,6 +627,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/composite-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conical-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolution-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dither.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gradient-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-gradient.Po@am__quote@ diff --git a/lib/pixman/demos/dither.c b/lib/pixman/demos/dither.c new file mode 100644 index 000000000..d72c250ed --- /dev/null +++ b/lib/pixman/demos/dither.c @@ -0,0 +1,279 @@ +/* + * Copyright 2012, Red Hat, Inc. + * Copyright 2012, Soren Sandmann + * Copyright 2018, Basile Clement + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <math.h> +#include <gtk/gtk.h> +#include <stdlib.h> +#include "../test/utils.h" +#include "gtk-utils.h" + +#define WIDTH 1024 +#define HEIGHT 640 + +typedef struct +{ + GtkBuilder * builder; + pixman_image_t * original; + pixman_format_code_t format; + pixman_dither_t dither; + int width; + int height; +} app_t; + +static GtkWidget * +get_widget (app_t *app, const char *name) +{ + GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (app->builder, name)); + + if (!widget) + g_error ("Widget %s not found\n", name); + + return widget; +} + +typedef struct +{ + char name [20]; + int value; +} named_int_t; + +static const named_int_t formats[] = +{ + { "a8r8g8b8", PIXMAN_a8r8g8b8 }, + { "rgb", PIXMAN_rgb_float }, + { "sRGB", PIXMAN_a8r8g8b8_sRGB }, + { "r5g6b5", PIXMAN_r5g6b5 }, + { "a4r4g4b4", PIXMAN_a4r4g4b4 }, + { "a2r2g2b2", PIXMAN_a2r2g2b2 }, + { "r3g3b2", PIXMAN_r3g3b2 }, + { "r1g2b1", PIXMAN_r1g2b1 }, + { "a1r1g1b1", PIXMAN_a1r1g1b1 }, +}; + +static const named_int_t dithers[] = +{ + { "None", PIXMAN_REPEAT_NONE }, + { "Bayer 8x8", PIXMAN_DITHER_ORDERED_BAYER_8 }, + { "Blue noise 64x64", PIXMAN_DITHER_ORDERED_BLUE_NOISE_64 }, +}; + +static int +get_value (app_t *app, const named_int_t table[], const char *box_name) +{ + GtkComboBox *box = GTK_COMBO_BOX (get_widget (app, box_name)); + + return table[gtk_combo_box_get_active (box)].value; +} + +static void +rescale (GtkWidget *may_be_null, app_t *app) +{ + app->dither = get_value (app, dithers, "dithering_combo_box"); + app->format = get_value (app, formats, "target_format_combo_box"); + + gtk_widget_set_size_request ( + get_widget (app, "drawing_area"), app->width + 0.5, app->height + 0.5); + + gtk_widget_queue_draw ( + get_widget (app, "drawing_area")); +} + +static gboolean +on_expose (GtkWidget *da, GdkEvent *event, gpointer data) +{ + app_t *app = data; + GdkRectangle *area = &event->expose.area; + cairo_surface_t *surface; + pixman_image_t *tmp, *final; + cairo_t *cr; + uint32_t *pixels; + + tmp = pixman_image_create_bits ( + app->format, area->width, area->height, NULL, 0); + pixman_image_set_dither (tmp, app->dither); + + pixman_image_composite ( + PIXMAN_OP_SRC, + app->original, NULL, tmp, + area->x, area->y, 0, 0, 0, 0, + app->width - area->x, + app->height - area->y); + + pixels = calloc (1, area->width * area->height * 4); + final = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, area->width, area->height, pixels, area->width * 4); + + pixman_image_composite ( + PIXMAN_OP_SRC, + tmp, NULL, final, + area->x, area->y, 0, 0, 0, 0, + app->width - area->x, + app->height - area->y); + + surface = cairo_image_surface_create_for_data ( + (uint8_t *)pixels, CAIRO_FORMAT_ARGB32, + area->width, area->height, area->width * 4); + + cr = gdk_cairo_create (da->window); + + cairo_set_source_surface (cr, surface, area->x, area->y); + + cairo_paint (cr); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + free (pixels); + pixman_image_unref (final); + pixman_image_unref (tmp); + + return TRUE; +} + +static void +set_up_combo_box (app_t *app, const char *box_name, + int n_entries, const named_int_t table[]) +{ + GtkWidget *widget = get_widget (app, box_name); + GtkListStore *model; + GtkCellRenderer *cell; + int i; + + model = gtk_list_store_new (1, G_TYPE_STRING); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, + "text", 0, + NULL); + + gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (model)); + + for (i = 0; i < n_entries; ++i) + { + const named_int_t *info = &(table[i]); + GtkTreeIter iter; + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, 0, info->name, -1); + } + + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); + + g_signal_connect (widget, "changed", G_CALLBACK (rescale), app); +} + +static app_t * +app_new (pixman_image_t *original) +{ + GtkWidget *widget; + app_t *app = g_malloc (sizeof *app); + GError *err = NULL; + + app->builder = gtk_builder_new (); + app->original = original; + + if (original->type == BITS) + { + app->width = pixman_image_get_width (original); + app->height = pixman_image_get_height (original); + } + else + { + app->width = WIDTH; + app->height = HEIGHT; + } + + if (!gtk_builder_add_from_file (app->builder, "dither.ui", &err)) + g_error ("Could not read file dither.ui: %s", err->message); + + widget = get_widget (app, "drawing_area"); + g_signal_connect (widget, "expose_event", G_CALLBACK (on_expose), app); + + set_up_combo_box (app, "target_format_combo_box", + G_N_ELEMENTS (formats), formats); + set_up_combo_box (app, "dithering_combo_box", + G_N_ELEMENTS (dithers), dithers); + + app->dither = get_value (app, dithers, "dithering_combo_box"); + app->format = get_value (app, formats, "target_format_combo_box"); + + rescale (NULL, app); + + return app; +} + +int +main (int argc, char **argv) +{ + GtkWidget *window; + pixman_image_t *image; + app_t *app; + + gtk_init (&argc, &argv); + + if (argc < 2) + { + pixman_gradient_stop_t stops[] = { + /* These colors make it very obvious that dithering + * is useful even for 8-bit gradients + */ + { 0x00000, { 0x1b1b, 0x5d5d, 0x7c7c, 0xffff } }, + { 0x10000, { 0x3838, 0x3232, 0x1010, 0xffff } }, + }; + pixman_point_fixed_t p1, p2; + + p1.x = p1.y = 0x0000; + p2.x = WIDTH << 16; + p2.y = HEIGHT << 16; + + if (!(image = pixman_image_create_linear_gradient ( + &p1, &p2, stops, ARRAY_LENGTH (stops)))) + { + printf ("Could not create gradient\n"); + return -1; + } + } + else if (!(image = pixman_image_from_file (argv[1], PIXMAN_a8r8g8b8))) + { + printf ("Could not load image \"%s\"\n", argv[1]); + return -1; + } + + app = app_new (image); + + window = get_widget (app, "main"); + + g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL); + + gtk_window_set_default_size (GTK_WINDOW (window), 1024, 768); + + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} diff --git a/lib/pixman/demos/dither.ui b/lib/pixman/demos/dither.ui new file mode 100644 index 000000000..7c3d068dc --- /dev/null +++ b/lib/pixman/demos/dither.ui @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="2.12"/> + <object class="GtkWindow" id="main"> + <property name="can_focus">False</property> + <child> + <placeholder/> + </child> + <child> + <object class="GtkHBox" id="u"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkViewport" id="viewport1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkDrawingArea" id="drawing_area"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="box1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkVBox" id="box6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkTable" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">8</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"><b>Target format:</b></property> + <property name="use_markup">True</property> + <property name="xalign">1</property> + </object> + </child> + <child> + <object class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"><b>Dithering:</b></property> + <property name="use_markup">True</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="target_format_combo_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="left_attach">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="dithering_combo_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="padding">6</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <object class="GtkAdjustment" id="rotate_adjustment"> + <property name="lower">-180</property> + <property name="upper">190</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + <property name="page_size">10</property> + </object> + <object class="GtkAdjustment" id="scale_x_adjustment"> + <property name="lower">-32</property> + <property name="upper">42</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + <property name="page_size">10</property> + </object> + <object class="GtkAdjustment" id="scale_y_adjustment"> + <property name="lower">-32</property> + <property name="upper">42</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + <property name="page_size">10</property> + </object> + <object class="GtkAdjustment" id="subsample_adjustment"> + <property name="upper">12</property> + <property name="value">4</property> + <property name="step_increment">1</property> + <property name="page_increment">1</property> + </object> +</interface> diff --git a/lib/pixman/demos/meson.build b/lib/pixman/demos/meson.build index 3461f795d..3f9d306ff 100644 --- a/lib/pixman/demos/meson.build +++ b/lib/pixman/demos/meson.build @@ -18,6 +18,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +extra_demo_cflags = [] +if cc.get_argument_syntax() == 'msvc' + extra_demo_cflags = ['-D_USE_MATH_DEFINES'] +endif + demos = [ 'gradient-test', 'alpha-test', @@ -34,6 +39,7 @@ demos = [ 'srgb-test', 'srgb-trap-test', 'scale', + 'dither', ] if dep_gtk.found() @@ -50,6 +56,7 @@ if dep_gtk.found() executable( d, [d + '.c', config_h, version_h], + c_args : extra_demo_cflags, link_with : [libdemo, libtestutils], dependencies : [dep_glib, dep_gtk, dep_openmp, idep_pixman], ) diff --git a/lib/pixman/meson.build b/lib/pixman/meson.build index fad22eea9..1cec22728 100644 --- a/lib/pixman/meson.build +++ b/lib/pixman/meson.build @@ -21,9 +21,9 @@ project( 'pixman', ['c'], - version : '0.38.4', + version : '0.40.0', license : 'MIT', - meson_version : '>= 0.47.2', + meson_version : '>= 0.50.0', default_options : ['buildtype=debugoptimized'], ) @@ -36,6 +36,7 @@ add_project_arguments( '-Wdeclaration-after-statement', '-fno-strict-aliasing', '-fvisibility=hidden', + '-Wundef', ]), language : ['c'] ) @@ -50,7 +51,7 @@ endforeach use_loongson_mmi = get_option('loongson-mmi') have_loongson_mmi = false -loongson_mmi_flags = ['-march=loongson2f'] +loongson_mmi_flags = ['-mloongson-mmi'] if not use_loongson_mmi.disabled() if host_machine.cpu_family() == 'mips64' and cc.compiles(''' #ifndef __mips_loongson_vector_rev @@ -84,9 +85,17 @@ endif use_mmx = get_option('mmx') have_mmx = false -mmx_flags = ['-mmmx', '-Winline'] +mmx_flags = [] + +if cc.get_id() == 'msvc' + mmx_flags = ['/w14710', '/w14714', '/wd4244'] +elif cc.get_id() == 'sun' + mmx_flags = ['-xarch=sse'] +else + mmx_flags = ['-mmmx', '-Winline'] +endif if not use_mmx.disabled() - if host_machine.cpu_family() == 'x86_64' + if host_machine.cpu_family() == 'x86_64' or cc.get_id() == 'msvc' have_mmx = true elif host_machine.cpu_family() == 'x86' and cc.compiles(''' #include <mmintrin.h> @@ -127,14 +136,23 @@ if not use_mmx.disabled() endif if have_mmx - config.set10('USE_X86_MMX', true) + # Inline assembly do not work on X64 MSVC, so we use + # compatibility intrinsics there + if cc.get_id() != 'msvc' or host_machine.cpu_family() != 'x86_64' + config.set10('USE_X86_MMX', true) + endif elif use_mmx.enabled() error('MMX Support unavailable, but required') endif use_sse2 = get_option('sse2') have_sse2 = false -sse2_flags = ['-msse2', '-Winline'] +sse2_flags = [] +if cc.get_id() == 'sun' + sse2_flags = ['-xarch=sse2'] +elif cc.get_id() != 'msvc' + sse2_flags = ['-msse2', '-Winline'] +endif if not use_sse2.disabled() if host_machine.cpu_family() == 'x86' if cc.compiles(''' @@ -169,8 +187,13 @@ endif use_ssse3 = get_option('ssse3') have_ssse3 = false -ssse3_flags =['-mssse3', '-Winline'] -if not use_ssse3.disabled() +ssse3_flags = [] +if cc.get_id() != 'msvc' + ssse3_flags = ['-mssse3', '-Winline'] +endif + +# x64 pre-2010 MSVC compilers crashes when building the ssse3 code +if not use_ssse3.disabled() and not (cc.get_id() == 'msvc' and cc.version().version_compare('<16') and host_machine.cpu_family() == 'x86_64') if host_machine.cpu_family().startswith('x86') if cc.compiles(''' #include <mmintrin.h> @@ -349,14 +372,21 @@ if get_option('gnuplot') config.set('PIXMAN_GNUPLOT', 1) endif -dep_openmp = dependency('openmp', required : get_option('openmp')) -if dep_openmp.found() - config.set10('USE_OPENMP', true) -elif meson.version().version_compare('<0.51.0') -# In versions of meson before 0.51 the openmp dependency can still -# inject arguments in the the auto case when it is not found, the -# detection does work correctly in that case however, so we just -# replace dep_openmp with null_dep to work around this. +if cc.get_id() != 'msvc' + dep_openmp = dependency('openmp', required : get_option('openmp')) + if dep_openmp.found() + config.set10('USE_OPENMP', true) + elif meson.version().version_compare('<0.51.0') + # In versions of meson before 0.51 the openmp dependency can still + # inject arguments in the the auto case when it is not found, the + # detection does work correctly in that case however, so we just + # replace dep_openmp with null_dep to work around this. + dep_openmp = null_dep + endif +else + # the MSVC implementation of openmp is not compliant enough for our + # uses here, so we disable it here. + # Please see: https://stackoverflow.com/questions/12560243/using-threadprivate-directive-in-visual-studio dep_openmp = null_dep endif @@ -364,17 +394,56 @@ dep_gtk = dependency('gtk+-2.0', version : '>= 2.16', required : get_option('gtk dep_glib = dependency('glib-2.0', required : get_option('gtk')) dep_pixman = dependency('pixman-1', required : get_option('gtk'), version : '>= ' + meson.project_version()) -dep_png = dependency('libpng', required : get_option('libpng')) + +dep_png = null_dep +if not get_option('libpng').disabled() + dep_png = dependency('libpng', required : false) + + # We need to look for the right library to link to for libpng, + # when looking for libpng manually + foreach png_ver : [ '16', '15', '14', '13', '12', '10' ] + if not dep_png.found() + dep_png = cc.find_library('libpng@0@'.format(png_ver), has_headers : ['png.h'], required : false) + endif + endforeach + + if get_option('libpng').enabled() and not dep_png.found() + error('libpng support requested but libpng library not found') + endif +endif + if dep_png.found() config.set('HAVE_LIBPNG', 1) endif dep_m = cc.find_library('m', required : false) dep_threads = dependency('threads') -if dep_threads.found() + +# MSVC-style compilers do not come with pthreads, so we must link +# to it explicitly, currently pthreads-win32 is supported +pthreads_found = false + +if dep_threads.found() and cc.has_header('pthread.h') + if cc.get_argument_syntax() == 'msvc' + pthread_lib = null_dep + foreach pthread_type : ['VC3', 'VSE3', 'VCE3', 'VC2', 'VSE2', 'VCE2'] + if not pthread_lib.found() + pthread_lib = cc.find_library('pthread@0@'.format(pthread_type), required : false) + endif + endforeach + if pthread_lib.found() + pthreads_found = true + dep_threads = pthread_lib + endif + else + pthreads_found = true + endif +endif + +if pthreads_found config.set('HAVE_PTHREADS', 1) endif -funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap'] +funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap', 'getisax', 'gettimeofday'] # mingw claimes to have posix_memalign, but it doesn't if host_machine.system() != 'windows' funcs += 'posix_memalign' @@ -386,10 +455,6 @@ foreach f : funcs endif endforeach -if cc.has_function('gettimeofday') - config.set('HAVE_GETTIMEOFDAY', 1) -endif - # This is only used in one test, that defines _GNU_SOURCE if cc.has_function('feenableexcept', prefix : '#define _GNU_SOURCE\n#include <fenv.h>', @@ -407,8 +472,12 @@ foreach h : ['sys/mman.h', 'fenv.h', 'unistd.h'] endif endforeach +# gcc on Windows only warns that __declspec(thread) isn't supported, +# passing -Werror=attributes makes it fail. if (host_machine.system() == 'windows' and - cc.compiles('int __declspec(thread) foo;', name : 'TLS via __declspec(thread)')) + cc.compiles('int __declspec(thread) foo;', + args : cc.get_supported_arguments(['-Werror=attributes']), + name : 'TLS via __declspec(thread)')) config.set('TLS', '__declspec(thread)') elif cc.compiles('int __thread foo;', name : 'TLS via __thread') config.set('TLS', '__thread') @@ -445,6 +514,8 @@ if host_machine.endian() == 'big' config.set('WORDS_BIGENDIAN', 1) endif +config.set('SIZEOF_LONG', cc.sizeof('long')) + # Required to make pixman-private.h config.set('PACKAGE', 'foo') diff --git a/lib/pixman/pixman/Makefile.am b/lib/pixman/pixman/Makefile.am index 3de26153e..8f780a145 100644 --- a/lib/pixman/pixman/Makefile.am +++ b/lib/pixman/pixman/Makefile.am @@ -12,6 +12,7 @@ noinst_LTLIBRARIES = EXTRA_DIST = \ Makefile.win32 \ + dither/make-blue-noise.c \ pixman-region.c \ solaris-hwcap.mapfile \ meson.build \ diff --git a/lib/pixman/pixman/Makefile.in b/lib/pixman/pixman/Makefile.in index 48e3b5c79..0b78b6847 100644 --- a/lib/pixman/pixman/Makefile.in +++ b/lib/pixman/pixman/Makefile.in @@ -454,6 +454,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -496,6 +497,7 @@ libpixman_sources = \ $(NULL) libpixman_headers = \ + dither/blue-noise-64x64.h \ pixman.h \ pixman-accessor.h \ pixman-combine32.h \ @@ -521,6 +523,7 @@ noinst_LTLIBRARIES = $(am__append_1) $(am__append_4) $(am__append_6) \ $(am__append_16) $(am__append_18) $(am__append_20) EXTRA_DIST = \ Makefile.win32 \ + dither/make-blue-noise.c \ pixman-region.c \ solaris-hwcap.mapfile \ meson.build \ diff --git a/lib/pixman/pixman/Makefile.sources b/lib/pixman/pixman/Makefile.sources index c624eb9a8..23d1d974d 100644 --- a/lib/pixman/pixman/Makefile.sources +++ b/lib/pixman/pixman/Makefile.sources @@ -32,6 +32,7 @@ libpixman_sources = \ $(NULL) libpixman_headers = \ + dither/blue-noise-64x64.h \ pixman.h \ pixman-accessor.h \ pixman-combine32.h \ diff --git a/lib/pixman/pixman/dither/blue-noise-64x64.h b/lib/pixman/pixman/dither/blue-noise-64x64.h new file mode 100644 index 000000000..93c8805b5 --- /dev/null +++ b/lib/pixman/pixman/dither/blue-noise-64x64.h @@ -0,0 +1,77 @@ +/* WARNING: This file is generated by make-blue-noise.c + * Please edit that file instead of this one. + */ + +#ifndef BLUE_NOISE_64X64_H +#define BLUE_NOISE_64X64_H + +#include <stdint.h> + +static const uint16_t dither_blue_noise_64x64[4096] = { + 3039, 1368, 3169, 103, 2211, 1248, 2981, 668, 2633, 37, 3963, 2903, 384, 2564, 3115, 1973, 3348, 830, 2505, 1293, 3054, 1060, 1505, 3268, 400, 1341, 593, 3802, 3384, 429, 4082, 1411, 2503, 3863, 126, 1292, 1887, 2855, 205, 2094, 2977, 1899, 3924, 356, 3088, 2500, 3942, 1409, 2293, 1734, 3732, 1291, 3227, 277, 2054, 786, 2871, 411, 2425, 1678, 3986, 455, 2879, 2288, + 388, 1972, 3851, 778, 2768, 3697, 944, 2123, 1501, 3533, 937, 1713, 1381, 3888, 156, 1242, 516, 2888, 1607, 3676, 632, 2397, 3804, 2673, 1898, 3534, 2593, 1777, 1170, 2299, 3013, 1838, 523, 3053, 1647, 3601, 3197, 959, 1520, 3633, 893, 2437, 3367, 2187, 1258, 137, 1965, 401, 3546, 643, 3087, 2498, 733, 2786, 3371, 4053, 1266, 1977, 3663, 183, 2570, 2107, 1183, 3708, + 907, 2473, 1151, 3363, 1527, 1902, 232, 3903, 3060, 496, 2486, 3206, 2165, 861, 2387, 3653, 2101, 3972, 132, 2162, 3437, 1827, 215, 895, 3114, 271, 969, 2932, 197, 1598, 878, 3696, 1140, 2120, 904, 2431, 302, 3846, 2675, 481, 3187, 66, 1440, 650, 3833, 2826, 3435, 901, 2936, 2111, 250, 1875, 3609, 1174, 1747, 162, 2346, 3420, 913, 3172, 1383, 752, 3298, 1735, + 3540, 2938, 249, 2324, 526, 3099, 2561, 1324, 2347, 1861, 1200, 3702, 257, 3442, 1514, 2999, 992, 1766, 2735, 1163, 478, 2943, 1279, 3635, 2177, 1464, 3672, 2386, 3871, 3340, 2690, 64, 3489, 2811, 3999, 633, 1948, 1243, 2269, 1807, 1143, 2750, 3729, 1790, 2363, 1053, 1537, 2636, 4065, 1076, 1476, 3869, 450, 2200, 2676, 658, 2979, 1548, 544, 1913, 2838, 3911, 116, 2698, + 517, 1295, 3997, 1739, 3665, 1083, 3509, 599, 3400, 118, 2956, 720, 2689, 1907, 567, 2523, 284, 3397, 711, 3219, 2450, 3985, 1665, 2549, 562, 3011, 1855, 729, 1355, 528, 1908, 2456, 1384, 337, 1540, 2654, 3138, 3513, 703, 4080, 3314, 2047, 855, 3037, 209, 3317, 577, 1828, 17, 2336, 3193, 2748, 962, 3441, 1450, 3246, 1075, 3878, 2615, 3497, 1033, 2310, 1442, 2183, + 1654, 3254, 2061, 738, 2832, 148, 2030, 1670, 909, 3850, 2109, 1533, 4046, 1085, 3098, 3897, 1378, 2248, 3829, 1495, 1966, 23, 797, 3427, 1124, 4057, 95, 2787, 2190, 3074, 3950, 742, 3194, 1999, 3386, 1113, 16, 1657, 2804, 201, 1543, 383, 2559, 1325, 3604, 2068, 2493, 3771, 1284, 3460, 710, 1716, 2447, 80, 3811, 2032, 347, 2227, 15, 1689, 397, 3084, 662, 3798, + 973, 43, 2608, 3143, 1459, 2423, 4066, 2770, 3191, 1283, 2630, 314, 3235, 2289, 72, 1822, 2840, 924, 350, 2653, 1057, 3715, 2235, 2775, 346, 2083, 1553, 3292, 1081, 274, 1686, 1188, 2327, 3743, 578, 2234, 3916, 2519, 1011, 3056, 2207, 3438, 3890, 537, 1617, 837, 3094, 373, 2795, 1980, 276, 3951, 1353, 3015, 844, 1724, 3651, 2923, 1316, 4092, 2504, 3627, 1936, 2854, + 2461, 3929, 1193, 421, 3746, 820, 1180, 286, 2261, 532, 3625, 1812, 802, 1327, 3527, 670, 3730, 2025, 3124, 3565, 529, 2960, 1769, 1390, 3196, 2494, 3756, 796, 3618, 2602, 3463, 2847, 166, 953, 1745, 2900, 438, 2070, 1418, 3741, 639, 1205, 1891, 2882, 2282, 4012, 1182, 1696, 3630, 951, 2904, 2170, 3530, 375, 2320, 2742, 1132, 701, 3216, 2023, 847, 1230, 310, 3431, + 770, 1961, 3531, 1702, 2181, 3370, 1877, 3072, 1571, 3389, 1071, 2415, 3782, 2803, 1610, 2454, 1211, 182, 1655, 2322, 1282, 3372, 287, 3935, 704, 1232, 415, 1910, 2286, 1399, 556, 1964, 4068, 2444, 3605, 1272, 3345, 816, 3526, 256, 2402, 2777, 955, 345, 3289, 111, 2727, 635, 2396, 1488, 3331, 600, 1032, 1575, 4026, 515, 3507, 2433, 1605, 460, 3364, 2783, 1810, 1397, + 2334, 223, 2945, 688, 2533, 99, 2705, 624, 3944, 2073, 46, 2978, 508, 2132, 269, 3173, 3453, 2631, 4076, 694, 1892, 2586, 972, 2178, 3470, 1695, 2849, 3141, 77, 3884, 994, 3029, 1536, 673, 3083, 124, 2583, 1722, 2821, 1944, 4027, 1661, 3176, 3728, 1337, 1813, 3503, 2035, 3930, 157, 2537, 1865, 3096, 2646, 1941, 3252, 1449, 135, 2836, 3758, 2139, 84, 3678, 3106, + 3862, 1545, 3307, 1320, 3955, 1031, 3664, 1306, 2460, 776, 1487, 3294, 1187, 3990, 1903, 1021, 549, 1484, 943, 3027, 97, 3853, 1499, 2880, 198, 2575, 3995, 1089, 1587, 2475, 3282, 339, 2657, 1158, 2105, 1493, 3943, 580, 3232, 1287, 846, 48, 2480, 2112, 771, 2534, 459, 3134, 850, 1298, 3790, 325, 3652, 1249, 193, 940, 2202, 3895, 1829, 911, 1366, 2577, 1069, 534, + 2104, 1009, 2667, 392, 1983, 2917, 1645, 324, 3439, 2869, 3705, 1767, 2592, 756, 2916, 3683, 2276, 2850, 2053, 3594, 2403, 3181, 634, 3699, 1933, 906, 519, 2150, 3673, 764, 1770, 2220, 3795, 3336, 502, 3547, 2339, 1110, 301, 2210, 3354, 3643, 569, 1518, 2940, 3973, 1138, 1613, 2773, 2127, 2983, 1671, 769, 2161, 3800, 2730, 3127, 1179, 533, 3259, 2284, 4014, 1651, 2820, + 3566, 653, 1839, 3455, 2399, 789, 3149, 2244, 1863, 1099, 474, 2307, 158, 3541, 1312, 1711, 0, 3902, 360, 1629, 1091, 395, 1781, 1191, 2374, 3353, 1419, 3225, 206, 2931, 3553, 1046, 54, 1646, 2470, 910, 1860, 3137, 3770, 2635, 1562, 2809, 1215, 3788, 222, 2199, 3335, 67, 3606, 524, 1001, 3309, 2410, 3473, 591, 1619, 291, 2502, 3629, 2891, 335, 741, 3378, 168, + 2384, 3129, 4051, 22, 1444, 3613, 543, 3893, 186, 2665, 4062, 933, 3058, 2142, 449, 2711, 3224, 849, 1330, 3349, 2195, 2670, 3484, 2993, 32, 3774, 2722, 1859, 2548, 1268, 583, 2027, 3165, 2807, 4029, 227, 2897, 1434, 721, 1816, 195, 905, 2066, 3258, 1754, 970, 2674, 1880, 2338, 3915, 1485, 2660, 14, 1313, 2914, 2046, 4074, 791, 1917, 1301, 1725, 2687, 2019, 1443, + 418, 1186, 1664, 2859, 1049, 2056, 2741, 1226, 1589, 3186, 2042, 1377, 3449, 1574, 3941, 1063, 1930, 2501, 3751, 2930, 671, 4031, 888, 2081, 1544, 684, 1117, 351, 4052, 1698, 2393, 3881, 1439, 785, 1277, 2013, 3488, 441, 2459, 3980, 3061, 3481, 2543, 419, 3020, 609, 3515, 1350, 799, 2878, 348, 2034, 3966, 1824, 950, 3281, 1394, 2239, 3452, 55, 3922, 3119, 892, 3785, + 3023, 2140, 782, 2492, 3817, 241, 3355, 2424, 856, 3639, 612, 2556, 245, 2858, 705, 2316, 3562, 495, 1748, 128, 1912, 1454, 280, 2552, 3905, 3130, 2274, 3472, 834, 3055, 240, 2692, 471, 2272, 3301, 2632, 1080, 3693, 2136, 1029, 1364, 590, 1611, 4067, 1190, 2360, 3827, 261, 3180, 1768, 3471, 1103, 3003, 520, 3674, 151, 2571, 555, 3033, 982, 2353, 504, 1259, 2555, + 149, 3889, 3380, 493, 3178, 1681, 663, 1924, 2990, 49, 1792, 3861, 1192, 1987, 3273, 297, 1457, 3043, 1177, 2292, 3249, 2829, 3682, 1154, 1758, 428, 2872, 1993, 1500, 3703, 1129, 3421, 1840, 3754, 163, 659, 1733, 3182, 38, 2875, 1957, 3614, 2237, 78, 1873, 2801, 1513, 2121, 1074, 2516, 667, 3710, 1429, 2430, 2088, 2830, 1072, 3557, 1531, 2733, 1955, 3286, 3590, 1826, + 2778, 1068, 1932, 1452, 2279, 1185, 3564, 3952, 1391, 2726, 3313, 2331, 870, 3709, 1674, 2772, 4085, 808, 2596, 3848, 927, 538, 2335, 3334, 773, 3597, 1347, 109, 2663, 608, 2108, 2994, 936, 1524, 2922, 3968, 2422, 1467, 845, 3870, 321, 2704, 1073, 3308, 3680, 823, 430, 3375, 4030, 112, 2171, 2695, 267, 3374, 731, 1627, 3919, 1871, 352, 3839, 1370, 234, 794, 1532, + 3245, 647, 3575, 74, 3045, 2766, 285, 2174, 498, 1059, 1551, 385, 3125, 2598, 143, 1128, 2095, 3395, 318, 1590, 3524, 1345, 1969, 242, 2759, 2092, 947, 3926, 3244, 2356, 1658, 6, 3593, 2554, 1172, 1995, 371, 2755, 3417, 2294, 1570, 3164, 748, 2517, 1401, 3111, 2420, 1662, 2910, 1276, 3276, 854, 1804, 4000, 1253, 2987, 229, 2344, 3184, 649, 2196, 2921, 4095, 2389, + 1289, 2193, 2579, 4023, 757, 1858, 986, 3199, 2514, 3475, 4021, 2154, 651, 1432, 3468, 2404, 574, 1799, 3105, 2145, 86, 2614, 3218, 1565, 4088, 2481, 3079, 1815, 323, 1212, 3837, 759, 2159, 435, 3223, 784, 3659, 1114, 1888, 550, 1221, 3786, 1803, 499, 2117, 185, 3763, 942, 589, 2001, 3838, 1483, 3154, 2256, 468, 2544, 3403, 898, 1208, 2610, 3622, 967, 1929, 378, + 3781, 220, 1656, 1115, 3347, 2428, 3822, 1577, 712, 1959, 110, 2765, 1762, 3854, 979, 2928, 3714, 1371, 746, 3969, 2884, 975, 3779, 641, 1142, 159, 1460, 702, 3485, 2866, 2495, 3330, 1305, 3937, 1635, 2229, 2962, 146, 4055, 3091, 2417, 100, 3508, 2933, 4006, 1167, 1920, 2760, 3552, 2545, 433, 2845, 142, 1056, 1886, 3616, 1435, 2099, 3803, 1749, 27, 1446, 3350, 2843, + 884, 3310, 2948, 2103, 447, 1351, 187, 2895, 3655, 1256, 3036, 932, 3325, 2257, 451, 1915, 40, 2780, 2438, 1112, 1814, 423, 2290, 1905, 2898, 3419, 2306, 3760, 1938, 486, 1019, 1791, 3010, 2628, 203, 3408, 1269, 2507, 1606, 862, 2779, 2078, 952, 1529, 2638, 708, 3332, 1413, 2, 1726, 1156, 3500, 2392, 3791, 3076, 812, 107, 2861, 501, 3050, 3487, 2455, 594, 1731, + 2685, 1498, 680, 3908, 2621, 3529, 1786, 2236, 342, 2569, 1526, 3722, 230, 1290, 3203, 3947, 1609, 3516, 467, 3267, 3685, 1461, 3140, 3569, 367, 1759, 928, 2754, 1332, 2219, 4034, 260, 655, 1984, 978, 3814, 617, 2086, 3525, 279, 3841, 1373, 3361, 319, 2251, 3066, 407, 2382, 3918, 3133, 2168, 762, 1523, 507, 2641, 1677, 4025, 2413, 1584, 793, 2049, 1109, 3962, 2218, + 1194, 3692, 266, 1687, 981, 3103, 740, 3983, 1005, 3434, 570, 2383, 1942, 2718, 676, 2462, 1007, 2089, 1308, 2222, 233, 2568, 829, 1241, 2669, 3987, 514, 3303, 69, 3142, 1603, 3560, 2295, 3288, 1497, 2696, 1764, 2865, 1058, 3271, 1914, 477, 2529, 3927, 1736, 1273, 3752, 2029, 1012, 565, 2798, 4078, 1949, 3305, 1175, 2179, 380, 3366, 1195, 3849, 2637, 416, 2959, 125, + 3396, 2467, 2036, 3234, 2340, 68, 2819, 1436, 2011, 3139, 1704, 4073, 860, 3582, 1468, 2969, 211, 3157, 4056, 866, 2935, 2000, 3923, 31, 2157, 1477, 2429, 1147, 3792, 2557, 774, 2802, 1153, 3747, 464, 3192, 42, 3904, 539, 1474, 2283, 803, 2876, 1061, 75, 3477, 747, 2893, 1538, 3626, 251, 1322, 2506, 189, 2791, 3667, 939, 2991, 1971, 175, 3195, 1416, 3648, 1857, + 3052, 454, 851, 3789, 1271, 1906, 3694, 2484, 406, 2757, 26, 1189, 2909, 296, 2215, 3784, 1864, 637, 2715, 1673, 3445, 581, 1572, 3059, 3469, 761, 2984, 1737, 2058, 440, 1414, 1921, 121, 2527, 894, 2223, 1302, 2377, 3077, 2666, 3759, 3198, 1811, 3661, 2166, 2731, 1883, 359, 3285, 2458, 1805, 3459, 926, 3834, 675, 1893, 1496, 2612, 657, 3523, 1763, 2354, 564, 961, + 1367, 3977, 1588, 2714, 322, 3446, 1088, 625, 3887, 1354, 3535, 2090, 3316, 1760, 1127, 483, 3491, 1421, 2301, 94, 1202, 3740, 2311, 1014, 1878, 3836, 180, 3412, 991, 2868, 3953, 3450, 3081, 1632, 4071, 1882, 3543, 726, 1719, 179, 1171, 364, 1420, 622, 3090, 1490, 946, 4007, 2212, 1102, 619, 2739, 2189, 1669, 2937, 3426, 39, 3940, 2191, 1264, 887, 4091, 2792, 2135, + 4, 2883, 2281, 631, 3044, 1641, 2232, 3243, 1773, 2319, 827, 2591, 629, 3938, 2426, 3222, 2629, 1044, 3879, 3293, 1952, 2749, 275, 2590, 472, 1372, 2496, 660, 3669, 2264, 208, 915, 2167, 561, 2828, 307, 3265, 1104, 3964, 2155, 3425, 1951, 4077, 2391, 283, 3387, 2581, 115, 1415, 3069, 3896, 141, 3158, 1214, 442, 2405, 1349, 3085, 425, 2528, 3002, 312, 1602, 3588, + 1137, 3323, 1963, 1002, 3578, 2521, 127, 925, 2970, 273, 3737, 1573, 167, 2863, 1509, 800, 147, 2059, 2942, 409, 921, 3151, 1451, 3909, 3333, 2844, 2096, 1512, 3136, 1210, 1798, 2709, 1331, 3586, 1034, 1521, 2441, 2926, 488, 2585, 775, 3031, 2693, 879, 3602, 1173, 2028, 3654, 2781, 841, 1975, 1507, 3646, 768, 3991, 2012, 996, 3544, 1666, 3810, 1990, 3360, 753, 2597, + 3736, 304, 1473, 3828, 485, 1334, 4008, 2072, 3495, 1136, 2806, 2004, 3236, 1010, 2130, 3819, 1750, 3567, 644, 2515, 1794, 3636, 698, 2137, 1162, 832, 3761, 326, 2613, 513, 3302, 3820, 357, 3163, 2259, 3733, 101, 1922, 1386, 3587, 1640, 28, 1286, 2141, 1761, 2918, 693, 1639, 457, 3250, 2434, 365, 2599, 1729, 3284, 2643, 306, 2793, 689, 1090, 104, 1309, 2305, 1831, + 2776, 859, 2446, 2915, 1778, 3337, 2677, 614, 1508, 2409, 469, 4033, 1321, 3563, 402, 3131, 2720, 1093, 1569, 4042, 1229, 2277, 216, 3046, 1817, 57, 3006, 1684, 4059, 2016, 795, 2440, 1652, 1960, 610, 2763, 920, 3864, 3110, 1026, 2326, 3762, 3233, 521, 3856, 173, 2457, 3939, 2138, 1262, 3572, 989, 3021, 2238, 119, 1445, 3832, 1809, 2297, 3467, 2700, 3684, 3102, 394, + 4036, 2050, 3256, 89, 2198, 1079, 248, 1845, 3805, 3104, 880, 1779, 2688, 717, 2373, 1375, 262, 2249, 3071, 13, 2813, 3429, 1600, 3984, 2416, 3603, 1299, 2298, 998, 3492, 1393, 2951, 10, 4009, 1247, 3462, 1679, 2204, 414, 2736, 316, 1894, 2816, 1050, 3373, 1462, 3107, 817, 3464, 21, 1835, 4070, 568, 1178, 3718, 875, 3168, 466, 2974, 1458, 2084, 616, 1564, 1018, + 1693, 546, 1244, 3899, 716, 3160, 3608, 2877, 1220, 334, 3443, 2270, 44, 3000, 1843, 3928, 3405, 766, 3686, 2040, 587, 993, 2647, 387, 930, 2753, 630, 3274, 150, 2808, 453, 3638, 1092, 2352, 3030, 239, 2562, 700, 3240, 1257, 4016, 730, 1515, 2203, 2551, 417, 1866, 1123, 2348, 2902, 1550, 2678, 2075, 3238, 1630, 2531, 2115, 1255, 4054, 840, 290, 3874, 2477, 3399, + 2250, 3577, 2817, 1626, 2576, 1356, 2315, 792, 2087, 2618, 1612, 3855, 1263, 3637, 1036, 494, 1535, 2553, 1198, 1715, 3867, 3170, 1359, 1954, 3483, 1539, 2069, 3886, 1772, 2487, 1534, 2045, 3242, 806, 1578, 2018, 3948, 1423, 3596, 2076, 2466, 3424, 139, 3688, 871, 4049, 2852, 3342, 547, 3719, 327, 852, 3505, 207, 2794, 542, 3600, 45, 2411, 3324, 1788, 3012, 1235, 61, + 2655, 917, 253, 1986, 3738, 313, 1706, 4072, 120, 3229, 957, 597, 2024, 3262, 2453, 2857, 2002, 3190, 210, 2784, 2206, 300, 2400, 3766, 553, 3152, 218, 1150, 2988, 883, 3753, 627, 2664, 3831, 437, 3385, 1008, 2957, 60, 1636, 891, 2899, 1776, 3062, 1315, 2026, 194, 1643, 2079, 1296, 3201, 2465, 1379, 1927, 3898, 1125, 1847, 2846, 1552, 1028, 2725, 2169, 787, 3202, + 1441, 3982, 3032, 1052, 3251, 605, 2639, 3073, 1431, 3642, 2329, 2949, 341, 1634, 833, 129, 4020, 916, 3571, 669, 1506, 3411, 821, 2856, 1207, 2337, 2683, 3448, 340, 2214, 3128, 235, 1738, 1288, 2833, 2419, 606, 1884, 2668, 552, 3765, 1176, 399, 2302, 596, 3591, 2634, 767, 3845, 2767, 995, 3967, 491, 3057, 814, 2300, 3422, 691, 3797, 254, 3645, 509, 3478, 1836, + 2119, 475, 2445, 1525, 2175, 3539, 914, 1926, 473, 1157, 1800, 3971, 2701, 3739, 2129, 3486, 1333, 1784, 2366, 2982, 1070, 4089, 1802, 73, 1642, 3958, 835, 1837, 1480, 4043, 1217, 2469, 3416, 2113, 88, 3668, 1240, 3255, 3920, 2355, 3167, 2003, 2645, 3936, 3228, 1592, 1144, 3474, 2394, 79, 1820, 2241, 1594, 3656, 2584, 153, 1448, 3034, 2005, 2511, 1692, 1335, 3913, 217, + 2822, 3391, 745, 3813, 192, 1274, 2941, 3847, 2489, 3440, 744, 161, 1422, 1086, 572, 3004, 2617, 338, 3807, 2031, 236, 2472, 3065, 2098, 3358, 362, 2163, 3574, 497, 2788, 1970, 948, 3885, 685, 3100, 1712, 2228, 292, 1408, 1016, 164, 3537, 1417, 941, 34, 2172, 3001, 358, 1491, 3147, 699, 3356, 258, 1149, 2946, 1787, 3931, 382, 1146, 3291, 818, 2890, 2379, 1096, + 3679, 1328, 1901, 3162, 2747, 1730, 2253, 5, 1556, 2818, 2093, 3166, 2522, 3410, 2287, 1701, 956, 3237, 620, 1596, 3300, 1307, 511, 3701, 1020, 2939, 1362, 2532, 3208, 749, 3641, 160, 1522, 2624, 1095, 4086, 826, 2841, 3583, 2173, 1727, 723, 2925, 1911, 2482, 3726, 863, 1962, 4028, 1111, 2835, 3773, 2449, 2022, 582, 3278, 923, 2619, 2152, 4039, 92, 1934, 3145, 677, + 2530, 53, 2303, 1003, 458, 3989, 739, 3321, 1064, 369, 3556, 877, 1900, 426, 3876, 1, 3617, 2106, 1197, 2805, 3634, 857, 2706, 1504, 2418, 682, 3868, 20, 1139, 1688, 2333, 3311, 2907, 1945, 265, 2385, 3433, 1601, 636, 2620, 3095, 4044, 386, 3382, 1184, 527, 2814, 3414, 2342, 465, 1889, 1343, 874, 3479, 1502, 2233, 3689, 1385, 559, 2745, 1463, 3465, 376, 1718, + 3217, 4045, 1580, 3612, 2525, 1228, 3018, 1958, 3725, 2358, 1361, 3996, 1581, 3063, 1224, 2737, 1475, 2442, 3946, 191, 1796, 2128, 3975, 134, 1916, 3318, 1597, 2071, 3749, 2672, 403, 1278, 602, 3745, 3220, 1374, 445, 2064, 3830, 243, 1252, 2390, 1563, 2724, 3875, 1818, 1346, 165, 1650, 3264, 2680, 117, 2998, 4081, 343, 2799, 9, 3122, 1743, 3724, 1040, 2231, 3842, 1209, + 900, 398, 2851, 697, 1797, 3482, 293, 2679, 1649, 566, 2954, 91, 2697, 714, 2060, 3211, 781, 480, 3040, 1038, 2611, 666, 2989, 3458, 1201, 2796, 548, 2975, 839, 3121, 1850, 4001, 2208, 1631, 790, 2558, 2972, 1148, 3213, 1849, 3624, 971, 2102, 108, 772, 3101, 2589, 3777, 1042, 656, 3907, 2097, 1615, 2540, 805, 1935, 1231, 3494, 2451, 268, 2995, 750, 2682, 2020, + 3024, 1392, 2124, 3279, 106, 2217, 1387, 822, 3214, 3825, 2160, 1000, 2395, 3691, 228, 4038, 1872, 3413, 1608, 2225, 3536, 303, 1653, 886, 2541, 224, 4037, 2252, 1428, 172, 3504, 958, 2848, 113, 3628, 1834, 3979, 19, 2317, 779, 2797, 518, 3174, 3549, 1482, 2266, 444, 2014, 3555, 2439, 1213, 3113, 535, 1135, 3204, 3858, 2309, 931, 623, 2009, 3359, 1566, 140, 3550, + 1808, 3872, 2488, 1152, 3764, 2892, 3960, 2412, 353, 1223, 1825, 3444, 3116, 1717, 1082, 2313, 1280, 2661, 82, 3852, 1389, 3200, 2330, 3812, 2038, 3581, 1728, 1039, 3339, 2427, 586, 2580, 1238, 3328, 2280, 1047, 595, 2662, 1363, 3338, 1620, 3934, 2497, 1881, 1054, 3954, 3215, 864, 2887, 1801, 320, 3519, 2378, 3704, 1753, 424, 2958, 1660, 4005, 2601, 1116, 3912, 2381, 573, + 2740, 200, 828, 1667, 432, 1931, 1035, 1616, 3598, 2640, 728, 264, 1437, 557, 3501, 2966, 372, 3734, 974, 1978, 758, 2719, 1145, 452, 1433, 725, 2681, 408, 3843, 1918, 1547, 3906, 1996, 503, 1456, 3019, 3493, 1700, 3742, 355, 2134, 176, 1311, 615, 2867, 315, 1680, 1314, 8, 3297, 1494, 783, 1950, 83, 2656, 1382, 3561, 138, 2834, 1404, 330, 1904, 3156, 1027, + 1357, 3381, 3041, 3666, 2729, 734, 3415, 177, 3051, 2021, 4079, 2823, 3775, 2186, 2616, 869, 1668, 3148, 2367, 3315, 393, 4075, 1870, 2920, 3343, 2362, 3188, 1303, 2782, 825, 3171, 259, 2905, 3717, 2538, 184, 2074, 838, 2860, 2407, 1024, 3496, 3008, 3706, 1985, 2349, 3623, 2582, 4058, 2184, 2694, 3873, 2964, 990, 3346, 690, 2033, 1066, 2201, 3490, 2971, 718, 3700, 2188, + 4061, 391, 1989, 2325, 1430, 3150, 2125, 2526, 592, 1403, 976, 2351, 1165, 1851, 114, 3921, 2063, 613, 1358, 2785, 1623, 2254, 25, 3542, 1045, 246, 1852, 3554, 87, 2243, 3615, 1169, 727, 1705, 968, 3957, 3185, 1251, 500, 4063, 1751, 2622, 842, 1519, 90, 3393, 819, 490, 1874, 999, 571, 1275, 2271, 1586, 4040, 2448, 3126, 3731, 436, 885, 1708, 2421, 24, 1599, + 889, 2563, 1199, 645, 70, 4013, 1237, 3723, 1694, 3499, 3, 3266, 484, 2997, 3390, 1233, 2842, 3687, 152, 3480, 1084, 3698, 881, 2490, 1542, 3992, 2209, 692, 1690, 3022, 1470, 2625, 2114, 3512, 2359, 381, 2684, 1897, 3368, 1395, 3080, 289, 2065, 3981, 2758, 1141, 3097, 1472, 2870, 3352, 3707, 225, 3159, 505, 1895, 214, 1222, 1774, 2686, 3978, 3275, 1196, 3518, 2825, + 3270, 1720, 3796, 3466, 2650, 1841, 298, 899, 2862, 2091, 2671, 1744, 3735, 801, 1560, 349, 2262, 903, 1833, 2524, 512, 3117, 1793, 2827, 476, 3038, 1216, 2550, 3826, 980, 431, 4048, 35, 2992, 1265, 1595, 765, 3675, 76, 2247, 696, 3456, 1254, 2452, 664, 1757, 2133, 3750, 145, 2332, 1554, 1981, 3580, 2712, 868, 3640, 2919, 638, 2275, 1427, 309, 2595, 2006, 492, + 2226, 178, 2911, 836, 1528, 3028, 2240, 3327, 404, 3970, 707, 1294, 2464, 2131, 4032, 2600, 3319, 1406, 2913, 3974, 2156, 1425, 221, 3877, 2017, 811, 3662, 272, 3287, 1988, 2408, 3357, 1746, 598, 3239, 3823, 2182, 2934, 1078, 2604, 3840, 1697, 2906, 413, 3210, 3880, 331, 2644, 1260, 848, 3042, 2535, 1077, 1438, 3261, 2365, 1561, 3799, 85, 3082, 1876, 674, 3932, 1101, + 3644, 1344, 1943, 2401, 390, 3835, 1048, 2572, 1541, 1133, 3075, 3584, 308, 2889, 1065, 1869, 601, 3783, 282, 1181, 736, 3312, 2368, 1126, 3383, 1675, 2734, 1426, 628, 2873, 1317, 843, 2717, 2048, 1004, 2536, 333, 1782, 3295, 1517, 219, 2153, 815, 3502, 1579, 2268, 987, 3409, 1780, 4018, 354, 665, 3914, 47, 1956, 456, 1006, 2010, 3406, 1130, 3621, 2894, 1549, 3092, + 2485, 640, 3993, 3179, 1270, 3436, 585, 1925, 3757, 2304, 136, 1976, 1486, 646, 3520, 50, 3155, 1637, 2435, 3522, 1937, 2756, 3748, 661, 2224, 58, 3230, 2357, 1830, 3892, 170, 3607, 1447, 3949, 190, 3392, 1336, 584, 4010, 918, 3016, 3670, 1155, 2406, 52, 1304, 3009, 607, 2085, 2699, 3205, 1848, 2291, 3402, 2764, 3865, 3048, 2508, 735, 2710, 443, 2341, 897, 263, + 1785, 2769, 983, 56, 2197, 1685, 2703, 202, 2944, 810, 3377, 2626, 3787, 3047, 2055, 1236, 2752, 2122, 945, 3093, 96, 1624, 439, 3014, 1388, 4015, 977, 448, 3506, 1098, 2242, 3026, 506, 2361, 2952, 1862, 3619, 2790, 1992, 2483, 525, 1868, 2652, 4093, 1998, 3595, 2478, 3816, 122, 1412, 929, 3716, 1166, 1648, 813, 1300, 199, 1489, 3998, 1771, 1310, 3808, 2052, 3423, + 434, 3712, 1625, 3558, 2955, 853, 4019, 1348, 3511, 1732, 1246, 487, 934, 1672, 2510, 3965, 788, 3711, 396, 1369, 4090, 1055, 2603, 1879, 3528, 2518, 2067, 3005, 1516, 2588, 751, 1740, 3418, 1131, 1576, 686, 2296, 1118, 18, 3263, 1365, 3401, 294, 737, 3177, 410, 867, 1633, 2963, 3579, 2375, 252, 2881, 479, 2471, 3576, 2180, 3306, 332, 2255, 3035, 41, 2648, 1396, + 2929, 2230, 1219, 2512, 446, 2008, 3189, 2388, 626, 2164, 2831, 4047, 2376, 174, 3272, 368, 1469, 3226, 2578, 1991, 2874, 2263, 3681, 876, 188, 1239, 683, 3776, 226, 3183, 4083, 2148, 63, 2649, 3859, 299, 3086, 3933, 1585, 2185, 3767, 988, 1707, 2908, 1407, 1844, 2771, 2245, 1161, 560, 1755, 3376, 2051, 4064, 3135, 1832, 652, 2853, 1051, 3649, 760, 3290, 1105, 3945, + 872, 154, 3207, 713, 3780, 1453, 281, 1087, 3695, 30, 3299, 1919, 1400, 3551, 1119, 1890, 2314, 618, 1703, 3428, 724, 295, 3146, 1557, 3341, 2896, 1683, 2723, 1974, 1017, 541, 1380, 3720, 804, 3280, 2082, 997, 2567, 777, 2961, 213, 2707, 2328, 3632, 1025, 3891, 3304, 255, 4003, 3108, 2587, 1323, 743, 1479, 105, 1013, 3901, 1618, 2044, 2627, 1465, 1846, 576, 1994, + 2560, 3521, 1742, 2118, 2800, 3404, 1783, 2609, 2968, 1582, 1022, 412, 2713, 687, 2976, 3857, 2761, 3620, 62, 1108, 3844, 1340, 2100, 540, 2345, 3925, 405, 3457, 1319, 2468, 3362, 2815, 1867, 2372, 1281, 1714, 3690, 482, 3498, 1842, 1285, 3994, 558, 2039, 81, 2499, 678, 1481, 1923, 964, 12, 3824, 2980, 2205, 2762, 3432, 2398, 181, 3247, 462, 4094, 2350, 3589, 3089, + 1555, 1094, 4041, 247, 1267, 908, 3959, 2041, 732, 3860, 2343, 3132, 3769, 2144, 1621, 237, 912, 1329, 3025, 2146, 2642, 1775, 3721, 2746, 1121, 1953, 902, 2285, 130, 3671, 1659, 278, 3153, 522, 2721, 123, 2996, 1466, 2380, 377, 3231, 873, 1510, 3476, 3123, 1250, 2147, 3650, 2839, 3451, 2323, 1122, 3545, 379, 1765, 1218, 603, 3768, 1360, 938, 2885, 133, 1245, 363, + 2364, 554, 2743, 3344, 2474, 530, 3112, 169, 1297, 3430, 536, 1741, 98, 1043, 2574, 3253, 2246, 1854, 4022, 510, 3283, 204, 858, 3398, 36, 3118, 1478, 3794, 2986, 706, 2176, 922, 3559, 1097, 3976, 3322, 2149, 1160, 2810, 3883, 2007, 2513, 2953, 328, 1721, 3793, 422, 2566, 807, 329, 1638, 1967, 648, 2520, 3727, 3109, 2116, 2927, 2491, 1939, 3365, 1709, 2728, 3815, + 2037, 3120, 831, 1405, 1896, 3592, 1622, 2369, 2864, 2151, 1107, 2542, 3532, 1410, 3917, 427, 3568, 709, 2509, 1503, 1037, 2973, 2436, 1604, 4035, 2594, 563, 1819, 2659, 1234, 4004, 2565, 1511, 2273, 1823, 336, 882, 3772, 575, 1628, 171, 3570, 1120, 2260, 2716, 935, 3064, 1806, 1342, 3144, 3900, 2744, 3296, 985, 1546, 238, 896, 1663, 305, 3660, 695, 2213, 960, 3407, + 144, 1795, 3894, 2267, 51, 2708, 1023, 3818, 366, 1821, 4087, 2985, 755, 2057, 2912, 949, 1583, 2774, 231, 3447, 2258, 3866, 1982, 672, 1225, 2077, 3320, 1062, 370, 3241, 1968, 7, 3068, 681, 3631, 2573, 1567, 3175, 2321, 1067, 3070, 722, 1856, 3744, 642, 1471, 4084, 131, 3514, 2443, 531, 1227, 155, 2265, 4024, 2658, 3326, 3910, 1168, 3078, 1530, 3956, 489, 1424, + 3647, 1203, 420, 2924, 3755, 719, 3248, 1376, 3067, 890, 196, 1559, 3269, 270, 2432, 1885, 3212, 1164, 3778, 1752, 579, 1338, 344, 3585, 3017, 288, 3658, 2371, 3882, 1691, 611, 2789, 3809, 1339, 389, 2950, 2015, 59, 3548, 2751, 2158, 4011, 1352, 29, 3388, 2370, 2812, 1946, 954, 2110, 1558, 2947, 3573, 1909, 1326, 679, 1853, 2312, 551, 2702, 33, 2414, 3209, 2824, + 2547, 2143, 3379, 966, 1492, 1979, 2479, 463, 2194, 3657, 2738, 2318, 1261, 3713, 604, 4002, 11, 2192, 2967, 919, 2607, 3369, 2837, 1676, 2539, 984, 1568, 93, 2901, 1318, 3538, 1041, 2216, 1756, 3454, 1030, 4050, 1402, 798, 1723, 311, 3277, 2546, 2886, 2043, 461, 1206, 3677, 361, 3260, 3988, 809, 2605, 470, 3007, 3517, 102, 3221, 1398, 2062, 3611, 1134, 1928, 865, + 4060, 621, 1710, 2606, 3510, 317, 4017, 1682, 3329, 1159, 1940, 654, 3461, 1789, 1015, 2691, 1455, 3599, 374, 1947, 4069, 71, 2126, 763, 3961, 2278, 3161, 1997, 824, 2623, 2080, 244, 3257, 780, 2732, 2308, 545, 3351, 2476, 3806, 1204, 588, 1591, 963, 3610, 1699, 754, 3049, 2651, 1106, 65, 2221, 1644, 3821, 1100, 2463, 1614, 3801, 965, 2965, 715, 3394, 1593, 212, +}; + +#endif /* BLUE_NOISE_64X64_H */ diff --git a/lib/pixman/pixman/dither/make-blue-noise.c b/lib/pixman/pixman/dither/make-blue-noise.c new file mode 100644 index 000000000..f9974b4d4 --- /dev/null +++ b/lib/pixman/pixman/dither/make-blue-noise.c @@ -0,0 +1,679 @@ +/* Blue noise generation using the void-and-cluster method as described in + * + * The void-and-cluster method for dither array generation + * Ulichney, Robert A (1993) + * + * http://cv.ulichney.com/papers/1993-void-cluster.pdf + * + * Note that running with openmp (-DUSE_OPENMP) will trigger additional + * randomness due to computing reductions in parallel, and is not recommended + * unless generating very large dither arrays. + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdint.h> +#include <math.h> +#include <stdio.h> + +/* Booleans and utility functions */ + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +typedef int bool_t; + +int +imin (int x, int y) +{ + return x < y ? x : y; +} + +/* Memory allocation */ +void * +malloc_abc (unsigned int a, unsigned int b, unsigned int c) +{ + if (a >= INT32_MAX / b) + return NULL; + else if (a * b >= INT32_MAX / c) + return NULL; + else + return malloc (a * b * c); +} + +/* Random number generation */ +typedef uint32_t xorwow_state_t[5]; + +uint32_t +xorwow_next (xorwow_state_t *state) +{ + uint32_t s = (*state)[0], + t = (*state)[3]; + (*state)[3] = (*state)[2]; + (*state)[2] = (*state)[1]; + (*state)[1] = s; + + t ^= t >> 2; + t ^= t << 1; + t ^= s ^ (s << 4); + + (*state)[0] = t; + (*state)[4] += 362437; + + return t + (*state)[4]; +} + +float +xorwow_float (xorwow_state_t *s) +{ + return (xorwow_next (s) >> 9) / (float)((1 << 23) - 1); +} + +/* Floating point matrices + * + * Used to cache the cluster sizes. + */ +typedef struct matrix_t { + int width; + int height; + float *buffer; +} matrix_t; + +bool_t +matrix_init (matrix_t *matrix, int width, int height) +{ + float *buffer; + + if (!matrix) + return FALSE; + + buffer = malloc_abc (width, height, sizeof (float)); + + if (!buffer) + return FALSE; + + matrix->buffer = buffer; + matrix->width = width; + matrix->height = height; + + return TRUE; +} + +bool_t +matrix_copy (matrix_t *dst, matrix_t const *src) +{ + float *srcbuf = src->buffer, + *srcend = src->buffer + src->width * src->height, + *dstbuf = dst->buffer; + + if (dst->width != src->width || dst->height != src->height) + return FALSE; + + while (srcbuf < srcend) + *dstbuf++ = *srcbuf++; + + return TRUE; +} + +float * +matrix_get (matrix_t *matrix, int x, int y) +{ + return &matrix->buffer[y * matrix->width + x]; +} + +void +matrix_destroy (matrix_t *matrix) +{ + free (matrix->buffer); +} + +/* Binary patterns */ +typedef struct pattern_t { + int width; + int height; + bool_t *buffer; +} pattern_t; + +bool_t +pattern_init (pattern_t *pattern, int width, int height) +{ + bool_t *buffer; + + if (!pattern) + return FALSE; + + buffer = malloc_abc (width, height, sizeof (bool_t)); + + if (!buffer) + return FALSE; + + pattern->buffer = buffer; + pattern->width = width; + pattern->height = height; + + return TRUE; +} + +bool_t +pattern_copy (pattern_t *dst, pattern_t const *src) +{ + bool_t *srcbuf = src->buffer, + *srcend = src->buffer + src->width * src->height, + *dstbuf = dst->buffer; + + if (dst->width != src->width || dst->height != src->height) + return FALSE; + + while (srcbuf < srcend) + *dstbuf++ = *srcbuf++; + + return TRUE; +} + +bool_t * +pattern_get (pattern_t *pattern, int x, int y) +{ + return &pattern->buffer[y * pattern->width + x]; +} + +void +pattern_fill_white_noise (pattern_t *pattern, float fraction, + xorwow_state_t *s) +{ + bool_t *buffer = pattern->buffer; + bool_t *end = buffer + (pattern->width * pattern->height); + + while (buffer < end) + *buffer++ = xorwow_float (s) < fraction; +} + +void +pattern_destroy (pattern_t *pattern) +{ + free (pattern->buffer); +} + +/* Dither arrays */ +typedef struct array_t { + int width; + int height; + uint32_t *buffer; +} array_t; + +bool_t +array_init (array_t *array, int width, int height) +{ + uint32_t *buffer; + + if (!array) + return FALSE; + + buffer = malloc_abc (width, height, sizeof (uint32_t)); + + if (!buffer) + return FALSE; + + array->buffer = buffer; + array->width = width; + array->height = height; + + return TRUE; +} + +uint32_t * +array_get (array_t *array, int x, int y) +{ + return &array->buffer[y * array->width + x]; +} + +bool_t +array_save_ppm (array_t *array, const char *filename) +{ + FILE *f = fopen(filename, "wb"); + + int i = 0; + int bpp = 2; + uint8_t buffer[1024]; + + if (!f) + return FALSE; + + if (array->width * array->height - 1 < 256) + bpp = 1; + + fprintf(f, "P5 %d %d %d\n", array->width, array->height, + array->width * array->height - 1); + while (i < array->width * array->height) + { + int j = 0; + for (; j < 1024 / bpp && j < array->width * array->height; ++j) + { + uint32_t v = array->buffer[i + j]; + if (bpp == 2) + { + buffer[2 * j] = v & 0xff; + buffer[2 * j + 1] = (v & 0xff00) >> 8; + } else { + buffer[j] = v; + } + } + + fwrite((void *)buffer, bpp, j, f); + i += j; + } + + if (fclose(f) != 0) + return FALSE; + + return TRUE; +} + +bool_t +array_save (array_t *array, const char *filename) +{ + int x, y; + FILE *f = fopen(filename, "wb"); + + if (!f) + return FALSE; + + fprintf (f, +"/* WARNING: This file is generated by make-blue-noise.c\n" +" * Please edit that file instead of this one.\n" +" */\n" +"\n" +"#ifndef BLUE_NOISE_%dX%d_H\n" +"#define BLUE_NOISE_%dX%d_H\n" +"\n" +"#include <stdint.h>\n" +"\n", array->width, array->height, array->width, array->height); + + fprintf (f, "static const uint16_t dither_blue_noise_%dx%d[%d] = {\n", + array->width, array->height, array->width * array->height); + + for (y = 0; y < array->height; ++y) + { + fprintf (f, " "); + for (x = 0; x < array->width; ++x) + { + if (x != 0) + fprintf (f, ", "); + + fprintf (f, "%d", *array_get (array, x, y)); + } + + fprintf (f, ",\n"); + } + fprintf (f, "};\n"); + + fprintf (f, "\n#endif /* BLUE_NOISE_%dX%d_H */\n", + array->width, array->height); + + if (fclose(f) != 0) + return FALSE; + + return TRUE; +} + +void +array_destroy (array_t *array) +{ + free (array->buffer); +} + +/* Dither array generation */ +bool_t +compute_cluster_sizes (pattern_t *pattern, matrix_t *matrix) +{ + int width = pattern->width, + height = pattern->height; + + if (matrix->width != width || matrix->height != height) + return FALSE; + + int px, py, qx, qy, dx, dy; + float tsqsi = 2.f * 1.5f * 1.5f; + +#ifdef USE_OPENMP +#pragma omp parallel for default (none) \ + private (py, px, qy, qx, dx, dy) \ + shared (height, width, pattern, matrix, tsqsi) +#endif + for (py = 0; py < height; ++py) + { + for (px = 0; px < width; ++px) + { + bool_t pixel = *pattern_get (pattern, px, py); + float dist = 0.f; + + for (qx = 0; qx < width; ++qx) + { + dx = imin (abs (qx - px), width - abs (qx - px)); + dx = dx * dx; + + for (qy = 0; qy < height; ++qy) + { + dy = imin (abs (qy - py), height - abs (qy - py)); + dy = dy * dy; + + dist += (pixel == *pattern_get (pattern, qx, qy)) + * expf (- (dx + dy) / tsqsi); + } + } + + *matrix_get (matrix, px, py) = dist; + } + } + + return TRUE; +} + +bool_t +swap_pixel (pattern_t *pattern, matrix_t *matrix, int x, int y) +{ + int width = pattern->width, + height = pattern->height; + + bool_t new; + + float f, + dist = 0.f, + tsqsi = 2.f * 1.5f * 1.5f; + + int px, py, dx, dy; + bool_t b; + + new = !*pattern_get (pattern, x, y); + *pattern_get (pattern, x, y) = new; + + if (matrix->width != width || matrix->height != height) + return FALSE; + + +#ifdef USE_OPENMP +#pragma omp parallel for reduction (+:dist) default (none) \ + private (px, py, dx, dy, b, f) \ + shared (x, y, width, height, pattern, matrix, new, tsqsi) +#endif + for (py = 0; py < height; ++py) + { + dy = imin (abs (py - y), height - abs (py - y)); + dy = dy * dy; + + for (px = 0; px < width; ++px) + { + dx = imin (abs (px - x), width - abs (px - x)); + dx = dx * dx; + + b = (*pattern_get (pattern, px, py) == new); + f = expf (- (dx + dy) / tsqsi); + *matrix_get (matrix, px, py) += (2 * b - 1) * f; + + dist += b * f; + } + } + + *matrix_get (matrix, x, y) = dist; + return TRUE; +} + +void +largest_cluster (pattern_t *pattern, matrix_t *matrix, + bool_t pixel, int *xmax, int *ymax) +{ + int width = pattern->width, + height = pattern->height; + + int x, y; + + float vmax = -INFINITY; + +#ifdef USE_OPENMP +#pragma omp parallel default (none) \ + private (x, y) \ + shared (height, width, pattern, matrix, pixel, xmax, ymax, vmax) +#endif + { + int xbest = -1, + ybest = -1; + +#ifdef USE_OPENMP + float vbest = -INFINITY; + +#pragma omp for reduction (max: vmax) collapse (2) +#endif + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + { + if (*pattern_get (pattern, x, y) != pixel) + continue; + + if (*matrix_get (matrix, x, y) > vmax) + { + vmax = *matrix_get (matrix, x, y); +#ifdef USE_OPENMP + vbest = vmax; +#endif + xbest = x; + ybest = y; + } + } + } + +#ifdef USE_OPENMP +#pragma omp barrier +#pragma omp critical + { + if (vmax == vbest) + { + *xmax = xbest; + *ymax = ybest; + } + } +#else + *xmax = xbest; + *ymax = ybest; +#endif + } + + assert (vmax > -INFINITY); +} + +void +generate_initial_binary_pattern (pattern_t *pattern, matrix_t *matrix) +{ + int xcluster = 0, + ycluster = 0, + xvoid = 0, + yvoid = 0; + + for (;;) + { + largest_cluster (pattern, matrix, TRUE, &xcluster, &ycluster); + assert (*pattern_get (pattern, xcluster, ycluster) == TRUE); + swap_pixel (pattern, matrix, xcluster, ycluster); + + largest_cluster (pattern, matrix, FALSE, &xvoid, &yvoid); + assert (*pattern_get (pattern, xvoid, yvoid) == FALSE); + swap_pixel (pattern, matrix, xvoid, yvoid); + + if (xcluster == xvoid && ycluster == yvoid) + return; + } +} + +bool_t +generate_dither_array (array_t *array, + pattern_t const *prototype, matrix_t const *matrix, + pattern_t *temp_pattern, matrix_t *temp_matrix) +{ + int width = prototype->width, + height = prototype->height; + + int x, y, rank; + + int initial_rank = 0; + + if (array->width != width || array->height != height) + return FALSE; + + // Make copies of the prototype and associated sizes matrix since we will + // trash them + if (!pattern_copy (temp_pattern, prototype)) + return FALSE; + + if (!matrix_copy (temp_matrix, matrix)) + return FALSE; + + // Compute initial rank + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + { + if (*pattern_get (temp_pattern, x, y)) + initial_rank += 1; + + *array_get (array, x, y) = 0; + } + } + + // Phase 1 + for (rank = initial_rank; rank > 0; --rank) + { + largest_cluster (temp_pattern, temp_matrix, TRUE, &x, &y); + swap_pixel (temp_pattern, temp_matrix, x, y); + *array_get (array, x, y) = rank - 1; + } + + // Make copies again for phases 2 & 3 + if (!pattern_copy (temp_pattern, prototype)) + return FALSE; + + if (!matrix_copy (temp_matrix, matrix)) + return FALSE; + + // Phase 2 & 3 + for (rank = initial_rank; rank < width * height; ++rank) + { + largest_cluster (temp_pattern, temp_matrix, FALSE, &x, &y); + swap_pixel (temp_pattern, temp_matrix, x, y); + *array_get (array, x, y) = rank; + } + + return TRUE; +} + +bool_t +generate (int size, xorwow_state_t *s, + char const *c_filename, char const *ppm_filename) +{ + bool_t ok = TRUE; + + pattern_t prototype, temp_pattern; + array_t array; + matrix_t matrix, temp_matrix; + + printf ("Generating %dx%d blue noise...\n", size, size); + + if (!pattern_init (&prototype, size, size)) + return FALSE; + + if (!pattern_init (&temp_pattern, size, size)) + { + pattern_destroy (&prototype); + return FALSE; + } + + if (!matrix_init (&matrix, size, size)) + { + pattern_destroy (&temp_pattern); + pattern_destroy (&prototype); + return FALSE; + } + + if (!matrix_init (&temp_matrix, size, size)) + { + matrix_destroy (&matrix); + pattern_destroy (&temp_pattern); + pattern_destroy (&prototype); + return FALSE; + } + + if (!array_init (&array, size, size)) + { + matrix_destroy (&temp_matrix); + matrix_destroy (&matrix); + pattern_destroy (&temp_pattern); + pattern_destroy (&prototype); + return FALSE; + } + + printf("Filling initial binary pattern with white noise...\n"); + pattern_fill_white_noise (&prototype, .1, s); + + printf("Initializing cluster sizes...\n"); + if (!compute_cluster_sizes (&prototype, &matrix)) + { + fprintf (stderr, "Error while computing cluster sizes\n"); + ok = FALSE; + goto out; + } + + printf("Generating initial binary pattern...\n"); + generate_initial_binary_pattern (&prototype, &matrix); + + printf("Generating dither array...\n"); + if (!generate_dither_array (&array, &prototype, &matrix, + &temp_pattern, &temp_matrix)) + { + fprintf (stderr, "Error while generating dither array\n"); + ok = FALSE; + goto out; + } + + printf("Saving dither array...\n"); + if (!array_save (&array, c_filename)) + { + fprintf (stderr, "Error saving dither array\n"); + ok = FALSE; + goto out; + } + +#if SAVE_PPM + if (!array_save_ppm (&array, ppm_filename)) + { + fprintf (stderr, "Error saving dither array PPM\n"); + ok = FALSE; + goto out; + } +#else + (void)ppm_filename; +#endif + + printf("All done!\n"); + +out: + array_destroy (&array); + matrix_destroy (&temp_matrix); + matrix_destroy (&matrix); + pattern_destroy (&temp_pattern); + pattern_destroy (&prototype); + return ok; +} + +int +main (void) +{ + xorwow_state_t s = {1185956906, 12385940, 983948, 349208051, 901842}; + + if (!generate (64, &s, "blue-noise-64x64.h", "blue-noise-64x64.ppm")) + return -1; + + return 0; +} diff --git a/lib/pixman/pixman/loongson-mmintrin.h b/lib/pixman/pixman/loongson-mmintrin.h index 086c6e0f1..0e79e8648 100644 --- a/lib/pixman/pixman/loongson-mmintrin.h +++ b/lib/pixman/pixman/loongson-mmintrin.h @@ -209,12 +209,13 @@ _mm_set_pi16 (uint16_t __w3, uint16_t __w2, uint16_t __w1, uint16_t __w0) : "f" (*(__m64 *)&val), "f" (*(__m64 *)&imm) ); return ret; + } else { + uint64_t val = ((uint64_t)__w3 << 48) + | ((uint64_t)__w2 << 32) + | ((uint64_t)__w1 << 16) + | ((uint64_t)__w0 << 0); + return *(__m64 *)&val; } - uint64_t val = ((uint64_t)__w3 << 48) - | ((uint64_t)__w2 << 32) - | ((uint64_t)__w1 << 16) - | ((uint64_t)__w0 << 0); - return *(__m64 *)&val; } extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -236,10 +237,11 @@ _mm_set_pi32 (unsigned __i1, unsigned __i0) : "f" (*(__m32 *)&__i1), "f" (*(__m64 *)&imm) ); return ret; + } else { + uint64_t val = ((uint64_t)__i1 << 32) + | ((uint64_t)__i0 << 0); + return *(__m64 *)&val; } - uint64_t val = ((uint64_t)__i1 << 32) - | ((uint64_t)__i0 << 0); - return *(__m64 *)&val; } #undef _MM_SHUFFLE diff --git a/lib/pixman/pixman/meson.build b/lib/pixman/pixman/meson.build index 6ce87e7ad..f48357f26 100644 --- a/lib/pixman/pixman/meson.build +++ b/lib/pixman/pixman/meson.build @@ -30,6 +30,11 @@ version_h = configure_file( install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'pixman-1') ) +libpixman_extra_cargs = [] +if cc.has_function_attribute('dllexport') + libpixman_extra_cargs = ['-DPIXMAN_API=__declspec(dllexport)'] +endif + pixman_simd_libs = [] simds = [ # the mmx library can be compiled with mmx on x86/x86_64, iwmmxt on @@ -97,10 +102,18 @@ pixman_files = files( 'pixman-utils.c', ) -libpixman = shared_library( +# We cannot use 'link_with' or 'link_whole' because meson wont do the right +# thing for static archives. +_obs = [] +foreach l : pixman_simd_libs + _obs += l.extract_all_objects() +endforeach + +libpixman = library( 'pixman-1', [pixman_files, config_h, version_h], - link_with : [pixman_simd_libs], + objects : _obs, + c_args : libpixman_extra_cargs, dependencies : [dep_m, dep_threads], version : meson.project_version(), install : true, diff --git a/lib/pixman/pixman/pixman-access.c b/lib/pixman/pixman/pixman-access.c index 8dfd35f45..7c5ce783f 100644 --- a/lib/pixman/pixman/pixman-access.c +++ b/lib/pixman/pixman/pixman-access.c @@ -68,14 +68,14 @@ #ifdef WORDS_BIGENDIAN #define FETCH_24(img,l,o) \ - ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0)) + ((uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16) | \ + (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ + (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0)) #else #define FETCH_24(img,l,o) \ - ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16)) + ((uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0) | \ + (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ + (uint32_t)(READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16)) #endif /* Store macros */ @@ -87,7 +87,7 @@ uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \ uint32_t __m, __v; \ \ - __m = 1 << (0x1f - ((o) & 0x1f)); \ + __m = 1U << (0x1f - ((o) & 0x1f)); \ __v = (v)? __m : 0; \ \ WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \ @@ -100,7 +100,7 @@ uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \ uint32_t __m, __v; \ \ - __m = 1 << ((o) & 0x1f); \ + __m = 1U << ((o) & 0x1f); \ __v = (v)? __m : 0; \ \ WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \ @@ -1091,7 +1091,7 @@ store_scanline_a2r10g10b10_float (bits_image_t * image, for (i = 0; i < width; ++i) { - uint16_t a, r, g, b; + uint32_t a, r, g, b; a = pixman_float_to_unorm (values[i].a, 2); r = pixman_float_to_unorm (values[i].r, 10); @@ -1117,7 +1117,7 @@ store_scanline_x2r10g10b10_float (bits_image_t * image, for (i = 0; i < width; ++i) { - uint16_t r, g, b; + uint32_t r, g, b; r = pixman_float_to_unorm (values[i].r, 10); g = pixman_float_to_unorm (values[i].g, 10); @@ -1142,7 +1142,7 @@ store_scanline_a2b10g10r10_float (bits_image_t * image, for (i = 0; i < width; ++i) { - uint16_t a, r, g, b; + uint32_t a, r, g, b; a = pixman_float_to_unorm (values[i].a, 2); r = pixman_float_to_unorm (values[i].r, 10); @@ -1168,7 +1168,7 @@ store_scanline_x2b10g10r10_float (bits_image_t * image, for (i = 0; i < width; ++i) { - uint16_t r, g, b; + uint32_t r, g, b; r = pixman_float_to_unorm (values[i].r, 10); g = pixman_float_to_unorm (values[i].g, 10); @@ -1193,7 +1193,7 @@ store_scanline_a8r8g8b8_sRGB_float (bits_image_t * image, for (i = 0; i < width; ++i) { - uint8_t a, r, g, b; + uint32_t a, r, g, b; a = pixman_float_to_unorm (values[i].a, 8); r = to_srgb (values[i].r); @@ -1266,7 +1266,7 @@ fetch_scanline_a8r8g8b8_32_sRGB (bits_image_t *image, while (pixel < end) { - uint8_t a, r, g, b; + uint32_t a, r, g, b; tmp = READ (image, pixel++); @@ -1290,7 +1290,7 @@ fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image, { uint32_t *bits = image->bits + line * image->rowstride; uint32_t tmp = READ (image, bits + offset); - uint8_t a, r, g, b; + uint32_t a, r, g, b; a = (tmp >> 24) & 0xff; r = (tmp >> 16) & 0xff; @@ -1319,7 +1319,7 @@ store_scanline_a8r8g8b8_32_sRGB (bits_image_t *image, for (i = 0; i < width; ++i) { - uint8_t a, r, g, b; + uint32_t a, r, g, b; tmp = values[i]; diff --git a/lib/pixman/pixman/pixman-arm.c b/lib/pixman/pixman/pixman-arm.c index 23374e41c..4a2ae8539 100644 --- a/lib/pixman/pixman/pixman-arm.c +++ b/lib/pixman/pixman/pixman-arm.c @@ -176,6 +176,31 @@ detect_cpu_features (void) return features; } +#elif defined (_3DS) /* 3DS homebrew (devkitARM) */ + +static arm_cpu_features_t +detect_cpu_features (void) +{ + arm_cpu_features_t features = 0; + + features |= ARM_V6; + + return features; +} + +#elif defined (PSP2) || defined (__SWITCH__) +/* Vita (VitaSDK) or Switch (devkitA64) homebrew */ + +static arm_cpu_features_t +detect_cpu_features (void) +{ + arm_cpu_features_t features = 0; + + features |= ARM_NEON; + + return features; +} + #else /* Unknown */ static arm_cpu_features_t diff --git a/lib/pixman/pixman/pixman-bits-image.c b/lib/pixman/pixman/pixman-bits-image.c index 564789e9c..4cfabe318 100644 --- a/lib/pixman/pixman/pixman-bits-image.c +++ b/lib/pixman/pixman/pixman-bits-image.c @@ -35,6 +35,7 @@ #include "pixman-private.h" #include "pixman-combine32.h" #include "pixman-inlines.h" +#include "dither/blue-noise-64x64.h" /* Fetch functions */ @@ -190,8 +191,8 @@ bits_image_fetch_pixel_bilinear_float (bits_image_t *image, *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty); } -static force_inline void accum_32(int *satot, int *srtot, - int *sgtot, int *sbtot, +static force_inline void accum_32(unsigned int *satot, unsigned int *srtot, + unsigned int *sgtot, unsigned int *sbtot, const void *p, pixman_fixed_t f) { uint32_t pixel = *(uint32_t *)p; @@ -202,8 +203,9 @@ static force_inline void accum_32(int *satot, int *srtot, *satot += (int)ALPHA_8 (pixel) * f; } -static force_inline void reduce_32(int satot, int srtot, - int sgtot, int sbtot, void *p) +static force_inline void reduce_32(unsigned int satot, unsigned int srtot, + unsigned int sgtot, unsigned int sbtot, + void *p) { uint32_t *ret = p; @@ -220,8 +222,8 @@ static force_inline void reduce_32(int satot, int srtot, *ret = ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); } -static force_inline void accum_float(int *satot, int *srtot, - int *sgtot, int *sbtot, +static force_inline void accum_float(unsigned int *satot, unsigned int *srtot, + unsigned int *sgtot, unsigned int *sbtot, const void *p, pixman_fixed_t f) { const argb_t *pixel = p; @@ -232,8 +234,8 @@ static force_inline void accum_float(int *satot, int *srtot, *sbtot += pixel->b * f; } -static force_inline void reduce_float(int satot, int srtot, - int sgtot, int sbtot, +static force_inline void reduce_float(unsigned int satot, unsigned int srtot, + unsigned int sgtot, unsigned int sbtot, void *p) { argb_t *ret = p; @@ -244,12 +246,13 @@ static force_inline void reduce_float(int satot, int srtot, ret->b = CLIP (sbtot / 65536.f, 0.f, 1.f); } -typedef void (* accumulate_pixel_t) (int *satot, int *srtot, - int *sgtot, int *sbtot, +typedef void (* accumulate_pixel_t) (unsigned int *satot, unsigned int *srtot, + unsigned int *sgtot, unsigned int *sbtot, const void *pixel, pixman_fixed_t f); -typedef void (* reduce_pixel_t) (int satot, int srtot, - int sgtot, int sbtot, void *out); +typedef void (* reduce_pixel_t) (unsigned int satot, unsigned int srtot, + unsigned int sgtot, unsigned int sbtot, + void *out); static force_inline void bits_image_fetch_pixel_convolution (bits_image_t *image, @@ -269,7 +272,7 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, pixman_repeat_t repeat_mode = image->common.repeat; int width = image->width; int height = image->height; - int srtot, sgtot, sbtot, satot; + unsigned int srtot, sgtot, sbtot, satot; params += 2; @@ -338,7 +341,7 @@ bits_image_fetch_pixel_separable_convolution (bits_image_t *image, int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; pixman_fixed_t *y_params; - int srtot, sgtot, sbtot, satot; + unsigned int srtot, sgtot, sbtot, satot; int32_t x1, x2, y1, y2; int32_t px, py; int i, j; @@ -432,29 +435,38 @@ bits_image_fetch_pixel_filtered (bits_image_t *image, case PIXMAN_FILTER_CONVOLUTION: if (wide) + { bits_image_fetch_pixel_convolution (image, x, y, get_pixel, out, accum_float, reduce_float); + } else + { bits_image_fetch_pixel_convolution (image, x, y, get_pixel, out, accum_32, reduce_32); + } break; case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: if (wide) + { bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel, out, accum_float, reduce_float); + } else + { bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel, out, accum_32, reduce_32); + } break; default: + assert (0); break; } } @@ -662,8 +674,8 @@ __bits_image_fetch_general (pixman_iter_t *iter, { if (w != 0) { - x0 = ((pixman_fixed_48_16_t)x << 16) / w; - y0 = ((pixman_fixed_48_16_t)y << 16) / w; + x0 = ((uint64_t)x << 16) / w; + y0 = ((uint64_t)y << 16) / w; } else { @@ -1039,6 +1051,119 @@ dest_write_back_narrow (pixman_iter_t *iter) iter->y++; } +static const float +dither_factor_blue_noise_64 (int x, int y) +{ + float m = dither_blue_noise_64x64[((y & 0x3f) << 6) | (x & 0x3f)]; + return m * (1. / 4096.f) + (1. / 8192.f); +} + +static const float +dither_factor_bayer_8 (int x, int y) +{ + uint32_t m; + + y ^= x; + + /* Compute reverse(interleave(xor(x mod n, y mod n), x mod n)) + * Here n = 8 and `mod n` is the bottom 3 bits. + */ + m = ((y & 0x1) << 5) | ((x & 0x1) << 4) | + ((y & 0x2) << 2) | ((x & 0x2) << 1) | + ((y & 0x4) >> 1) | ((x & 0x4) >> 2); + + /* m is in range [0, 63]. We scale it to [0, 63.0f/64.0f], then + * shift it to to [1.0f/128.0f, 127.0f/128.0f] so that 0 < d < 1. + * This ensures exact values are not changed by dithering. + */ + return (float)(m) * (1 / 64.0f) + (1.0f / 128.0f); +} + +typedef float (* dither_factor_t)(int x, int y); + +static force_inline float +dither_apply_channel (float f, float d, float s) +{ + /* float_to_unorm splits the [0, 1] segment in (1 << n_bits) + * subsections of equal length; however unorm_to_float does not + * map to the center of those sections. In fact, pixel value u is + * mapped to: + * + * u u u 1 + * -------------- = ---------- + -------------- * ---------- + * 2^n_bits - 1 2^n_bits 2^n_bits - 1 2^n_bits + * + * Hence if f = u / (2^n_bits - 1) is exactly representable on a + * n_bits palette, all the numbers between + * + * u + * ---------- = f - f * 2^n_bits = f + (0 - f) * 2^n_bits + * 2^n_bits + * + * and + * + * u + 1 + * ---------- = f - (f - 1) * 2^n_bits = f + (1 - f) * 2^n_bits + * 2^n_bits + * + * are also mapped back to u. + * + * Hence the following calculation ensures that we add as much + * noise as possible without perturbing values which are exactly + * representable in the target colorspace. Note that this corresponds to + * mixing the original color with noise with a ratio of `1 / 2^n_bits`. + */ + return f + (d - f) * s; +} + +static force_inline float +dither_compute_scale (int n_bits) +{ + // No dithering for wide formats + if (n_bits == 0 || n_bits >= 32) + return 0.f; + + return 1.f / (float)(1 << n_bits); +} + +static const uint32_t * +dither_apply_ordered (pixman_iter_t *iter, dither_factor_t factor) +{ + bits_image_t *image = &iter->image->bits; + int x = iter->x + image->dither_offset_x; + int y = iter->y + image->dither_offset_y; + int width = iter->width; + argb_t *buffer = (argb_t *)iter->buffer; + + pixman_format_code_t format = image->format; + int a_size = PIXMAN_FORMAT_A (format); + int r_size = PIXMAN_FORMAT_R (format); + int g_size = PIXMAN_FORMAT_G (format); + int b_size = PIXMAN_FORMAT_B (format); + + float a_scale = dither_compute_scale (a_size); + float r_scale = dither_compute_scale (r_size); + float g_scale = dither_compute_scale (g_size); + float b_scale = dither_compute_scale (b_size); + + int i; + float d; + + for (i = 0; i < width; ++i) + { + d = factor (x + i, y); + + buffer->a = dither_apply_channel (buffer->a, d, a_scale); + buffer->r = dither_apply_channel (buffer->r, d, r_scale); + buffer->g = dither_apply_channel (buffer->g, d, g_scale); + buffer->b = dither_apply_channel (buffer->b, d, b_scale); + + buffer++; + } + + return iter->buffer; +} + static void dest_write_back_wide (pixman_iter_t *iter) { @@ -1048,6 +1173,23 @@ dest_write_back_wide (pixman_iter_t *iter) int width = iter->width; const uint32_t *buffer = iter->buffer; + switch (image->dither) + { + case PIXMAN_DITHER_NONE: + break; + + case PIXMAN_DITHER_GOOD: + case PIXMAN_DITHER_BEST: + case PIXMAN_DITHER_ORDERED_BLUE_NOISE_64: + buffer = dither_apply_ordered (iter, dither_factor_blue_noise_64); + break; + + case PIXMAN_DITHER_FAST: + case PIXMAN_DITHER_ORDERED_BAYER_8: + buffer = dither_apply_ordered (iter, dither_factor_bayer_8); + break; + } + image->store_scanline_float (image, x, y, width, buffer); if (image->common.alpha_map) @@ -1163,6 +1305,9 @@ _pixman_bits_image_init (pixman_image_t * image, image->bits.height = height; image->bits.bits = bits; image->bits.free_me = free_me; + image->bits.dither = PIXMAN_DITHER_NONE; + image->bits.dither_offset_x = 0; + image->bits.dither_offset_y = 0; image->bits.read_func = NULL; image->bits.write_func = NULL; image->bits.rowstride = rowstride; diff --git a/lib/pixman/pixman/pixman-combine32.c b/lib/pixman/pixman/pixman-combine32.c index 4c484d3e3..4a89384d9 100644 --- a/lib/pixman/pixman/pixman-combine32.c +++ b/lib/pixman/pixman/pixman-combine32.c @@ -568,7 +568,7 @@ combine_multiply_ca (pixman_implementation_t *imp, uint8_t isa = ~sa; \ uint8_t da = ALPHA_8 (d); \ uint8_t ida = ~da; \ - int32_t ra, rr, rg, rb; \ + uint32_t ra, rr, rg, rb; \ \ ra = da * 0xff + sa * 0xff - sa * da; \ rr = isa * RED_8 (d) + ida * RED_8 (s); \ @@ -609,7 +609,7 @@ combine_multiply_ca (pixman_implementation_t *imp, uint32_t d = *(dest + i); \ uint8_t da = ALPHA_8 (d); \ uint8_t ida = ~da; \ - int32_t ra, rr, rg, rb; \ + uint32_t ra, rr, rg, rb; \ uint8_t ira, iga, iba; \ \ combine_mask_ca (&s, &m); \ diff --git a/lib/pixman/pixman/pixman-combine32.h b/lib/pixman/pixman/pixman-combine32.h index cdd56a61a..59bb2477a 100644 --- a/lib/pixman/pixman/pixman-combine32.h +++ b/lib/pixman/pixman/pixman-combine32.h @@ -12,7 +12,7 @@ #define RB_MASK 0xff00ff #define AG_MASK 0xff00ff00 #define RB_ONE_HALF 0x800080 -#define RB_MASK_PLUS_ONE 0x10000100 +#define RB_MASK_PLUS_ONE 0x1000100 #define ALPHA_8(x) ((x) >> A_SHIFT) #define RED_8(x) (((x) >> R_SHIFT) & MASK) diff --git a/lib/pixman/pixman/pixman-compiler.h b/lib/pixman/pixman/pixman-compiler.h index 2489adc38..a02aa4936 100644 --- a/lib/pixman/pixman/pixman-compiler.h +++ b/lib/pixman/pixman/pixman-compiler.h @@ -95,6 +95,8 @@ /* Sun Studio 8 visibility */ #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) # define PIXMAN_EXPORT __global +#elif defined (_MSC_VER) || defined(__MINGW32__) +# define PIXMAN_EXPORT PIXMAN_API #else # define PIXMAN_EXPORT #endif diff --git a/lib/pixman/pixman/pixman-fast-path.c b/lib/pixman/pixman/pixman-fast-path.c index b4daa2657..4b7a6f897 100644 --- a/lib/pixman/pixman/pixman-fast-path.c +++ b/lib/pixman/pixman/pixman-fast-path.c @@ -908,7 +908,7 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp, #define CREATE_BITMASK(n) (0x80000000 >> (n)) #define UPDATE_BITMASK(n) ((n) >> 1) #else -#define CREATE_BITMASK(n) (1 << (n)) +#define CREATE_BITMASK(n) (1U << (n)) #define UPDATE_BITMASK(n) ((n) << 1) #endif @@ -2800,7 +2800,7 @@ bits_image_fetch_separable_convolution_affine (pixman_image_t * image, repeat (repeat_mode, &rx, bits->width); repeat (repeat_mode, &ry, bits->height); - row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; + row = (uint8_t *)(bits->bits + bits->rowstride * ry); pixel = convert_pixel (row, rx) | mask; } else @@ -2811,7 +2811,7 @@ bits_image_fetch_separable_convolution_affine (pixman_image_t * image, } else { - row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; + row = (uint8_t *)(bits->bits + bits->rowstride * ry); pixel = convert_pixel (row, rx) | mask; } } @@ -2913,8 +2913,8 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image, repeat (repeat_mode, &x2, width); repeat (repeat_mode, &y2, height); - row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; - row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; + row1 = (uint8_t *)(bits->bits + bits->rowstride * y1); + row2 = (uint8_t *)(bits->bits + bits->rowstride * y2); tl = convert_pixel (row1, x1) | mask; tr = convert_pixel (row1, x2) | mask; @@ -2949,7 +2949,7 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image, } else { - row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; + row1 = (uint8_t *)(bits->bits + bits->rowstride * y1); row1 += bpp / 8 * x1; mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; @@ -2962,7 +2962,7 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image, } else { - row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; + row2 = (uint8_t *)(bits->bits + bits->rowstride * y2); row2 += bpp / 8 * x1; mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; @@ -3060,7 +3060,7 @@ bits_image_fetch_nearest_affine (pixman_image_t * image, repeat (repeat_mode, &y0, height); } - row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0; + row = (uint8_t *)(bits->bits + bits->rowstride * y0); buffer[i] = convert_pixel (row, x0) | mask; } @@ -3086,7 +3086,7 @@ convert_x8r8g8b8 (const uint8_t *row, int x) static force_inline uint32_t convert_a8 (const uint8_t *row, int x) { - return *(row + x) << 24; + return (uint32_t) *(row + x) << 24; } static force_inline uint32_t diff --git a/lib/pixman/pixman/pixman-general.c b/lib/pixman/pixman/pixman-general.c index 6141cb0a3..7e5a0d09c 100644 --- a/lib/pixman/pixman/pixman-general.c +++ b/lib/pixman/pixman/pixman-general.c @@ -141,7 +141,8 @@ general_composite_rect (pixman_implementation_t *imp, if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && (dest_image->common.flags & FAST_PATH_NARROW_FORMAT) && - !(operator_needs_division (op))) + !(operator_needs_division (op)) && + (dest_image->bits.dither == PIXMAN_DITHER_NONE)) { width_flag = ITER_NARROW; Bpp = 4; @@ -164,6 +165,12 @@ general_composite_rect (pixman_implementation_t *imp, if (!scanline_buffer) return; + + memset (scanline_buffer, 0, width * Bpp * 3 + 15 * 3); + } + else + { + memset (stack_scanline_buffer, 0, sizeof (stack_scanline_buffer)); } src_buffer = ALIGN (scanline_buffer); diff --git a/lib/pixman/pixman/pixman-gradient-walker.c b/lib/pixman/pixman/pixman-gradient-walker.c index af4df586b..fb7f401da 100644 --- a/lib/pixman/pixman/pixman-gradient-walker.c +++ b/lib/pixman/pixman/pixman-gradient-walker.c @@ -213,10 +213,10 @@ pixman_gradient_walker_pixel_32 (pixman_gradient_walker_t *walker, f.g = f.a * (walker->g_s * y + walker->g_b); f.b = f.a * (walker->b_s * y + walker->b_b); - return (((uint8_t)(f.a + .5f) << 24) & 0xff000000) | - (((uint8_t)(f.r + .5f) << 16) & 0x00ff0000) | - (((uint8_t)(f.g + .5f) << 8) & 0x0000ff00) | - (((uint8_t)(f.b + .5f) >> 0) & 0x000000ff); + return (((uint32_t)(f.a + .5f) << 24) & 0xff000000) | + (((uint32_t)(f.r + .5f) << 16) & 0x00ff0000) | + (((uint32_t)(f.g + .5f) << 8) & 0x0000ff00) | + (((uint32_t)(f.b + .5f) >> 0) & 0x000000ff); } void diff --git a/lib/pixman/pixman/pixman-image.c b/lib/pixman/pixman/pixman-image.c index 7a851e221..db29ff5b4 100644 --- a/lib/pixman/pixman/pixman-image.c +++ b/lib/pixman/pixman/pixman-image.c @@ -684,6 +684,41 @@ pixman_image_set_repeat (pixman_image_t *image, image_property_changed (image); } +PIXMAN_EXPORT void +pixman_image_set_dither (pixman_image_t *image, + pixman_dither_t dither) +{ + if (image->type == BITS) + { + if (image->bits.dither == dither) + return; + + image->bits.dither = dither; + + image_property_changed (image); + } +} + +PIXMAN_EXPORT void +pixman_image_set_dither_offset (pixman_image_t *image, + int offset_x, + int offset_y) +{ + if (image->type == BITS) + { + if (image->bits.dither_offset_x == offset_x && + image->bits.dither_offset_y == offset_y) + { + return; + } + + image->bits.dither_offset_x = offset_x; + image->bits.dither_offset_y = offset_y; + + image_property_changed (image); + } +} + PIXMAN_EXPORT pixman_bool_t pixman_image_set_filter (pixman_image_t * image, pixman_filter_t filter, @@ -925,7 +960,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp, else if (image->bits.format == PIXMAN_x8r8g8b8) result = image->bits.bits[0] | 0xff000000; else if (image->bits.format == PIXMAN_a8) - result = (*(uint8_t *)image->bits.bits) << 24; + result = (uint32_t)(*(uint8_t *)image->bits.bits) << 24; else goto otherwise; } diff --git a/lib/pixman/pixman/pixman-inlines.h b/lib/pixman/pixman/pixman-inlines.h index 332e20814..f785910f8 100644 --- a/lib/pixman/pixman/pixman-inlines.h +++ b/lib/pixman/pixman/pixman-inlines.h @@ -231,7 +231,7 @@ bilinear_interpolation_float (argb_t tl, argb_t tr, argb_t r; distxy = distx * disty; - distxiy = distx - (1.f - distxy); + distxiy = distx * (1.f - disty); distixy = (1.f - distx) * disty; distixiy = (1.f - distx) * (1.f - disty); diff --git a/lib/pixman/pixman/pixman-matrix.c b/lib/pixman/pixman/pixman-matrix.c index 4032c137a..81b6e613e 100644 --- a/lib/pixman/pixman/pixman-matrix.c +++ b/lib/pixman/pixman/pixman-matrix.c @@ -273,7 +273,7 @@ pixman_transform_point_31_16 (const pixman_transform_t *t, { /* the divisor is small, we can actually keep all the bits */ int64_t hi, rhi, lo, rlo; - int64_t div = (divint << 16) + divfrac; + int64_t div = ((uint64_t)divint << 16) + divfrac; fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32); rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); diff --git a/lib/pixman/pixman/pixman-mmx.c b/lib/pixman/pixman/pixman-mmx.c index dec397432..d7cf2659d 100644 --- a/lib/pixman/pixman/pixman-mmx.c +++ b/lib/pixman/pixman/pixman-mmx.c @@ -387,8 +387,10 @@ in_over (__m64 src, __m64 srca, __m64 mask, __m64 dest) static force_inline __m64 ldq_u(__m64 *p) { #ifdef USE_X86_MMX - /* x86's alignment restrictions are very relaxed. */ - return *(__m64 *)p; + /* x86's alignment restrictions are very relaxed, but that's no excuse */ + __m64 r; + memcpy(&r, p, sizeof(__m64)); + return r; #elif defined USE_ARM_IWMMXT int align = (uintptr_t)p & 7; __m64 *aligned_p; @@ -407,7 +409,9 @@ static force_inline uint32_t ldl_u(const uint32_t *p) { #ifdef USE_X86_MMX /* x86's alignment restrictions are very relaxed. */ - return *p; + uint32_t r; + memcpy(&r, p, sizeof(uint32_t)); + return r; #else struct __una_u32 { uint32_t x __attribute__((packed)); }; const struct __una_u32 *ptr = (const struct __una_u32 *) p; @@ -3950,7 +3954,7 @@ mmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) while (w && (((uintptr_t)dst) & 15)) { - *dst++ = *(src++) << 24; + *dst++ = (uint32_t)*(src++) << 24; w--; } @@ -3977,7 +3981,7 @@ mmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) while (w) { - *dst++ = *(src++) << 24; + *dst++ = (uint32_t)*(src++) << 24; w--; } diff --git a/lib/pixman/pixman/pixman-private.h b/lib/pixman/pixman/pixman-private.h index 1bd969591..d836cc5b4 100644 --- a/lib/pixman/pixman/pixman-private.h +++ b/lib/pixman/pixman/pixman-private.h @@ -180,6 +180,10 @@ struct bits_image uint32_t * free_me; int rowstride; /* in number of uint32_t's */ + pixman_dither_t dither; + uint32_t dither_offset_y; + uint32_t dither_offset_x; + fetch_scanline_t fetch_scanline_32; fetch_pixel_32_t fetch_pixel_32; store_scanline_t store_scanline_32; @@ -1102,16 +1106,19 @@ _pixman_log_error (const char *function, const char *message); typedef struct { pixman_fixed_48_16_t v[3]; } pixman_vector_48_16_t; +PIXMAN_EXPORT pixman_bool_t pixman_transform_point_31_16 (const pixman_transform_t *t, const pixman_vector_48_16_t *v, pixman_vector_48_16_t *result); +PIXMAN_EXPORT void pixman_transform_point_31_16_3d (const pixman_transform_t *t, const pixman_vector_48_16_t *v, pixman_vector_48_16_t *result); +PIXMAN_EXPORT void pixman_transform_point_31_16_affine (const pixman_transform_t *t, const pixman_vector_48_16_t *v, diff --git a/lib/pixman/pixman/pixman-sse2.c b/lib/pixman/pixman/pixman-sse2.c index 895510372..2644b0a62 100644 --- a/lib/pixman/pixman/pixman-sse2.c +++ b/lib/pixman/pixman/pixman-sse2.c @@ -518,7 +518,8 @@ core_combine_over_u_pixel_sse2 (uint32_t src, uint32_t dst) static force_inline uint32_t combine1 (const uint32_t *ps, const uint32_t *pm) { - uint32_t s = *ps; + uint32_t s; + memcpy(&s, ps, sizeof(uint32_t)); if (pm) { @@ -3256,7 +3257,7 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp, while (w >= 4) { - m = *((uint32_t*)mask); + memcpy(&m, mask, sizeof(uint32_t)); if (srca == 0xff && m == 0xffffffff) { @@ -3333,8 +3334,8 @@ sse2_fill (pixman_implementation_t *imp, if (bpp == 8) { - uint8_t b; - uint16_t w; + uint32_t b; + uint32_t w; stride = stride * (int) sizeof (uint32_t) / 1; byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x); @@ -3528,7 +3529,7 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp, while (w >= 4) { - m = *((uint32_t*)mask); + memcpy(&m, mask, sizeof(uint32_t)); if (srca == 0xff && m == 0xffffffff) { @@ -3650,7 +3651,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, unpack_565_128_4x128 (xmm_dst, &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - m = *((uint32_t*)mask); + memcpy(&m, mask, sizeof(uint32_t)); mask += 4; if (m) @@ -3670,7 +3671,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, &xmm_dst0, &xmm_dst1); } - m = *((uint32_t*)mask); + memcpy(&m, mask, sizeof(uint32_t)); mask += 4; if (m) @@ -4636,7 +4637,9 @@ sse2_composite_add_n_8_8888 (pixman_implementation_t *imp, while (w >= 4) { - uint32_t m = *(uint32_t*)mask; + uint32_t m; + memcpy(&m, mask, sizeof(uint32_t)); + if (m) { __m128i xmm_mask_lo, xmm_mask_hi; @@ -4743,7 +4746,7 @@ sse2_blt (pixman_implementation_t *imp, while (w >= 2 && ((uintptr_t)d & 3)) { - *(uint16_t *)d = *(uint16_t *)s; + memmove(d, s, 2); w -= 2; s += 2; d += 2; @@ -4751,7 +4754,7 @@ sse2_blt (pixman_implementation_t *imp, while (w >= 4 && ((uintptr_t)d & 15)) { - *(uint32_t *)d = *(uint32_t *)s; + memmove(d, s, 4); w -= 4; s += 4; @@ -4788,7 +4791,7 @@ sse2_blt (pixman_implementation_t *imp, while (w >= 4) { - *(uint32_t *)d = *(uint32_t *)s; + memmove(d, s, 4); w -= 4; s += 4; @@ -4797,7 +4800,7 @@ sse2_blt (pixman_implementation_t *imp, if (w >= 2) { - *(uint16_t *)d = *(uint16_t *)s; + memmove(d, s, 2); w -= 2; s += 2; d += 2; @@ -4859,7 +4862,7 @@ sse2_composite_over_x888_8_8888 (pixman_implementation_t *imp, while (w && (uintptr_t)dst & 15) { s = 0xff000000 | *src++; - m = (uint32_t) *mask++; + memcpy(&m, mask++, sizeof(uint32_t)); d = *dst; ms = unpack_32_1x128 (s); @@ -4877,7 +4880,7 @@ sse2_composite_over_x888_8_8888 (pixman_implementation_t *imp, while (w >= 4) { - m = *(uint32_t*) mask; + memcpy(&m, mask, sizeof(uint32_t)); xmm_src = _mm_or_si128 ( load_128_unaligned ((__m128i*)src), mask_ff000000); @@ -4913,7 +4916,7 @@ sse2_composite_over_x888_8_8888 (pixman_implementation_t *imp, while (w) { - m = (uint32_t) *mask++; + memcpy(&m, mask++, sizeof(uint32_t)); if (m) { @@ -5016,7 +5019,7 @@ sse2_composite_over_8888_8_8888 (pixman_implementation_t *imp, while (w >= 4) { - m = *(uint32_t *) mask; + memcpy(&m, mask, sizeof(uint32_t)); if (m) { @@ -5970,7 +5973,7 @@ scaled_bilinear_scanline_sse2_8888_8_8888_OVER (uint32_t * dst, __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - m = *(uint32_t*)mask; + memcpy(&m, mask, sizeof(uint32_t)); if (m) { @@ -6410,7 +6413,7 @@ sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) while (w && (((uintptr_t)dst) & 15)) { - *dst++ = *(src++) << 24; + *dst++ = (uint32_t)(*(src++)) << 24; w--; } @@ -6437,7 +6440,7 @@ sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) while (w) { - *dst++ = *(src++) << 24; + *dst++ = (uint32_t)(*(src++)) << 24; w--; } diff --git a/lib/pixman/pixman/pixman-utils.c b/lib/pixman/pixman/pixman-utils.c index 4a3a835c4..2c2dddd64 100644 --- a/lib/pixman/pixman/pixman-utils.c +++ b/lib/pixman/pixman/pixman-utils.c @@ -206,7 +206,7 @@ pixman_contract_from_float (uint32_t *dst, for (i = 0; i < width; ++i) { - uint8_t a, r, g, b; + uint32_t a, r, g, b; a = float_to_unorm (src[i].a, 8); r = float_to_unorm (src[i].r, 8); diff --git a/lib/pixman/pixman/pixman-version.h.in b/lib/pixman/pixman/pixman-version.h.in index 256b2e6f1..64778a595 100644 --- a/lib/pixman/pixman/pixman-version.h.in +++ b/lib/pixman/pixman/pixman-version.h.in @@ -47,4 +47,8 @@ PIXMAN_VERSION_MINOR, \ PIXMAN_VERSION_MICRO) +#ifndef PIXMAN_API +# define PIXMAN_API +#endif + #endif /* PIXMAN_VERSION_H__ */ diff --git a/lib/pixman/pixman/pixman-x86.c b/lib/pixman/pixman/pixman-x86.c index 05297c476..0130b7bfa 100644 --- a/lib/pixman/pixman/pixman-x86.c +++ b/lib/pixman/pixman/pixman-x86.c @@ -187,6 +187,7 @@ detect_cpu_features (void) memcpy (vendor + 8, &c, 4); if (strcmp (vendor, "AuthenticAMD") == 0 || + strcmp (vendor, "HygonGenuine") == 0 || strcmp (vendor, "Geode by NSC") == 0) { pixman_cpuid (0x80000000, &a, &b, &c, &d); diff --git a/lib/pixman/pixman/pixman.h b/lib/pixman/pixman/pixman.h index d644589d6..08303b549 100644 --- a/lib/pixman/pixman/pixman.h +++ b/lib/pixman/pixman/pixman.h @@ -127,7 +127,7 @@ typedef pixman_fixed_16_16_t pixman_fixed_t; #define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e) #define pixman_fixed_minus_1 (pixman_int_to_fixed(-1)) #define pixman_fixed_to_int(f) ((int) ((f) >> 16)) -#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16)) +#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((uint32_t) (i) << 16)) #define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1) #define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0)) #define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e) @@ -184,42 +184,73 @@ struct pixman_transform struct pixman_box16; typedef union pixman_image pixman_image_t; +PIXMAN_API void pixman_transform_init_identity (struct pixman_transform *matrix); + +PIXMAN_API pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform, struct pixman_vector *vector); + +PIXMAN_API pixman_bool_t pixman_transform_point (const struct pixman_transform *transform, struct pixman_vector *vector); + +PIXMAN_API pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst, const struct pixman_transform *l, const struct pixman_transform *r); + +PIXMAN_API void pixman_transform_init_scale (struct pixman_transform *t, pixman_fixed_t sx, pixman_fixed_t sy); + +PIXMAN_API pixman_bool_t pixman_transform_scale (struct pixman_transform *forward, struct pixman_transform *reverse, pixman_fixed_t sx, pixman_fixed_t sy); + +PIXMAN_API void pixman_transform_init_rotate (struct pixman_transform *t, pixman_fixed_t cos, pixman_fixed_t sin); + +PIXMAN_API pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward, struct pixman_transform *reverse, pixman_fixed_t c, pixman_fixed_t s); + +PIXMAN_API void pixman_transform_init_translate (struct pixman_transform *t, pixman_fixed_t tx, pixman_fixed_t ty); + +PIXMAN_API pixman_bool_t pixman_transform_translate (struct pixman_transform *forward, struct pixman_transform *reverse, pixman_fixed_t tx, pixman_fixed_t ty); + +PIXMAN_API pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix, struct pixman_box16 *b); + +PIXMAN_API pixman_bool_t pixman_transform_invert (struct pixman_transform *dst, const struct pixman_transform *src); + +PIXMAN_API pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t); + +PIXMAN_API pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t); + +PIXMAN_API pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t); + +PIXMAN_API pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a, const struct pixman_transform *b); @@ -239,42 +270,70 @@ struct pixman_f_transform double m[3][3]; }; + +PIXMAN_API pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t, const struct pixman_f_transform *ft); + +PIXMAN_API void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft, const struct pixman_transform *t); + +PIXMAN_API pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst, const struct pixman_f_transform *src); + +PIXMAN_API pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t, struct pixman_f_vector *v); + +PIXMAN_API void pixman_f_transform_point_3d (const struct pixman_f_transform *t, struct pixman_f_vector *v); + +PIXMAN_API void pixman_f_transform_multiply (struct pixman_f_transform *dst, const struct pixman_f_transform *l, const struct pixman_f_transform *r); + +PIXMAN_API void pixman_f_transform_init_scale (struct pixman_f_transform *t, double sx, double sy); + +PIXMAN_API pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward, struct pixman_f_transform *reverse, double sx, double sy); + +PIXMAN_API void pixman_f_transform_init_rotate (struct pixman_f_transform *t, double cos, double sin); + +PIXMAN_API pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward, struct pixman_f_transform *reverse, double c, double s); + +PIXMAN_API void pixman_f_transform_init_translate (struct pixman_f_transform *t, double tx, double ty); + +PIXMAN_API pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward, struct pixman_f_transform *reverse, double tx, double ty); + +PIXMAN_API pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t, struct pixman_box16 *b); + +PIXMAN_API void pixman_f_transform_init_identity (struct pixman_f_transform *t); typedef enum @@ -287,6 +346,16 @@ typedef enum typedef enum { + PIXMAN_DITHER_NONE, + PIXMAN_DITHER_FAST, + PIXMAN_DITHER_GOOD, + PIXMAN_DITHER_BEST, + PIXMAN_DITHER_ORDERED_BAYER_8, + PIXMAN_DITHER_ORDERED_BLUE_NOISE_64, +} pixman_dither_t; + +typedef enum +{ PIXMAN_FILTER_FAST, PIXMAN_FILTER_GOOD, PIXMAN_FILTER_BEST, @@ -423,73 +492,120 @@ typedef enum /* This function exists only to make it possible to preserve * the X ABI - it should go away at first opportunity. */ +PIXMAN_API void pixman_region_set_static_pointers (pixman_box16_t *empty_box, pixman_region16_data_t *empty_data, pixman_region16_data_t *broken_data); /* creation/destruction */ +PIXMAN_API void pixman_region_init (pixman_region16_t *region); + +PIXMAN_API void pixman_region_init_rect (pixman_region16_t *region, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region_init_rects (pixman_region16_t *region, const pixman_box16_t *boxes, int count); + +PIXMAN_API void pixman_region_init_with_extents (pixman_region16_t *region, pixman_box16_t *extents); + +PIXMAN_API void pixman_region_init_from_image (pixman_region16_t *region, pixman_image_t *image); + +PIXMAN_API void pixman_region_fini (pixman_region16_t *region); /* manipulation */ +PIXMAN_API void pixman_region_translate (pixman_region16_t *region, int x, int y); + +PIXMAN_API pixman_bool_t pixman_region_copy (pixman_region16_t *dest, pixman_region16_t *source); + +PIXMAN_API pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg, pixman_region16_t *reg1, pixman_region16_t *reg2); + +PIXMAN_API pixman_bool_t pixman_region_union (pixman_region16_t *new_reg, pixman_region16_t *reg1, pixman_region16_t *reg2); + +PIXMAN_API pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest, pixman_region16_t *source, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest, pixman_region16_t *source, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d, pixman_region16_t *reg_m, pixman_region16_t *reg_s); + +PIXMAN_API pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg, pixman_region16_t *reg1, pixman_box16_t *inv_rect); + +PIXMAN_API pixman_bool_t pixman_region_contains_point (pixman_region16_t *region, int x, int y, pixman_box16_t *box); + +PIXMAN_API pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region, pixman_box16_t *prect); + +PIXMAN_API pixman_bool_t pixman_region_not_empty (pixman_region16_t *region); + +PIXMAN_API pixman_box16_t * pixman_region_extents (pixman_region16_t *region); + +PIXMAN_API int pixman_region_n_rects (pixman_region16_t *region); + +PIXMAN_API pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region, int *n_rects); + +PIXMAN_API pixman_bool_t pixman_region_equal (pixman_region16_t *region1, pixman_region16_t *region2); + +PIXMAN_API pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region); + +PIXMAN_API void pixman_region_reset (pixman_region16_t *region, pixman_box16_t *box); + +PIXMAN_API void pixman_region_clear (pixman_region16_t *region); /* * 32 bit regions @@ -523,72 +639,119 @@ struct pixman_region32 }; /* creation/destruction */ +PIXMAN_API void pixman_region32_init (pixman_region32_t *region); + +PIXMAN_API void pixman_region32_init_rect (pixman_region32_t *region, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region, const pixman_box32_t *boxes, int count); + +PIXMAN_API void pixman_region32_init_with_extents (pixman_region32_t *region, pixman_box32_t *extents); + +PIXMAN_API void pixman_region32_init_from_image (pixman_region32_t *region, pixman_image_t *image); + +PIXMAN_API void pixman_region32_fini (pixman_region32_t *region); /* manipulation */ +PIXMAN_API void pixman_region32_translate (pixman_region32_t *region, int x, int y); + +PIXMAN_API pixman_bool_t pixman_region32_copy (pixman_region32_t *dest, pixman_region32_t *source); + +PIXMAN_API pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg, pixman_region32_t *reg1, pixman_region32_t *reg2); + +PIXMAN_API pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg, pixman_region32_t *reg1, pixman_region32_t *reg2); + +PIXMAN_API pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest, pixman_region32_t *source, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest, pixman_region32_t *source, int x, int y, unsigned int width, unsigned int height); + +PIXMAN_API pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d, pixman_region32_t *reg_m, pixman_region32_t *reg_s); + +PIXMAN_API pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg, pixman_region32_t *reg1, pixman_box32_t *inv_rect); + +PIXMAN_API pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region, int x, int y, pixman_box32_t *box); + +PIXMAN_API pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region, pixman_box32_t *prect); + +PIXMAN_API pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region); + +PIXMAN_API pixman_box32_t * pixman_region32_extents (pixman_region32_t *region); + +PIXMAN_API int pixman_region32_n_rects (pixman_region32_t *region); + +PIXMAN_API pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region, int *n_rects); + +PIXMAN_API pixman_bool_t pixman_region32_equal (pixman_region32_t *region1, pixman_region32_t *region2); + +PIXMAN_API pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region); + +PIXMAN_API void pixman_region32_reset (pixman_region32_t *region, pixman_box32_t *box); + +PIXMAN_API void pixman_region32_clear (pixman_region32_t *region); /* Copy / Fill / Misc */ +PIXMAN_API pixman_bool_t pixman_blt (uint32_t *src_bits, uint32_t *dst_bits, int src_stride, @@ -601,6 +764,8 @@ pixman_bool_t pixman_blt (uint32_t *src_bits, int dest_y, int width, int height); + +PIXMAN_API pixman_bool_t pixman_fill (uint32_t *bits, int stride, int bpp, @@ -610,7 +775,11 @@ pixman_bool_t pixman_fill (uint32_t *bits, int height, uint32_t _xor); + +PIXMAN_API int pixman_version (void); + +PIXMAN_API const char* pixman_version_string (void); /* @@ -776,30 +945,44 @@ typedef enum { } pixman_format_code_t; /* Querying supported format values. */ +PIXMAN_API pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format); + +PIXMAN_API pixman_bool_t pixman_format_supported_source (pixman_format_code_t format); /* Constructors */ +PIXMAN_API pixman_image_t *pixman_image_create_solid_fill (const pixman_color_t *color); + +PIXMAN_API pixman_image_t *pixman_image_create_linear_gradient (const pixman_point_fixed_t *p1, const pixman_point_fixed_t *p2, const pixman_gradient_stop_t *stops, int n_stops); + +PIXMAN_API pixman_image_t *pixman_image_create_radial_gradient (const pixman_point_fixed_t *inner, const pixman_point_fixed_t *outer, pixman_fixed_t inner_radius, pixman_fixed_t outer_radius, const pixman_gradient_stop_t *stops, int n_stops); + +PIXMAN_API pixman_image_t *pixman_image_create_conical_gradient (const pixman_point_fixed_t *center, pixman_fixed_t angle, const pixman_gradient_stop_t *stops, int n_stops); + +PIXMAN_API pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, int width, int height, uint32_t *bits, int rowstride_bytes); + +PIXMAN_API pixman_image_t *pixman_image_create_bits_no_clear (pixman_format_code_t format, int width, int height, @@ -807,48 +990,99 @@ pixman_image_t *pixman_image_create_bits_no_clear (pixman_format_code_t forma int rowstride_bytes); /* Destructor */ +PIXMAN_API pixman_image_t *pixman_image_ref (pixman_image_t *image); + +PIXMAN_API pixman_bool_t pixman_image_unref (pixman_image_t *image); + +PIXMAN_API void pixman_image_set_destroy_function (pixman_image_t *image, pixman_image_destroy_func_t function, void *data); + +PIXMAN_API void * pixman_image_get_destroy_data (pixman_image_t *image); /* Set properties */ +PIXMAN_API pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image, pixman_region16_t *region); + +PIXMAN_API pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image, pixman_region32_t *region); + +PIXMAN_API void pixman_image_set_has_client_clip (pixman_image_t *image, pixman_bool_t clien_clip); + +PIXMAN_API pixman_bool_t pixman_image_set_transform (pixman_image_t *image, const pixman_transform_t *transform); + +PIXMAN_API void pixman_image_set_repeat (pixman_image_t *image, pixman_repeat_t repeat); + +PIXMAN_API +void pixman_image_set_dither (pixman_image_t *image, + pixman_dither_t dither); + +PIXMAN_API +void pixman_image_set_dither_offset (pixman_image_t *image, + int offset_x, + int offset_y); + +PIXMAN_API pixman_bool_t pixman_image_set_filter (pixman_image_t *image, pixman_filter_t filter, const pixman_fixed_t *filter_params, int n_filter_params); + +PIXMAN_API void pixman_image_set_source_clipping (pixman_image_t *image, pixman_bool_t source_clipping); + +PIXMAN_API void pixman_image_set_alpha_map (pixman_image_t *image, pixman_image_t *alpha_map, int16_t x, int16_t y); + +PIXMAN_API void pixman_image_set_component_alpha (pixman_image_t *image, pixman_bool_t component_alpha); + +PIXMAN_API pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image); + +PIXMAN_API void pixman_image_set_accessors (pixman_image_t *image, pixman_read_memory_func_t read_func, pixman_write_memory_func_t write_func); + +PIXMAN_API void pixman_image_set_indexed (pixman_image_t *image, const pixman_indexed_t *indexed); + +PIXMAN_API uint32_t *pixman_image_get_data (pixman_image_t *image); + +PIXMAN_API int pixman_image_get_width (pixman_image_t *image); + +PIXMAN_API int pixman_image_get_height (pixman_image_t *image); + +PIXMAN_API int pixman_image_get_stride (pixman_image_t *image); /* in bytes */ + +PIXMAN_API int pixman_image_get_depth (pixman_image_t *image); + +PIXMAN_API pixman_format_code_t pixman_image_get_format (pixman_image_t *image); typedef enum @@ -866,6 +1100,7 @@ typedef enum /* Create the parameter list for a SEPARABLE_CONVOLUTION filter * with the given kernels and scale parameters. */ +PIXMAN_API pixman_fixed_t * pixman_filter_create_separable_convolution (int *n_values, pixman_fixed_t scale_x, @@ -877,11 +1112,15 @@ pixman_filter_create_separable_convolution (int *n_values, int subsample_bits_x, int subsample_bits_y); + +PIXMAN_API pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op, pixman_image_t *image, const pixman_color_t *color, int n_rects, const pixman_rectangle16_t *rects); + +PIXMAN_API pixman_bool_t pixman_image_fill_boxes (pixman_op_t op, pixman_image_t *dest, const pixman_color_t *color, @@ -889,6 +1128,7 @@ pixman_bool_t pixman_image_fill_boxes (pixman_op_t const pixman_box32_t *boxes); /* Composite */ +PIXMAN_API pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region, pixman_image_t *src_image, pixman_image_t *mask_image, @@ -901,6 +1141,8 @@ pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region, int16_t dest_y, uint16_t width, uint16_t height); + +PIXMAN_API void pixman_image_composite (pixman_op_t op, pixman_image_t *src, pixman_image_t *mask, @@ -913,6 +1155,8 @@ void pixman_image_composite (pixman_op_t op, int16_t dest_y, uint16_t width, uint16_t height); + +PIXMAN_API void pixman_image_composite32 (pixman_op_t op, pixman_image_t *src, pixman_image_t *mask, @@ -944,6 +1188,7 @@ void pixman_image_composite32 (pixman_op_t op, * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this * function is a no-op. */ +PIXMAN_API void pixman_disable_out_of_bounds_workaround (void); /* @@ -956,29 +1201,48 @@ typedef struct const void *glyph; } pixman_glyph_t; +PIXMAN_API pixman_glyph_cache_t *pixman_glyph_cache_create (void); + +PIXMAN_API void pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache); + +PIXMAN_API void pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache); + +PIXMAN_API void pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache); + +PIXMAN_API const void * pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache, void *font_key, void *glyph_key); + +PIXMAN_API const void * pixman_glyph_cache_insert (pixman_glyph_cache_t *cache, void *font_key, void *glyph_key, int origin_x, int origin_y, pixman_image_t *glyph_image); + +PIXMAN_API void pixman_glyph_cache_remove (pixman_glyph_cache_t *cache, void *font_key, void *glyph_key); + +PIXMAN_API void pixman_glyph_get_extents (pixman_glyph_cache_t *cache, int n_glyphs, pixman_glyph_t *glyphs, pixman_box32_t *extents); + +PIXMAN_API pixman_format_code_t pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache, int n_glyphs, const pixman_glyph_t *glyphs); + +PIXMAN_API void pixman_composite_glyphs (pixman_op_t op, pixman_image_t *src, pixman_image_t *dest, @@ -994,6 +1258,8 @@ void pixman_composite_glyphs (pixman_op_t op, pixman_glyph_cache_t *cache, int n_glyphs, const pixman_glyph_t *glyphs); + +PIXMAN_API void pixman_composite_glyphs_no_mask (pixman_op_t op, pixman_image_t *src, pixman_image_t *dest, @@ -1061,12 +1327,19 @@ struct pixman_trap pixman_span_fix_t top, bot; }; +PIXMAN_API pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y, int bpp); + +PIXMAN_API pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y, int bpp); + +PIXMAN_API void pixman_edge_step (pixman_edge_t *e, int n); + +PIXMAN_API void pixman_edge_init (pixman_edge_t *e, int bpp, pixman_fixed_t y_start, @@ -1074,31 +1347,43 @@ void pixman_edge_init (pixman_edge_t *e, pixman_fixed_t y_top, pixman_fixed_t x_bot, pixman_fixed_t y_bot); + +PIXMAN_API void pixman_line_fixed_edge_init (pixman_edge_t *e, int bpp, pixman_fixed_t y, const pixman_line_fixed_t *line, int x_off, int y_off); + +PIXMAN_API void pixman_rasterize_edges (pixman_image_t *image, pixman_edge_t *l, pixman_edge_t *r, pixman_fixed_t t, pixman_fixed_t b); + +PIXMAN_API void pixman_add_traps (pixman_image_t *image, int16_t x_off, int16_t y_off, int ntrap, const pixman_trap_t *traps); + +PIXMAN_API void pixman_add_trapezoids (pixman_image_t *image, int16_t x_off, int y_off, int ntraps, const pixman_trapezoid_t *traps); + +PIXMAN_API void pixman_rasterize_trapezoid (pixman_image_t *image, const pixman_trapezoid_t *trap, int x_off, int y_off); + +PIXMAN_API void pixman_composite_trapezoids (pixman_op_t op, pixman_image_t * src, pixman_image_t * dst, @@ -1109,6 +1394,8 @@ void pixman_composite_trapezoids (pixman_op_t op, int y_dst, int n_traps, const pixman_trapezoid_t * traps); + +PIXMAN_API void pixman_composite_triangles (pixman_op_t op, pixman_image_t * src, pixman_image_t * dst, @@ -1119,6 +1406,8 @@ void pixman_composite_triangles (pixman_op_t op, int y_dst, int n_tris, const pixman_triangle_t * tris); + +PIXMAN_API void pixman_add_triangles (pixman_image_t *image, int32_t x_off, int32_t y_off, diff --git a/lib/pixman/test/Makefile.in b/lib/pixman/test/Makefile.in index fa245417e..e06827821 100644 --- a/lib/pixman/test/Makefile.in +++ b/lib/pixman/test/Makefile.in @@ -533,6 +533,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/lib/pixman/test/affine-test.c b/lib/pixman/test/affine-test.c index 8e19023a3..f51685668 100644 --- a/lib/pixman/test/affine-test.c +++ b/lib/pixman/test/affine-test.c @@ -171,7 +171,7 @@ test_composite (int testnum, int i = prng_rand_n (2); int j = prng_rand_n (3); int bitnum = prng_rand_n (32); - transform.matrix[i][j] ^= 1 << bitnum; + transform.matrix[i][j] ^= 1U << bitnum; if (prng_rand_n (2)) break; } diff --git a/lib/pixman/test/lowlevel-blt-bench.c b/lib/pixman/test/lowlevel-blt-bench.c index 28ff66991..7ba29868b 100644 --- a/lib/pixman/test/lowlevel-blt-bench.c +++ b/lib/pixman/test/lowlevel-blt-bench.c @@ -180,7 +180,6 @@ bench_L (pixman_op_t op, int64_t i, j, k; int x = 0; int q = 0; - volatile int qx; for (i = 0; i < n; i++) { @@ -204,7 +203,6 @@ bench_L (pixman_op_t op, x = 0; call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 63 - x, 0, width, lines_count); } - qx = q; return (double)n * lines_count * width; } diff --git a/lib/pixman/test/meson.build b/lib/pixman/test/meson.build index a2da1085b..59a0d4289 100644 --- a/lib/pixman/test/meson.build +++ b/lib/pixman/test/meson.build @@ -34,7 +34,6 @@ tests = [ 'scaling-crash-test', 'alpha-loop', 'scaling-helpers-test', - 'thread-test', 'rotate-test', 'alphamap', 'gradient-crash-test', @@ -54,6 +53,12 @@ tests = [ 'tolerance-test', ] +# Remove/update this once thread-test.c supports threading methods +# other than PThreads and Windows threads +if pthreads_found or host_machine.system() == 'windows' + tests += 'thread-test' +endif + progs = [ 'lowlevel-blt-bench', 'radial-perf-test', diff --git a/lib/pixman/test/solid-test.c b/lib/pixman/test/solid-test.c index c6ea39770..b118d37de 100644 --- a/lib/pixman/test/solid-test.c +++ b/lib/pixman/test/solid-test.c @@ -26,6 +26,7 @@ #include "utils.h" #include <stdlib.h> +#include <stdint.h> #include <stdio.h> #define WIDTH 32 diff --git a/lib/pixman/test/stress-test.c b/lib/pixman/test/stress-test.c index 6b4f7d606..13d99790d 100644 --- a/lib/pixman/test/stress-test.c +++ b/lib/pixman/test/stress-test.c @@ -521,7 +521,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) if (image->type == BITS && prng_rand_n (8) != 0) { uint32_t width, height; - int x, y; + uint32_t x, y; int i; /* Also add a couple of clip rectangles inside the image diff --git a/lib/pixman/test/thread-test.c b/lib/pixman/test/thread-test.c index 1c2f0407a..12c51e334 100644 --- a/lib/pixman/test/thread-test.c +++ b/lib/pixman/test/thread-test.c @@ -1,23 +1,34 @@ #include "utils.h" -#ifndef HAVE_PTHREADS +#if !defined (HAVE_PTHREADS) && !defined (_WIN32) int main () { - printf ("Skipped thread-test - pthreads not supported\n"); + printf ("Skipped thread-test - pthreads or Windows Threads not supported\n"); return 0; } #else #include <stdlib.h> -#include <pthread.h> + +#ifdef HAVE_PTHREADS +# include <pthread.h> +#elif defined (_WIN32) +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#endif + +#define THREADS 16 typedef struct { int thread_no; uint32_t *dst_buf; prng_t prng_state; +#if defined (_WIN32) && !defined (HAVE_PTHREADS) + uint32_t crc32; +#endif } info_t; static const pixman_op_t operators[] = @@ -67,8 +78,13 @@ static const pixman_format_code_t formats[] = #define DEST_WIDTH (7) +#ifdef HAVE_PTHREADS static void * thread (void *data) +#elif defined (_WIN32) +DWORD WINAPI +thread (LPVOID data) +#endif { info_t *info = data; uint32_t crc32 = 0x0; @@ -112,7 +128,12 @@ thread (void *data) pixman_image_unref (dst_img); } +#ifdef HAVE_PTHREADS return (void *)(uintptr_t)crc32; +#elif defined (_WIN32) + info->crc32 = crc32; + return 0; +#endif } static inline uint32_t @@ -127,26 +148,34 @@ byteswap32 (uint32_t x) int main (void) { - uint32_t dest[16 * DEST_WIDTH]; - info_t info[16] = { { 0 } }; - pthread_t threads[16]; - void *retvals[16]; - uint32_t crc32s[16], crc32; + uint32_t dest[THREADS * DEST_WIDTH]; + info_t info[THREADS] = { { 0 } }; + +#ifdef HAVE_PTHREADS + pthread_t threads[THREADS]; + void *retvals[THREADS]; +#elif defined (_WIN32) + HANDLE hThreadArray[THREADS]; + DWORD dwThreadIdArray[THREADS]; +#endif + + uint32_t crc32s[THREADS], crc32; int i; - for (i = 0; i < 16; ++i) + for (i = 0; i < THREADS; ++i) { info[i].thread_no = i; info[i].dst_buf = &dest[i * DEST_WIDTH]; } - for (i = 0; i < 16; ++i) - pthread_create (&threads[i], NULL, thread, &info[i]); +#ifdef HAVE_PTHREADS + for (i = 0; i < THREADS; ++i) + pthread_create (&threads[i], NULL, thread, &info[i]); - for (i = 0; i < 16; ++i) - pthread_join (threads[i], &retvals[i]); + for (i = 0; i < THREADS; ++i) + pthread_join (threads[i], &retvals[i]); - for (i = 0; i < 16; ++i) + for (i = 0; i < THREADS; ++i) { crc32s[i] = (uintptr_t)retvals[i]; @@ -154,6 +183,36 @@ main (void) crc32s[i] = byteswap32 (crc32s[i]); } +#elif defined (_WIN32) + for (i = 0; i < THREADS; ++i) + { + hThreadArray[i] = CreateThread(NULL, + 0, + thread, + &info[i], + 0, + &dwThreadIdArray[i]); + if (hThreadArray[i] == NULL) + { + printf ("Windows thread creation failed!\n"); + return 1; + } + } + for (i = 0; i < THREADS; ++i) + { + WaitForSingleObject (hThreadArray[i], INFINITE); + CloseHandle(hThreadArray[i]); + } + + for (i = 0; i < THREADS; ++i) + { + crc32s[i] = info[i].crc32; + + if (is_little_endian()) + crc32s[i] = byteswap32 (crc32s[i]); + } +#endif + crc32 = compute_crc32 (0, crc32s, sizeof crc32s); #define EXPECTED 0x82C4D9FB diff --git a/lib/pixman/test/tolerance-test.c b/lib/pixman/test/tolerance-test.c index 320bb7fe0..3c6e818c6 100644 --- a/lib/pixman/test/tolerance-test.c +++ b/lib/pixman/test/tolerance-test.c @@ -76,6 +76,12 @@ static const pixman_op_t operators[] = PIXMAN_OP_EXCLUSION, }; +static const pixman_dither_t dithers[] = +{ + PIXMAN_DITHER_ORDERED_BAYER_8, + PIXMAN_DITHER_ORDERED_BLUE_NOISE_64, +}; + #define RANDOM_ELT(array) \ (array[prng_rand_n (ARRAY_LENGTH (array))]) @@ -176,7 +182,8 @@ verify (int test_no, pixman_image_t *orig_dest, int x, int y, int width, int height, - pixman_bool_t component_alpha) + pixman_bool_t component_alpha, + pixman_dither_t dither) { pixel_checker_t dest_checker, src_checker, mask_checker; int i, j; @@ -185,6 +192,9 @@ verify (int test_no, pixel_checker_init (&dest_checker, dest->bits.format); pixel_checker_init (&mask_checker, mask->bits.format); + if (dest->bits.dither != PIXMAN_DITHER_NONE) + pixel_checker_allow_dither (&dest_checker); + assert (dest->bits.format == orig_dest->bits.format); for (j = y; j < y + height; ++j) @@ -220,6 +230,7 @@ verify (int test_no, printf (" operator: %s (%s alpha)\n", operator_name (op), component_alpha? "component" : "unified"); + printf (" dither: %s\n", dither_name (dither)); printf (" dest_x, dest_y: %d %d\n", x, y); printf (" width, height: %d %d\n", width, height); printf (" source: format: %-14s size: %2d x %2d\n", @@ -275,6 +286,7 @@ do_check (int i) pixman_image_t *dest_copy; pixman_bool_t result = TRUE; pixman_bool_t component_alpha; + pixman_dither_t dither = PIXMAN_DITHER_NONE; prng_srand (i); op = RANDOM_ELT (operators); @@ -296,6 +308,12 @@ do_check (int i) if (y + height > dest->bits.height) height = dest->bits.height - y; + if (prng_rand_n (2)) + { + dither = RANDOM_ELT (dithers); + pixman_image_set_dither (dest, dither); + } + component_alpha = prng_rand_n (2); pixman_image_set_component_alpha (mask, component_alpha); @@ -305,7 +323,8 @@ do_check (int i) x, y, width, height); if (!verify (i, op, source, mask, dest, dest_copy, - x, y, width, height, component_alpha)) + x, y, width, height, component_alpha, + dither)) { result = FALSE; } diff --git a/lib/pixman/test/utils.c b/lib/pixman/test/utils.c index 4eeb06849..cd9ab26d5 100644 --- a/lib/pixman/test/utils.c +++ b/lib/pixman/test/utils.c @@ -993,9 +993,11 @@ enable_invalid_exceptions (void) { #ifdef HAVE_FENV_H #ifdef HAVE_FEENABLEEXCEPT +#ifdef FE_INVALID feenableexcept (FE_INVALID); #endif #endif +#endif } void * @@ -1174,6 +1176,32 @@ static const operator_entry_t op_list[] = #undef ALIAS }; +typedef struct { + pixman_dither_t dither; + const char *name; + pixman_bool_t is_alias; +} dither_entry_t; + +static const dither_entry_t dither_list[] = +{ +#define ENTRY(dither) \ + { PIXMAN_DITHER_##dither, "PIXMAN_DITHER_" #dither, FALSE } +#define ALIAS(dither, nam) \ + { PIXMAN_DITHER_##dither, nam, TRUE } + + /* dither_name () will return the first hit in this table, + * so keep the list properly ordered between entries and aliases. + * Aliases are not listed by list_dithers (). + */ + + ENTRY (ORDERED_BAYER_8), + ENTRY (ORDERED_BLUE_NOISE_64), + ENTRY (NONE), + +#undef ENTRY +#undef ALIAS +}; + struct format_entry { pixman_format_code_t format; @@ -1382,6 +1410,28 @@ list_operators (void) printf ("\n\n"); } +void +list_dithers (void) +{ + int n_chars; + int i; + + printf ("Dithers:\n "); + + n_chars = 0; + for (i = 0; i < ARRAY_LENGTH (dither_list); ++i) + { + const dither_entry_t *ent = &dither_list[i]; + + if (ent->is_alias) + continue; + + emit (ent->name, &n_chars); + } + + printf ("\n\n"); +} + pixman_op_t operator_from_string (const char *s) { @@ -1406,6 +1456,22 @@ operator_from_string (const char *s) return PIXMAN_OP_NONE; } +pixman_dither_t +dither_from_string (const char *s) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (dither_list); ++i) + { + const dither_entry_t *ent = &dither_list[i]; + + if (strcasecmp (ent->name, s) == 0) + return ent->dither; + } + + return PIXMAN_DITHER_NONE; +} + const char * operator_name (pixman_op_t op) { @@ -1438,6 +1504,22 @@ format_name (pixman_format_code_t format) return "<unknown format>"; }; +const char * +dither_name (pixman_dither_t dither) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (dither_list); ++i) + { + const dither_entry_t *ent = &dither_list[i]; + + if (ent->dither == dither) + return ent->name; + } + + return "<unknown dither>"; +} + #define IS_ZERO(f) (-DBL_MIN < (f) && (f) < DBL_MIN) typedef double (* blend_func_t) (double as, double s, double ad, double d); @@ -1924,6 +2006,10 @@ round_color (pixman_format_code_t format, color_t *color) color->a = round_channel (color->a, PIXMAN_FORMAT_A (format)); } +/* The acceptable deviation in units of [0.0, 1.0] + */ +#define DEVIATION (0.0128) + /* Check whether @pixel is a valid quantization of the a, r, g, b * parameters. Some slack is permitted. */ @@ -1983,15 +2069,31 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) break; } - checker->am = ((1 << PIXMAN_FORMAT_A (format)) - 1) << checker->as; - checker->rm = ((1 << PIXMAN_FORMAT_R (format)) - 1) << checker->rs; - checker->gm = ((1 << PIXMAN_FORMAT_G (format)) - 1) << checker->gs; - checker->bm = ((1 << PIXMAN_FORMAT_B (format)) - 1) << checker->bs; + checker->am = ((1U << PIXMAN_FORMAT_A (format)) - 1) << checker->as; + checker->rm = ((1U << PIXMAN_FORMAT_R (format)) - 1) << checker->rs; + checker->gm = ((1U << PIXMAN_FORMAT_G (format)) - 1) << checker->gs; + checker->bm = ((1U << PIXMAN_FORMAT_B (format)) - 1) << checker->bs; checker->aw = PIXMAN_FORMAT_A (format); checker->rw = PIXMAN_FORMAT_R (format); checker->gw = PIXMAN_FORMAT_G (format); checker->bw = PIXMAN_FORMAT_B (format); + + checker->ad = DEVIATION; + checker->rd = DEVIATION; + checker->gd = DEVIATION; + checker->bd = DEVIATION; +} + +/* When dithering is enabled, we allow one extra pixel of tolerance + */ +void +pixel_checker_allow_dither (pixel_checker_t *checker) +{ + checker->ad += 1 / (double)((1 << checker->aw) - 1); + checker->rd += 1 / (double)((1 << checker->rw) - 1); + checker->gd += 1 / (double)((1 << checker->gw) - 1); + checker->bd += 1 / (double)((1 << checker->bw) - 1); } static void @@ -2085,7 +2187,7 @@ convert (double v, uint32_t width, uint32_t mask, uint32_t shift, double def) } static void -get_limits (const pixel_checker_t *checker, double limit, +get_limits (const pixel_checker_t *checker, double sign, color_t *color, int *ao, int *ro, int *go, int *bo) { @@ -2101,23 +2203,23 @@ get_limits (const pixel_checker_t *checker, double limit, color = &tmp; } - *ao = convert (color->a + limit, checker->aw, checker->am, checker->as, 1.0); - *ro = convert (color->r + limit, checker->rw, checker->rm, checker->rs, 0.0); - *go = convert (color->g + limit, checker->gw, checker->gm, checker->gs, 0.0); - *bo = convert (color->b + limit, checker->bw, checker->bm, checker->bs, 0.0); + *ao = convert (color->a + sign * checker->ad, + checker->aw, checker->am, checker->as, 1.0); + *ro = convert (color->r + sign * checker->rd, + checker->rw, checker->rm, checker->rs, 0.0); + *go = convert (color->g + sign * checker->gd, + checker->gw, checker->gm, checker->gs, 0.0); + *bo = convert (color->b + sign * checker->bd, + checker->bw, checker->bm, checker->bs, 0.0); } -/* The acceptable deviation in units of [0.0, 1.0] - */ -#define DEVIATION (0.0128) - void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, int *am, int *rm, int *gm, int *bm) { pixel_checker_require_uint32_format(checker); - get_limits (checker, DEVIATION, color, am, rm, gm, bm); + get_limits (checker, 1, color, am, rm, gm, bm); } void @@ -2126,7 +2228,7 @@ pixel_checker_get_min (const pixel_checker_t *checker, color_t *color, { pixel_checker_require_uint32_format(checker); - get_limits (checker, - DEVIATION, color, am, rm, gm, bm); + get_limits (checker, - 1, color, am, rm, gm, bm); } pixman_bool_t diff --git a/lib/pixman/test/utils.h b/lib/pixman/test/utils.h index e5ac945ab..701417fe7 100644 --- a/lib/pixman/test/utils.h +++ b/lib/pixman/test/utils.h @@ -219,15 +219,23 @@ list_formats (void); void list_operators (void); +void list_dithers (void); + pixman_op_t operator_from_string (const char *s); +pixman_dither_t +dither_from_string (const char *s); + const char * operator_name (pixman_op_t op); const char * format_name (pixman_format_code_t format); +const char * +dither_name (pixman_dither_t dither); + typedef struct { double r, g, b, a; @@ -250,12 +258,16 @@ typedef struct uint32_t am, rm, gm, bm; uint32_t as, rs, gs, bs; uint32_t aw, rw, gw, bw; + float ad, rd, gd, bd; } pixel_checker_t; void pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format); void +pixel_checker_allow_dither (pixel_checker_t *checker); + +void pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel, int *a, int *r, int *g, int *b); |