Compare commits

..

No commits in common. "debian-unstable" and "pixman-0.25.2-1" have entirely different histories.

227 changed files with 29501 additions and 50327 deletions

View File

@ -1,11 +0,0 @@
# To use this config on you editor, follow the instructions at:
# http://editorconfig.org
root = true
[*]
tab_width = 8
[meson.build,meson_options.txt]
indent_style = space
indent_size = 2

49
.gitignore vendored
View File

@ -26,28 +26,51 @@ stamp-h?
config.h
config.h.in
.*.swp
demos/*-test
demos/checkerboard
demos/alpha-test
demos/clip-in
demos/linear-gradient
demos/quad2quad
demos/scale
demos/dither
pixman/pixman-srgb.c
demos/clip-test
demos/composite-test
demos/convolution-test
demos/gradient-test
demos/radial-test
demos/screen-test
demos/trap-test
demos/tri-test
pixman/pixman-combine32.c
pixman/pixman-combine32.h
pixman/pixman-combine64.c
pixman/pixman-combine64.h
pixman/pixman-version.h
test/*-test
test/affine-bench
test/a1-trap-test
test/affine-test
test/alpha-loop
test/alphamap
test/check-formats
test/alpha-test
test/blitters-test
test/clip-in
test/clip-test
test/composite
test/infinite-loop
test/composite-test
test/composite-traps-test
test/convolution-test
test/fetch-test
test/gradient-crash-test
test/gradient-test
test/lowlevel-blt-bench
test/radial-invalid
test/oob-test
test/pdf-op-test
test/region-contains-test
test/region-test
test/region-translate
test/scaling-bench
test/region-translate-test
test/scaling-crash-test
test/scaling-helpers-test
test/scaling-test
test/screen-test
test/stress-test
test/trap-crasher
test/trap-test
test/window-test
*.pdb
*.dll
*.lib

View File

@ -1,80 +0,0 @@
# Docker build stage
#
# It builds a multi-arch image for all required architectures. Each image can be
# later easily used with properly configured Docker (which uses binfmt and QEMU
# underneath).
docker:
stage: docker
image: quay.io/buildah/stable
rules:
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event' && $TARGET =~ $ACTIVE_TARGET_PATTERN"
changes:
paths:
- .gitlab-ci.d/01-docker.yml
- .gitlab-ci.d/01-docker/**/*
variables:
DOCKER_TAG: $CI_COMMIT_REF_SLUG
DOCKER_IMAGE_NAME: ${CI_REGISTRY_IMAGE}/pixman:${DOCKER_TAG}
- if: "$CI_PIPELINE_SOURCE == 'schedule' && $TARGET =~ $ACTIVE_TARGET_PATTERN"
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $TARGET =~ $ACTIVE_TARGET_PATTERN"
- if: "$CI_COMMIT_TAG && $TARGET =~ $ACTIVE_TARGET_PATTERN"
variables:
# Use vfs with buildah. Docker offers overlayfs as a default, but Buildah
# cannot stack overlayfs on top of another overlayfs filesystem.
STORAGE_DRIVER: vfs
# Write all image metadata in the docker format, not the standard OCI
# format. Newer versions of docker can handle the OCI format, but older
# versions, like the one shipped with Fedora 30, cannot handle the format.
BUILDAH_FORMAT: docker
BUILDAH_ISOLATION: chroot
CACHE_IMAGE: ${CI_REGISTRY_IMAGE}/cache
CACHE_ARGS: --cache-from ${CACHE_IMAGE} --cache-to ${CACHE_IMAGE}
before_script:
# Login to the target registry.
- echo "${CI_REGISTRY_PASSWORD}" |
buildah login -u "${CI_REGISTRY_USER}" --password-stdin ${CI_REGISTRY}
# Docker Hub login is optional, and can be used to circumvent image pull
# quota for anonymous pulls for base images.
- echo "${DOCKERHUB_PASSWORD}" |
buildah login -u "${DOCKERHUB_USER}" --password-stdin docker.io ||
echo "Failed to login to Docker Hub."
parallel:
matrix:
- TARGET:
- linux-386
- linux-amd64
- linux-arm-v5
- linux-arm-v7
- linux-arm64-v8
- linux-mips
- linux-mips64el
- linux-mipsel
- linux-ppc
- linux-ppc64
- linux-ppc64le
- linux-riscv64
- windows-686
- windows-amd64
- windows-arm64-v8
script:
# Prepare environment.
- ${LOAD_TARGET_ENV}
- FULL_IMAGE_NAME=${DOCKER_IMAGE_NAME}-${TARGET}
# Build and push the image.
- buildah bud
--tag ${FULL_IMAGE_NAME}
--layers ${CACHE_ARGS}
--target ${TARGET}
--platform=${DOCKER_PLATFORM}
--build-arg BASE_IMAGE=${BASE_IMAGE}
--build-arg BASE_IMAGE_TAG=${BASE_IMAGE_TAG}
--build-arg LLVM_VERSION=${LLVM_VERSION}
-f Dockerfile .gitlab-ci.d/01-docker/
- buildah images
- buildah push ${FULL_IMAGE_NAME}

View File

@ -1,150 +0,0 @@
ARG BASE_IMAGE=docker.io/debian
ARG BASE_IMAGE_TAG=bookworm-slim
FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} AS base
LABEL org.opencontainers.image.title="Pixman build environment for platform coverage" \
org.opencontainers.image.authors="Marek Pikuła <m.pikula@partner.samsung.com>"
ARG DEBIAN_FRONTEND=noninteractive
ENV APT_UPDATE="apt-get update" \
APT_INSTALL="apt-get install -y --no-install-recommends" \
APT_CLEANUP="rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*"
ARG GCOVR_VERSION="~=7.2"
ARG MESON_VERSION="~=1.6"
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} \
# Build dependencies.
build-essential \
ninja-build \
pkg-config \
qemu-user \
# pipx dependencies.
python3-argcomplete \
python3-packaging \
python3-pip \
python3-platformdirs \
python3-userpath \
python3-venv \
# gcovr dependencies.
libxml2-dev \
libxslt-dev \
python3-dev \
&& ${APT_CLEANUP} \
# Install pipx using pip to have a more recent version of pipx, which
# supports the `--global` flag.
&& pip install pipx --break-system-packages \
# Install a recent version of meson and gcovr using pipx to have the same
# version across all variants regardless of base.
&& pipx install --global \
gcovr${GCOVR_VERSION} \
meson${MESON_VERSION} \
&& gcovr --version \
&& echo Meson version: \
&& meson --version
FROM base AS llvm-base
# LLVM 16 is the highest available in Bookworm. Preferably, we should use the
# same version for all platforms, but it's not possible at the moment.
ARG LLVM_VERSION=16
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} \
clang-${LLVM_VERSION} \
libclang-rt-${LLVM_VERSION}-dev \
lld-${LLVM_VERSION} \
llvm-${LLVM_VERSION} \
&& ${APT_CLEANUP} \
&& ln -f /usr/bin/clang-${LLVM_VERSION} /usr/bin/clang \
&& ln -f /usr/bin/lld-${LLVM_VERSION} /usr/bin/lld \
&& ln -f /usr/bin/llvm-ar-${LLVM_VERSION} /usr/bin/llvm-ar \
&& ln -f /usr/bin/llvm-strip-${LLVM_VERSION} /usr/bin/llvm-strip
FROM llvm-base AS native-base
ARG LLVM_VERSION=16
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} \
# Runtime library dependencies.
libglib2.0-dev \
libgtk-3-dev \
libpng-dev \
# Install libomp-dev if available (OpenMP support for LLVM). It's done only
# for the native images, as OpenMP support in cross-build environment is
# tricky for LLVM.
&& (${APT_INSTALL} libomp-${LLVM_VERSION}-dev \
|| echo "OpenMP not available on this platform.") \
&& ${APT_CLEANUP}
# The following targets differ in BASE_IMAGE.
FROM native-base AS linux-386
FROM native-base AS linux-amd64
FROM native-base AS linux-arm-v5
FROM native-base AS linux-arm-v7
FROM native-base AS linux-arm64-v8
FROM native-base AS linux-mips64el
FROM native-base AS linux-mipsel
FROM native-base AS linux-ppc64le
FROM native-base AS linux-riscv64
# The following targets should have a common BASE_IMAGE.
FROM llvm-base AS linux-mips
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} gcc-multilib-mips-linux-gnu \
&& ${APT_CLEANUP}
FROM llvm-base AS linux-ppc
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} gcc-multilib-powerpc-linux-gnu \
&& ${APT_CLEANUP}
FROM llvm-base AS linux-ppc64
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} gcc-multilib-powerpc64-linux-gnu \
&& ${APT_CLEANUP}
# We use a common image for Windows i686 and amd64, as it doesn't make sense to
# make them separate in terms of build time and image size. After two runs they
# should use the same cache layers, so in the end it makes the collective image
# size smaller.
FROM base AS windows-base
ARG LLVM_MINGW_RELEASE=20240619
ARG LLVM_MINGW_VARIANT=llvm-mingw-${LLVM_MINGW_RELEASE}-msvcrt-ubuntu-20.04-x86_64
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} wget \
&& ${APT_CLEANUP} \
&& cd /opt \
&& wget https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_RELEASE}/${LLVM_MINGW_VARIANT}.tar.xz \
&& tar -xf ${LLVM_MINGW_VARIANT}.tar.xz \
&& rm -f ${LLVM_MINGW_VARIANT}.tar.xz
ENV PATH=${PATH}:/opt/${LLVM_MINGW_VARIANT}/bin
FROM windows-base AS windows-x86-base
RUN dpkg --add-architecture i386 \
&& ${APT_UPDATE} \
&& ${APT_INSTALL} \
gcc-mingw-w64-i686 \
gcc-mingw-w64-x86-64 \
mingw-w64-tools \
procps \
wine \
wine32 \
wine64 \
&& ${APT_CLEANUP} \
# Inspired by https://code.videolan.org/videolan/docker-images
&& wine wineboot --init \
&& while pgrep wineserver > /dev/null; do \
echo "waiting ..."; \
sleep 1; \
done \
&& rm -rf /tmp/wine-*
FROM windows-x86-base AS windows-686
FROM windows-x86-base AS windows-amd64
# aarch64 image requires linaro/wine-arm64 as a base.
FROM windows-base AS windows-arm64-v8
RUN wine-arm64 wineboot --init \
&& while pgrep wineserver > /dev/null; do \
echo "waiting ..."; \
sleep 1; \
done \
&& rm -rf /tmp/wine-*

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/386
BASE_IMAGE=docker.io/i386/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/amd64
BASE_IMAGE=docker.io/amd64/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/arm/v5
BASE_IMAGE=docker.io/arm32v5/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/arm/v7
BASE_IMAGE=docker.io/arm32v7/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/arm64/v8
BASE_IMAGE=docker.io/arm64v8/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/amd64
BASE_IMAGE=docker.io/amd64/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/mips64el
BASE_IMAGE=docker.io/mips64le/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/mipsel
BASE_IMAGE=docker.io/serenitycode/debian-debootstrap
BASE_IMAGE_TAG=mipsel-bookworm-slim
LLVM_VERSION=14

View File

@ -1 +0,0 @@
linux-amd64.env

View File

@ -1 +0,0 @@
linux-amd64.env

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/ppc64le
BASE_IMAGE=docker.io/ppc64le/debian
BASE_IMAGE_TAG=bookworm-slim
LLVM_VERSION=16

View File

@ -1,4 +0,0 @@
DOCKER_PLATFORM=linux/riscv64
BASE_IMAGE=docker.io/riscv64/debian
BASE_IMAGE_TAG=sid-slim
LLVM_VERSION=18

View File

@ -1 +0,0 @@
linux-amd64.env

View File

@ -1 +0,0 @@
linux-amd64.env

View File

@ -1,3 +0,0 @@
DOCKER_PLATFORM=linux/amd64
BASE_IMAGE=docker.io/linaro/wine-arm64
BASE_IMAGE_TAG=latest

View File

@ -1,107 +0,0 @@
# Build stage
#
# This stage builds pixman with enabled coverage for all supported
# architectures.
#
# Some targets don't support atomic profile update, so to decrease the number of
# gcov errors, they need to be built without OpenMP (single threaded) by adding
# `-Dopenmp=disabled` Meson argument.
variables:
# Used in test stage as well.
BUILD_DIR: build-${TOOLCHAIN}
# Applicable to all build targets.
include:
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-386
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-amd64
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-arm-v5
qemu_cpu: arm1136
# Disable coverage, as the tests take too long to run with a single thread.
enable_gnu_coverage: false
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-arm-v7
qemu_cpu: max
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-arm64-v8
qemu_cpu: max
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-mips
toolchain: [gnu]
qemu_cpu: 74Kf
enable_gnu_coverage: false
# TODO: Merge with the one above once the following issue is resolved:
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/105).
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-mips
toolchain: [llvm]
qemu_cpu: 74Kf
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-mips64el
qemu_cpu: Loongson-3A4000
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-mipsel
toolchain: [gnu]
qemu_cpu: 74Kf
# Disable coverage, as the tests take too long to run with a single thread.
enable_gnu_coverage: false
# TODO: Merge with the one above once the following issue is resolved:
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/105).
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-mipsel
toolchain: [llvm]
qemu_cpu: 74Kf
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-ppc
qemu_cpu: g4
enable_gnu_coverage: false
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-ppc64
qemu_cpu: ppc64
enable_gnu_coverage: false
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-ppc64le
qemu_cpu: power10
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: linux-riscv64
qemu_cpu: rv64
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: windows-686
enable_gnu_coverage: false
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: windows-amd64
enable_gnu_coverage: false
- local: .gitlab-ci.d/templates/build.yml
inputs:
target: windows-arm64-v8
toolchain: [llvm] # GNU toolchain doesn't seem to support Windows on ARM.
qemu_cpu: max
enable_gnu_coverage: false

View File

@ -1,175 +0,0 @@
# Test stage
#
# This stage executes the test suite for pixman for all architectures in
# different configurations. Build and test is split, as some architectures can
# have different QEMU configuration or have multiple supported pixman backends,
# which are executed as job matrix.
#
# Mind that `PIXMAN_ENABLE` variable in matrix runs does nothing, but it looks
# better in CI to indicate what is actually being tested.
#
# Some emulated targets are really slow or cannot be run in multithreaded mode
# (mipsel, arm-v5). Thus coverage reporting is disabled for them.
variables:
# Used in summary stage as well.
COVERAGE_BASE_DIR: coverage
COVERAGE_OUT: ${COVERAGE_BASE_DIR}/${CI_JOB_ID}
TEST_NAME: "" # Allow to specify a set of tests to run with run variables.
include:
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-386
toolchain: [gnu]
pixman_disable:
- "sse2 ssse3" # Testing "mmx"
- "mmx ssse3" # Testing "sse2"
- "mmx sse2" # Testing "ssse3"
# TODO: Merge up after resolving
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/106
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-386
toolchain: [llvm]
pixman_disable:
# Same as above.
- "sse2 ssse3"
- "mmx ssse3"
- "mmx sse2"
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-amd64
pixman_disable:
- ""
- "fast"
- "wholeops"
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-arm-v5
toolchain: [gnu]
qemu_cpu: [arm1136]
pixman_disable: ["arm-neon"] # Test only arm-simd.
timeout: 3h
test_timeout_multiplier: 40
# TODO: Merge up after resolving
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/107
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-arm-v5
toolchain: [llvm]
qemu_cpu: [arm1136]
pixman_disable: ["arm-neon"] # Test only arm-simd.
timeout: 3h
test_timeout_multiplier: 40
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-arm-v7
qemu_cpu: [max]
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-arm64-v8
qemu_cpu: [max]
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-mips
toolchain: [gnu] # TODO: Add llvm once the build is fixed.
qemu_cpu: [74Kf]
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true # Some tests seem to fail.
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-mips64el
toolchain: [gnu]
qemu_cpu: [Loongson-3A4000]
# TODO: Merge up after resolving
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/108
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-mips64el
toolchain: [llvm]
qemu_cpu: [Loongson-3A4000]
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-mipsel
toolchain: [gnu] # TODO: Add llvm once the build is fixed.
qemu_cpu: [74Kf]
timeout: 2h
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-ppc
qemu_cpu: [g4]
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true # SIGILL for some tests
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-ppc64
qemu_cpu: [ppc64]
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true # SIGSEGV for some tests
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-ppc64le
toolchain: [gnu]
qemu_cpu: [power10]
# TODO: Merge up after resolving
# https://gitlab.freedesktop.org/pixman/pixman/-/issues/109
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-ppc64le
toolchain: [llvm]
qemu_cpu: [power10]
job_name_prefix: "."
job_name_suffix: ":failing"
allow_failure: true
retry: 0
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: linux-riscv64
qemu_cpu:
# Test on target without RVV (verify no autovectorization).
- rv64,v=false
# Test correctness for different VLENs.
- rv64,v=true,vext_spec=v1.0,vlen=128,elen=64
- rv64,v=true,vext_spec=v1.0,vlen=256,elen=64
- rv64,v=true,vext_spec=v1.0,vlen=512,elen=64
- rv64,v=true,vext_spec=v1.0,vlen=1024,elen=64
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: windows-686
pixman_disable:
# The same as for linux-386.
- "sse2 ssse3"
- "mmx ssse3"
- "mmx sse2"
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: windows-amd64
pixman_disable:
# The same as for linux-amd64.
- ""
- "fast"
- "wholeops"
- local: .gitlab-ci.d/templates/test.yml
inputs:
target: windows-arm64-v8
toolchain: [llvm]
qemu_cpu: [max]

View File

@ -1,47 +0,0 @@
# Summary stage
#
# This stage takes coverage reports from test runs for all architectures, and
# merges it into a single report, with GitLab visualization. There is also an
# HTML report generated as a separate artifact.
summary:
extends: .target:all
stage: summary
variables:
TARGET: linux-amd64
COVERAGE_SUMMARY_DIR: ${COVERAGE_BASE_DIR}/summary
needs:
- job: test:linux-386
optional: true
- job: test:linux-amd64
optional: true
- job: test:linux-arm-v7
optional: true
- job: test:linux-arm64-v8
optional: true
- job: test:linux-mips64el
optional: true
- job: test:linux-ppc64le
optional: true
- job: test:linux-riscv64
optional: true
script:
- echo "Input coverage reports:" && ls ${COVERAGE_BASE_DIR}/*.json || (echo "No coverage reports available." && exit)
- |
args=( )
for f in ${COVERAGE_BASE_DIR}/*.json; do
args+=( "-a" "$f" )
done
- mkdir -p ${COVERAGE_SUMMARY_DIR}
- gcovr "${args[@]}"
--cobertura-pretty --cobertura ${COVERAGE_SUMMARY_DIR}/coverage.xml
--html-details ${COVERAGE_SUMMARY_DIR}/coverage.html
--txt --print-summary
coverage: '/^TOTAL.*\s+(\d+\%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: ${COVERAGE_SUMMARY_DIR}/coverage.xml
paths:
- ${COVERAGE_SUMMARY_DIR}/

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1 +0,0 @@
native-gnu-noopenmp.meson

View File

@ -1 +0,0 @@
native-llvm-noopenmp.meson

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1,11 +0,0 @@
[binaries]
c = ['mips-linux-gnu-gcc', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'mips-linux-gnu-ar'
strip = 'mips-linux-gnu-strip'
exe_wrapper = ['qemu-mips', '-L', '/usr/mips-linux-gnu/']
[host_machine]
system = 'linux'
cpu_family = 'mips32'
cpu = 'mips32'
endian = 'big'

View File

@ -1,14 +0,0 @@
[binaries]
c = ['clang', '-target', 'mips-linux-gnu', '-fPIC', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'llvm-ar'
strip = 'llvm-strip'
exe_wrapper = ['qemu-mips', '-L', '/usr/mips-linux-gnu/']
[built-in options]
c_link_args = ['-target', 'mips-linux-gnu', '-fuse-ld=lld']
[host_machine]
system = 'linux'
cpu_family = 'mips32'
cpu = 'mips32'
endian = 'big'

View File

@ -1,8 +0,0 @@
[binaries]
c = ['gcc', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'ar'
strip = 'strip'
pkg-config = 'pkg-config'
[project options]
mips-dspr2 = 'disabled'

View File

@ -1,8 +0,0 @@
[binaries]
c = ['clang', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'llvm-ar'
strip = 'llvm-strip'
pkg-config = 'pkg-config'
[project options]
mips-dspr2 = 'disabled'

View File

@ -1 +0,0 @@
native-gnu-noopenmp.meson

View File

@ -1 +0,0 @@
native-llvm-noopenmp.meson

View File

@ -1,11 +0,0 @@
[binaries]
c = 'powerpc-linux-gnu-gcc'
ar = 'powerpc-linux-gnu-ar'
strip = 'powerpc-linux-gnu-strip'
exe_wrapper = ['qemu-ppc', '-L', '/usr/powerpc-linux-gnu']
[host_machine]
system = 'linux'
cpu_family = 'ppc'
cpu = 'ppc'
endian = 'big'

View File

@ -1,15 +0,0 @@
[binaries]
c = ['clang', '-target', 'powerpc-linux-gnu']
ar = 'llvm-ar'
strip = 'llvm-strip'
exe_wrapper = ['qemu-ppc', '-L', '/usr/powerpc-linux-gnu/']
[built-in options]
# We cannot use LLD, as it doesn't support big-endian PPC.
c_link_args = ['-target', 'powerpc-linux-gnu']
[host_machine]
system = 'linux'
cpu_family = 'ppc'
cpu = 'ppc'
endian = 'big'

View File

@ -1,11 +0,0 @@
[binaries]
c = 'powerpc64-linux-gnu-gcc'
ar = 'powerpc64-linux-gnu-ar'
strip = 'powerpc64-linux-gnu-strip'
exe_wrapper = ['qemu-ppc64', '-L', '/usr/powerpc64-linux-gnu/']
[host_machine]
system = 'linux'
cpu_family = 'ppc64'
cpu = 'ppc64'
endian = 'big'

View File

@ -1,15 +0,0 @@
[binaries]
c = ['clang', '-target', 'powerpc64-linux-gnu']
ar = 'llvm-ar'
strip = 'llvm-strip'
exe_wrapper = ['qemu-ppc64', '-L', '/usr/powerpc64-linux-gnu/']
[built-in options]
# We cannot use LLD, as it doesn't support big-endian PPC.
c_link_args = ['-target', 'powerpc64-linux-gnu']
[host_machine]
system = 'linux'
cpu_family = 'ppc64'
cpu = 'ppc64'
endian = 'big'

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1 +0,0 @@
native-gnu.meson

View File

@ -1 +0,0 @@
native-llvm.meson

View File

@ -1,8 +0,0 @@
[binaries]
c = ['gcc', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'ar'
strip = 'strip'
pkg-config = 'pkg-config'
[project options]
openmp = 'disabled'

View File

@ -1,5 +0,0 @@
[binaries]
c = 'gcc'
ar = 'ar'
strip = 'strip'
pkg-config = 'pkg-config'

View File

@ -1,8 +0,0 @@
[binaries]
c = ['clang', '-DCI_HAS_ALL_MIPS_CPU_FEATURES']
ar = 'llvm-ar'
strip = 'llvm-strip'
pkg-config = 'pkg-config'
[project options]
openmp = 'disabled'

View File

@ -1,5 +0,0 @@
[binaries]
c = 'clang'
ar = 'llvm-ar'
strip = 'llvm-strip'
pkg-config = 'pkg-config'

View File

@ -1,18 +0,0 @@
[binaries]
c = 'i686-w64-mingw32-gcc'
ar = 'i686-w64-mingw32-ar'
strip = 'i686-w64-mingw32-strip'
windres = 'i686-w64-mingw32-windres'
exe_wrapper = 'wine'
[built-in options]
c_link_args = ['-static-libgcc']
[host_machine]
system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
[project options]
openmp = 'disabled'

View File

@ -1,18 +0,0 @@
[binaries]
c = 'i686-w64-mingw32-clang'
ar = 'i686-w64-mingw32-llvm-ar'
strip = 'i686-w64-mingw32-strip'
windres = 'i686-w64-mingw32-windres'
exe_wrapper = 'wine'
[built-in options]
c_link_args = ['-static']
[project options]
openmp = 'disabled'
[host_machine]
system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

View File

@ -1,15 +0,0 @@
[binaries]
c = 'x86_64-w64-mingw32-gcc'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'
exe_wrapper = 'wine'
[built-in options]
c_link_args = ['-static-libgcc']
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

View File

@ -1,20 +0,0 @@
[binaries]
c = 'x86_64-w64-mingw32-clang'
ar = 'x86_64-w64-mingw32-llvm-ar'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'
exe_wrapper = 'wine'
[built-in options]
# Static linking is a workaround around `libwinpthread-1` not being discovered correctly.
c_link_args = ['-static']
[project options]
# OpenMP is disabled as it is not being discovered correctly during tests.
openmp = 'disabled'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

View File

@ -1,18 +0,0 @@
[binaries]
c = 'aarch64-w64-mingw32-clang'
ar = 'aarch64-w64-mingw32-llvm-ar'
strip = 'aarch64-w64-mingw32-strip'
windres = 'aarch64-w64-mingw32-windres'
exe_wrapper = 'wine-arm64'
[built-in options]
c_link_args = ['-static']
[project options]
openmp = 'disabled'
[host_machine]
system = 'windows'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

View File

@ -1,65 +0,0 @@
# This file contains the set of jobs run by the pixman project:
# https://gitlab.freedesktop.org/pixman/pixman/-/pipelines
stages:
- docker
- build
- test
- summary
variables:
# Make it possible to change RUNNER_TAG from GitLab variables. The default
# `kvm` tag has been tested with FDO infrastructure.
RUNNER_TAG: kvm
# Docker image global configuration.
DOCKER_TAG: latest
DOCKER_IMAGE_NAME: registry.freedesktop.org/pixman/pixman/pixman:${DOCKER_TAG}
# Execute to load a target-specific environment.
LOAD_TARGET_ENV: source .gitlab-ci.d/01-docker/target-env/${TARGET}.env
# Enable/disable specific targets for code and platform coverage targets.
ACTIVE_TARGET_PATTERN: '/linux-386|linux-amd64|linux-arm-v5|linux-arm-v7|linux-arm64-v8|linux-mips|linux-mips64el|linux-mipsel|linux-ppc|linux-ppc64|linux-ppc64le|linux-riscv64|windows-686|windows-amd64|windows-arm64-v8/i'
workflow:
rules:
# Use modified Docker image if building in MR and Docker image is affected
# by the MR.
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
changes:
paths:
- .gitlab-ci.d/01-docker.yml
- .gitlab-ci.d/01-docker/**/*
variables:
DOCKER_TAG: $CI_COMMIT_REF_SLUG
DOCKER_IMAGE_NAME: ${CI_REGISTRY_IMAGE}/pixman:${DOCKER_TAG}
# A standard set of GitLab CI triggers (i.e., MR, schedule, default branch,
# and tag).
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_PIPELINE_SOURCE == 'schedule'
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH
- if: $CI_COMMIT_TAG
auto_cancel:
on_new_commit: conservative
on_job_failure: all
default:
tags:
- $RUNNER_TAG
# Retry in case the runner is misconfigured for multi-arch builds or some
# random unexpected runner error occurs (it happened during testing).
retry: 1
include:
- local: "/.gitlab-ci.d/templates/targets.yml"
- local: "/.gitlab-ci.d/01-docker.yml"
- local: "/.gitlab-ci.d/02-build.yml"
- local: "/.gitlab-ci.d/03-test.yml"
- local: "/.gitlab-ci.d/04-summary.yml"

View File

@ -1,80 +0,0 @@
spec:
inputs:
target:
description:
Build target in form of "OS-ARCH" pair (e.g., linux-amd64). Mostly the
same as platform string for Docker but with a hyphen instead of slash.
toolchain:
description:
An array of toolchains to test with. Each toolchain should have an
appropriate Meson cross file.
type: array
default: [gnu, llvm]
qemu_cpu:
description:
QEMU_CPU environmental variable used by Docker (which uses QEMU
underneath). It is not used by x86 targets, as they are executed
natively on the host.
default: ""
enable_gnu_coverage:
description:
Enable coverage build flags. It can be later used to compile a coverage
report for all the jobs. Should be enabled only for native build
environments as they have all the optional dependencies, and are the
most reliable and uniform (so disable for cross environments).
type: boolean
default: true
job_name_prefix:
description:
Additional prefix for the job name. Can be used to disable a job with a
"." prefix.
default: ""
job_name_suffix:
description:
Additional suffix for the job name. Can be used to prevent job
duplication for jobs for the same target.
default: ""
allow_failure:
description:
Set the `allow_failure` flag for jobs that are expected to fail.
Remember to set `retry` argument to 0 to prevent unnecessary retries.
type: boolean
default: false
retry:
description:
Set the `retry` flag for a job. Usually used together with
`allow_failure`.
type: number
default: 1
---
"$[[ inputs.job_name_prefix ]]build:$[[ inputs.target ]]$[[ inputs.job_name_suffix ]]":
extends: .target:all
stage: build
allow_failure: $[[ inputs.allow_failure ]]
retry: $[[ inputs.retry ]]
needs:
- job: docker
optional: true
parallel:
matrix:
- TARGET: $[[ inputs.target ]]
variables:
TARGET: $[[ inputs.target ]]
QEMU_CPU: $[[ inputs.qemu_cpu ]]
parallel:
matrix:
- TOOLCHAIN: $[[ inputs.toolchain ]]
script:
- |
if [ "$[[ inputs.enable_gnu_coverage ]]" == "true" ] && [ "${TOOLCHAIN}" == "gnu" ]; then
COV_C_ARGS=-fprofile-update=atomic
COV_MESON_BUILD_ARGS=-Db_coverage=true
fi
- meson setup ${BUILD_DIR}
--cross-file .gitlab-ci.d/meson-cross/${TARGET}-${TOOLCHAIN}.meson
-Dc_args="${COV_C_ARGS}" ${COV_MESON_BUILD_ARGS}
- meson compile -C ${BUILD_DIR}
artifacts:
paths:
- ${BUILD_DIR}/

View File

@ -1,9 +0,0 @@
# General target templates.
.target:all:
image:
name: $DOCKER_IMAGE_NAME-$TARGET
rules:
- if: "$TARGET =~ $ACTIVE_TARGET_PATTERN"
before_script:
- ${LOAD_TARGET_ENV}

View File

@ -1,112 +0,0 @@
spec:
inputs:
target:
description:
Build target in form of "OS-ARCH" pair (e.g., linux-amd64). Mostly the
same as platform string for Docker but with a hyphen instead of slash.
toolchain:
description:
An array of toolchains to test with. Each toolchain should have an
appropriate Meson cross file.
type: array
default: [gnu, llvm]
qemu_cpu:
description:
An array of QEMU_CPU environmental variables used as a job matrix
variable, and in turn by Docker (which uses QEMU underneath). It is not
used by x86 targets, as they are executed natively on the host.
type: array
default: [""]
pixman_disable:
description:
An array of PIXMAN_DISABLE targets used as a job matrix variable.
type: array
default: [""]
timeout:
description:
GitLab job timeout property. May need to be increased for slow
targets.
default: 1h
test_timeout_multiplier:
description:
Test timeout multiplier flag used for Meson test execution. May need to
be increased for slow targets.
type: number
default: 20
meson_testthreads:
description:
Sets MESON_TESTTHREADS environmental variable. For some platforms, the
tests should be executed one by one (without multithreading) to prevent
gcovr errors.
type: number
default: 0
gcovr_flags:
description:
Additional flags passed to gcovr tool.
default: ""
job_name_prefix:
description:
Additional prefix for the job name. Can be used to disable a job with a
"." prefix.
default: ""
job_name_suffix:
description:
Additional suffix for the job name. Can be used to prevent job
duplication for jobs for the same target.
default: ""
allow_failure:
description:
Set the `allow_failure` flag for jobs that are expected to fail.
Remember to set `retry` argument to 0 to prevent unnecessary retries.
type: boolean
default: false
retry:
description:
Set the `retry` flag for a job. Usually used together with
`allow_failure`.
type: number
default: 1
---
"$[[ inputs.job_name_prefix ]]test:$[[ inputs.target ]]$[[ inputs.job_name_suffix ]]":
extends: .target:all
stage: test
allow_failure: $[[ inputs.allow_failure ]]
retry: $[[ inputs.retry ]]
timeout: $[[ inputs.timeout ]]
needs:
- job: docker
optional: true
parallel:
matrix:
- TARGET: $[[ inputs.target ]]
- job: build:$[[ inputs.target ]]
parallel:
matrix:
- TOOLCHAIN: $[[ inputs.toolchain ]]
variables:
TARGET: $[[ inputs.target ]]
TEST_TIMEOUT_MULTIPLIER: $[[ inputs.test_timeout_multiplier ]]
GCOVR_FLAGS: $[[ inputs.gcovr_flags ]]
MESON_ARGS: -t ${TEST_TIMEOUT_MULTIPLIER} --no-rebuild -v ${TEST_NAME}
MESON_TESTTHREADS: $[[ inputs.meson_testthreads ]]
parallel:
matrix:
- TOOLCHAIN: $[[ inputs.toolchain ]]
PIXMAN_DISABLE: $[[ inputs.pixman_disable ]]
QEMU_CPU: $[[ inputs.qemu_cpu ]]
script:
- meson test -C ${BUILD_DIR} ${MESON_ARGS}
after_script:
- mkdir -p ${COVERAGE_OUT}
- gcovr ${GCOVR_FLAGS} -r ./ ${BUILD_DIR} -e ./subprojects
--json ${COVERAGE_OUT}.json
--html-details ${COVERAGE_OUT}/coverage.html
--print-summary || echo "No coverage data available."
artifacts:
paths:
- ${BUILD_DIR}/meson-logs/testlog.txt
- ${COVERAGE_BASE_DIR}/
reports:
junit:
- ${BUILD_DIR}/meson-logs/testlog.junit.xml

View File

@ -1,16 +0,0 @@
#
# This is the GitLab CI configuration file for the mainstream pixman project:
# https://gitlab.freedesktop.org/pixman/pixman/-/pipelines
#
# !!! DO NOT ADD ANY NEW CONFIGURATION TO THIS FILE !!!
#
# Only documentation or comments is accepted.
#
# To use a different set of jobs than the mainstream project, you need to set
# the location of your custom yml file at "custom CI/CD configuration path", on
# your GitLab CI namespace:
# https://docs.gitlab.com/ee/ci/pipelines/settings.html#custom-cicd-configuration-path
#
include:
- local: '/.gitlab-ci.d/pixman-project.yml'

16309
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

133
Makefile.am Normal file
View File

@ -0,0 +1,133 @@
SUBDIRS = pixman demos test
pkgconfigdir=$(libdir)/pkgconfig
pkgconfig_DATA=pixman-1.pc
$(pkgconfig_DATA): pixman-1.pc.in
snapshot:
distdir="$(distdir)-`date '+%Y%m%d'`"; \
test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \
$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist
GPGKEY=6FF7C1A8
USERNAME=$$USER
RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi)
RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org
RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s
RELEASE_CAIRO_URL = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s
RELEASE_XORG_URL = http://xorg.freedesktop.org/archive/individual/lib
RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org
RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib
RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org
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
$(sha1_tgz): $(tar_gz)
sha1sum $^ > $@
$(md5_tgz): $(tar_gz)
md5sum $^ > $@
$(sha1_tbz2): $(tar_bz2)
sha1sum $^ > $@
$(md5_tbz2): $(tar_bz2)
md5sum $^ > $@
$(gpg_file): $(sha1_tgz)
@echo "Please enter your GPG password to sign the checksum."
gpg --armor --sign $^
HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2)
release-verify-newer:
@echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..."
@ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \
|| (echo "Ouch." && echo "Found: $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)/$(tar_gz)" \
&& echo "Refusing to try to generate a new release of the same name." \
&& false)
@ssh $(RELEASE_CAIRO_HOST) test ! -e $(RELEASE_CAIRO_DIR)/$(tar_gz) \
|| (echo "Ouch." && echo "Found: $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)/$(tar_gz)" \
&& echo "Refusing to try to generate a new release of the same name." \
&& false)
@echo "Good."
release-remove-old:
$(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file)
ensure-prev:
@if [[ "$(PREV)" == "" ]]; then \
echo "" && \
echo "You must set the PREV variable on the make command line to" && \
echo "the last version." && \
echo "" && \
echo "For example:" && \
echo " make PREV=0.7.3" && \
echo "" && \
false; \
fi
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)
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)
release-publish-message: $(HASHFILES) ensure-prev
@echo "Please follow the instructions in RELEASING to push stuff out and"
@echo "send out the announcement mails. Here is the excerpt you need:"
@echo ""
@echo "Lists: $(RELEASE_ANNOUNCE_LIST)"
@echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available"
@echo "============================== CUT HERE =============================="
@echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)"
@echo ""
@echo "tar.gz:"
@echo " $(RELEASE_CAIRO_URL)/$(tar_gz)"
@echo " $(RELEASE_XORG_URL)/$(tar_gz)"
@echo ""
@echo "tar.bz2:"
@echo " $(RELEASE_XORG_URL)/$(tar_bz2)"
@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 ""
@echo "GPG signature:"
@echo " $(RELEASE_CAIRO_URL)/$(gpg_file)"
@echo " (signed by `git config --get user.name` <`git config --get user.email`>)"
@echo ""
@echo "Git:"
@echo " git://git.freedesktop.org/git/pixman"
@echo " tag: $(PACKAGE)-$(VERSION)"
@echo ""
@echo "Log:"
@git log --no-merges "$(PACKAGE)-$(PREV)".."$(PACKAGE)-$(VERSION)" | git shortlog | awk '{ printf "\t"; print ; }' | cut -b1-80
@echo "============================== CUT HERE =============================="
@echo ""
release-publish: release-upload release-tag release-publish-message
.PHONY: release-upload release-publish release-publish-message release-tag

25
Makefile.win32 Normal file
View File

@ -0,0 +1,25 @@
default: all
top_srcdir = .
include $(top_srcdir)/Makefile.win32.common
# Recursive targets
pixman_r:
@$(MAKE) -C pixman -f Makefile.win32
test_r:
@$(MAKE) -C test -f Makefile.win32
clean_r:
@$(MAKE) -C pixman -f Makefile.win32 clean
@$(MAKE) -C test -f Makefile.win32 clean
check_r:
@$(MAKE) -C test -f Makefile.win32 check
# Base targets
all: test_r
clean: clean_r
check: check_r

54
Makefile.win32.common Normal file
View File

@ -0,0 +1,54 @@
LIBRARY = pixman-1
CC = cl
LD = link
AR = lib
PERL = perl
ifeq ($(top_builddir),)
top_builddir = $(top_srcdir)
endif
CFG_VAR = $(CFG)
ifeq ($(CFG_VAR),)
CFG_VAR = release
endif
ifeq ($(CFG_VAR),debug)
CFG_CFLAGS = -MDd -Od -Zi
CFG_LDFLAGS = -DEBUG
else
CFG_CFLAGS = -MD -O2
CFG_LDFLAGS =
endif
# Package definitions, to be used instead of those provided in config.h
PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT=""
BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman
PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS)
PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS)
PIXMAN_ARFLAGS = -nologo $(LDFLAGS)
inform:
ifneq ($(CFG),release)
ifneq ($(CFG),debug)
ifneq ($(CFG),)
@echo "Invalid specified configuration option: "$(CFG)"."
@echo
@echo "Possible choices for configuration are 'release' and 'debug'"
@exit 1
endif
@echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)"
endif
endif
$(CFG_VAR)/%.obj: %.c $(BUILT_SOURCES)
@mkdir -p $(CFG_VAR)
@$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $<
clean: inform
@$(RM) $(CFG_VAR)/*.{exe,ilk,lib,obj,pdb} $(BUILT_SOURCES) || exit 0

136
README
View File

@ -1,134 +1,22 @@
Pixman
======
Pixman is a library that provides low-level pixel manipulation
pixman is a library that provides low-level pixel manipulation
features such as image compositing and trapezoid rasterization.
Questions should be directed to the pixman mailing list:
All questions regarding this software should be directed to the pixman
mailing list:
https://lists.freedesktop.org/mailman/listinfo/pixman
http://lists.freedesktop.org/mailman/listinfo/pixman
You can also file bugs at
Please send patches and bug reports either to the mailing list above,
or file them at the freedesktop bug tracker:
https://gitlab.freedesktop.org/pixman/pixman/-/issues/new
https://bugs.freedesktop.org/enter_bug.cgi?product=pixman
or submit improvements in form of a Merge Request via
The master development code repository can be found at:
https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests
git://anongit.freedesktop.org/git/pixman
For real time discussions about pixman, feel free to join the IRC
channels #cairo and #xorg-devel on the FreeNode IRC network.
http://gitweb.freedesktop.org/?p=pixman;a=summary
For more information on the git code manager, see:
Contributing
------------
In order to contribute to pixman, you will need a working knowledge of
the git version control system. For a quick getting started guide,
there is the "Everyday Git With 20 Commands Or So guide"
https://www.kernel.org/pub/software/scm/git/docs/everyday.html
from the Git homepage. For more in depth git documentation, see the
resources on the Git community documentation page:
https://git-scm.com/documentation
Pixman uses the infrastructure from the freedesktop.org umbrella
project. For instructions about how to use the git service on
freedesktop.org, see:
https://www.freedesktop.org/wiki/Infrastructure/git/Developers
The Pixman master repository can be found at:
https://gitlab.freedesktop.org/pixman/pixman
Sending patches
---------------
Patches should be submitted in form of Merge Requests via Gitlab.
You will first need to create a fork of the main pixman repository at
https://gitlab.freedesktop.org/pixman/pixman
via the Fork button on the top right. Once that is done you can add your
personal repository as a remote to your local pixman development git checkout:
git remote add my-gitlab git@gitlab.freedesktop.org:YOURUSERNAME/pixman.git
git fetch my-gitlab
Make sure to have added ssh keys to your gitlab profile at
https://gitlab.freedesktop.org/profile/keys
Once that is set up, the general workflow for sending patches is to create a
new local branch with your improvements and once it's ready push it to your
personal pixman fork:
git checkout -b fix-some-bug
...
git push my-gitlab
The output of the `git push` command will include a link that allows you to
create a Merge Request against the official pixman repository.
Whenever you make changes to your branch (add new commits or fix up commits)
you push them back to your personal pixman fork:
git push -f my-gitlab
If there is an open Merge Request Gitlab will automatically pick up the
changes from your branch and pixman developers can review them anew.
In order for your patches to be accepted, please consider the
following guidelines:
- At each point in the series, pixman should compile and the test
suite should pass.
The exception here is if you are changing the test suite to
demonstrate a bug. In this case, make one commit that makes the
test suite fail due to the bug, and then another commit that fixes
the bug.
You can run the test suite with
meson test -C builddir
It will take around two minutes to run on a modern PC.
- Follow the coding style described in the CODING_STYLE file
- For bug fixes, include an update to the test suite to make sure
the bug doesn't reappear.
- For new features, add tests of the feature to the test
suite. Also, add a program demonstrating the new feature to the
demos/ directory.
- Write descriptive commit messages. Useful information to include:
- Benchmark results, before and after
- Description of the bug that was fixed
- Detailed rationale for any new API
- Alternative approaches that were rejected (and why they
don't work)
- If review comments were incorporated, a brief version
history describing what those changes were.
- For big patch series, write an introductory post with an overall
description of the patch series, including benchmarks and
motivation. Each commit message should still be descriptive and
include enough information to understand why this particular commit
was necessary.
Pixman has high standards for code quality and so almost everybody
should expect to have the first versions of their patches rejected.
If you think that the reviewers are wrong about something, or that the
guidelines above are wrong, feel free to discuss the issue. The purpose
of the guidelines and code review is to ensure high code quality; it is
not an exercise in compliance.
http://wiki.x.org/wiki/GitPage

View File

@ -10,11 +10,12 @@ Here are the steps to follow to create a new pixman release:
git log master...origin (no output; note: *3* dots)
2) Increment the version in meson.build.
2) Increment pixman_(major|minor|micro) in configure.ac according to
the directions in that file.
3) Make sure that new version works, including
- meson test passes
- make distcheck passes
- the X server still works with the new pixman version
installed
@ -54,5 +55,3 @@ Here are the steps to follow to create a new pixman release:
You must use "--tags" here; otherwise the new tag will not
be pushed out.
8) Change the topic of the #cairo IRC channel on freenode to advertise
the new version.

271
TODO Normal file
View File

@ -0,0 +1,271 @@
- Testing
- Test implementations against each other
- Test both with and without the operator strength reduction.
They shold be identical.
- SSE 2 issues:
- Use MM_HINT_NTA instead of MM_HINT_T0
- Use of fbCompositeOver_x888x8x8888sse2()
- Update the RLEASING file
- Things to keep in mind if breaking ABI:
- There should be a guard #ifndef I_AM_EITHER_CAIRO_OR_THE_X_SERVER
- X server will require 16.16 essentially forever. Can we get
the required precision by simply adding offset_x/y to the
relevant rendering API?
- Get rid of workaround for X server bug.
- pixman_image_set_indexed() should copy its argument, and X
should be ported over to use a pixman_image as the
representation of a Picture, rather than creating one on each
operation.
- We should get rid of pixman_set_static_pointers()
- We should get rid of the various trapezoid helper functions().
(They only exist because they are theoretically available to
drivers).
- 16 bit regions should be deleted
- There should only be one trap rasterization API.
- The PIXMAN_g8/c8/etc formats should use the A channel
to indicate the actual depth. That way PIXMAN_x4c4 and PIXMAN_c8
won't collide.
- Maybe bite the bullet and make configure.ac generate a pixman-types.h
file that can be included from pixman.h to avoid the #ifdef magic
in pixman.h
- Make pixman_region_point_in() survive a NULL box, then fix up
pixman-compose.c
- Possibly look into inlining the fetch functions
- There is a bug with source clipping demonstrated by clip-test in the
test directory. If we interprete source clipping as given in
destination coordinates, which is probably the only sane choice,
then the result should have two red bars down the sides.
- Test suite
- Add a general way of dealing with architecture specific
fast-paths. The current idea is to have each operation that can
be optimized is called through a function pointer that is
initially set to an initialization function that is responsible for
setting the function pointer to the appropriate fast-path.
- Go through things marked FIXME
- Add calls to prepare and finish access where necessary. grep for
ACCESS_MEM, and make sure they are correctly wrapped in prepare
and finish.
- restore READ/WRITE in the fbcompose combiners since they sometimes
store directly to destination drawables.
- It probably makes sense to move the more strange X region API
into pixman as well, but guarded with PIXMAN_XORG_COMPATIBILITY
- Reinstate the FbBits typedef? At the moment we don't
even have the FbBits type; we just use uint32_t everywhere.
Keith says in bug 2335:
The 64-bit code in fb (pixman) is probably broken; it hasn't been
used in quite some time as PCI (and AGP) is 32-bits wide, so
doing things 64-bits at a time is a net loss. To quickly fix
this, I suggest just using 32-bit datatypes by setting
IC_SHIFT to 5 for all machines.
- Consider optimizing the 8/16 bit solid fills in pixman-util.c by
storing more than one value at a time.
- Add an image cache to prevent excessive malloc/free. Note that pixman
needs to be thread safe when used from cairo.
- Moving to 24.8 coordinates. This is tricky because X is still
defined as 16.16 and will be basically forever. It's possible we
could do this by adding extra offset_x/y parameters to the
trapezoid calls. The X server could then just call the API with
(0, 0). Cairo would have to make sure that the delta *within* a
batch of trapezoids does not exceed 16 bit.
- Consider adding actual backends. Brain dump:
A backend is something that knows how to
- Create images
- Composite three images
- Rasterize trapezoids
- Do solid fills and blits
These operations are provided by a vtable that the backend will
create when it is initialized. Initial backends:
- VMX
- SSE2
- MMX
- Plain Old C
When the SIMD backends are initialized, they will be passed a
pointer to the Plain Old C backend that they can use for fallback
purposes.
Images would gain a vtable as well that would contain things like
- Read scanline
- Write scanline
(Or even read_patch/write_patch as suggested by Keith a while
back).
This could simplify the compositing code considerably.
- Review the pixman_format_code_t enum to make sure it will support
future formats. Some formats we will probably need:
ARGB/ABGR with 16/32/64 bit integer/floating channels
YUV2,
YV12
Also we may need the ability to distinguish between PICT_c8 and
PICT_x4c4. (This could be done by interpreting the A channel as
the depth for TYPE_COLOR and TYPE_GRAY formats).
A possibility may be to reserve the two top bits and make them
encode "number of places to shift the channel widths given" Since
these bits are 00 at the moment everything will continue to work,
but these additional widths will be allowed:
All even widths between 18-32
All multiples of four widths between 33 and 64
All multiples of eight between 64 and 128
This means things like r21g22b21 won't work - is that worth
worrying about? I don't think so. And of course the bpp field
can't handle a depth of over 256, so > 64 bit channels arent'
really all that useful.
We could reserve one extra bit to indicate floating point, but
we may also just add
PIXMAN_TYPE_ARGB_FLOAT
PIXMAN_TYPE_BGRA_FLOAT
PIXMAN_TYPE_A_FLOAT
image types. With five bits we can support up to 32 different
format types, which should be enough for everybody, even if we
decide to support all the various video formats here:
http://www.fourcc.org/yuv.php
It may make sense to have a PIXMAN_TYPE_YUV, and then use the
channel bits to specify the exact subtype.
Another possibility is to add
PIXMAN_TYPE_ARGB_W
PIXMAN_TYPE_ARGB_WW
where the channel widths would get 16 and 32 added to them,
respectively.
What about color spaces such a linear vs. srGB etc.?
done:
- Use pixmanFillsse2 and pixmanBltsse2
- Be consistent about calling sse2 sse2
- Rename "SSE" to "MMX_EXTENSIONS". (Deleted mmx extensions).
- Commented-out uses of fbCompositeCopyAreasse2()
- Consider whether calling regions region16 is really such a great
idea. Vlad wants 32 bit regions for Cairo. This will break X server
ABI, but should otherwise be mostly harmless, though a
pixman_region_get_boxes16() may be useful.
- Altivec signal issue (Company has fix, there is also a patch by
dwmw2 in rawhide).
- Behdad's MMX issue - see list
- SSE2 issues:
- Crashes in Mozilla because of unaligned stack. Possible fixes
- Make use of gcc 4.2 feature to align the stack
- Write some sort of trampoline that aligns the stack
before calling SSE functions.
- Get rid of the switch-of-doom; replace it with a big table
describing the various fast paths.
- Make source clipping optional.
- done: source clipping happens through an indirection.
still needs to make the indirection settable. (And call it
from X)
- Run cairo test suite; fix bugs
- one bug in source-scale-clip
- Remove the warning suppression in the ACCESS_MEM macro and fix the
warnings that are real
- irrelevant now.
- make the wrapper functions global instead of image specific
- this won't work since pixman is linked to both fb and wfb
- Add non-mmx solid fill
- Make sure the endian-ness macros are defined correctly.
- The rectangles in a region probably shouldn't be returned const as
the X server will be changing them.
- Right now we _always_ have a clip region, which is empty by default.
Why does this work at all? It probably doesn't. The server
distinguishes two cases, one where nothing is clipped (CT_NONE), and
one where there is a clip region (CT_REGION).
- Default clip region should be the full image
- Test if pseudo color still works. It does, but it also shows that
copying a pixman_indexed_t on every composite operation is not
going to fly. So, for now set_indexed() does not copy the
indexed table.
Also just the malloc() to allocate a pixman image shows up pretty
high.
Options include
- Make all the setters not copy their arguments
- Possibly combined with going back to the stack allocated
approach that we already use for regions.
- Keep a cached pixman_image_t around for every picture. It would
have to be kept uptodate every time something changes about the
picture.
- Break the X server ABI and simply have the relevant parameter
stored in the pixman image. This would have the additional benefits
that:
- We can get rid of the annoying repeat field which is duplicated
elsewhere.
- We can use pixman_color_t and pixman_gradient_stop_t
etc. instead of the types that are defined in
renderproto.h

View File

@ -1,5 +0,0 @@
.text
.arch armv8-a
.altmacro
prfm pldl2strm, [x0]
xtn v0.8b, v0.8h

View File

@ -1,10 +0,0 @@
.text
.arch armv6
.object_arch armv4
.arm
.altmacro
#ifndef __ARM_EABI__
#error EABI is required (to be sure that calling conventions are compatible)
#endif
pld [r0]
uqadd8 r0, r0, r0

14
autogen.sh Executable file
View File

@ -0,0 +1,14 @@
#! /bin/sh
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd $srcdir
autoreconf -v --install || exit 1
cd $ORIGDIR || exit $?
if test -z "$NOCONFIGURE"; then
$srcdir/configure "$@"
fi

951
configure.ac Normal file
View File

@ -0,0 +1,951 @@
dnl Copyright 2005 Red Hat, Inc.
dnl
dnl Permission to use, copy, modify, distribute, and sell this software and its
dnl documentation for any purpose is hereby granted without fee, provided that
dnl the above copyright notice appear in all copies and that both that
dnl copyright notice and this permission notice appear in supporting
dnl documentation, and that the name of Red Hat not be used in
dnl advertising or publicity pertaining to distribution of the software without
dnl specific, written prior permission. Red Hat makes no
dnl representations about the suitability of this software for any purpose. It
dnl is provided "as is" without express or implied warranty.
dnl
dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
dnl EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dnl PERFORMANCE OF THIS SOFTWARE.
dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ([2.57])
# Pixman versioning scheme
#
# - The version in git has an odd MICRO version number
#
# - Released versions, both development and stable, have an
# even MICRO version number
#
# - Released development versions have an odd MINOR number
#
# - Released stable versions have an even MINOR number
#
# - Versions that break ABI must have a new MAJOR number
#
# - If you break the ABI, then at least this must be done:
#
# - increment MAJOR
#
# - In the first development release where you break ABI, find
# all instances of "pixman-n" and change them to pixman-(n+1)
#
# This needs to be done at least in
# configure.ac
# all Makefile.am's
# pixman-n.pc.in
#
# This ensures that binary incompatible versions can be installed
# in parallel. See http://www106.pair.com/rhp/parallel.html for
# more information
#
m4_define([pixman_major], 0)
m4_define([pixman_minor], 25)
m4_define([pixman_micro], 2)
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])
# Suppress verbose compile lines
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
test_CFLAGS=${CFLAGS+set} # We may override autoconf default CFLAGS.
AC_PROG_CC
AM_PROG_AS
AC_PROG_LIBTOOL
AC_CHECK_FUNCS([getisax])
AC_C_BIGENDIAN
AC_C_INLINE
dnl PIXMAN_LINK_WITH_ENV(env-setup, program, true-action, false-action)
dnl
dnl Compiles and links the given program in the environment setup by env-setup
dnl and executes true-action on success and false-action on failure.
AC_DEFUN([PIXMAN_LINK_WITH_ENV],[dnl
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
save_LIBS="$LIBS"
CFLAGS=""
LDFLAGS=""
LIBS=""
$1
AC_LINK_IFELSE(
[AC_LANG_SOURCE([$2])],
[pixman_cc_stderr=`test -f conftest.err && cat conftest.err`
pixman_cc_flag=yes],
[pixman_cc_stderr=`test -f conftest.err && cat conftest.err`
pixman_cc_flag=no])
if test "x$pixman_cc_stderr" != "x"; then
pixman_cc_flag=no
fi
if test "x$pixman_cc_flag" = "xyes"; then
ifelse([$3], , :, [$3])
else
ifelse([$4], , :, [$4])
fi
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
])
dnl Find a -Werror for catching warnings.
WERROR=
for w in -Werror -errwarn; do
if test "z$WERROR" = "z"; then
AC_MSG_CHECKING([whether the compiler supports $w])
PIXMAN_LINK_WITH_ENV(
[CFLAGS=$w],
[int main(int c, char **v) { (void)c; (void)v; return 0; }],
[WERROR=$w; yesno=yes], [yesno=no])
AC_MSG_RESULT($yesno)
fi
done
dnl PIXMAN_CHECK_CFLAG(flag, [program])
dnl Adds flag to CFLAGS if the given program links without warnings or errors.
AC_DEFUN([PIXMAN_CHECK_CFLAG], [dnl
AC_MSG_CHECKING([whether the compiler supports $1])
PIXMAN_LINK_WITH_ENV(
[CFLAGS="$WERROR $1"],
[$2
int main(int c, char **v) { (void)c; (void)v; return 0; }
],
[_yesno=yes],
[_yesno=no])
if test "x$_yesno" = xyes; then
CFLAGS="$CFLAGS $1"
fi
AC_MSG_RESULT($_yesno)
])
AC_CHECK_SIZEOF(long)
# Checks for Sun Studio compilers
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
AC_CHECK_DECL([__amd64], [AMD64_ABI="yes"], [AMD64_ABI="no"])
# Default CFLAGS to -O -g rather than just the -g from AC_PROG_CC
# if we're using Sun Studio and neither the user nor a config.site
# has set CFLAGS.
if test $SUNCC = yes && \
test "x$test_CFLAGS" = "x" && \
test "$CFLAGS" = "-g"
then
CFLAGS="-O -g"
fi
#
# We ignore pixman_major in the version here because the major version should
# always be encoded in the actual library name. Ie., the soname is:
#
# pixman-$(pixman_major).0.minor.micro
#
m4_define([lt_current], [pixman_minor])
m4_define([lt_revision], [pixman_micro])
m4_define([lt_age], [pixman_minor])
LT_VERSION_INFO="lt_current:lt_revision:lt_age"
PIXMAN_VERSION_MAJOR=pixman_major()
AC_SUBST(PIXMAN_VERSION_MAJOR)
PIXMAN_VERSION_MINOR=pixman_minor()
AC_SUBST(PIXMAN_VERSION_MINOR)
PIXMAN_VERSION_MICRO=pixman_micro()
AC_SUBST(PIXMAN_VERSION_MICRO)
AC_SUBST(LT_VERSION_INFO)
# Check for dependencies
PIXMAN_CHECK_CFLAG([-Wall])
PIXMAN_CHECK_CFLAG([-fno-strict-aliasing])
AC_PATH_PROG(PERL, perl, no)
if test "x$PERL" = xno; then
AC_MSG_ERROR([Perl is required to build pixman.])
fi
AC_SUBST(PERL)
dnl =========================================================================
dnl OpenMP for the test suite?
dnl
# Check for OpenMP support only when autoconf support that (require autoconf >=2.62)
OPENMP_CFLAGS=
m4_ifdef([AC_OPENMP], [AC_OPENMP])
if test "x$enable_openmp" = "xyes" && test "x$ac_cv_prog_c_openmp" = "xunsupported" ; then
AC_MSG_WARN([OpenMP support requested but found unsupported])
fi
dnl May not fail to link without -Wall -Werror added
dnl So try to link only when openmp is supported
dnl ac_cv_prog_c_openmp is not defined when --disable-openmp is used
if test "x$ac_cv_prog_c_openmp" != "xunsupported" && test "x$ac_cv_prog_c_openmp" != "x"; then
m4_define([openmp_test_program],[dnl
#include <stdio.h>
extern unsigned int lcg_seed;
#pragma omp threadprivate(lcg_seed)
unsigned int lcg_seed;
unsigned function(unsigned a, unsigned b)
{
lcg_seed ^= b;
return ((a + b) ^ a ) + lcg_seed;
}
int main(int argc, char **argv)
{
int i;
int n1 = 0, n2 = argc;
unsigned checksum = 0;
int verbose = argv != NULL;
unsigned (*test_function)(unsigned, unsigned);
test_function = function;
#pragma omp parallel for reduction(+:checksum) default(none) \
shared(n1, n2, test_function, verbose)
for (i = n1; i < n2; i++)
{
unsigned crc = test_function (i, 0);
if (verbose)
printf ("%d: %08X\n", i, crc);
checksum += crc;
}
printf("%u\n", checksum);
return 0;
}
])
PIXMAN_LINK_WITH_ENV(
[CFLAGS="$OPENMP_CFLAGS" LDFLAGS="$OPENMP_CFLAGS"],
[openmp_test_program],
[have_openmp=yes],
[have_openmp=no])
if test "x$have_openmp" = "xyes" ; then
AC_DEFINE(USE_OPENMP, 1, [use OpenMP in the test suite])
fi
fi
AC_SUBST(OPENMP_CFLAGS)
dnl =========================================================================
dnl -fvisibility stuff
PIXMAN_CHECK_CFLAG([-fvisibility=hidden], [dnl
#if defined(__GNUC__) && (__GNUC__ >= 4)
#ifdef _WIN32
#error Have -fvisibility but it is ignored and generates a warning
#endif
#else
#error Need GCC 4.0 for visibility
#endif
])
PIXMAN_CHECK_CFLAG([-xldscope=hidden], [dnl
#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
#else
#error Need Sun Studio 8 for visibility
#endif
])
dnl ===========================================================================
dnl Check for MMX
if test "x$MMX_CFLAGS" = "x" ; then
if test "x$SUNCC" = "xyes"; then
# Sun Studio doesn't have an -xarch=mmx flag, so we have to use sse
# but if we're building 64-bit, mmx & sse support is on by default and
# -xarch=sse throws an error instead
if test "$AMD64_ABI" = "no" ; then
MMX_CFLAGS="-xarch=sse"
fi
else
MMX_CFLAGS="-mmmx -Winline"
fi
fi
have_mmx_intrinsics=no
AC_MSG_CHECKING(whether to use MMX intrinsics)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="$MMX_CFLAGS $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
#error "Need GCC >= 3.4 for MMX intrinsics"
#endif
#if defined(__clang__)
#error "clang chokes on the inline assembly in pixman-mmx.c"
#endif
#include <mmintrin.h>
int main () {
__m64 v = _mm_cvtsi32_si64 (1);
return _mm_cvtsi64_si32 (v);
}]])], have_mmx_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(mmx,
[AC_HELP_STRING([--disable-mmx],
[disable x86 MMX fast paths])],
[enable_mmx=$enableval], [enable_mmx=auto])
if test $enable_mmx = no ; then
have_mmx_intrinsics=disabled
fi
if test $have_mmx_intrinsics = yes ; then
AC_DEFINE(USE_X86_MMX, 1, [use x86 MMX compiler intrinsics])
else
MMX_CFLAGS=
fi
AC_MSG_RESULT($have_mmx_intrinsics)
if test $enable_mmx = yes && test $have_mmx_intrinsics = no ; then
AC_MSG_ERROR([x86 MMX intrinsics not detected])
fi
AM_CONDITIONAL(USE_X86_MMX, test $have_mmx_intrinsics = yes)
dnl ===========================================================================
dnl Check for SSE2
if test "x$SSE2_CFLAGS" = "x" ; then
if test "x$SUNCC" = "xyes"; then
# SSE2 is enabled by default in the Sun Studio 64-bit environment
if test "$AMD64_ABI" = "no" ; then
SSE2_CFLAGS="-xarch=sse2"
fi
else
SSE2_CFLAGS="-msse2 -Winline"
fi
fi
have_sse2_intrinsics=no
AC_MSG_CHECKING(whether to use SSE2 intrinsics)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="$SSE2_CFLAGS $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
# if !defined(__amd64__) && !defined(__x86_64__)
# error "Need GCC >= 4.2 for SSE2 intrinsics on x86"
# endif
#endif
#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>
int main () {
__m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
c = _mm_xor_si128 (a, b);
return 0;
}]])], have_sse2_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(sse2,
[AC_HELP_STRING([--disable-sse2],
[disable SSE2 fast paths])],
[enable_sse2=$enableval], [enable_sse2=auto])
if test $enable_sse2 = no ; then
have_sse2_intrinsics=disabled
fi
if test $have_sse2_intrinsics = yes ; then
AC_DEFINE(USE_SSE2, 1, [use SSE2 compiler intrinsics])
fi
AC_MSG_RESULT($have_sse2_intrinsics)
if test $enable_sse2 = yes && test $have_sse2_intrinsics = no ; then
AC_MSG_ERROR([SSE2 intrinsics not detected])
fi
AM_CONDITIONAL(USE_SSE2, test $have_sse2_intrinsics = yes)
dnl ===========================================================================
dnl Other special flags needed when building code using MMX or SSE instructions
case $host_os in
solaris*)
# When building 32-bit binaries, apply a mapfile to ensure that the
# binaries aren't flagged as only able to run on MMX+SSE capable CPUs
# since they check at runtime before using those instructions.
# Not all linkers grok the mapfile format so we check for that first.
if test "$AMD64_ABI" = "no" ; then
use_hwcap_mapfile=no
AC_MSG_CHECKING(whether to use a hardware capability map file)
hwcap_save_LDFLAGS="$LDFLAGS"
HWCAP_LDFLAGS='-Wl,-M,$(srcdir)/solaris-hwcap.mapfile'
LDFLAGS="$LDFLAGS -Wl,-M,pixman/solaris-hwcap.mapfile"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])],
use_hwcap_mapfile=yes,
HWCAP_LDFLAGS="")
LDFLAGS="$hwcap_save_LDFLAGS"
AC_MSG_RESULT($use_hwcap_mapfile)
fi
if test "x$MMX_LDFLAGS" = "x" ; then
MMX_LDFLAGS="$HWCAP_LDFLAGS"
fi
if test "x$SSE2_LDFLAGS" = "x" ; then
SSE2_LDFLAGS="$HWCAP_LDFLAGS"
fi
;;
esac
AC_SUBST(IWMMXT_CFLAGS)
AC_SUBST(MMX_CFLAGS)
AC_SUBST(MMX_LDFLAGS)
AC_SUBST(SSE2_CFLAGS)
AC_SUBST(SSE2_LDFLAGS)
dnl ===========================================================================
dnl Check for VMX/Altivec
if test -n "`$CC -v 2>&1 | grep version | grep Apple`"; then
VMX_CFLAGS="-faltivec"
else
VMX_CFLAGS="-maltivec -mabi=altivec"
fi
have_vmx_intrinsics=no
AC_MSG_CHECKING(whether to use VMX/Altivec intrinsics)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="$VMX_CFLAGS $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
#error "Need GCC >= 3.4 for sane altivec support"
#endif
#include <altivec.h>
int main () {
vector unsigned int v = vec_splat_u32 (1);
v = vec_sub (v, v);
return 0;
}]])], have_vmx_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(vmx,
[AC_HELP_STRING([--disable-vmx],
[disable VMX fast paths])],
[enable_vmx=$enableval], [enable_vmx=auto])
if test $enable_vmx = no ; then
have_vmx_intrinsics=disabled
fi
if test $have_vmx_intrinsics = yes ; then
AC_DEFINE(USE_VMX, 1, [use VMX compiler intrinsics])
else
VMX_CFLAGS=
fi
AC_MSG_RESULT($have_vmx_intrinsics)
if test $enable_vmx = yes && test $have_vmx_intrinsics = no ; then
AC_MSG_ERROR([VMX intrinsics not detected])
fi
AC_SUBST(VMX_CFLAGS)
AM_CONDITIONAL(USE_VMX, test $have_vmx_intrinsics = yes)
dnl ==========================================================================
dnl Check if assembler is gas compatible and supports ARM SIMD instructions
have_arm_simd=no
AC_MSG_CHECKING(whether to use ARM SIMD assembler)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="-x assembler-with-cpp $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.arch armv6
.object_arch armv4
.arm
.altmacro
#ifndef __ARM_EABI__
#error EABI is required (to be sure that calling conventions are compatible)
#endif
pld [r0]
uqadd8 r0, r0, r0]])], have_arm_simd=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(arm-simd,
[AC_HELP_STRING([--disable-arm-simd],
[disable ARM SIMD fast paths])],
[enable_arm_simd=$enableval], [enable_arm_simd=auto])
if test $enable_arm_simd = no ; then
have_arm_simd=disabled
fi
if test $have_arm_simd = yes ; then
AC_DEFINE(USE_ARM_SIMD, 1, [use ARM SIMD assembly optimizations])
fi
AM_CONDITIONAL(USE_ARM_SIMD, test $have_arm_simd = yes)
AC_MSG_RESULT($have_arm_simd)
if test $enable_arm_simd = yes && test $have_arm_simd = no ; then
AC_MSG_ERROR([ARM SIMD intrinsics not detected])
fi
dnl ==========================================================================
dnl Check if assembler is gas compatible and supports NEON instructions
have_arm_neon=no
AC_MSG_CHECKING(whether to use ARM NEON assembler)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="-x assembler-with-cpp $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.fpu neon
.arch armv7a
.object_arch armv4
.eabi_attribute 10, 0
.arm
.altmacro
#ifndef __ARM_EABI__
#error EABI is required (to be sure that calling conventions are compatible)
#endif
pld [r0]
vmovn.u16 d0, q0]])], have_arm_neon=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(arm-neon,
[AC_HELP_STRING([--disable-arm-neon],
[disable ARM NEON fast paths])],
[enable_arm_neon=$enableval], [enable_arm_neon=auto])
if test $enable_arm_neon = no ; then
have_arm_neon=disabled
fi
if test $have_arm_neon = yes ; then
AC_DEFINE(USE_ARM_NEON, 1, [use ARM NEON assembly optimizations])
fi
AM_CONDITIONAL(USE_ARM_NEON, test $have_arm_neon = yes)
AC_MSG_RESULT($have_arm_neon)
if test $enable_arm_neon = yes && test $have_arm_neon = no ; then
AC_MSG_ERROR([ARM NEON intrinsics not detected])
fi
dnl ===========================================================================
dnl Check for IWMMXT
if test "x$IWMMXT_CFLAGS" = "x" ; then
IWMMXT_CFLAGS="-march=iwmmxt -flax-vector-conversions -Winline"
fi
have_iwmmxt_intrinsics=no
AC_MSG_CHECKING(whether to use ARM IWMMXT intrinsics)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="$IWMMXT_CFLAGS $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#ifndef __arm__
#error "IWMMXT is only available on ARM"
#endif
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6))
#error "Need GCC >= 4.6 for IWMMXT intrinsics"
#endif
#include <mmintrin.h>
int main () {
union {
__m64 v;
char c[8];
} a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
int b = 4;
__m64 c = _mm_srli_si64 (a.v, b);
}]])], have_iwmmxt_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(arm-iwmmxt,
[AC_HELP_STRING([--disable-arm-iwmmxt],
[disable ARM IWMMXT fast paths])],
[enable_iwmmxt=$enableval], [enable_iwmmxt=auto])
if test $enable_iwmmxt = no ; then
have_iwmmxt_intrinsics=disabled
fi
if test $have_iwmmxt_intrinsics = yes ; then
AC_DEFINE(USE_ARM_IWMMXT, 1, [use ARM IWMMXT compiler intrinsics])
else
IWMMXT_CFLAGS=
fi
AC_MSG_RESULT($have_iwmmxt_intrinsics)
if test $enable_iwmmxt = yes && test $have_iwmmxt_intrinsics = no ; then
AC_MSG_ERROR([IWMMXT intrinsics not detected])
fi
AM_CONDITIONAL(USE_ARM_IWMMXT, test $have_iwmmxt_intrinsics = yes)
dnl ==========================================================================
dnl Check if assembler is gas compatible and supports MIPS DSPr2 instructions
have_mips_dspr2=no
AC_MSG_CHECKING(whether to use MIPS DSPr2 assembler)
xserver_save_CFLAGS=$CFLAGS
CFLAGS="-mdspr2 $CFLAGS"
AC_COMPILE_IFELSE([[
#if !(defined(__mips__) && __mips_isa_rev >= 2)
#error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
#endif
int
main ()
{
int c = 0, a = 0, b = 0;
__asm__ __volatile__ (
"precr.qb.ph %[c], %[a], %[b] \n\t"
: [c] "=r" (c)
: [a] "r" (a), [b] "r" (b)
);
return c;
}]], have_mips_dspr2=yes)
CFLAGS=$xserver_save_CFLAGS
AC_ARG_ENABLE(mips-dspr2,
[AC_HELP_STRING([--disable-mips-dspr2],
[disable MIPS DSPr2 fast paths])],
[enable_mips_dspr2=$enableval], [enable_mips_dspr2=auto])
if test $enable_mips_dspr2 = no ; then
have_mips_dspr2=disabled
fi
if test $have_mips_dspr2 = yes ; then
AC_DEFINE(USE_MIPS_DSPR2, 1, [use MIPS DSPr2 assembly optimizations])
fi
AM_CONDITIONAL(USE_MIPS_DSPR2, test $have_mips_dspr2 = yes)
AC_MSG_RESULT($have_mips_dspr2)
if test $enable_mips_dspr2 = yes && test $have_mips_dspr2 = no ; then
AC_MSG_ERROR([MIPS DSPr2 instructions not detected])
fi
dnl =========================================================================================
dnl Check for GNU-style inline assembly support
have_gcc_inline_asm=no
AC_MSG_CHECKING(whether to use GNU-style inline assembler)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
int main () {
/* Most modern architectures have a NOP instruction, so this is a fairly generic test. */
asm volatile ( "\tnop\n" : : : "cc", "memory" );
return 0;
}]])], have_gcc_inline_asm=yes)
AC_ARG_ENABLE(gcc-inline-asm,
[AC_HELP_STRING([--disable-gcc-inline-asm],
[disable GNU-style inline assembler])],
[enable_gcc_inline_asm=$enableval], [enable_gcc_inline_asm=auto])
if test $enable_gcc_inline_asm = no ; then
have_gcc_inline_asm=disabled
fi
if test $have_gcc_inline_asm = yes ; then
AC_DEFINE(USE_GCC_INLINE_ASM, 1, [use GNU-style inline assembler])
fi
AC_MSG_RESULT($have_gcc_inline_asm)
if test $enable_gcc_inline_asm = yes && test $have_gcc_inline_asm = no ; then
AC_MSG_ERROR([GNU-style inline assembler not detected])
fi
AM_CONDITIONAL(USE_GCC_INLINE_ASM, test $have_gcc_inline_asm = yes)
dnl ==============================================
dnl Static test programs
AC_ARG_ENABLE(static-testprogs,
[AC_HELP_STRING([--enable-static-testprogs],
[build test programs as static binaries [default=no]])],
[enable_static_testprogs=$enableval], [enable_static_testprogs=no])
TESTPROGS_EXTRA_LDFLAGS=
if test "x$enable_static_testprogs" = "xyes" ; then
TESTPROGS_EXTRA_LDFLAGS="-all-static"
fi
AC_SUBST(TESTPROGS_EXTRA_LDFLAGS)
dnl ==============================================
dnl Timers
AC_ARG_ENABLE(timers,
[AC_HELP_STRING([--enable-timers],
[enable TIMER_BEGIN and TIMER_END macros [default=no]])],
[enable_timers=$enableval], [enable_timers=no])
if test $enable_timers = yes ; then
AC_DEFINE(PIXMAN_TIMERS, 1, [enable TIMER_BEGIN/TIMER_END macros])
fi
AC_SUBST(PIXMAN_TIMERS)
dnl ===================================
dnl GTK+
AC_ARG_ENABLE(gtk,
[AC_HELP_STRING([--enable-gtk],
[enable tests using GTK+ [default=auto]])],
[enable_gtk=$enableval], [enable_gtk=auto])
PKG_PROG_PKG_CONFIG
if test $enable_gtk = yes ; then
AC_CHECK_LIB([pixman-1], [pixman_version_string])
PKG_CHECK_MODULES(GTK, [gtk+-2.0 pixman-1])
fi
if test $enable_gtk = auto ; then
AC_CHECK_LIB([pixman-1], [pixman_version_string], [enable_gtk=auto], [enable_gtk=no])
fi
if test $enable_gtk = auto ; then
PKG_CHECK_MODULES(GTK, [gtk+-2.0 pixman-1], [enable_gtk=yes], [enable_gtk=no])
fi
AM_CONDITIONAL(HAVE_GTK, [test "x$enable_gtk" = xyes])
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
AC_SUBST(DEP_CFLAGS)
AC_SUBST(DEP_LIBS)
dnl =====================================
dnl posix_memalign, sigaction, alarm, gettimeofday
AC_CHECK_FUNC(posix_memalign, have_posix_memalign=yes, have_posix_memalign=no)
if test x$have_posix_memalign = xyes; then
AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Whether we have posix_memalign()])
fi
AC_CHECK_FUNC(sigaction, have_sigaction=yes, have_sigaction=no)
if test x$have_sigaction = xyes; then
AC_DEFINE(HAVE_SIGACTION, 1, [Whether we have sigaction()])
fi
AC_CHECK_FUNC(alarm, have_alarm=yes, have_alarm=no)
if test x$have_alarm = xyes; then
AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()])
fi
AC_CHECK_HEADER([sys/mman.h],
[AC_DEFINE(HAVE_SYS_MMAN_H, [1], [Define to 1 if we have <sys/mman.h>])])
AC_CHECK_FUNC(mmap, have_mmap=yes, have_mmap=no)
if test x$have_mmap = xyes; then
AC_DEFINE(HAVE_MMAP, 1, [Whether we have mmap()])
fi
AC_CHECK_FUNC(mprotect, have_mprotect=yes, have_mprotect=no)
if test x$have_mprotect = xyes; then
AC_DEFINE(HAVE_MPROTECT, 1, [Whether we have mprotect()])
fi
AC_CHECK_FUNC(getpagesize, have_getpagesize=yes, have_getpagesize=no)
if test x$have_getpagesize = xyes; then
AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
fi
AC_CHECK_HEADER([fenv.h],
[AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have <fenv.h>])])
AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no)
if test x$have_feenableexcept = xyes; then
AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
fi
AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Whether we have gettimeofday()])
fi
dnl =====================================
dnl Thread local storage
support_for__thread=no
AC_MSG_CHECKING(for __thread)
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#if defined(__MINGW32__) && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#error This MinGW version has broken __thread support
#endif
#ifdef __OpenBSD__
#error OpenBSD has broken __thread support
#endif
static __thread int x ;
int main () { x = 123; return x; }
]])], support_for__thread=yes)
if test $support_for__thread = yes; then
AC_DEFINE([TOOLCHAIN_SUPPORTS__THREAD],[],[Whether the tool chain supports __thread])
fi
AC_MSG_RESULT($support_for__thread)
dnl
dnl posix tls
dnl
m4_define([pthread_test_program],AC_LANG_SOURCE([[dnl
#include <stdlib.h>
#include <pthread.h>
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
static pthread_key_t key;
static void
make_key (void)
{
pthread_key_create (&key, NULL);
}
int
main ()
{
void *value = NULL;
if (pthread_once (&once_control, make_key) != 0)
{
value = NULL;
}
else
{
value = pthread_getspecific (key);
if (!value)
{
value = malloc (100);
pthread_setspecific (key, value);
}
}
return 0;
}
]]))
AC_DEFUN([PIXMAN_CHECK_PTHREAD],[dnl
if test "z$support_for_pthread_setspecific" != "zyes"; then
PIXMAN_LINK_WITH_ENV(
[$1], [pthread_test_program],
[PTHREAD_CFLAGS="$CFLAGS"
PTHREAD_LIBS="$LIBS"
PTHREAD_LDFLAGS="$LDFLAGS"
support_for_pthread_setspecific=yes])
fi
])
if test $support_for__thread = no; then
support_for_pthread_setspecific=no
AC_MSG_CHECKING(for pthread_setspecific)
PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LIBS="-lpthread"])
PIXMAN_CHECK_PTHREAD([CFLAGS="-pthread"; LDFLAGS="-pthread"])
PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LDFLAGS="-lroot"])
if test $support_for_pthread_setspecific = yes; then
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
AC_DEFINE([HAVE_PTHREAD_SETSPECIFIC], [], [Whether pthread_setspecific() is supported])
fi
AC_MSG_RESULT($support_for_pthread_setspecific);
fi
AC_SUBST(TOOLCHAIN_SUPPORTS__THREAD)
AC_SUBST(HAVE_PTHREAD_SETSPECIFIC)
AC_SUBST(PTHREAD_LDFLAGS)
AC_SUBST(PTHREAD_LIBS)
dnl =====================================
dnl __attribute__((constructor))
support_for_attribute_constructor=no
AC_MSG_CHECKING(for __attribute__((constructor)))
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
/* attribute 'constructor' is supported since gcc 2.7, but some compilers
* may only pretend to be gcc, so let's try to actually use it
*/
static int x = 1;
static void __attribute__((constructor)) constructor_function () { x = 0; }
int main (void) { return x; }
#else
#error not gcc or gcc version is older than 2.7
#endif
]])], support_for_attribute_constructor=yes)
if test x$support_for_attribute_constructor = xyes; then
AC_DEFINE([TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR],
[],[Whether the tool chain supports __attribute__((constructor))])
fi
AC_MSG_RESULT($support_for_attribute_constructor)
AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
dnl ==================
dnl libpng
AC_ARG_ENABLE(libpng, AS_HELP_STRING([--enable-libpng], [Build support for libpng (default: auto)]),
[have_libpng=$enableval], [have_libpng=auto])
case x$have_libpng in
xyes) PKG_CHECK_MODULES(PNG, [libpng]) ;;
xno) ;;
*) PKG_CHECK_MODULES(PNG, [libpng], have_libpng=yes, have_libpng=no) ;;
esac
if test x$have_libpng = xyes; then
AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
fi
AC_SUBST(HAVE_LIBPNG)
AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
pixman/Makefile
pixman/pixman-version.h
demos/Makefile
test/Makefile])
m4_if(m4_eval(pixman_minor % 2), [1], [
echo
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
echo
echo " Thanks for testing this development snapshot of pixman. Please"
echo " report any problems you find, either by sending email to "
echo
echo " pixman@lists.freedesktop.org"
echo
echo " or by filing a bug at "
echo
echo " https://bugs.freedesktop.org/enter_bug.cgi?product=pixman "
echo
echo " If you are looking for a stable release of pixman, please note "
echo " that stable releases have _even_ minor version numbers. Ie., "
echo " pixman-0.]m4_eval(pixman_minor & ~1)[.x are stable releases, whereas pixman-$PIXMAN_VERSION_MAJOR.$PIXMAN_VERSION_MINOR.$PIXMAN_VERSION_MICRO is a "
echo " development snapshot that may contain bugs and experimental "
echo " features. "
echo
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
echo
])

226
debian/changelog vendored
View File

@ -1,229 +1,3 @@
pixman (0.44.0-4) UNRELEASED; urgency=medium
* Team upload.
* debian/copyright: Convert to machine-readable format
-- Dylan Aïssi <daissi@debian.org> Thu, 31 Jul 2025 22:16:23 +0200
pixman (0.44.0-3) unstable; urgency=medium
* Replace timeout bump patch by using a multiplier option instead.
Thanks, Aurelien Jarno! (Closes: #1086999)
-- Timo Aaltonen <tjaalton@debian.org> Sat, 09 Nov 2024 11:02:55 +0200
pixman (0.44.0-2) unstable; urgency=medium
* patches: Increase test timeout 120->240s. (Closes: #1086999)
-- Timo Aaltonen <tjaalton@debian.org> Fri, 08 Nov 2024 09:58:04 +0200
pixman (0.44.0-1) unstable; urgency=medium
* New upstream release.
* patches: Refresh patch.
* control, rules: Build with meson.
* symbols: Updated.
* control: Migrate to pkgconf.
* rules: Drop obsolete dbgsym-migration.
-- Timo Aaltonen <tjaalton@debian.org> Thu, 07 Nov 2024 16:48:29 +0200
pixman (0.42.2-1) unstable; urgency=medium
* New upstream release.
* d/p/Avoid-integer-overflow-leading-to-out-of-bounds-writ.diff:
- Removed, fixed upstream.
-- Emilio Pozuelo Monfort <pochu@debian.org> Fri, 11 Nov 2022 13:42:25 +0100
pixman (0.40.0-1.1) unstable; urgency=medium
* Non-maintainer upload.
* Avoid integer overflow leading to out-of-bounds write (CVE-2022-44638)
(Closes: #1023427)
-- Salvatore Bonaccorso <carnil@debian.org> Thu, 03 Nov 2022 23:07:46 +0100
pixman (0.40.0-1) unstable; urgency=medium
* New upstream release. (Closes: #958298, #832579, #838650)
* control, rules: Migrate to debhelper-compat, bump to 13.
* symbols: Updated, bump shlibs.
-- Timo Aaltonen <tjaalton@debian.org> Thu, 03 Dec 2020 15:28:13 +0200
pixman (0.36.0-1) unstable; urgency=medium
* New upstream release.
* Update to my Debian address.
* Update Vcs-* URLs to point to salsa.debian.org.
* Use https URL in debian/copyright.
* Set source format to 1.0.
* Bump debhelper compat to 11.
* Bump standards version to 4.2.1.
-- Andreas Boll <aboll@debian.org> Wed, 12 Dec 2018 22:02:44 +0100
pixman (0.34.0-2) unstable; urgency=medium
* Declare Multi-Arch: same for libpixman-1-dev (Closes: #884166).
* Switch to dbsym package.
* Stop passing --disable-silent-rules to configure, debhelper does it
now.
* Bump standards version to 4.1.2.
-- Andreas Boll <andreas.boll.dev@gmail.com> Sun, 17 Dec 2017 13:33:55 +0100
pixman (0.34.0-1) unstable; urgency=medium
* Team upload.
* New upstream release (no actual changes)
* Use https URL in debian/watch.
-- Julien Cristau <jcristau@debian.org> Sat, 24 Sep 2016 13:25:16 +0200
pixman (0.33.6-1) unstable; urgency=medium
* New upstream release candidate.
* Add myself to Uploaders.
-- Andreas Boll <andreas.boll.dev@gmail.com> Thu, 14 Jan 2016 13:46:28 +0100
pixman (0.33.4-1) unstable; urgency=medium
* Team upload.
* New upstream release candidate.
-- Andreas Boll <andreas.boll.dev@gmail.com> Wed, 04 Nov 2015 13:26:18 +0100
pixman (0.33.2-2) sid; urgency=medium
* Run tests with VERBOSE=1.
-- Julien Cristau <jcristau@debian.org> Sat, 12 Sep 2015 20:31:06 +0200
pixman (0.33.2-1) sid; urgency=medium
[ Andreas Boll ]
* New upstream release candidate.
* Enable vmx on ppc64el (closes: #786345).
* Update Vcs-* fields.
* Add upstream url.
* Drop XC- prefix from Package-Type field.
* Bump standards version to 3.9.6.
[ intrigeri ]
* Simplify hardening build flags handling (closes: #760100).
Thanks to Simon Ruderich <simon@ruderich.org> for the patch.
* Enable all hardening build flags. Thanks to Simon Ruderich too.
-- Julien Cristau <jcristau@debian.org> Sat, 12 Sep 2015 13:08:02 +0200
pixman (0.32.6-3) sid; urgency=medium
[ intrigeri ]
* Enable hardening build flags with dpkg-buildflags.
-- Julien Cristau <jcristau@debian.org> Sat, 23 Aug 2014 22:16:40 -0700
pixman (0.32.6-2) sid; urgency=medium
[ Julien Cristau ]
* Disable vmx on ppc64el (closes: #745547). Thanks, Breno Leitao!
-- Cyril Brulebois <kibi@debian.org> Mon, 18 Aug 2014 22:50:39 +0200
pixman (0.32.6-1) sid; urgency=medium
* New upstream release.
* Bump debhelper compat level to 9.
* Remove Cyril from Uploaders.
-- Julien Cristau <jcristau@debian.org> Sun, 13 Jul 2014 16:31:06 +0200
pixman (0.32.4-1) sid; urgency=low
* New upstream release.
-- Julien Cristau <jcristau@debian.org> Tue, 17 Dec 2013 22:04:15 +0100
pixman (0.30.2-2) sid; urgency=low
* Cherry-pick upstream bigfixes for fixing a crash when rendering
invalid trapezoids. (LP: #1197921)
Addresses CVE-2013-6425.
-- Maarten Lankhorst <maarten.lankhorst@ubuntu.com> Mon, 18 Nov 2013 15:08:56 +0100
pixman (0.30.2-1) sid; urgency=low
* New upstream release
- includes big-endian matrix-test fix
* Increase alpha-loop test timeout some more.
-- Julien Cristau <jcristau@debian.org> Tue, 13 Aug 2013 12:08:18 +0200
pixman (0.30.0-3) sid; urgency=low
* Increase timeout for the alpha-loop test. That will hopefully let it pass
on the mips buildd.
-- Julien Cristau <jcristau@debian.org> Sat, 03 Aug 2013 10:24:29 +0200
pixman (0.30.0-2) sid; urgency=low
* Disable silent Makefile rules.
* Disable arm iwmmxt fast paths. It breaks the build.
* Fix matrix-test on big endian (patch from Siarhei Siamashka).
-- Julien Cristau <jcristau@debian.org> Sat, 27 Jul 2013 21:40:48 +0200
pixman (0.30.0-1) sid; urgency=low
[ Maarten Lankhorst, Cyril Brulebois, Julien Cristau ]
* New upstream release.
-- Julien Cristau <jcristau@debian.org> Fri, 26 Jul 2013 14:58:25 +0200
pixman (0.26.0-4) sid; urgency=high
* Fix for CVE-2013-1591 (stack-based buffer overflow), cherry-picked from
0.27.4 (closes: #700308).
-- Julien Cristau <jcristau@debian.org> Mon, 18 Feb 2013 19:58:33 +0100
pixman (0.26.0-3) unstable; urgency=low
* Pass LS_CFLAGS=" " to configure to prevent -march=loongson2f from
being passed to gcc, which would break on loongson2e (see fdo bug
#51451). This fixes the test suite failures on mipsel, and should
avoid any crashes depending on user systems.
-- Cyril Brulebois <kibi@debian.org> Wed, 27 Jun 2012 12:11:54 +0200
pixman (0.26.0-2) unstable; urgency=low
* Cherry-pick from upstream master branch to fix FTBFS on *i386:
- da6193b1fc “mmx: add missing _mm_empty calls”
-- Cyril Brulebois <kibi@debian.org> Fri, 15 Jun 2012 01:25:20 +0200
pixman (0.26.0-1) unstable; urgency=low
* New upstream release.
-- Cyril Brulebois <kibi@debian.org> Fri, 15 Jun 2012 00:16:47 +0200
pixman (0.25.6-1) experimental; urgency=low
* New upstream release candidate.
* Remove demos/parrot.jpg before building the source package to avoid
“binary file contents changed” until it's shipped in the upstream
tarball.
-- Cyril Brulebois <kibi@debian.org> Sun, 20 May 2012 17:56:35 +0200
pixman (0.25.2-1) experimental; urgency=low
* New upstream release candidate.

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
8

30
debian/control vendored
View File

@ -2,16 +2,15 @@ Source: pixman
Section: devel
Priority: optional
Maintainer: Debian X Strike Force <debian-x@lists.debian.org>
Uploaders: Andreas Boll <aboll@debian.org>
Uploaders: Cyril Brulebois <kibi@debian.org>
Build-Depends:
debhelper-compat (= 13),
meson,
pkgconf,
debhelper (>= 8.1.3),
dh-autoreconf,
pkg-config,
quilt,
Standards-Version: 4.2.1
Vcs-Git: https://salsa.debian.org/xorg-team/lib/pixman.git
Vcs-Browser: https://salsa.debian.org/xorg-team/lib/pixman
Homepage: http://pixman.org/
Standards-Version: 3.9.2
Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/pixman
Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/pixman.git
Package: libpixman-1-0
Section: libs
@ -29,7 +28,7 @@ Description: pixel-manipulation library for X and cairo
Package: libpixman-1-0-udeb
Section: debian-installer
Package-Type: udeb
XC-Package-Type: udeb
Architecture: any
Depends:
${shlibs:Depends},
@ -38,13 +37,24 @@ Description: pixel-manipulation library for X and cairo
This package contains a minimal set of libraries needed for the Debian
installer. Do not install it on a normal system.
Package: libpixman-1-0-dbg
Section: debug
Priority: extra
Architecture: any
Depends:
libpixman-1-0 (= ${binary:Version}),
${misc:Depends},
Multi-Arch: same
Description: pixel-manipulation library for X and cairo (debugging symbols)
Debugging symbols for the Cairo/X pixel manipulation library. This is
needed to debug programs linked against libpixman0.
Package: libpixman-1-dev
Section: libdevel
Architecture: any
Depends:
libpixman-1-0 (= ${binary:Version}),
${misc:Depends},
Multi-Arch: same
Description: pixel-manipulation library for X and cairo (development files)
Development libraries, header files and documentation needed by
programs that want to compile with the Cairo/X pixman library.

89
debian/copyright vendored
View File

@ -1,48 +1,47 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: pixman
Source: https://gitlab.freedesktop.org/pixman/pixman
License: Expat
This package was downloaded from
http://xorg.freedesktop.org/releases/individual/lib/
Files: *
Copyright: 1987-1998 The Open Group
1987-1989 Digital Equipment Corporation
1999-2008 Keith Packard
2000 SuSE, Inc.
2000 Keith Packard, member of The XFree86 Project, Inc.
2004-2010 Red Hat, Inc.
2004 Nicholas Miell
2005 Lars Knoll & Zack Rusin, Trolltech
2005 Trolltech AS
2007 Luca Barbato
2008 Aaron Plattner, NVIDIA Corporation
2008 Rodrigo Kumpera
2008 André Tupinambá
2008 Mozilla Corporation
2008 Frederic Plourde
2009, Oracle and/or its affiliates. All rights reserved.
2009-2010 Nokia Corporation
License: Expat
Debian packaging by Julien Cristau <jcristau@debian.org>, 18 May 2007.
Files: debian/*
Copyright: 2007 Julien Cristau <jcristau@debian.org>
License: Expat
The following is the MIT license, agreed upon by most contributors.
Copyright holders of new code should use this license statement where
possible. They may also add themselves to the list below.
License: Expat
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.
/*
* Copyright 1987, 1988, 1989, 1998 The Open Group
* Copyright 1987, 1988, 1989 Digital Equipment Corporation
* Copyright 1999, 2004, 2008 Keith Packard
* Copyright 2000 SuSE, Inc.
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
* Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
* Copyright 2004 Nicholas Miell
* Copyright 2005 Lars Knoll & Zack Rusin, Trolltech
* Copyright 2005 Trolltech AS
* Copyright 2007 Luca Barbato
* Copyright 2008 Aaron Plattner, NVIDIA Corporation
* Copyright 2008 Rodrigo Kumpera
* Copyright 2008 André Tupinambá
* Copyright 2008 Mozilla Corporation
* Copyright 2008 Frederic Plourde
* Copyright 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Nokia Corporation
*
* 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.
*/

View File

@ -1,2 +0,0 @@
libpixman-1-0: symbols-declares-dependency-on-other-package libpixman-1-0-private

View File

@ -1,12 +1,8 @@
libpixman-1.so.0 libpixman-1-0 #MINVER#
| libpixman-1-0-private
_pixman_internal_only_get_implementation@Base 0 1
pixman_add_trapezoids@Base 0
pixman_add_traps@Base 0
pixman_add_triangles@Base 0.21.6
pixman_blt@Base 0
pixman_composite_glyphs@Base 0.27.2
pixman_composite_glyphs_no_mask@Base 0.27.2
pixman_composite_trapezoids@Base 0.21.6
pixman_composite_triangles@Base 0.21.6
pixman_compute_composite_region@Base 0
@ -27,22 +23,9 @@ libpixman-1.so.0 libpixman-1-0 #MINVER#
pixman_f_transform_scale@Base 0.13.2
pixman_f_transform_translate@Base 0.13.2
pixman_fill@Base 0
pixman_filter_create_separable_convolution@Base 0.30.0
pixman_format_supported_destination@Base 0.15.16
pixman_format_supported_source@Base 0.15.16
pixman_glyph_cache_create@Base 0.27.2
pixman_glyph_cache_destroy@Base 0.27.2
pixman_glyph_cache_freeze@Base 0.27.2
pixman_glyph_cache_insert@Base 0.27.2
pixman_glyph_cache_lookup@Base 0.27.2
pixman_glyph_cache_remove@Base 0.27.2
pixman_glyph_cache_thaw@Base 0.27.2
pixman_glyph_get_extents@Base 0.27.2
pixman_glyph_get_mask_format@Base 0.27.2
pixman_image_composite@Base 0.15.14
pixman_image_composite32@Base 0.18.0
pixman_image_create_bits@Base 0.15.12
pixman_image_create_bits_no_clear@Base 0.27.4
pixman_image_create_conical_gradient@Base 0
pixman_image_create_linear_gradient@Base 0
pixman_image_create_radial_gradient@Base 0
@ -64,9 +47,7 @@ libpixman-1.so.0 libpixman-1-0 #MINVER#
pixman_image_set_clip_region@Base 0
pixman_image_set_component_alpha@Base 0
pixman_image_set_destroy_function@Base 0.15.12
pixman_image_set_dither@Base 0.40.0
pixman_image_set_dither_offset@Base 0.40.0
pixman_image_set_filter@Base 0.30.0
pixman_image_set_filter@Base 0
pixman_image_set_has_client_clip@Base 0
pixman_image_set_indexed@Base 0
pixman_image_set_repeat@Base 0
@ -80,7 +61,6 @@ libpixman-1.so.0 libpixman-1-0 #MINVER#
pixman_region32_contains_point@Base 0.11.2
pixman_region32_contains_rectangle@Base 0.11.2
pixman_region32_copy@Base 0.11.2
pixman_region32_empty@Base 0.44.0
pixman_region32_equal@Base 0.11.2
pixman_region32_extents@Base 0.11.2
pixman_region32_fini@Base 0.11.2
@ -105,7 +85,6 @@ libpixman-1.so.0 libpixman-1-0 #MINVER#
pixman_region_contains_point@Base 0
pixman_region_contains_rectangle@Base 0
pixman_region_copy@Base 0
pixman_region_empty@Base 0.44.0
pixman_region_equal@Base 0
pixman_region_extents@Base 0
pixman_region_fini@Base 0
@ -142,12 +121,11 @@ libpixman-1.so.0 libpixman-1-0 #MINVER#
pixman_transform_is_scale@Base 0.13.2
pixman_transform_multiply@Base 0.13.2
pixman_transform_point@Base 0.13.2
pixman_transform_point_31_16@Base 0 1
pixman_transform_point_31_16_3d@Base 0 1
pixman_transform_point_31_16_affine@Base 0 1
pixman_transform_rotate@Base 0.13.2
pixman_transform_scale@Base 0.13.2
pixman_transform_translate@Base 0.13.2
pixman_transform_point_3d@Base 0
pixman_version@Base 0.10.0
pixman_version_string@Base 0.10.0
pixman_format_supported_destination@Base 0.15.16
pixman_format_supported_source@Base 0.15.16

View File

@ -1,3 +1,4 @@
usr/lib/*/libpixman-1.so
usr/lib/*/libpixman-1.a
usr/lib/*/pkgconfig
usr/include/pixman-1

View File

@ -1 +1 @@
test-increase-timeout.diff
# placeholder

View File

@ -1,11 +0,0 @@
--- a/test/alpha-loop.c
+++ b/test/alpha-loop.c
@@ -22,7 +22,7 @@ main (int argc, char **argv)
d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4);
- fail_after (5, "Infinite loop detected: 5 seconds without progress\n");
+ fail_after (50, "Infinite loop detected: 50 seconds without progress\n");
pixman_image_set_alpha_map (s, a, 0, 0);
pixman_image_set_alpha_map (a, s, 0, 0);

22
debian/rules vendored
View File

@ -1,16 +1,14 @@
#!/usr/bin/make -f
PACKAGE = libpixman-1-0
SHLIBS = 0.40.0
SHLIBS = 0.25.2
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
# Disable Gtk+ autodetection:
override_dh_auto_configure:
# also avoid loongson2f optimizations on mipsel, see 0.26.0-3
# changelog entry:
LS_CFLAGS=" " dh_auto_configure -- \
-Dgtk=disabled
dh_auto_configure -- --disable-gtk \
--libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)
# Install in debian/tmp to retain control through dh_install:
override_dh_auto_install:
@ -19,14 +17,16 @@ override_dh_auto_install:
# Kill *.la files, and forget no-one:
override_dh_install:
find debian/tmp -name '*.la' -delete
dh_install
dh_install --fail-missing
# Debug package:
override_dh_strip:
dh_strip -p$(PACKAGE) --dbg-package=$(PACKAGE)-dbg
dh_strip -N$(PACKAGE)
# Shlibs:
override_dh_makeshlibs:
dh_makeshlibs -p$(PACKAGE) --add-udeb $(PACKAGE)-udeb -V"$(PACKAGE) (>= $(SHLIBS))" -- -c4
override_dh_auto_test:
dh_auto_test -- --verbose --timeout-multiplier 3
%:
dh $@ --with quilt --builddirectory=build/
dh $@ --with quilt,autoreconf --builddirectory=build/ --parallel

View File

@ -1 +0,0 @@
1.0

2
debian/watch vendored
View File

@ -1,3 +1,3 @@
#git=git://anongit.freedesktop.org/pixman
version=3
https://xorg.freedesktop.org/releases/individual/lib/ pixman-(.*)\.tar\.gz
http://xorg.freedesktop.org/releases/individual/lib/ pixman-(.*)\.tar\.gz

36
demos/Makefile.am Normal file
View File

@ -0,0 +1,36 @@
if HAVE_GTK
AM_CFLAGS = $(OPENMP_CFLAGS)
AM_LDFLAGS = $(OPENMP_CFLAGS)
LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS)
INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS) $(PNG_CFLAGS)
GTK_UTILS = gtk-utils.c gtk-utils.h
DEMOS = \
clip-test \
clip-in \
composite-test \
gradient-test \
radial-test \
alpha-test \
screen-test \
convolution-test \
trap-test \
tri-test
gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
alpha_test_SOURCES = alpha-test.c $(GTK_UTILS)
composite_test_SOURCES = composite-test.c $(GTK_UTILS)
clip_test_SOURCES = clip-test.c $(GTK_UTILS)
clip_in_SOURCES = clip-in.c $(GTK_UTILS)
trap_test_SOURCES = trap-test.c $(GTK_UTILS)
screen_test_SOURCES = screen-test.c $(GTK_UTILS)
convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
radial_test_SOURCES = radial-test.c ../test/utils.c ../test/utils.h $(GTK_UTILS)
tri_test_SOURCES = tri-test.c ../test/utils.c ../test/utils.h $(GTK_UTILS)
noinst_PROGRAMS = $(DEMOS)
endif

View File

@ -1,71 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "pixman.h"
#include "gtk-utils.h"
int
main (int argc, char **argv)
{
#define WIDTH 400
#define HEIGHT 400
#define TILE_SIZE 25
pixman_image_t *checkerboard;
pixman_image_t *destination;
#define D2F(d) (pixman_double_to_fixed(d))
pixman_transform_t trans = { {
{ D2F (-1.96830), D2F (-1.82250), D2F (512.12250)},
{ D2F (0.00000), D2F (-7.29000), D2F (1458.00000)},
{ D2F (0.00000), D2F (-0.00911), D2F (0.59231)},
}};
int i, j;
checkerboard = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
NULL, 0);
destination = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
NULL, 0);
for (i = 0; i < HEIGHT / TILE_SIZE; ++i)
{
for (j = 0; j < WIDTH / TILE_SIZE; ++j)
{
double u = (double)(j + 1) / (WIDTH / TILE_SIZE);
double v = (double)(i + 1) / (HEIGHT / TILE_SIZE);
pixman_color_t black = { 0, 0, 0, 0xffff };
pixman_color_t white = {
v * 0xffff,
u * 0xffff,
(1 - (double)u) * 0xffff,
0xffff };
pixman_color_t *c;
pixman_image_t *fill;
if ((j & 1) != (i & 1))
c = &black;
else
c = &white;
fill = pixman_image_create_solid_fill (c);
pixman_image_composite (PIXMAN_OP_SRC, fill, NULL, checkerboard,
0, 0, 0, 0, j * TILE_SIZE, i * TILE_SIZE,
TILE_SIZE, TILE_SIZE);
}
}
pixman_image_set_transform (checkerboard, &trans);
pixman_image_set_filter (checkerboard, PIXMAN_FILTER_BEST, NULL, 0);
pixman_image_set_repeat (checkerboard, PIXMAN_REPEAT_NONE);
pixman_image_composite (PIXMAN_OP_SRC,
checkerboard, NULL, destination,
0, 0, 0, 0, 0, 0,
WIDTH, HEIGHT);
show_image (destination);
return 0;
}

View File

@ -3,10 +3,9 @@
#include <stdio.h>
#include "pixman.h"
#include "gtk-utils.h"
#include "parrot.c"
#define WIDTH 80
#define HEIGHT 80
#define WIDTH 60
#define HEIGHT 60
typedef struct {
const char *name;
@ -88,24 +87,26 @@ int
main (int argc, char **argv)
{
#define d2f pixman_double_to_fixed
GtkWidget *window, *swindow;
GtkWidget *table;
uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
uint32_t *src = malloc (WIDTH * HEIGHT * 4);
pixman_image_t *gradient, *parrot;
pixman_image_t *src_img;
pixman_image_t *dest_img;
pixman_point_fixed_t p1 = { -10 << 16, 10 << 16 };
pixman_point_fixed_t p2 = { (WIDTH + 10) << 16, (HEIGHT - 10) << 16 };
uint16_t alpha = 0xdddd;
pixman_point_fixed_t p1 = { -10 << 0, 0 };
pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 };
uint16_t full = 0xcfff;
uint16_t low = 0x5000;
uint16_t alpha = 0xffff;
pixman_gradient_stop_t stops[6] =
{
{ d2f (0.0), { 0xf2f2, 0x8787, 0x7d7d, alpha } },
{ d2f (0.22), { 0xf3f3, 0xeaea, 0x8383, alpha } },
{ d2f (0.42), { 0x6b6b, 0xc0c0, 0x7777, alpha } },
{ d2f (0.57), { 0x4b4b, 0xc9c9, 0xf5f5, alpha } },
{ d2f (0.75), { 0x6a6a, 0x7f7f, 0xbebe, alpha } },
{ d2f (1.0), { 0xeded, 0x8282, 0xb0b0, alpha } },
{ d2f (0.0), { full, low, low, alpha } },
{ d2f (0.25), { full, full, low, alpha } },
{ d2f (0.4), { low, full, low, alpha } },
{ d2f (0.6), { low, full, full, alpha } },
{ d2f (0.8), { low, low, full, alpha } },
{ d2f (1.0), { full, low, full, alpha } },
};
int i;
@ -115,20 +116,20 @@ main (int argc, char **argv)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "delete-event",
G_CALLBACK (gtk_main_quit),
NULL);
table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);
gradient = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops));
parrot = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, (uint32_t *)parrot_bits, WIDTH * 4);
pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD);
src_img = pixman_image_create_linear_gradient (&p1, &p2, stops,
G_N_ELEMENTS (stops));
pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
NULL,
dest,
WIDTH * 4);
pixman_image_set_accessors (dest_img, reader, writer);
@ -138,6 +139,7 @@ main (int argc, char **argv)
GdkPixbuf *pixbuf;
GtkWidget *vbox;
GtkWidget *label;
int j, k;
vbox = gtk_vbox_new (FALSE, 0);
@ -145,11 +147,14 @@ main (int argc, char **argv)
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
gtk_widget_show (label);
pixman_image_composite (PIXMAN_OP_SRC, gradient, NULL, dest_img,
for (j = 0; j < HEIGHT; ++j)
{
for (k = 0; k < WIDTH; ++k)
dest[j * WIDTH + k] = 0x7f6f6f00;
}
pixman_image_composite (operators[i].op, src_img, NULL, dest_img,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
pixman_image_composite (operators[i].op, parrot, NULL, dest_img,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img),
pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE,
WIDTH, HEIGHT, WIDTH * 4);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
@ -162,7 +167,7 @@ main (int argc, char **argv)
g_object_unref (pixbuf);
}
pixman_image_unref (gradient);
pixman_image_unref (src_img);
free (src);
pixman_image_unref (dest_img);
free (dest);
@ -171,7 +176,7 @@ main (int argc, char **argv)
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
gtk_widget_show (table);

View File

@ -1,100 +0,0 @@
#include "utils.h"
#include "gtk-utils.h"
#define SIZE 128
#define GRADIENTS_PER_ROW 7
#define NUM_ROWS ((NUM_GRADIENTS + GRADIENTS_PER_ROW - 1) / GRADIENTS_PER_ROW)
#define WIDTH (SIZE * GRADIENTS_PER_ROW)
#define HEIGHT (SIZE * NUM_ROWS)
#define NUM_GRADIENTS 35
#define double_to_color(x) \
(((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16))
#define PIXMAN_STOP(offset,r,g,b,a) \
{ pixman_double_to_fixed (offset), \
{ \
double_to_color (r), \
double_to_color (g), \
double_to_color (b), \
double_to_color (a) \
} \
}
static const pixman_gradient_stop_t stops[] = {
PIXMAN_STOP (0.25, 1, 0, 0, 0.7),
PIXMAN_STOP (0.5, 1, 1, 0, 0.7),
PIXMAN_STOP (0.75, 0, 1, 0, 0.7),
PIXMAN_STOP (1.0, 0, 0, 1, 0.7)
};
#define NUM_STOPS (sizeof (stops) / sizeof (stops[0]))
static pixman_image_t *
create_conical (int index)
{
pixman_point_fixed_t c;
double angle;
c.x = pixman_double_to_fixed (0);
c.y = pixman_double_to_fixed (0);
angle = (0.5 / NUM_GRADIENTS + index / (double)NUM_GRADIENTS) * 720 - 180;
return pixman_image_create_conical_gradient (
&c, pixman_double_to_fixed (angle), stops, NUM_STOPS);
}
int
main (int argc, char **argv)
{
pixman_transform_t transform;
pixman_image_t *src_img, *dest_img;
int i;
enable_divbyzero_exceptions ();
dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
NULL, 0);
draw_checkerboard (dest_img, 25, 0xffaaaaaa, 0xff888888);
pixman_transform_init_identity (&transform);
pixman_transform_translate (NULL, &transform,
pixman_double_to_fixed (0.5),
pixman_double_to_fixed (0.5));
pixman_transform_scale (NULL, &transform,
pixman_double_to_fixed (SIZE),
pixman_double_to_fixed (SIZE));
pixman_transform_translate (NULL, &transform,
pixman_double_to_fixed (0.5),
pixman_double_to_fixed (0.5));
for (i = 0; i < NUM_GRADIENTS; i++)
{
int column = i % GRADIENTS_PER_ROW;
int row = i / GRADIENTS_PER_ROW;
src_img = create_conical (i);
pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
pixman_image_set_transform (src_img, &transform);
pixman_image_composite32 (
PIXMAN_OP_OVER, src_img, NULL,dest_img,
0, 0, 0, 0, column * SIZE, row * SIZE,
SIZE, SIZE);
pixman_image_unref (src_img);
}
show_image (dest_img);
pixman_image_unref (dest_img);
return 0;
}

View File

@ -1,277 +0,0 @@
/*
* 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 "pixman-config.h"
#endif
#include <math.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include "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_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
app_t *app = user_data;
GdkRectangle area;
cairo_surface_t *surface;
pixman_image_t *tmp, *final;
uint32_t *pixels;
gdk_cairo_get_clip_rectangle(cr, &area);
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);
cairo_set_source_surface (cr, surface, area.x, area.y);
cairo_paint (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, "draw", G_CALLBACK (on_draw), 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;
}

View File

@ -1,147 +0,0 @@
<?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">&lt;b&gt;Target format:&lt;/b&gt;</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">&lt;b&gt;Dithering:&lt;/b&gt;</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>

View File

@ -1,78 +1,13 @@
#include <gtk/gtk.h>
#ifdef HAVE_CONFIG_H
#include <pixman-config.h>
#endif
#include "utils.h"
#include <config.h>
#include "pixman-private.h" /* For image->bits.format
* FIXME: there should probably be public API for this
*/
#include "gtk-utils.h"
pixman_image_t *
pixman_image_from_file (const char *filename, pixman_format_code_t format)
{
GdkPixbuf *pixbuf;
pixman_image_t *image;
int width, height;
uint32_t *data, *d;
uint8_t *gdk_data;
int n_channels;
int j, i;
int stride;
if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
return NULL;
image = NULL;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
gdk_data = gdk_pixbuf_get_pixels (pixbuf);
stride = gdk_pixbuf_get_rowstride (pixbuf);
if (!(data = malloc (width * height * sizeof (uint32_t))))
goto out;
d = data;
for (j = 0; j < height; ++j)
{
uint8_t *gdk_line = gdk_data;
for (i = 0; i < width; ++i)
{
int r, g, b, a;
uint32_t pixel;
r = gdk_line[0];
g = gdk_line[1];
b = gdk_line[2];
if (n_channels == 4)
a = gdk_line[3];
else
a = 0xff;
r = (r * a + 127) / 255;
g = (g * a + 127) / 255;
b = (b * a + 127) / 255;
pixel = (a << 24) | (r << 16) | (g << 8) | b;
*d++ = pixel;
gdk_line += n_channels;
}
gdk_data += stride;
}
image = pixman_image_create_bits (
format, width, height, data, width * 4);
out:
g_object_unref (pixbuf);
return image;
}
GdkPixbuf *
pixbuf_from_argb32 (uint32_t *bits,
gboolean has_alpha,
int width,
int height,
int stride)
@ -81,43 +16,56 @@ pixbuf_from_argb32 (uint32_t *bits,
8, width, height);
int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
int i;
for (i = 0; i < height; ++i)
int w, h;
for (h = 0; h < height; ++h)
{
uint32_t *src_row = &bits[i * (stride / 4)];
uint32_t *dst_row = p_bits + i * (p_stride / 4);
for (w = 0; w < width; ++w)
{
uint32_t argb = bits[h * (stride / 4) + w];
guint r, g, b, a;
char *pb = (char *)p_bits;
a8r8g8b8_to_rgba_np (dst_row, src_row, width);
pb += h * p_stride + w * 4;
r = (argb & 0x00ff0000) >> 16;
g = (argb & 0x0000ff00) >> 8;
b = (argb & 0x000000ff) >> 0;
a = has_alpha? (argb & 0xff000000) >> 24 : 0xff;
if (a)
{
r = (r * 255) / a;
g = (g * 255) / a;
b = (b * 255) / a;
}
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
pb[0] = r;
pb[1] = g;
pb[2] = b;
pb[3] = a;
}
}
return pixbuf;
}
static gboolean
on_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
on_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data)
{
pixman_image_t *pimage = user_data;
int width = pixman_image_get_width (pimage);
int height = pixman_image_get_height (pimage);
int stride = pixman_image_get_stride (pimage);
cairo_surface_t *cimage;
cairo_format_t format;
if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8)
format = CAIRO_FORMAT_RGB24;
else
format = CAIRO_FORMAT_ARGB32;
cimage = cairo_image_surface_create_for_data (
(uint8_t *)pixman_image_get_data (pimage),
format, width, height, stride);
cairo_rectangle (cr, 0, 0, width, height);
cairo_set_source_surface (cr, cimage, 0, 0);
cairo_fill (cr);
cairo_surface_destroy (cimage);
GdkPixbuf *pixbuf = data;
gdk_draw_pixbuf (widget->window, NULL,
pixbuf, 0, 0, 0, 0,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
GDK_RGB_DITHER_NONE,
0, 0);
return TRUE;
}
@ -126,12 +74,13 @@ void
show_image (pixman_image_t *image)
{
GtkWidget *window;
int width, height;
GdkPixbuf *pixbuf;
int width, height, stride;
int argc;
char **argv;
char *arg0 = g_strdup ("pixman-test-program");
gboolean has_alpha;
pixman_format_code_t format;
pixman_image_t *copy;
argc = 1;
argv = (char **)&arg0;
@ -141,34 +90,23 @@ show_image (pixman_image_t *image)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
width = pixman_image_get_width (image);
height = pixman_image_get_height (image);
stride = pixman_image_get_stride (image);
gtk_window_set_default_size (GTK_WINDOW (window), width, height);
format = pixman_image_get_format (image);
/* We always display the image as if it contains sRGB data. That
* means that no conversion should take place when the image
* has the a8r8g8b8_sRGB format.
*/
switch (format)
{
case PIXMAN_a8r8g8b8_sRGB:
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
copy = pixman_image_ref (image);
break;
default:
copy = pixman_image_create_bits (PIXMAN_a8r8g8b8,
width, height, NULL, -1);
pixman_image_composite32 (PIXMAN_OP_SRC,
image, NULL, copy,
0, 0, 0, 0, 0, 0,
width, height);
break;
}
g_signal_connect (window, "draw", G_CALLBACK (on_draw), copy);
format = image->bits.format;
if (format == PIXMAN_a8r8g8b8)
has_alpha = TRUE;
else if (format == PIXMAN_x8r8g8b8)
has_alpha = FALSE;
else
g_error ("Can't deal with this format: %x\n", format);
pixbuf = pixbuf_from_argb32 (pixman_image_get_data (image), has_alpha,
width, height, stride);
g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), pixbuf);
g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show (window);

View File

@ -6,10 +6,8 @@
void show_image (pixman_image_t *image);
pixman_image_t *
pixman_image_from_file (const char *filename, pixman_format_code_t format);
GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits,
gboolean has_alpha,
int width,
int height,
int stride);

View File

@ -1,50 +0,0 @@
#include "utils.h"
#include "gtk-utils.h"
#define WIDTH 1024
#define HEIGHT 640
int
main (int argc, char **argv)
{
pixman_image_t *src_img, *dest_img;
pixman_gradient_stop_t stops[] = {
{ 0x00000, { 0x0000, 0x0000, 0x4444, 0xdddd } },
{ 0x10000, { 0xeeee, 0xeeee, 0x8888, 0xdddd } },
#if 0
/* These colors make it very obvious that dithering
* is useful even for 8-bit gradients
*/
{ 0x00000, { 0x6666, 0x3333, 0x3333, 0xffff } },
{ 0x10000, { 0x3333, 0x6666, 0x6666, 0xffff } },
#endif
};
pixman_point_fixed_t p1, p2;
enable_divbyzero_exceptions ();
dest_img = pixman_image_create_bits (PIXMAN_x8r8g8b8,
WIDTH, HEIGHT,
NULL, 0);
p1.x = p1.y = 0x0000;
p2.x = WIDTH << 16;
p2.y = HEIGHT << 16;
src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, ARRAY_LENGTH (stops));
pixman_image_composite32 (PIXMAN_OP_OVER,
src_img,
NULL,
dest_img,
0, 0,
0, 0,
0, 0,
WIDTH, HEIGHT);
show_image (dest_img);
pixman_image_unref (dest_img);
return 0;
}

View File

@ -1,66 +0,0 @@
# Copyright © 2018 Intel Corporation
# 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 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.
extra_demo_cflags = []
if cc.get_argument_syntax() == 'msvc'
extra_demo_cflags = ['-D_USE_MATH_DEFINES']
endif
demos = [
'gradient-test',
'alpha-test',
'composite-test',
'clip-test',
'trap-test',
'screen-test',
'convolution-test',
'radial-test',
'linear-gradient',
'conical-test',
'tri-test',
'checkerboard',
'srgb-test',
'srgb-trap-test',
'scale',
'dither',
]
if dep_gtk.found()
libdemo = static_library(
'demo',
['gtk-utils.c', config_h, version_h],
dependencies : [libtestutils_dep, dep_gtk, dep_glib, dep_png, dep_m, dep_openmp],
include_directories : inc_pixman,
)
if dep_gtk.found()
foreach d : demos
executable(
d,
[d + '.c', config_h, version_h],
c_args : extra_demo_cflags,
link_with : [libdemo],
dependencies : [idep_pixman, libtestutils_dep, dep_glib, dep_gtk, dep_openmp, dep_png],
)
endforeach
endif
endif

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#include "utils.h"
#include "../test/utils.h"
#include "gtk-utils.h"
#define NUM_GRADIENTS 9
#define NUM_GRADIENTS 7
#define NUM_STOPS 3
#define NUM_REPEAT 4
#define SIZE 128
@ -28,9 +28,6 @@
* centers (0, 0) and (1, 0), but with different radiuses. From left
* to right:
*
* - Degenerate start circle completely inside the end circle
* 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0
*
* - Small start circle completely inside the end circle
* 0.25 -> 1.75; dr = 1.5 > 0; a = 1 - 1.50^2 < 0
*
@ -52,20 +49,15 @@
* - Small end circle completely inside the start circle
* 1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0
*
* - Degenerate end circle completely inside the start circle
* 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0
*
*/
const static double radiuses[NUM_GRADIENTS] = {
0.00,
0.25,
0.50,
0.50,
1.00,
1.00,
1.50,
1.75,
1.75
};
@ -141,14 +133,12 @@ main (int argc, char **argv)
pixman_image_t *src_img, *dest_img;
int i, j;
enable_divbyzero_exceptions ();
enable_fp_exceptions ();
dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
NULL, 0);
draw_checkerboard (dest_img, 25, 0xffaaaaaa, 0xffbbbbbb);
pixman_transform_init_identity (&transform);
/*

View File

@ -1,454 +0,0 @@
/*
* Copyright 2012, Red Hat, Inc.
* Copyright 2012, Soren Sandmann
*
* 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.
*
* Author: Soren Sandmann <soren.sandmann@gmail.com>
*/
#ifdef HAVE_CONFIG_H
#include "pixman-config.h"
#endif
#include <math.h>
#include <gtk/gtk.h>
#include <pixman.h>
#include <stdlib.h>
#include "gtk-utils.h"
typedef struct
{
GtkBuilder * builder;
pixman_image_t * original;
GtkAdjustment * scale_x_adjustment;
GtkAdjustment * scale_y_adjustment;
GtkAdjustment * rotate_adjustment;
GtkAdjustment * subsample_adjustment;
int scaled_width;
int scaled_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;
}
/* Figure out the boundary of a diameter=1 circle transformed into an ellipse
* by trans. Proof that this is the correct calculation:
*
* Transform x,y to u,v by this matrix calculation:
*
* |u| |a c| |x|
* |v| = |b d|*|y|
*
* Horizontal component:
*
* u = ax+cy (1)
*
* For each x,y on a radius-1 circle (p is angle to the point):
*
* x^2+y^2 = 1
* x = cos(p)
* y = sin(p)
* dx/dp = -sin(p) = -y
* dy/dp = cos(p) = x
*
* Figure out derivative of (1) relative to p:
*
* du/dp = a(dx/dp) + c(dy/dp)
* = -ay + cx
*
* The min and max u are when du/dp is zero:
*
* -ay + cx = 0
* cx = ay
* c = ay/x (2)
* y = cx/a (3)
*
* Substitute (2) into (1) and simplify:
*
* u = ax + ay^2/x
* = a(x^2+y^2)/x
* = a/x (because x^2+y^2 = 1)
* x = a/u (4)
*
* Substitute (4) into (3) and simplify:
*
* y = c(a/u)/a
* y = c/u (5)
*
* Square (4) and (5) and add:
*
* x^2+y^2 = (a^2+c^2)/u^2
*
* But x^2+y^2 is 1:
*
* 1 = (a^2+c^2)/u^2
* u^2 = a^2+c^2
* u = hypot(a,c)
*
* Similarily the max/min of v is at:
*
* v = hypot(b,d)
*
*/
static void
compute_extents (pixman_f_transform_t *trans, double *sx, double *sy)
{
*sx = hypot (trans->m[0][0], trans->m[0][1]) / trans->m[2][2];
*sy = hypot (trans->m[1][0], trans->m[1][1]) / trans->m[2][2];
}
typedef struct
{
char name [20];
int value;
} named_int_t;
static const named_int_t filters[] =
{
{ "Box", PIXMAN_KERNEL_BOX },
{ "Impulse", PIXMAN_KERNEL_IMPULSE },
{ "Linear", PIXMAN_KERNEL_LINEAR },
{ "Cubic", PIXMAN_KERNEL_CUBIC },
{ "Lanczos2", PIXMAN_KERNEL_LANCZOS2 },
{ "Lanczos3", PIXMAN_KERNEL_LANCZOS3 },
{ "Lanczos3 Stretched", PIXMAN_KERNEL_LANCZOS3_STRETCHED },
{ "Gaussian", PIXMAN_KERNEL_GAUSSIAN },
};
static const named_int_t repeats[] =
{
{ "None", PIXMAN_REPEAT_NONE },
{ "Normal", PIXMAN_REPEAT_NORMAL },
{ "Reflect", PIXMAN_REPEAT_REFLECT },
{ "Pad", PIXMAN_REPEAT_PAD },
};
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
copy_to_counterpart (app_t *app, GObject *object)
{
static const char *xy_map[] =
{
"reconstruct_x_combo_box", "reconstruct_y_combo_box",
"sample_x_combo_box", "sample_y_combo_box",
"scale_x_adjustment", "scale_y_adjustment",
};
GObject *counterpart = NULL;
int i;
for (i = 0; i < G_N_ELEMENTS (xy_map); i += 2)
{
GObject *x = gtk_builder_get_object (app->builder, xy_map[i]);
GObject *y = gtk_builder_get_object (app->builder, xy_map[i + 1]);
if (object == x)
counterpart = y;
if (object == y)
counterpart = x;
}
if (!counterpart)
return;
if (GTK_IS_COMBO_BOX (counterpart))
{
gtk_combo_box_set_active (
GTK_COMBO_BOX (counterpart),
gtk_combo_box_get_active (
GTK_COMBO_BOX (object)));
}
else if (GTK_IS_ADJUSTMENT (counterpart))
{
gtk_adjustment_set_value (
GTK_ADJUSTMENT (counterpart),
gtk_adjustment_get_value (
GTK_ADJUSTMENT (object)));
}
}
static double
to_scale (double v)
{
return pow (1.15, v);
}
static void
rescale (GtkWidget *may_be_null, app_t *app)
{
pixman_f_transform_t ftransform;
pixman_transform_t transform;
double new_width, new_height;
double fscale_x, fscale_y;
double rotation;
pixman_fixed_t *params;
int n_params;
double sx, sy;
pixman_f_transform_init_identity (&ftransform);
if (may_be_null && gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (get_widget (app, "lock_checkbutton"))))
{
copy_to_counterpart (app, G_OBJECT (may_be_null));
}
fscale_x = gtk_adjustment_get_value (app->scale_x_adjustment);
fscale_y = gtk_adjustment_get_value (app->scale_y_adjustment);
rotation = gtk_adjustment_get_value (app->rotate_adjustment);
fscale_x = to_scale (fscale_x);
fscale_y = to_scale (fscale_y);
new_width = pixman_image_get_width (app->original) * fscale_x;
new_height = pixman_image_get_height (app->original) * fscale_y;
pixman_f_transform_scale (&ftransform, NULL, fscale_x, fscale_y);
pixman_f_transform_translate (&ftransform, NULL, - new_width / 2.0, - new_height / 2.0);
rotation = (rotation / 360.0) * 2 * M_PI;
pixman_f_transform_rotate (&ftransform, NULL, cos (rotation), sin (rotation));
pixman_f_transform_translate (&ftransform, NULL, new_width / 2.0, new_height / 2.0);
pixman_f_transform_invert (&ftransform, &ftransform);
compute_extents (&ftransform, &sx, &sy);
pixman_transform_from_pixman_f_transform (&transform, &ftransform);
pixman_image_set_transform (app->original, &transform);
params = pixman_filter_create_separable_convolution (
&n_params,
sx * 65536.0 + 0.5,
sy * 65536.0 + 0.5,
get_value (app, filters, "reconstruct_x_combo_box"),
get_value (app, filters, "reconstruct_y_combo_box"),
get_value (app, filters, "sample_x_combo_box"),
get_value (app, filters, "sample_y_combo_box"),
gtk_adjustment_get_value (app->subsample_adjustment),
gtk_adjustment_get_value (app->subsample_adjustment));
pixman_image_set_filter (app->original, PIXMAN_FILTER_SEPARABLE_CONVOLUTION, params, n_params);
pixman_image_set_repeat (
app->original, get_value (app, repeats, "repeat_combo_box"));
free (params);
app->scaled_width = ceil (new_width);
app->scaled_height = ceil (new_height);
gtk_widget_set_size_request (
get_widget (app, "drawing_area"), new_width + 0.5, new_height + 0.5);
gtk_widget_queue_draw (
get_widget (app, "drawing_area"));
}
static gboolean
on_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
app_t *app = user_data;
GdkRectangle area;
cairo_surface_t *surface;
pixman_image_t *tmp;
uint32_t *pixels;
gdk_cairo_get_clip_rectangle(cr, &area);
pixels = calloc (1, area.width * area.height * 4);
tmp = pixman_image_create_bits (
PIXMAN_a8r8g8b8, area.width, area.height, pixels, area.width * 4);
if (area.x < app->scaled_width && area.y < app->scaled_height)
{
pixman_image_composite (
PIXMAN_OP_SRC,
app->original, NULL, tmp,
area.x, area.y, 0, 0, 0, 0,
app->scaled_width - area.x, app->scaled_height - area.y);
}
surface = cairo_image_surface_create_for_data (
(uint8_t *)pixels, CAIRO_FORMAT_ARGB32,
area.width, area.height, area.width * 4);
cairo_set_source_surface (cr, surface, area.x, area.y);
cairo_paint (cr);
cairo_surface_destroy (surface);
free (pixels);
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 void
set_up_filter_box (app_t *app, const char *box_name)
{
set_up_combo_box (app, box_name, G_N_ELEMENTS (filters), filters);
}
static char *
format_value (GtkWidget *widget, double value)
{
return g_strdup_printf ("%.4f", to_scale (value));
}
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 (!gtk_builder_add_from_file (app->builder, "scale.ui", &err))
g_error ("Could not read file scale.ui: %s", err->message);
app->scale_x_adjustment =
GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_x_adjustment"));
app->scale_y_adjustment =
GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_y_adjustment"));
app->rotate_adjustment =
GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "rotate_adjustment"));
app->subsample_adjustment =
GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "subsample_adjustment"));
g_signal_connect (app->scale_x_adjustment, "value_changed", G_CALLBACK (rescale), app);
g_signal_connect (app->scale_y_adjustment, "value_changed", G_CALLBACK (rescale), app);
g_signal_connect (app->rotate_adjustment, "value_changed", G_CALLBACK (rescale), app);
g_signal_connect (app->subsample_adjustment, "value_changed", G_CALLBACK (rescale), app);
widget = get_widget (app, "scale_x_scale");
gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
widget = get_widget (app, "scale_y_scale");
gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
widget = get_widget (app, "rotate_scale");
gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
widget = get_widget (app, "drawing_area");
g_signal_connect (widget, "draw", G_CALLBACK (on_draw), app);
set_up_filter_box (app, "reconstruct_x_combo_box");
set_up_filter_box (app, "reconstruct_y_combo_box");
set_up_filter_box (app, "sample_x_combo_box");
set_up_filter_box (app, "sample_y_combo_box");
set_up_combo_box (
app, "repeat_combo_box", G_N_ELEMENTS (repeats), repeats);
g_signal_connect (
gtk_builder_get_object (app->builder, "lock_checkbutton"),
"toggled", G_CALLBACK (rescale), app);
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)
{
printf ("%s <image file>\n", argv[0]);
return -1;
}
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;
}

View File

@ -1,334 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<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_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="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="subsample_adjustment">
<property name="lower">0</property>
<property name="upper">12</property>
<property name="step_increment">1</property>
<property name="page_increment">1</property>
<property name="page_size">0</property>
<property name="value">4</property>
</object>
<object class="GtkWindow" id="main">
<child>
<object class="GtkHBox" id="u">
<property name="visible">True</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>
<child>
<object class="GtkDrawingArea" id="drawing_area">
<property name="visible">True</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box1">
<property name="visible">True</property>
<property name="spacing">12</property>
<child>
<object class="GtkHBox" id="box2">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkVBox" id="box3">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Scale X&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVScale" id="scale_x_scale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">scale_x_adjustment</property>
<property name="fill_level">32</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box4">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Scale Y&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVScale" id="scale_y_scale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">scale_y_adjustment</property>
<property name="fill_level">32</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box5">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Rotate&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVScale" id="rotate_scale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">rotate_adjustment</property>
<property name="fill_level">180</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box6">
<property name="visible">True</property>
<child>
<object class="GtkCheckButton"
id="lock_checkbutton">
<property name="label" translatable="yes">Lock X and Y Dimensions</property>
<property name="xalign">0.0</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">6</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkTable" id="grid1">
<property name="visible">True</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="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Reconstruct X:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Reconstruct Y:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Sample X:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Sample Y:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Repeat:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Subsample:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="reconstruct_x_combo_box">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="reconstruct_y_combo_box">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="sample_x_combo_box">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="sample_y_combo_box">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="repeat_combo_box">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="subsample_spin_button">
<property name="visible">True</property>
<property name="adjustment">subsample_adjustment</property>
<property name="value">4</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="padding">6</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -1,87 +0,0 @@
#include <math.h>
#include "pixman.h"
#include "gtk-utils.h"
static uint32_t
linear_argb_to_premult_argb (float a,
float r,
float g,
float b)
{
r *= a;
g *= a;
b *= a;
return (uint32_t) (a * 255.0f + 0.5f) << 24
| (uint32_t) (r * 255.0f + 0.5f) << 16
| (uint32_t) (g * 255.0f + 0.5f) << 8
| (uint32_t) (b * 255.0f + 0.5f) << 0;
}
static float
lin2srgb (float linear)
{
if (linear < 0.0031308f)
return linear * 12.92f;
else
return 1.055f * powf (linear, 1.0f/2.4f) - 0.055f;
}
static uint32_t
linear_argb_to_premult_srgb_argb (float a,
float r,
float g,
float b)
{
r = lin2srgb (r * a);
g = lin2srgb (g * a);
b = lin2srgb (b * a);
return (uint32_t) (a * 255.0f + 0.5f) << 24
| (uint32_t) (r * 255.0f + 0.5f) << 16
| (uint32_t) (g * 255.0f + 0.5f) << 8
| (uint32_t) (b * 255.0f + 0.5f) << 0;
}
int
main (int argc, char **argv)
{
#define WIDTH 400
#define HEIGHT 200
int y, x, p;
float alpha;
uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
pixman_image_t *dest_img, *src1_img;
dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8_sRGB,
WIDTH, HEIGHT,
dest,
WIDTH * 4);
src1_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
WIDTH, HEIGHT,
src1,
WIDTH * 4);
for (y = 0; y < HEIGHT; y ++)
{
p = WIDTH * y;
for (x = 0; x < WIDTH; x ++)
{
alpha = (float) x / WIDTH;
src1[p + x] = linear_argb_to_premult_argb (alpha, 1, 0, 1);
dest[p + x] = linear_argb_to_premult_srgb_argb (1-alpha, 0, 1, 0);
}
}
pixman_image_composite (PIXMAN_OP_ADD, src1_img, NULL, dest_img,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
pixman_image_unref (src1_img);
free (src1);
show_image (dest_img);
pixman_image_unref (dest_img);
free (dest);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More