├── AUTHORS ├── NEWS ├── ChangeLog ├── demos ├── parrot.jpg ├── zone_plate.png ├── gtk-utils.h ├── linear-gradient.c ├── convolution-test.c ├── tri-test.c ├── screen-test.c ├── trap-test.c ├── clip-in.c ├── Makefile.am ├── checkerboard.c ├── srgb-test.c ├── gradient-test.c ├── conical-test.c ├── clip-test.c ├── srgb-trap-test.c ├── alpha-test.c ├── gtk-utils.c ├── composite-test.c └── radial-test.c ├── pixman ├── pixman-access-accessors.c ├── pixman-edge-accessors.c ├── pixman-arm-detect-win32.asm ├── pixman-accessor.h ├── Makefile.sources ├── pixman-arm-asm.h ├── solaris-hwcap.mapfile ├── pixman-region32.c ├── pixman-version.h.in ├── pixman-timer.c ├── Makefile.win32 ├── pixman-solid-fill.c ├── pixman-region16.c ├── make-srgb.pl ├── pixman-mips.c ├── pixman-ppc.c ├── Makefile.am ├── pixman-noop.c ├── pixman-edge-imp.h ├── pixman-arm-simd-asm-scaled.S ├── rounding.txt ├── pixman-conical-gradient.c ├── pixman-arm.c └── pixman-gradient-walker.c ├── pixman-1-uninstalled.pc.in ├── autogen.sh ├── pixman-1.pc.in ├── Makefile.win32 ├── test ├── Makefile.am ├── trap-crasher.c ├── region-translate-test.c ├── alpha-loop.c ├── infinite-loop.c ├── Makefile.sources ├── radial-invalid.c ├── radial-perf-test.c ├── Makefile.win32 ├── pdf-op-test.c ├── a1-trap-test.c ├── oob-test.c ├── scaling-bench.c ├── scaling-helpers-test.c ├── fuzzer-find-diff.pl ├── filter-reduction-test.c ├── rotate-test.c ├── region-test.c ├── combiner-test.c ├── thread-test.c ├── region-contains-test.c ├── fetch-test.c ├── gradient-crash-test.c ├── check-formats.c ├── prng-test.c └── scaling-crash-test.c ├── .gitignore ├── Makefile.win32.common ├── RELEASING ├── COPYING ├── README ├── CODING_STYLE └── Makefile.am /AUTHORS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demos/parrot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libpixman/pixman/HEAD/demos/parrot.jpg -------------------------------------------------------------------------------- /demos/zone_plate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libpixman/pixman/HEAD/demos/zone_plate.png -------------------------------------------------------------------------------- /pixman/pixman-access-accessors.c: -------------------------------------------------------------------------------- 1 | #define PIXMAN_FB_ACCESSORS 2 | 3 | #include "pixman-access.c" 4 | -------------------------------------------------------------------------------- /pixman/pixman-edge-accessors.c: -------------------------------------------------------------------------------- 1 | 2 | #define PIXMAN_FB_ACCESSORS 3 | 4 | #include "pixman-edge.c" 5 | -------------------------------------------------------------------------------- /pixman-1-uninstalled.pc.in: -------------------------------------------------------------------------------- 1 | Name: Pixman 2 | Description: The pixman library (version 1) 3 | Version: @PACKAGE_VERSION@ 4 | Cflags: -I${pc_top_builddir}/${pcfiledir}/pixman 5 | Libs: ${pc_top_builddir}/${pcfiledir}/pixman/libpixman-1.la 6 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | srcdir=`dirname $0` 4 | test -z "$srcdir" && srcdir=. 5 | 6 | ORIGDIR=`pwd` 7 | cd $srcdir 8 | 9 | autoreconf -v --install || exit 1 10 | cd $ORIGDIR || exit $? 11 | 12 | if test -z "$NOCONFIGURE"; then 13 | $srcdir/configure "$@" 14 | fi 15 | -------------------------------------------------------------------------------- /pixman-1.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Pixman 7 | Description: The pixman library (version 1) 8 | Version: @PACKAGE_VERSION@ 9 | Cflags: -I${includedir}/pixman-1 10 | Libs: -L${libdir} -lpixman-1 11 | 12 | -------------------------------------------------------------------------------- /demos/gtk-utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "pixman.h" 6 | 7 | void show_image (pixman_image_t *image); 8 | 9 | pixman_image_t * 10 | pixman_image_from_file (const char *filename, pixman_format_code_t format); 11 | 12 | GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits, 13 | int width, 14 | int height, 15 | int stride); 16 | -------------------------------------------------------------------------------- /Makefile.win32: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | top_srcdir = . 4 | include $(top_srcdir)/Makefile.win32.common 5 | 6 | all: pixman test 7 | 8 | pixman: 9 | @$(MAKE) -C pixman -f Makefile.win32 10 | 11 | test: 12 | @$(MAKE) -C test -f Makefile.win32 13 | 14 | clean_r: 15 | @$(MAKE) -C pixman -f Makefile.win32 clean 16 | @$(MAKE) -C test -f Makefile.win32 clean 17 | 18 | check: 19 | @$(MAKE) -C test -f Makefile.win32 check 20 | 21 | 22 | clean: clean_r 23 | 24 | 25 | .PHONY: all pixman test clean check 26 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | include $(top_srcdir)/test/Makefile.sources 2 | 3 | AM_CFLAGS = $(OPENMP_CFLAGS) $(PTHREAD_CFLAGS) 4 | AM_LDFLAGS = $(OPENMP_CFLAGS) $(TESTPROGS_EXTRA_LDFLAGS) $(PTHREAD_LDFLAGS) 5 | LDADD = libutils.la $(top_builddir)/pixman/libpixman-1.la -lm $(PNG_LIBS) $(PTHREAD_LIBS) 6 | AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(PNG_CFLAGS) 7 | 8 | libutils_la_SOURCES = $(libutils_sources) $(libutils_headers) 9 | 10 | noinst_LTLIBRARIES = libutils.la 11 | noinst_PROGRAMS = $(TESTPROGRAMS) $(OTHERPROGRAMS) 12 | 13 | TESTS = $(TESTPROGRAMS) 14 | -------------------------------------------------------------------------------- /pixman/pixman-arm-detect-win32.asm: -------------------------------------------------------------------------------- 1 | area pixman_msvc, code, readonly 2 | 3 | export pixman_msvc_try_arm_simd_op 4 | 5 | pixman_msvc_try_arm_simd_op 6 | ;; I don't think the msvc arm asm knows how to do SIMD insns 7 | ;; uqadd8 r3,r3,r3 8 | dcd 0xe6633f93 9 | mov pc,lr 10 | endp 11 | 12 | export pixman_msvc_try_arm_neon_op 13 | 14 | pixman_msvc_try_arm_neon_op 15 | ;; I don't think the msvc arm asm knows how to do NEON insns 16 | ;; veor d0,d0,d0 17 | dcd 0xf3000110 18 | mov pc,lr 19 | endp 20 | 21 | end 22 | -------------------------------------------------------------------------------- /test/trap-crasher.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | int 5 | main() 6 | { 7 | pixman_image_t *dst; 8 | pixman_trapezoid_t traps[] = { 9 | { 10 | 2147483646, 11 | 2147483647, 12 | { 13 | { 0, 0 }, 14 | { 0, 2147483647 } 15 | }, 16 | { 17 | { 65536, 0 }, 18 | { 0, 2147483647 } 19 | } 20 | }, 21 | { 22 | 32768, 23 | - 2147483647, 24 | { 25 | { 0, 0 }, 26 | { 0, 2147483647 } 27 | }, 28 | { 29 | { 65536, 0 }, 30 | { 0, 2147483647 } 31 | } 32 | }, 33 | }; 34 | 35 | dst = pixman_image_create_bits (PIXMAN_a8, 1, 1, NULL, -1); 36 | 37 | pixman_add_trapezoids (dst, 0, 0, ARRAY_LENGTH (traps), traps); 38 | return (0); 39 | } 40 | -------------------------------------------------------------------------------- /pixman/pixman-accessor.h: -------------------------------------------------------------------------------- 1 | #ifdef PIXMAN_FB_ACCESSORS 2 | 3 | #define READ(img, ptr) \ 4 | (((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr)))) 5 | #define WRITE(img, ptr,val) \ 6 | (((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr)))) 7 | 8 | #define MEMSET_WRAPPED(img, dst, val, size) \ 9 | do { \ 10 | size_t _i; \ 11 | uint8_t *_dst = (uint8_t*)(dst); \ 12 | for(_i = 0; _i < (size_t) size; _i++) { \ 13 | WRITE((img), _dst +_i, (val)); \ 14 | } \ 15 | } while (0) 16 | 17 | #else 18 | 19 | #define READ(img, ptr) (*(ptr)) 20 | #define WRITE(img, ptr, val) (*(ptr) = (val)) 21 | #define MEMSET_WRAPPED(img, dst, val, size) \ 22 | memset(dst, val, size) 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /test/region-translate-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | /* Pixman had a bug where 32bit regions where clipped to 16bit sizes when 5 | * pixman_region32_translate() was called. This test exercises that bug. 6 | */ 7 | 8 | #define LARGE 32000 9 | 10 | int 11 | main (int argc, char **argv) 12 | { 13 | pixman_box32_t rect = { -LARGE, -LARGE, LARGE, LARGE }; 14 | pixman_region32_t r1, r2; 15 | 16 | pixman_region32_init_rects (&r1, &rect, 1); 17 | pixman_region32_init_rect (&r2, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); 18 | 19 | assert (pixman_region32_equal (&r1, &r2)); 20 | 21 | pixman_region32_translate (&r1, -LARGE, LARGE); 22 | pixman_region32_translate (&r1, LARGE, -LARGE); 23 | 24 | assert (pixman_region32_equal (&r1, &r2)); 25 | 26 | pixman_region32_fini (&r1); 27 | pixman_region32_fini (&r2); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | .deps 4 | .libs 5 | .msg 6 | *.pc 7 | *.lo 8 | *.la 9 | *.a 10 | *.o 11 | *~ 12 | aclocal.m4 13 | autom4te.cache 14 | compile 15 | config.guess 16 | config.log 17 | config.status 18 | config.sub 19 | configure 20 | depcomp 21 | install-sh 22 | libtool 23 | ltmain.sh 24 | missing 25 | stamp-h? 26 | config.h 27 | config.h.in 28 | .*.swp 29 | demos/*-test 30 | demos/checkerboard 31 | demos/clip-in 32 | demos/linear-gradient 33 | demos/quad2quad 34 | demos/scale 35 | pixman/pixman-srgb.c 36 | pixman/pixman-version.h 37 | test/*-test 38 | test/affine-bench 39 | test/alpha-loop 40 | test/alphamap 41 | test/check-formats 42 | test/clip-in 43 | test/composite 44 | test/infinite-loop 45 | test/lowlevel-blt-bench 46 | test/radial-invalid 47 | test/region-translate 48 | test/scaling-bench 49 | test/trap-crasher 50 | *.pdb 51 | *.dll 52 | *.lib 53 | *.ilk 54 | *.obj 55 | *.exe 56 | -------------------------------------------------------------------------------- /pixman/Makefile.sources: -------------------------------------------------------------------------------- 1 | libpixman_sources = \ 2 | pixman.c \ 3 | pixman-access.c \ 4 | pixman-access-accessors.c \ 5 | pixman-bits-image.c \ 6 | pixman-combine32.c \ 7 | pixman-combine-float.c \ 8 | pixman-conical-gradient.c \ 9 | pixman-filter.c \ 10 | pixman-x86.c \ 11 | pixman-mips.c \ 12 | pixman-arm.c \ 13 | pixman-ppc.c \ 14 | pixman-edge.c \ 15 | pixman-edge-accessors.c \ 16 | pixman-fast-path.c \ 17 | pixman-glyph.c \ 18 | pixman-general.c \ 19 | pixman-gradient-walker.c \ 20 | pixman-image.c \ 21 | pixman-implementation.c \ 22 | pixman-linear-gradient.c \ 23 | pixman-matrix.c \ 24 | pixman-noop.c \ 25 | pixman-radial-gradient.c \ 26 | pixman-region16.c \ 27 | pixman-region32.c \ 28 | pixman-solid-fill.c \ 29 | pixman-timer.c \ 30 | pixman-trap.c \ 31 | pixman-utils.c \ 32 | $(NULL) 33 | 34 | libpixman_headers = \ 35 | pixman.h \ 36 | pixman-accessor.h \ 37 | pixman-combine32.h \ 38 | pixman-compiler.h \ 39 | pixman-edge-imp.h \ 40 | pixman-inlines.h \ 41 | pixman-private.h \ 42 | $(NULL) 43 | -------------------------------------------------------------------------------- /test/alpha-loop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | #define WIDTH 400 6 | #define HEIGHT 200 7 | 8 | int 9 | main (int argc, char **argv) 10 | { 11 | pixman_image_t *a, *d, *s; 12 | uint8_t *alpha; 13 | uint32_t *src, *dest; 14 | 15 | prng_srand (0); 16 | 17 | alpha = make_random_bytes (WIDTH * HEIGHT); 18 | src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); 19 | dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); 20 | 21 | a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH); 22 | d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); 23 | s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4); 24 | 25 | fail_after (5, "Infinite loop detected: 5 seconds without progress\n"); 26 | 27 | pixman_image_set_alpha_map (s, a, 0, 0); 28 | pixman_image_set_alpha_map (a, s, 0, 0); 29 | 30 | pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 31 | 32 | pixman_image_unref (s); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/infinite-loop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "utils.h" 6 | 7 | int 8 | main (int argc, char **argv) 9 | { 10 | #define SRC_WIDTH 16 11 | #define SRC_HEIGHT 12 12 | #define DST_WIDTH 7 13 | #define DST_HEIGHT 2 14 | 15 | static const pixman_transform_t transform = { 16 | { { 0x200017bd, 0x00000000, 0x000e6465 }, 17 | { 0x00000000, 0x000a42fd, 0x000e6465 }, 18 | { 0x00000000, 0x00000000, 0x00010000 }, 19 | } 20 | }; 21 | pixman_image_t *src, *dest; 22 | 23 | src = pixman_image_create_bits ( 24 | PIXMAN_a8r8g8b8, SRC_WIDTH, SRC_HEIGHT, NULL, -1); 25 | dest = pixman_image_create_bits ( 26 | PIXMAN_a8r8g8b8, DST_WIDTH, DST_HEIGHT, NULL, -1); 27 | 28 | pixman_image_set_transform (src, &transform); 29 | pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL); 30 | pixman_image_set_filter (src, PIXMAN_FILTER_BILINEAR, NULL, 0); 31 | 32 | if (argc == 1 || strcmp (argv[1], "-nf") != 0) 33 | fail_after (1, "infinite loop detected"); 34 | 35 | pixman_image_composite ( 36 | PIXMAN_OP_OVER, src, NULL, dest, -3, -3, 0, 0, 0, 0, 6, 2); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /demos/linear-gradient.c: -------------------------------------------------------------------------------- 1 | #include "../test/utils.h" 2 | #include "gtk-utils.h" 3 | 4 | #define WIDTH 1024 5 | #define HEIGHT 640 6 | 7 | int 8 | main (int argc, char **argv) 9 | { 10 | pixman_image_t *src_img, *dest_img; 11 | pixman_gradient_stop_t stops[] = { 12 | { 0x00000, { 0x0000, 0x0000, 0x4444, 0xdddd } }, 13 | { 0x10000, { 0xeeee, 0xeeee, 0x8888, 0xdddd } }, 14 | #if 0 15 | /* These colors make it very obvious that dithering 16 | * is useful even for 8-bit gradients 17 | */ 18 | { 0x00000, { 0x6666, 0x3333, 0x3333, 0xffff } }, 19 | { 0x10000, { 0x3333, 0x6666, 0x6666, 0xffff } }, 20 | #endif 21 | }; 22 | pixman_point_fixed_t p1, p2; 23 | 24 | enable_divbyzero_exceptions (); 25 | 26 | dest_img = pixman_image_create_bits (PIXMAN_x8r8g8b8, 27 | WIDTH, HEIGHT, 28 | NULL, 0); 29 | 30 | p1.x = p1.y = 0x0000; 31 | p2.x = WIDTH << 16; 32 | p2.y = HEIGHT << 16; 33 | 34 | src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, ARRAY_LENGTH (stops)); 35 | 36 | pixman_image_composite32 (PIXMAN_OP_OVER, 37 | src_img, 38 | NULL, 39 | dest_img, 40 | 0, 0, 41 | 0, 0, 42 | 0, 0, 43 | WIDTH, HEIGHT); 44 | 45 | show_image (dest_img); 46 | 47 | pixman_image_unref (dest_img); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /demos/convolution-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | int 7 | main (int argc, char **argv) 8 | { 9 | #define WIDTH 200 10 | #define HEIGHT 200 11 | 12 | #define d2f pixman_double_to_fixed 13 | 14 | uint32_t *src = malloc (WIDTH * HEIGHT * 4); 15 | uint32_t *mask = malloc (WIDTH * HEIGHT * 4); 16 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 17 | pixman_fixed_t convolution[] = 18 | { 19 | d2f (3), d2f (3), 20 | d2f (0.5), d2f (0.5), d2f (0.5), 21 | d2f (0.5), d2f (0.5), d2f (0.5), 22 | d2f (0.5), d2f (0.5), d2f (0.5), 23 | }; 24 | pixman_image_t *simg, *mimg, *dimg; 25 | 26 | int i; 27 | 28 | for (i = 0; i < WIDTH * HEIGHT; ++i) 29 | { 30 | src[i] = 0x7f007f00; 31 | mask[i] = (i % 256) * 0x01000000; 32 | dest[i] = 0; 33 | } 34 | 35 | simg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src, WIDTH * 4); 36 | mimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, mask, WIDTH * 4); 37 | dimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); 38 | 39 | pixman_image_set_filter (mimg, PIXMAN_FILTER_CONVOLUTION, 40 | convolution, 11); 41 | 42 | pixman_image_composite (PIXMAN_OP_OVER, simg, mimg, dimg, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 43 | 44 | show_image (dimg); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /test/Makefile.sources: -------------------------------------------------------------------------------- 1 | # Tests (sorted by expected completion time) 2 | TESTPROGRAMS = \ 3 | oob-test \ 4 | infinite-loop \ 5 | trap-crasher \ 6 | fence-image-self-test \ 7 | region-translate-test \ 8 | fetch-test \ 9 | a1-trap-test \ 10 | prng-test \ 11 | radial-invalid \ 12 | pdf-op-test \ 13 | region-test \ 14 | combiner-test \ 15 | scaling-crash-test \ 16 | alpha-loop \ 17 | scaling-helpers-test \ 18 | thread-test \ 19 | rotate-test \ 20 | alphamap \ 21 | gradient-crash-test \ 22 | pixel-test \ 23 | matrix-test \ 24 | filter-reduction-test \ 25 | composite-traps-test \ 26 | region-contains-test \ 27 | glyph-test \ 28 | solid-test \ 29 | stress-test \ 30 | cover-test \ 31 | blitters-test \ 32 | affine-test \ 33 | scaling-test \ 34 | composite \ 35 | tolerance-test \ 36 | $(NULL) 37 | 38 | # Other programs 39 | OTHERPROGRAMS = \ 40 | lowlevel-blt-bench \ 41 | radial-perf-test \ 42 | check-formats \ 43 | scaling-bench \ 44 | affine-bench \ 45 | $(NULL) 46 | 47 | # Utility functions 48 | libutils_sources = \ 49 | utils.c \ 50 | utils-prng.c \ 51 | $(NULL) 52 | 53 | libutils_headers = \ 54 | utils.h \ 55 | utils-prng.h \ 56 | $(NULL) 57 | -------------------------------------------------------------------------------- /demos/tri-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../test/utils.h" 5 | #include "gtk-utils.h" 6 | 7 | int 8 | main (int argc, char **argv) 9 | { 10 | #define WIDTH 200 11 | #define HEIGHT 200 12 | 13 | #define POINT(x,y) \ 14 | { pixman_double_to_fixed ((x)), pixman_double_to_fixed ((y)) } 15 | 16 | pixman_image_t *src_img, *dest_img; 17 | pixman_triangle_t tris[4] = 18 | { 19 | { POINT (100, 100), POINT (10, 50), POINT (110, 10) }, 20 | { POINT (100, 100), POINT (150, 10), POINT (200, 50) }, 21 | { POINT (100, 100), POINT (10, 170), POINT (90, 175) }, 22 | { POINT (100, 100), POINT (170, 150), POINT (120, 190) }, 23 | }; 24 | pixman_color_t color = { 0x4444, 0x4444, 0xffff, 0xffff }; 25 | uint32_t *bits = malloc (WIDTH * HEIGHT * 4); 26 | int i; 27 | 28 | for (i = 0; i < WIDTH * HEIGHT; ++i) 29 | bits[i] = (i / HEIGHT) * 0x01010000; 30 | 31 | src_img = pixman_image_create_solid_fill (&color); 32 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4); 33 | 34 | pixman_composite_triangles (PIXMAN_OP_ATOP_REVERSE, 35 | src_img, 36 | dest_img, 37 | PIXMAN_a8, 38 | 200, 200, 39 | -5, 5, 40 | ARRAY_LENGTH (tris), tris); 41 | show_image (dest_img); 42 | 43 | pixman_image_unref (src_img); 44 | pixman_image_unref (dest_img); 45 | free (bits); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test/radial-invalid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | 6 | #define WIDTH 100 7 | #define HEIGHT 100 8 | 9 | int 10 | main () 11 | { 12 | pixman_image_t *radial; 13 | pixman_image_t *dest = pixman_image_create_bits ( 14 | PIXMAN_a8r8g8b8, WIDTH, HEIGHT, NULL, -1); 15 | 16 | static const pixman_transform_t xform = 17 | { 18 | { { 0x346f7, 0x0, 0x0 }, 19 | { 0x0, 0x346f7, 0x0 }, 20 | { 0x0, 0x0, 0x10000 } 21 | }, 22 | }; 23 | 24 | static const pixman_gradient_stop_t stops[] = 25 | { 26 | { 0xde61, { 0x4481, 0x96e8, 0x1e6a, 0x29e1 } }, 27 | { 0xfdd5, { 0xfa10, 0xcc26, 0xbc43, 0x1eb7 } }, 28 | { 0xfe1e, { 0xd257, 0x5bac, 0x6fc2, 0xa33b } }, 29 | }; 30 | 31 | static const pixman_point_fixed_t inner = { 0x320000, 0x320000 }; 32 | static const pixman_point_fixed_t outer = { 0x320000, 0x3cb074 }; 33 | 34 | enable_divbyzero_exceptions (); 35 | enable_invalid_exceptions (); 36 | 37 | radial = pixman_image_create_radial_gradient ( 38 | &inner, 39 | &outer, 40 | 0xab074, /* inner radius */ 41 | 0x0, /* outer radius */ 42 | stops, sizeof (stops) / sizeof (stops[0])); 43 | 44 | pixman_image_set_repeat (radial, PIXMAN_REPEAT_REFLECT); 45 | pixman_image_set_transform (radial, &xform); 46 | 47 | pixman_image_composite ( 48 | PIXMAN_OP_OVER, 49 | radial, NULL, dest, 50 | 0, 0, 0, 0, 51 | 0, 0, WIDTH, HEIGHT); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Makefile.win32.common: -------------------------------------------------------------------------------- 1 | LIBRARY = pixman-1 2 | 3 | CC = cl 4 | LD = link 5 | AR = lib 6 | PERL = perl 7 | 8 | ifneq ($(shell echo ""),) 9 | RM = del 10 | endif 11 | 12 | ifeq ($(top_builddir),) 13 | top_builddir = $(top_srcdir) 14 | endif 15 | 16 | CFG_VAR = $(CFG) 17 | ifeq ($(CFG_VAR),) 18 | CFG_VAR = release 19 | endif 20 | 21 | ifeq ($(CFG_VAR),debug) 22 | CFG_CFLAGS = -MDd -Od -Zi 23 | CFG_LDFLAGS = -DEBUG 24 | else 25 | CFG_CFLAGS = -MD -O2 26 | CFG_LDFLAGS = 27 | endif 28 | 29 | # Package definitions, to be used instead of those provided in config.h 30 | PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT="" 31 | 32 | BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman 33 | 34 | PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS) 35 | PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS) 36 | PIXMAN_ARFLAGS = -nologo $(LDFLAGS) 37 | 38 | 39 | inform: 40 | ifneq ($(CFG),release) 41 | ifneq ($(CFG),debug) 42 | ifneq ($(CFG),) 43 | @echo "Invalid specified configuration option: "$(CFG)"." 44 | @echo 45 | @echo "Possible choices for configuration are 'release' and 'debug'" 46 | @exit 1 47 | endif 48 | @echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)" 49 | endif 50 | endif 51 | 52 | $(CFG_VAR): 53 | @mkdir $@ 54 | 55 | $(CFG_VAR)/%.obj: %.c $(libpixman_headers) | $(CFG_VAR) 56 | @$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $< 57 | 58 | clean: inform $(CFG_VAR) 59 | @cd $(CFG_VAR) && echo > silence_error.exe && $(RM) *.exe *.ilk *.lib *.obj *.pdb 60 | 61 | .PHONY: inform clean 62 | -------------------------------------------------------------------------------- /demos/screen-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | int 7 | main (int argc, char **argv) 8 | { 9 | #define WIDTH 40 10 | #define HEIGHT 40 11 | 12 | uint32_t *src1 = malloc (WIDTH * HEIGHT * 4); 13 | uint32_t *src2 = malloc (WIDTH * HEIGHT * 4); 14 | uint32_t *src3 = malloc (WIDTH * HEIGHT * 4); 15 | uint32_t *dest = malloc (3 * WIDTH * 2 * HEIGHT * 4); 16 | pixman_image_t *simg1, *simg2, *simg3, *dimg; 17 | 18 | int i; 19 | 20 | for (i = 0; i < WIDTH * HEIGHT; ++i) 21 | { 22 | src1[i] = 0x7ff00000; 23 | src2[i] = 0x7f00ff00; 24 | src3[i] = 0x7f0000ff; 25 | } 26 | 27 | for (i = 0; i < 3 * WIDTH * 2 * HEIGHT; ++i) 28 | { 29 | dest[i] = 0x0; 30 | } 31 | 32 | simg1 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src1, WIDTH * 4); 33 | simg2 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src2, WIDTH * 4); 34 | simg3 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src3, WIDTH * 4); 35 | dimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, 3 * WIDTH, 2 * HEIGHT, dest, 3 * WIDTH * 4); 36 | 37 | pixman_image_composite (PIXMAN_OP_SCREEN, simg1, NULL, dimg, 0, 0, 0, 0, WIDTH, HEIGHT / 4, WIDTH, HEIGHT); 38 | pixman_image_composite (PIXMAN_OP_SCREEN, simg2, NULL, dimg, 0, 0, 0, 0, (WIDTH/2), HEIGHT / 4 + HEIGHT / 2, WIDTH, HEIGHT); 39 | pixman_image_composite (PIXMAN_OP_SCREEN, simg3, NULL, dimg, 0, 0, 0, 0, (4 * WIDTH) / 3, HEIGHT, WIDTH, HEIGHT); 40 | 41 | show_image (dimg); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /demos/trap-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pixman.h" 5 | #include "gtk-utils.h" 6 | 7 | int 8 | main (int argc, char **argv) 9 | { 10 | #define WIDTH 200 11 | #define HEIGHT 200 12 | 13 | pixman_image_t *src_img; 14 | pixman_image_t *mask_img; 15 | pixman_image_t *dest_img; 16 | pixman_trap_t trap; 17 | pixman_color_t white = { 0x0000, 0xffff, 0x0000, 0xffff }; 18 | uint32_t *bits = malloc (WIDTH * HEIGHT * 4); 19 | uint32_t *mbits = malloc (WIDTH * HEIGHT); 20 | 21 | memset (mbits, 0, WIDTH * HEIGHT); 22 | memset (bits, 0xff, WIDTH * HEIGHT * 4); 23 | 24 | trap.top.l = pixman_int_to_fixed (50) + 0x8000; 25 | trap.top.r = pixman_int_to_fixed (150) + 0x8000; 26 | trap.top.y = pixman_int_to_fixed (30); 27 | 28 | trap.bot.l = pixman_int_to_fixed (50) + 0x8000; 29 | trap.bot.r = pixman_int_to_fixed (150) + 0x8000; 30 | trap.bot.y = pixman_int_to_fixed (150); 31 | 32 | mask_img = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, mbits, WIDTH); 33 | src_img = pixman_image_create_solid_fill (&white); 34 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4); 35 | 36 | pixman_add_traps (mask_img, 0, 0, 1, &trap); 37 | 38 | pixman_image_composite (PIXMAN_OP_OVER, 39 | src_img, mask_img, dest_img, 40 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 41 | 42 | show_image (dest_img); 43 | 44 | pixman_image_unref (src_img); 45 | pixman_image_unref (dest_img); 46 | free (bits); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /pixman/pixman-arm-asm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Mozilla Corporation 3 | * Copyright © 2010 Nokia Corporation 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of Mozilla Corporation not be used in 10 | * advertising or publicity pertaining to distribution of the software without 11 | * specific, written prior permission. Mozilla Corporation makes no 12 | * representations about the suitability of this software for any purpose. It 13 | * is provided "as is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 20 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 21 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 22 | * SOFTWARE. 23 | * 24 | * Author: Jeff Muizelaar (jeff@infidigm.net) 25 | * 26 | */ 27 | 28 | /* Supplementary macro for setting function attributes */ 29 | .macro pixman_asm_function fname 30 | .func fname 31 | .global fname 32 | #ifdef __ELF__ 33 | .hidden fname 34 | .type fname, %function 35 | #endif 36 | fname: 37 | .endm 38 | -------------------------------------------------------------------------------- /pixman/solaris-hwcap.mapfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Copyright 2009, Oracle and/or its affiliates. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a 6 | # copy of this software and associated documentation files (the "Software"), 7 | # to deal in the Software without restriction, including without limitation 8 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | # and/or sell copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice (including the next 13 | # paragraph) shall be included in all copies or substantial portions of the 14 | # Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | ############################################################################### 25 | # 26 | # Override the linker's detection of CMOV/MMX/SSE instructions so this 27 | # library isn't flagged as only usable on CPU's with those ISA's, since it 28 | # checks at runtime for availability before calling them 29 | 30 | hwcap_1 = V0x0 FPU OVERRIDE; 31 | -------------------------------------------------------------------------------- /demos/clip-in.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pixman.h" 5 | #include "gtk-utils.h" 6 | 7 | /* This test demonstrates that clipping is done totally different depending 8 | * on whether the source is transformed or not. 9 | */ 10 | int 11 | main (int argc, char **argv) 12 | { 13 | #define WIDTH 200 14 | #define HEIGHT 200 15 | 16 | #define SMALL 25 17 | 18 | uint32_t *sbits = malloc (SMALL * SMALL * 4); 19 | uint32_t *bits = malloc (WIDTH * HEIGHT * 4); 20 | pixman_transform_t trans = { 21 | { 22 | { pixman_double_to_fixed (1.0), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.1), }, 23 | { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.1), }, 24 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } 25 | } }; 26 | 27 | pixman_image_t *src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, SMALL, SMALL, sbits, 4 * SMALL); 28 | pixman_image_t *dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, 4 * WIDTH); 29 | 30 | memset (bits, 0xff, WIDTH * HEIGHT * 4); 31 | memset (sbits, 0x00, SMALL * SMALL * 4); 32 | 33 | pixman_image_composite (PIXMAN_OP_IN, 34 | src_img, NULL, dest_img, 35 | 0, 0, 0, 0, SMALL, SMALL, 200, 200); 36 | 37 | pixman_image_set_transform (src_img, &trans); 38 | 39 | pixman_image_composite (PIXMAN_OP_IN, 40 | src_img, NULL, dest_img, 41 | 0, 0, 0, 0, SMALL * 2, SMALL * 2, 200, 200); 42 | 43 | show_image (dest_img); 44 | 45 | pixman_image_unref (src_img); 46 | pixman_image_unref (dest_img); 47 | free (bits); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /demos/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = parrot.c parrot.jpg scale.ui 2 | 3 | if HAVE_GTK 4 | 5 | AM_CFLAGS = $(OPENMP_CFLAGS) 6 | AM_LDFLAGS = $(OPENMP_CFLAGS) 7 | 8 | LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS) 9 | AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS) $(PNG_CFLAGS) 10 | 11 | GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h \ 12 | ../test/utils-prng.c ../test/utils-prng.h 13 | 14 | DEMOS = \ 15 | clip-test \ 16 | clip-in \ 17 | composite-test \ 18 | gradient-test \ 19 | radial-test \ 20 | linear-gradient \ 21 | conical-test \ 22 | alpha-test \ 23 | screen-test \ 24 | convolution-test \ 25 | trap-test \ 26 | tri-test \ 27 | quad2quad \ 28 | checkerboard \ 29 | srgb-trap-test \ 30 | srgb-test \ 31 | scale 32 | 33 | gradient_test_SOURCES = gradient-test.c $(GTK_UTILS) 34 | alpha_test_SOURCES = alpha-test.c $(GTK_UTILS) 35 | composite_test_SOURCES = composite-test.c $(GTK_UTILS) 36 | clip_test_SOURCES = clip-test.c $(GTK_UTILS) 37 | clip_in_SOURCES = clip-in.c $(GTK_UTILS) 38 | trap_test_SOURCES = trap-test.c $(GTK_UTILS) 39 | screen_test_SOURCES = screen-test.c $(GTK_UTILS) 40 | convolution_test_SOURCES = convolution-test.c $(GTK_UTILS) 41 | radial_test_SOURCES = radial-test.c $(GTK_UTILS) 42 | linear_gradient_SOURCES = linear-gradient.c $(GTK_UTILS) 43 | conical_test_SOURCES = conical-test.c $(GTK_UTILS) 44 | tri_test_SOURCES = tri-test.c $(GTK_UTILS) 45 | checkerboard_SOURCES = checkerboard.c $(GTK_UTILS) 46 | srgb_test_SOURCES = srgb-test.c $(GTK_UTILS) 47 | srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS) 48 | scale_SOURCES = scale.c $(GTK_UTILS) 49 | 50 | noinst_PROGRAMS = $(DEMOS) 51 | 52 | endif 53 | -------------------------------------------------------------------------------- /test/radial-perf-test.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | 4 | int 5 | main () 6 | { 7 | static const pixman_point_fixed_t inner = { 0x0000, 0x0000 }; 8 | static const pixman_point_fixed_t outer = { 0x0000, 0x0000 }; 9 | static const pixman_fixed_t r_inner = 0; 10 | static const pixman_fixed_t r_outer = 64 << 16; 11 | static const pixman_gradient_stop_t stops[] = { 12 | { 0x00000, { 0x6666, 0x6666, 0x6666, 0xffff } }, 13 | { 0x10000, { 0x0000, 0x0000, 0x0000, 0xffff } } 14 | }; 15 | static const pixman_transform_t transform = { 16 | { { 0x0, 0x26ee, 0x0}, 17 | { 0xffffeeef, 0x0, 0x0}, 18 | { 0x0, 0x0, 0x10000} 19 | } 20 | }; 21 | static const pixman_color_t z = { 0x0000, 0x0000, 0x0000, 0x0000 }; 22 | pixman_image_t *dest, *radial, *zero; 23 | int i; 24 | double before, after; 25 | 26 | dest = pixman_image_create_bits ( 27 | PIXMAN_x8r8g8b8, 640, 429, NULL, -1); 28 | zero = pixman_image_create_solid_fill (&z); 29 | radial = pixman_image_create_radial_gradient ( 30 | &inner, &outer, r_inner, r_outer, stops, ARRAY_LENGTH (stops)); 31 | pixman_image_set_transform (radial, &transform); 32 | pixman_image_set_repeat (radial, PIXMAN_REPEAT_PAD); 33 | 34 | #define N_COMPOSITE 500 35 | 36 | before = gettime(); 37 | for (i = 0; i < N_COMPOSITE; ++i) 38 | { 39 | before -= gettime(); 40 | 41 | pixman_image_composite ( 42 | PIXMAN_OP_SRC, zero, NULL, dest, 43 | 0, 0, 0, 0, 0, 0, 640, 429); 44 | 45 | before += gettime(); 46 | 47 | pixman_image_composite32 ( 48 | PIXMAN_OP_OVER, radial, NULL, dest, 49 | - 150, -158, 0, 0, 0, 0, 640, 361); 50 | } 51 | 52 | after = gettime(); 53 | 54 | write_png (dest, "radial.png"); 55 | 56 | printf ("Average time to composite: %f\n", (after - before) / N_COMPOSITE); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /RELEASING: -------------------------------------------------------------------------------- 1 | Here are the steps to follow to create a new pixman release: 2 | 3 | 1) Ensure that there are no uncommitted changes or unpushed commits, 4 | and that you are up to date with the latest commits in the central 5 | repository. Here are a couple of useful commands: 6 | 7 | git diff (no output) 8 | 9 | git status (should report "nothing to commit") 10 | 11 | git log master...origin (no output; note: *3* dots) 12 | 13 | 2) Increment pixman_(major|minor|micro) in configure.ac according to 14 | the directions in that file. 15 | 16 | 3) Make sure that new version works, including 17 | 18 | - make distcheck passes 19 | 20 | - the X server still works with the new pixman version 21 | installed 22 | 23 | - the cairo test suite hasn't gained any new failures compared 24 | to last pixman version. 25 | 26 | 4) Use "git commit" to record the changes made in step 2 and 3. 27 | 28 | 5) Generate and publish the tar files by running 29 | 30 | make PREV= GPGKEY= release-publish 31 | 32 | If your freedesktop user name is different from your local one, 33 | then also set the variable USER to your freedesktop user name. 34 | 35 | 6) Run 36 | 37 | make release-publish-message 38 | 39 | to generate a draft release announcement. Edit it as appropriate and 40 | send it to 41 | 42 | cairo-announce@cairographics.org 43 | 44 | pixman@lists.freedesktop.org 45 | 46 | xorg-announce@lists.freedesktop.org 47 | 48 | 7) Increment pixman_micro to the next larger (odd) number in 49 | configure.ac. Commit this change, and push all commits created 50 | during this process using 51 | 52 | git push 53 | git push --tags 54 | 55 | You must use "--tags" here; otherwise the new tag will not 56 | be pushed out. 57 | 58 | 8) Change the topic of the #cairo IRC channel on freenode to advertise 59 | the new version. 60 | -------------------------------------------------------------------------------- /pixman/pixman-region32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Red Hat, Inc. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software 5 | * and its documentation for any purpose is hereby granted without 6 | * fee, provided that the above copyright notice appear in all copies 7 | * and that both that copyright notice and this permission notice 8 | * appear in supporting documentation, and that the name of 9 | * Red Hat, Inc. not be used in advertising or publicity pertaining to 10 | * distribution of the software without specific, written prior 11 | * permission. Red Hat, Inc. makes no representations about the 12 | * suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, 18 | * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 19 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 20 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 21 | * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | * 23 | * Author: Soren Sandmann 24 | */ 25 | #ifdef HAVE_CONFIG_H 26 | #include 27 | #endif 28 | 29 | #include "pixman-private.h" 30 | 31 | #include 32 | 33 | typedef pixman_box32_t box_type_t; 34 | typedef pixman_region32_data_t region_data_type_t; 35 | typedef pixman_region32_t region_type_t; 36 | typedef int64_t overflow_int_t; 37 | 38 | typedef struct { 39 | int x, y; 40 | } point_type_t; 41 | 42 | #define PREFIX(x) pixman_region32##x 43 | 44 | #define PIXMAN_REGION_MAX INT32_MAX 45 | #define PIXMAN_REGION_MIN INT32_MIN 46 | 47 | #include "pixman-region.c" 48 | -------------------------------------------------------------------------------- /test/Makefile.win32: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | top_srcdir = .. 4 | include $(top_srcdir)/test/Makefile.sources 5 | include $(top_srcdir)/Makefile.win32.common 6 | 7 | TEST_LDADD = \ 8 | $(top_builddir)/pixman/$(CFG_VAR)/$(LIBRARY).lib \ 9 | $(CFG_VAR)/libutils.lib \ 10 | $(NULL) 11 | 12 | libutils_OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libutils_sources)) 13 | 14 | SOURCES = $(patsubst %, %.c, $(TESTPROGRAMS) $(OTHERPROGRAMS)) 15 | OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(SOURCES)) 16 | TESTS = $(patsubst %, $(CFG_VAR)/%.exe, $(TESTPROGRAMS)) 17 | OTHERS = $(patsubst %, $(CFG_VAR)/%.exe, $(OTHERPROGRAMS)) 18 | 19 | all: inform $(TESTS) $(OTHERS) 20 | 21 | check: inform $(TESTS) 22 | @total=0 ; \ 23 | pass=0 ; \ 24 | skip=0 ; \ 25 | fail=0 ; \ 26 | for test in $(TESTS) ; \ 27 | do \ 28 | total=`expr $$total + 1` ; \ 29 | ./$$test ; \ 30 | r=$$? ; \ 31 | if test $$r -eq 0 ; \ 32 | then echo "PASS: $$test" ; \ 33 | pass=`expr $$pass + 1` ; \ 34 | elif test $$r -eq 77 ; \ 35 | then echo "SKIP: $$test" ; \ 36 | skip=`expr $$skip + 1` ; \ 37 | else echo "FAIL: $$test" ; \ 38 | fail=`expr $$fail + 1` ; \ 39 | fi ; \ 40 | done ; \ 41 | dashes="============================================================================" ; \ 42 | echo "$$dashes" ; \ 43 | echo "Testsuite summary for pixman:" ; \ 44 | echo "$$dashes" ; \ 45 | echo "# TOTAL: $$total" ; \ 46 | echo "# PASS: $$pass" ; \ 47 | echo "# SKIP: $$skip" ; \ 48 | echo "# FAIL: $$fail" ; \ 49 | echo "$$dashes" ; \ 50 | test $$fail -eq 0 51 | 52 | $(CFG_VAR)/libutils.lib: $(libutils_OBJECTS) 53 | @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ 54 | 55 | $(CFG_VAR)/%.exe: $(CFG_VAR)/%.obj $(TEST_LDADD) 56 | @$(LD) $(PIXMAN_LDFLAGS) -OUT:$@ $^ 57 | 58 | $(top_builddir)/pixman/$(CFG_VAR)/$(LIBRARY).lib: 59 | @$(MAKE) -C $(top_builddir)/pixman -f Makefile.win32 60 | 61 | .PHONY: all check 62 | -------------------------------------------------------------------------------- /test/pdf-op-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | static const pixman_op_t pdf_ops[] = 5 | { 6 | PIXMAN_OP_MULTIPLY, 7 | PIXMAN_OP_SCREEN, 8 | PIXMAN_OP_OVERLAY, 9 | PIXMAN_OP_DARKEN, 10 | PIXMAN_OP_LIGHTEN, 11 | PIXMAN_OP_COLOR_DODGE, 12 | PIXMAN_OP_COLOR_BURN, 13 | PIXMAN_OP_HARD_LIGHT, 14 | PIXMAN_OP_SOFT_LIGHT, 15 | PIXMAN_OP_DIFFERENCE, 16 | PIXMAN_OP_EXCLUSION, 17 | PIXMAN_OP_HSL_HUE, 18 | PIXMAN_OP_HSL_SATURATION, 19 | PIXMAN_OP_HSL_COLOR, 20 | PIXMAN_OP_HSL_LUMINOSITY 21 | }; 22 | 23 | static const uint32_t pixels[] = 24 | { 25 | 0x00808080, 26 | 0x80123456, 27 | 0x00000000, 28 | 0xffffffff, 29 | 0x00ffffff, 30 | 0x80808080, 31 | 0x00123456, 32 | }; 33 | 34 | int 35 | main () 36 | { 37 | int o, s, m, d; 38 | 39 | enable_divbyzero_exceptions(); 40 | 41 | for (o = 0; o < ARRAY_LENGTH (pdf_ops); ++o) 42 | { 43 | pixman_op_t op = pdf_ops[o]; 44 | 45 | for (s = 0; s < ARRAY_LENGTH (pixels); ++s) 46 | { 47 | pixman_image_t *src; 48 | 49 | src = pixman_image_create_bits ( 50 | PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)&(pixels[s]), 4); 51 | 52 | for (m = -1; m < ARRAY_LENGTH (pixels); ++m) 53 | { 54 | pixman_image_t *msk = NULL; 55 | if (m >= 0) 56 | { 57 | msk = pixman_image_create_bits ( 58 | PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)&(pixels[m]), 4); 59 | } 60 | 61 | for (d = 0; d < ARRAY_LENGTH (pixels); ++d) 62 | { 63 | pixman_image_t *dst; 64 | uint32_t dp = pixels[d]; 65 | 66 | dst = pixman_image_create_bits ( 67 | PIXMAN_a8r8g8b8, 1, 1, &dp, 4); 68 | 69 | pixman_image_composite (op, src, msk, dst, 70 | 0, 0, 0, 0, 0, 0, 1, 1); 71 | 72 | pixman_image_unref (dst); 73 | } 74 | if (msk) 75 | pixman_image_unref (msk); 76 | } 77 | 78 | pixman_image_unref (src); 79 | } 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /test/a1-trap-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "utils.h" 6 | 7 | int 8 | main (int argc, char **argv) 9 | { 10 | #define WIDTH 20 11 | #define HEIGHT 20 12 | 13 | pixman_image_t *src_img; 14 | pixman_image_t *mask_img; 15 | pixman_image_t *dest_img; 16 | pixman_trap_t trap; 17 | pixman_color_t red = { 0xffff, 0x0000, 0x0000, 0xffff }; 18 | uint32_t *bits = malloc (WIDTH * HEIGHT * 4); 19 | uint32_t *mbits = malloc (WIDTH * HEIGHT); 20 | 21 | memset (mbits, 0, WIDTH * HEIGHT); 22 | memset (bits, 0xff, WIDTH * HEIGHT * 4); 23 | 24 | trap.top.l = pixman_double_to_fixed (0.5); 25 | trap.top.r = pixman_double_to_fixed (1.5); 26 | trap.top.y = pixman_double_to_fixed (0.5); 27 | 28 | trap.bot.l = pixman_double_to_fixed (0.5); 29 | trap.bot.r = pixman_double_to_fixed (1.5); 30 | trap.bot.y = pixman_double_to_fixed (1.5); 31 | 32 | mask_img = pixman_image_create_bits ( 33 | PIXMAN_a1, WIDTH, HEIGHT, mbits, WIDTH); 34 | src_img = pixman_image_create_solid_fill (&red); 35 | dest_img = pixman_image_create_bits ( 36 | PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4); 37 | 38 | pixman_add_traps (mask_img, 0, 0, 1, &trap); 39 | 40 | pixman_image_composite (PIXMAN_OP_OVER, 41 | src_img, mask_img, dest_img, 42 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 43 | 44 | assert (bits[0] == 0xffff0000); 45 | assert (bits[1] == 0xffffffff); 46 | assert (bits[1 * WIDTH + 0] == 0xffffffff); 47 | assert (bits[1 * WIDTH + 1] == 0xffffffff); 48 | 49 | /* The check-formats test depends on operator_name() and format_name() returning 50 | * these precise formats, so if those change, check-formats.c must be updated too. 51 | */ 52 | assert ( 53 | strcmp (operator_name (PIXMAN_OP_DISJOINT_OVER), "PIXMAN_OP_DISJOINT_OVER") == 0); 54 | assert ( 55 | strcmp (format_name (PIXMAN_r5g6b5), "r5g6b5") == 0); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /pixman/pixman-version.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Red Hat, Inc. 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, copy, 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies 9 | * of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | * Author: Carl D. Worth 25 | */ 26 | 27 | #ifndef PIXMAN_VERSION_H__ 28 | #define PIXMAN_VERSION_H__ 29 | 30 | #ifndef PIXMAN_H__ 31 | # error pixman-version.h should only be included by pixman.h 32 | #endif 33 | 34 | #define PIXMAN_VERSION_MAJOR @PIXMAN_VERSION_MAJOR@ 35 | #define PIXMAN_VERSION_MINOR @PIXMAN_VERSION_MINOR@ 36 | #define PIXMAN_VERSION_MICRO @PIXMAN_VERSION_MICRO@ 37 | 38 | #define PIXMAN_VERSION_STRING "@PIXMAN_VERSION_MAJOR@.@PIXMAN_VERSION_MINOR@.@PIXMAN_VERSION_MICRO@" 39 | 40 | #define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \ 41 | ((major) * 10000) \ 42 | + ((minor) * 100) \ 43 | + ((micro) * 1)) 44 | 45 | #define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \ 46 | PIXMAN_VERSION_MAJOR, \ 47 | PIXMAN_VERSION_MINOR, \ 48 | PIXMAN_VERSION_MICRO) 49 | 50 | #endif /* PIXMAN_VERSION_H__ */ 51 | -------------------------------------------------------------------------------- /demos/checkerboard.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | int 7 | main (int argc, char **argv) 8 | { 9 | #define WIDTH 400 10 | #define HEIGHT 400 11 | #define TILE_SIZE 25 12 | 13 | pixman_image_t *checkerboard; 14 | pixman_image_t *destination; 15 | #define D2F(d) (pixman_double_to_fixed(d)) 16 | pixman_transform_t trans = { { 17 | { D2F (-1.96830), D2F (-1.82250), D2F (512.12250)}, 18 | { D2F (0.00000), D2F (-7.29000), D2F (1458.00000)}, 19 | { D2F (0.00000), D2F (-0.00911), D2F (0.59231)}, 20 | }}; 21 | int i, j; 22 | 23 | checkerboard = pixman_image_create_bits (PIXMAN_a8r8g8b8, 24 | WIDTH, HEIGHT, 25 | NULL, 0); 26 | 27 | destination = pixman_image_create_bits (PIXMAN_a8r8g8b8, 28 | WIDTH, HEIGHT, 29 | NULL, 0); 30 | 31 | for (i = 0; i < HEIGHT / TILE_SIZE; ++i) 32 | { 33 | for (j = 0; j < WIDTH / TILE_SIZE; ++j) 34 | { 35 | double u = (double)(j + 1) / (WIDTH / TILE_SIZE); 36 | double v = (double)(i + 1) / (HEIGHT / TILE_SIZE); 37 | pixman_color_t black = { 0, 0, 0, 0xffff }; 38 | pixman_color_t white = { 39 | v * 0xffff, 40 | u * 0xffff, 41 | (1 - (double)u) * 0xffff, 42 | 0xffff }; 43 | pixman_color_t *c; 44 | pixman_image_t *fill; 45 | 46 | if ((j & 1) != (i & 1)) 47 | c = &black; 48 | else 49 | c = &white; 50 | 51 | fill = pixman_image_create_solid_fill (c); 52 | 53 | pixman_image_composite (PIXMAN_OP_SRC, fill, NULL, checkerboard, 54 | 0, 0, 0, 0, j * TILE_SIZE, i * TILE_SIZE, 55 | TILE_SIZE, TILE_SIZE); 56 | } 57 | } 58 | 59 | pixman_image_set_transform (checkerboard, &trans); 60 | pixman_image_set_filter (checkerboard, PIXMAN_FILTER_BEST, NULL, 0); 61 | pixman_image_set_repeat (checkerboard, PIXMAN_REPEAT_NONE); 62 | 63 | pixman_image_composite (PIXMAN_OP_SRC, 64 | checkerboard, NULL, destination, 65 | 0, 0, 0, 0, 0, 0, 66 | WIDTH, HEIGHT); 67 | 68 | show_image (destination); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /pixman/pixman-timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007 Red Hat, Inc. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that 7 | * copyright notice and this permission notice appear in supporting 8 | * documentation, and that the name of Red Hat not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. Red Hat makes no representations about the 11 | * suitability of this software for any purpose. It is provided "as is" 12 | * without express or implied warranty. 13 | * 14 | * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT 16 | * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 18 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 19 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include 24 | #endif 25 | 26 | #include 27 | #include 28 | #include "pixman-private.h" 29 | 30 | #ifdef PIXMAN_TIMERS 31 | 32 | static pixman_timer_t *timers; 33 | 34 | static void 35 | dump_timers (void) 36 | { 37 | pixman_timer_t *timer; 38 | 39 | for (timer = timers; timer != NULL; timer = timer->next) 40 | { 41 | printf ("%s: total: %llu n: %llu avg: %f\n", 42 | timer->name, 43 | timer->total, 44 | timer->n_times, 45 | timer->total / (double)timer->n_times); 46 | } 47 | } 48 | 49 | void 50 | pixman_timer_register (pixman_timer_t *timer) 51 | { 52 | static int initialized; 53 | 54 | int atexit (void (*function)(void)); 55 | 56 | if (!initialized) 57 | { 58 | atexit (dump_timers); 59 | initialized = 1; 60 | } 61 | 62 | timer->next = timers; 63 | timers = timer; 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | The following is the MIT license, agreed upon by most contributors. 2 | Copyright holders of new code should use this license statement where 3 | possible. They may also add themselves to the list below. 4 | 5 | /* 6 | * Copyright 1987, 1988, 1989, 1998 The Open Group 7 | * Copyright 1987, 1988, 1989 Digital Equipment Corporation 8 | * Copyright 1999, 2004, 2008 Keith Packard 9 | * Copyright 2000 SuSE, Inc. 10 | * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc. 11 | * Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc. 12 | * Copyright 2004 Nicholas Miell 13 | * Copyright 2005 Lars Knoll & Zack Rusin, Trolltech 14 | * Copyright 2005 Trolltech AS 15 | * Copyright 2007 Luca Barbato 16 | * Copyright 2008 Aaron Plattner, NVIDIA Corporation 17 | * Copyright 2008 Rodrigo Kumpera 18 | * Copyright 2008 André Tupinambá 19 | * Copyright 2008 Mozilla Corporation 20 | * Copyright 2008 Frederic Plourde 21 | * Copyright 2009, Oracle and/or its affiliates. All rights reserved. 22 | * Copyright 2009, 2010 Nokia Corporation 23 | * 24 | * Permission is hereby granted, free of charge, to any person obtaining a 25 | * copy of this software and associated documentation files (the "Software"), 26 | * to deal in the Software without restriction, including without limitation 27 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 28 | * and/or sell copies of the Software, and to permit persons to whom the 29 | * Software is furnished to do so, subject to the following conditions: 30 | * 31 | * The above copyright notice and this permission notice (including the next 32 | * paragraph) shall be included in all copies or substantial portions of the 33 | * Software. 34 | * 35 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 38 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 40 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 41 | * DEALINGS IN THE SOFTWARE. 42 | */ 43 | -------------------------------------------------------------------------------- /demos/srgb-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | static uint32_t 7 | linear_argb_to_premult_argb (float a, 8 | float r, 9 | float g, 10 | float b) 11 | { 12 | r *= a; 13 | g *= a; 14 | b *= a; 15 | return (uint32_t) (a * 255.0f + 0.5f) << 24 16 | | (uint32_t) (r * 255.0f + 0.5f) << 16 17 | | (uint32_t) (g * 255.0f + 0.5f) << 8 18 | | (uint32_t) (b * 255.0f + 0.5f) << 0; 19 | } 20 | 21 | static float 22 | lin2srgb (float linear) 23 | { 24 | if (linear < 0.0031308f) 25 | return linear * 12.92f; 26 | else 27 | return 1.055f * powf (linear, 1.0f/2.4f) - 0.055f; 28 | } 29 | 30 | static uint32_t 31 | linear_argb_to_premult_srgb_argb (float a, 32 | float r, 33 | float g, 34 | float b) 35 | { 36 | r = lin2srgb (r * a); 37 | g = lin2srgb (g * a); 38 | b = lin2srgb (b * a); 39 | return (uint32_t) (a * 255.0f + 0.5f) << 24 40 | | (uint32_t) (r * 255.0f + 0.5f) << 16 41 | | (uint32_t) (g * 255.0f + 0.5f) << 8 42 | | (uint32_t) (b * 255.0f + 0.5f) << 0; 43 | } 44 | 45 | int 46 | main (int argc, char **argv) 47 | { 48 | #define WIDTH 400 49 | #define HEIGHT 200 50 | int y, x, p; 51 | float alpha; 52 | 53 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 54 | uint32_t *src1 = malloc (WIDTH * HEIGHT * 4); 55 | pixman_image_t *dest_img, *src1_img; 56 | 57 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8_sRGB, 58 | WIDTH, HEIGHT, 59 | dest, 60 | WIDTH * 4); 61 | src1_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 62 | WIDTH, HEIGHT, 63 | src1, 64 | WIDTH * 4); 65 | 66 | for (y = 0; y < HEIGHT; y ++) 67 | { 68 | p = WIDTH * y; 69 | for (x = 0; x < WIDTH; x ++) 70 | { 71 | alpha = (float) x / WIDTH; 72 | src1[p + x] = linear_argb_to_premult_argb (alpha, 1, 0, 1); 73 | dest[p + x] = linear_argb_to_premult_srgb_argb (1-alpha, 0, 1, 0); 74 | } 75 | } 76 | 77 | pixman_image_composite (PIXMAN_OP_ADD, src1_img, NULL, dest_img, 78 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 79 | pixman_image_unref (src1_img); 80 | free (src1); 81 | 82 | show_image (dest_img); 83 | pixman_image_unref (dest_img); 84 | free (dest); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /pixman/Makefile.win32: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | top_srcdir = .. 4 | include $(top_srcdir)/pixman/Makefile.sources 5 | include $(top_srcdir)/Makefile.win32.common 6 | 7 | MMX_VAR = $(MMX) 8 | ifeq ($(MMX_VAR),) 9 | MMX_VAR=on 10 | endif 11 | 12 | SSE2_VAR = $(SSE2) 13 | ifeq ($(SSE2_VAR),) 14 | SSE2_VAR=on 15 | endif 16 | 17 | SSSE3_VAR = $(SSSE3) 18 | ifeq ($(SSSE3_VAR),) 19 | SSSE3_VAR=on 20 | endif 21 | 22 | MMX_CFLAGS = -DUSE_X86_MMX -w14710 -w14714 23 | SSE2_CFLAGS = -DUSE_SSE2 24 | SSSE3_CFLAGS = -DUSE_SSSE3 25 | 26 | # MMX compilation flags 27 | ifeq ($(MMX_VAR),on) 28 | PIXMAN_CFLAGS += $(MMX_CFLAGS) 29 | libpixman_sources += pixman-mmx.c 30 | endif 31 | 32 | # SSE2 compilation flags 33 | ifeq ($(SSE2_VAR),on) 34 | PIXMAN_CFLAGS += $(SSE2_CFLAGS) 35 | libpixman_sources += pixman-sse2.c 36 | endif 37 | 38 | # SSSE3 compilation flags 39 | ifeq ($(SSSE3_VAR),on) 40 | PIXMAN_CFLAGS += $(SSSE3_CFLAGS) 41 | libpixman_sources += pixman-ssse3.c 42 | endif 43 | 44 | OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources)) 45 | 46 | # targets 47 | all: inform informMMX informSSE2 informSSSE3 $(CFG_VAR)/$(LIBRARY).lib 48 | 49 | informMMX: 50 | ifneq ($(MMX),off) 51 | ifneq ($(MMX),on) 52 | ifneq ($(MMX),) 53 | @echo "Invalid specified MMX option : "$(MMX_VAR)"." 54 | @echo 55 | @echo "Possible choices for MMX are 'on' or 'off'" 56 | @exit 1 57 | endif 58 | @echo "Setting MMX flag to default value 'on'... (use MMX=on or MMX=off)" 59 | endif 60 | endif 61 | 62 | informSSE2: 63 | ifneq ($(SSE2),off) 64 | ifneq ($(SSE2),on) 65 | ifneq ($(SSE2),) 66 | @echo "Invalid specified SSE option : "$(SSE2)"." 67 | @echo 68 | @echo "Possible choices for SSE2 are 'on' or 'off'" 69 | @exit 1 70 | endif 71 | @echo "Setting SSE2 flag to default value 'on'... (use SSE2=on or SSE2=off)" 72 | endif 73 | endif 74 | 75 | informSSSE3: 76 | ifneq ($(SSSE3),off) 77 | ifneq ($(SSSE3),on) 78 | ifneq ($(SSSE3),) 79 | @echo "Invalid specified SSE option : "$(SSSE3)"." 80 | @echo 81 | @echo "Possible choices for SSSE3 are 'on' or 'off'" 82 | @exit 1 83 | endif 84 | @echo "Setting SSSE3 flag to default value 'on'... (use SSSE3=on or SSSE3=off)" 85 | endif 86 | endif 87 | 88 | 89 | # pixman linking 90 | $(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS) 91 | @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ 92 | 93 | .PHONY: all informMMX informSSE2 informSSSE3 94 | -------------------------------------------------------------------------------- /test/oob-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | typedef struct 6 | { 7 | int width; 8 | int height; 9 | int stride; 10 | pixman_format_code_t format; 11 | 12 | } image_info_t; 13 | 14 | typedef struct 15 | { 16 | pixman_op_t op; 17 | 18 | image_info_t src; 19 | image_info_t dest; 20 | 21 | int src_x; 22 | int src_y; 23 | int dest_x; 24 | int dest_y; 25 | int width; 26 | int height; 27 | } composite_info_t; 28 | 29 | const composite_info_t info[] = 30 | { 31 | { 32 | PIXMAN_OP_SRC, 33 | { 3, 6, 16, PIXMAN_a8r8g8b8 }, 34 | { 5, 7, 20, PIXMAN_x8r8g8b8 }, 35 | 1, 8, 36 | 1, -1, 37 | 1, 8 38 | }, 39 | { 40 | PIXMAN_OP_SRC, 41 | { 7, 5, 36, PIXMAN_a8r8g8b8 }, 42 | { 6, 5, 28, PIXMAN_x8r8g8b8 }, 43 | 8, 5, 44 | 5, 3, 45 | 1, 2 46 | }, 47 | { 48 | PIXMAN_OP_OVER, 49 | { 10, 10, 40, PIXMAN_a2b10g10r10 }, 50 | { 10, 10, 40, PIXMAN_a2b10g10r10 }, 51 | 0, 0, 52 | 0, 0, 53 | 10, 10 54 | }, 55 | { 56 | PIXMAN_OP_OVER, 57 | { 10, 10, 40, PIXMAN_x2b10g10r10 }, 58 | { 10, 10, 40, PIXMAN_x2b10g10r10 }, 59 | 0, 0, 60 | 0, 0, 61 | 10, 10 62 | }, 63 | }; 64 | 65 | static pixman_image_t * 66 | make_image (const image_info_t *info) 67 | { 68 | char *data = malloc (info->stride * info->height); 69 | int i; 70 | 71 | for (i = 0; i < info->height * info->stride; ++i) 72 | data[i] = (i % 255) ^ (((i % 16) << 4) | (i & 0xf0)); 73 | 74 | return pixman_image_create_bits (info->format, info->width, info->height, (uint32_t *)data, info->stride); 75 | } 76 | 77 | static void 78 | test_composite (const composite_info_t *info) 79 | { 80 | pixman_image_t *src = make_image (&info->src); 81 | pixman_image_t *dest = make_image (&info->dest); 82 | 83 | pixman_image_composite (PIXMAN_OP_SRC, src, NULL, dest, 84 | info->src_x, info->src_y, 85 | 0, 0, 86 | info->dest_x, info->dest_y, 87 | info->width, info->height); 88 | } 89 | 90 | 91 | 92 | int 93 | main (int argc, char **argv) 94 | { 95 | int i; 96 | 97 | for (i = 0; i < ARRAY_LENGTH (info); ++i) 98 | test_composite (&info[i]); 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /test/scaling-bench.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | #define SOURCE_WIDTH 320 5 | #define SOURCE_HEIGHT 240 6 | #define TEST_REPEATS 3 7 | 8 | static pixman_image_t * 9 | make_source (void) 10 | { 11 | size_t n_bytes = (SOURCE_WIDTH + 2) * (SOURCE_HEIGHT + 2) * 4; 12 | uint32_t *data = malloc (n_bytes); 13 | pixman_image_t *source; 14 | 15 | prng_randmemset (data, n_bytes, 0); 16 | 17 | source = pixman_image_create_bits ( 18 | PIXMAN_a8r8g8b8, SOURCE_WIDTH + 2, SOURCE_HEIGHT + 2, 19 | data, 20 | (SOURCE_WIDTH + 2) * 4); 21 | 22 | pixman_image_set_filter (source, PIXMAN_FILTER_BILINEAR, NULL, 0); 23 | 24 | return source; 25 | } 26 | 27 | int 28 | main () 29 | { 30 | double scale; 31 | pixman_image_t *src; 32 | 33 | prng_srand (23874); 34 | 35 | src = make_source (); 36 | printf ("# %-6s %-22s %-14s %-12s\n", 37 | "ratio", 38 | "resolutions", 39 | "time / ms", 40 | "time per pixel / ns"); 41 | for (scale = 0.1; scale < 10.005; scale += 0.01) 42 | { 43 | int i; 44 | int dest_width = SOURCE_WIDTH * scale + 0.5; 45 | int dest_height = SOURCE_HEIGHT * scale + 0.5; 46 | int dest_byte_stride = (dest_width * 4 + 15) & ~15; 47 | pixman_fixed_t s = (1 / scale) * 65536.0 + 0.5; 48 | pixman_transform_t transform; 49 | pixman_image_t *dest; 50 | double t1, t2, t = -1; 51 | uint32_t *dest_buf = aligned_malloc (16, dest_byte_stride * dest_height); 52 | memset (dest_buf, 0, dest_byte_stride * dest_height); 53 | 54 | pixman_transform_init_scale (&transform, s, s); 55 | pixman_image_set_transform (src, &transform); 56 | 57 | dest = pixman_image_create_bits ( 58 | PIXMAN_a8r8g8b8, dest_width, dest_height, dest_buf, dest_byte_stride); 59 | 60 | for (i = 0; i < TEST_REPEATS; i++) 61 | { 62 | t1 = gettime(); 63 | pixman_image_composite ( 64 | PIXMAN_OP_OVER, src, NULL, dest, 65 | scale, scale, 0, 0, 0, 0, dest_width, dest_height); 66 | t2 = gettime(); 67 | if (t < 0 || t2 - t1 < t) 68 | t = t2 - t1; 69 | } 70 | 71 | printf ("%6.2f : %4dx%-4d => %4dx%-4d : %12.4f : %12.4f\n", 72 | scale, SOURCE_WIDTH, SOURCE_HEIGHT, dest_width, dest_height, 73 | t * 1000, (t / (dest_width * dest_height)) * 1000000000); 74 | 75 | pixman_image_unref (dest); 76 | free (dest_buf); 77 | } 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /pixman/pixman-solid-fill.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2000 SuSE, Inc. 3 | * Copyright © 2007, 2009 Red Hat, Inc. 4 | * Copyright © 2009 Soren Sandmann 5 | * 6 | * Permission to use, copy, modify, distribute, and sell this software and its 7 | * documentation for any purpose is hereby granted without fee, provided that 8 | * the above copyright notice appear in all copies and that both that 9 | * copyright notice and this permission notice appear in supporting 10 | * documentation, and that the name of SuSE not be used in advertising or 11 | * publicity pertaining to distribution of the software without specific, 12 | * written prior permission. SuSE makes no representations about the 13 | * suitability of this software for any purpose. It is provided "as is" 14 | * without express or implied warranty. 15 | * 16 | * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 18 | * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 20 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 21 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | */ 23 | 24 | #ifdef HAVE_CONFIG_H 25 | #include 26 | #endif 27 | #include "pixman-private.h" 28 | 29 | static uint32_t 30 | color_to_uint32 (const pixman_color_t *color) 31 | { 32 | return 33 | (color->alpha >> 8 << 24) | 34 | (color->red >> 8 << 16) | 35 | (color->green & 0xff00) | 36 | (color->blue >> 8); 37 | } 38 | 39 | static argb_t 40 | color_to_float (const pixman_color_t *color) 41 | { 42 | argb_t result; 43 | 44 | result.a = pixman_unorm_to_float (color->alpha, 16); 45 | result.r = pixman_unorm_to_float (color->red, 16); 46 | result.g = pixman_unorm_to_float (color->green, 16); 47 | result.b = pixman_unorm_to_float (color->blue, 16); 48 | 49 | return result; 50 | } 51 | 52 | PIXMAN_EXPORT pixman_image_t * 53 | pixman_image_create_solid_fill (const pixman_color_t *color) 54 | { 55 | pixman_image_t *img = _pixman_image_allocate (); 56 | 57 | if (!img) 58 | return NULL; 59 | 60 | img->type = SOLID; 61 | img->solid.color = *color; 62 | img->solid.color_32 = color_to_uint32 (color); 63 | img->solid.color_float = color_to_float (color); 64 | 65 | return img; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /test/scaling-helpers-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | #include "pixman-inlines.h" 6 | 7 | /* A trivial reference implementation for 8 | * 'bilinear_pad_repeat_get_scanline_bounds' 9 | */ 10 | static void 11 | bilinear_pad_repeat_get_scanline_bounds_ref (int32_t source_image_width, 12 | pixman_fixed_t vx_, 13 | pixman_fixed_t unit_x, 14 | int32_t * left_pad, 15 | int32_t * left_tz, 16 | int32_t * width, 17 | int32_t * right_tz, 18 | int32_t * right_pad) 19 | { 20 | int w = *width; 21 | int64_t vx = vx_; 22 | *left_pad = 0; 23 | *left_tz = 0; 24 | *width = 0; 25 | *right_tz = 0; 26 | *right_pad = 0; 27 | while (--w >= 0) 28 | { 29 | if (vx < 0) 30 | { 31 | if (vx + pixman_fixed_1 < 0) 32 | *left_pad += 1; 33 | else 34 | *left_tz += 1; 35 | } 36 | else if (vx + pixman_fixed_1 >= pixman_int_to_fixed (source_image_width)) 37 | { 38 | if (vx >= pixman_int_to_fixed (source_image_width)) 39 | *right_pad += 1; 40 | else 41 | *right_tz += 1; 42 | } 43 | else 44 | { 45 | *width += 1; 46 | } 47 | vx += unit_x; 48 | } 49 | } 50 | 51 | int 52 | main (void) 53 | { 54 | int i; 55 | prng_srand (0); 56 | for (i = 0; i < 10000; i++) 57 | { 58 | int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1; 59 | int32_t left_pad2, left_tz2, width2, right_tz2, right_pad2; 60 | pixman_fixed_t vx = prng_rand_n(10000 << 16) - (3000 << 16); 61 | int32_t width = prng_rand_n(10000); 62 | int32_t source_image_width = prng_rand_n(10000) + 1; 63 | pixman_fixed_t unit_x = prng_rand_n(10 << 16) + 1; 64 | width1 = width2 = width; 65 | 66 | bilinear_pad_repeat_get_scanline_bounds_ref (source_image_width, 67 | vx, 68 | unit_x, 69 | &left_pad1, 70 | &left_tz1, 71 | &width1, 72 | &right_tz1, 73 | &right_pad1); 74 | 75 | bilinear_pad_repeat_get_scanline_bounds (source_image_width, 76 | vx, 77 | unit_x, 78 | &left_pad2, 79 | &left_tz2, 80 | &width2, 81 | &right_tz2, 82 | &right_pad2); 83 | 84 | assert (left_pad1 == left_pad2); 85 | assert (left_tz1 == left_tz2); 86 | assert (width1 == width2); 87 | assert (right_tz1 == right_tz2); 88 | assert (right_pad1 == right_pad2); 89 | } 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /test/fuzzer-find-diff.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | $usage = "Usage: 4 | fuzzer-find-diff.pl reference_binary new_binary [number_of_tests_to_run] 5 | 6 | The first two input arguments are the commands to run the test programs 7 | based on fuzzer_test_main() function from 'util.c' (preferably they should 8 | be statically compiled, this can be achieved via '--disable-shared' pixman 9 | configure option). The third optional argument is the number of test rounds 10 | to run (if not specified, then testing runs infinitely or until some problem 11 | is detected). 12 | 13 | Usage examples: 14 | fuzzer-find-diff.pl ./blitters-test-with-sse-disabled ./blitters-test 9000000 15 | fuzzer-find-diff.pl ./blitters-test \"ssh ppc64_host /path/to/blitters-test\" 16 | "; 17 | 18 | $#ARGV >= 1 or die $usage; 19 | 20 | $batch_size = 10000; 21 | 22 | if ($#ARGV >= 2) { 23 | $number_of_tests = int($ARGV[2]); 24 | } else { 25 | $number_of_tests = -1 26 | } 27 | 28 | sub test_range { 29 | my $min = shift; 30 | my $max = shift; 31 | 32 | # check that [$min, $max] range is "bad", otherwise return 33 | if (`$ARGV[0] $min $max 2>/dev/null` eq `$ARGV[1] $min $max 2>/dev/null`) { 34 | return; 35 | } 36 | 37 | # check that $min itself is "good", otherwise return 38 | if (`$ARGV[0] $min 2>/dev/null` ne `$ARGV[1] $min 2>/dev/null`) { 39 | return $min; 40 | } 41 | 42 | # start bisecting 43 | while ($max != $min + 1) { 44 | my $avg = int(($min + $max) / 2); 45 | my $res1 = `$ARGV[0] $min $avg 2>/dev/null`; 46 | my $res2 = `$ARGV[1] $min $avg 2>/dev/null`; 47 | if ($res1 ne $res2) { 48 | $max = $avg; 49 | } else { 50 | $min = $avg; 51 | } 52 | } 53 | return $max; 54 | } 55 | 56 | $base = 1; 57 | while ($number_of_tests <= 0 || $base <= $number_of_tests) { 58 | printf("testing %-12d\r", $base + $batch_size - 1); 59 | my $res = test_range($base, $base + $batch_size - 1); 60 | if ($res) { 61 | printf("Failure: results are different for test %d:\n", $res); 62 | 63 | printf("\n-- ref --\n"); 64 | print `$ARGV[0] $res`; 65 | printf("-- new --\n"); 66 | print `$ARGV[1] $res`; 67 | 68 | printf("The problematic conditions can be reproduced by running:\n"); 69 | printf("$ARGV[1] %d\n", $res); 70 | 71 | exit(1); 72 | } 73 | $base += $batch_size; 74 | } 75 | printf("Success: %d tests finished\n", $base - 1); 76 | -------------------------------------------------------------------------------- /pixman/pixman-region16.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Red Hat, Inc. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software 5 | * and its documentation for any purpose is hereby granted without 6 | * fee, provided that the above copyright notice appear in all copies 7 | * and that both that copyright notice and this permission notice 8 | * appear in supporting documentation, and that the name of 9 | * Red Hat, Inc. not be used in advertising or publicity pertaining to 10 | * distribution of the software without specific, written prior 11 | * permission. Red Hat, Inc. makes no representations about the 12 | * suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, 18 | * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 19 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 20 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 21 | * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | * 23 | * Author: Soren Sandmann 24 | */ 25 | #ifdef HAVE_CONFIG_H 26 | #include 27 | #endif 28 | 29 | #undef PIXMAN_DISABLE_DEPRECATED 30 | 31 | #include "pixman-private.h" 32 | 33 | #include 34 | 35 | typedef pixman_box16_t box_type_t; 36 | typedef pixman_region16_data_t region_data_type_t; 37 | typedef pixman_region16_t region_type_t; 38 | typedef int32_t overflow_int_t; 39 | 40 | typedef struct { 41 | int x, y; 42 | } point_type_t; 43 | 44 | #define PREFIX(x) pixman_region##x 45 | 46 | #define PIXMAN_REGION_MAX INT16_MAX 47 | #define PIXMAN_REGION_MIN INT16_MIN 48 | 49 | #include "pixman-region.c" 50 | 51 | /* This function exists only to make it possible to preserve the X ABI - 52 | * it should go away at first opportunity. 53 | * 54 | * The problem is that the X ABI exports the three structs and has used 55 | * them through macros. So the X server calls this function with 56 | * the addresses of those structs which makes the existing code continue to 57 | * work. 58 | */ 59 | PIXMAN_EXPORT void 60 | pixman_region_set_static_pointers (pixman_box16_t *empty_box, 61 | pixman_region16_data_t *empty_data, 62 | pixman_region16_data_t *broken_data) 63 | { 64 | pixman_region_empty_box = empty_box; 65 | pixman_region_empty_data = empty_data; 66 | pixman_broken_data = broken_data; 67 | } 68 | -------------------------------------------------------------------------------- /pixman/make-srgb.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | 5 | sub linear_to_srgb 6 | { 7 | my ($c) = @_; 8 | 9 | if ($c < 0.0031308) 10 | { 11 | return $c * 12.92; 12 | } 13 | else 14 | { 15 | return 1.055 * $c ** (1.0/2.4) - 0.055; 16 | } 17 | } 18 | 19 | sub srgb_to_linear 20 | { 21 | my ($c) = @_; 22 | 23 | if ($c < 0.04045) 24 | { 25 | return $c / 12.92; 26 | } 27 | else 28 | { 29 | return (($c + 0.055) / 1.055) ** 2.4 30 | } 31 | } 32 | 33 | my @linear_to_srgb; 34 | for my $linear (0 .. 4095) 35 | { 36 | my $srgb = int(linear_to_srgb($linear / 4095.0) * 255.0 + 0.5); 37 | push @linear_to_srgb, $srgb; 38 | } 39 | 40 | my @srgb_to_linear; 41 | for my $srgb (0 .. 255) 42 | { 43 | my $linear = int(srgb_to_linear($srgb / 255.0) * 65535.0 + 0.5); 44 | push @srgb_to_linear, $linear; 45 | } 46 | 47 | # Ensure that we have a lossless sRGB and back conversion loop. 48 | # some of the darkest shades need a little bias -- maximum is just 49 | # 5 increments out of 16. This gives us useful property with 50 | # least amount of error in the sRGB-to-linear table, and keeps the actual 51 | # table lookup in the other direction as simple as possible. 52 | for my $srgb (0 .. $#srgb_to_linear) 53 | { 54 | my $add = 0; 55 | while (1) 56 | { 57 | my $linear = $srgb_to_linear[$srgb]; 58 | my $srgb_lossy = $linear_to_srgb[$linear >> 4]; 59 | last if $srgb == $srgb_lossy; 60 | 61 | # Add slight bias to this component until it rounds correctly 62 | $srgb_to_linear[$srgb] ++; 63 | $add ++; 64 | } 65 | die "Too many adds at $srgb" if $add > 5; 66 | } 67 | 68 | print <<"PROLOG"; 69 | /* WARNING: This file is generated by $0. 70 | * Please edit that file instead of this one. 71 | */ 72 | 73 | #include 74 | 75 | #ifdef HAVE_CONFIG_H 76 | #include 77 | #endif 78 | 79 | #include "pixman-private.h" 80 | 81 | PROLOG 82 | 83 | print "const uint8_t linear_to_srgb[" . @linear_to_srgb . "] =\n"; 84 | print "{\n"; 85 | for my $linear (0 .. $#linear_to_srgb) 86 | { 87 | if (($linear % 10) == 0) 88 | { 89 | print "\t"; 90 | } 91 | print sprintf("%d, ", $linear_to_srgb[$linear]); 92 | if (($linear % 10) == 9) 93 | { 94 | print "\n"; 95 | } 96 | } 97 | print "\n};\n"; 98 | print "\n"; 99 | 100 | print "const uint16_t srgb_to_linear[" . @srgb_to_linear . "] =\n"; 101 | print "{\n"; 102 | for my $srgb (0 .. $#srgb_to_linear) 103 | { 104 | if (($srgb % 10) == 0) 105 | { 106 | print "\t"; 107 | } 108 | print sprintf("%d, ", $srgb_to_linear[$srgb]); 109 | if (($srgb % 10) == 9) 110 | { 111 | print "\n"; 112 | } 113 | } 114 | print "\n};\n"; 115 | 116 | -------------------------------------------------------------------------------- /demos/gradient-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | int 7 | main (int argc, char **argv) 8 | { 9 | #define WIDTH 400 10 | #define HEIGHT 200 11 | 12 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 13 | pixman_image_t *src_img; 14 | pixman_image_t *dest_img; 15 | int i; 16 | pixman_gradient_stop_t stops[2] = 17 | { 18 | { pixman_int_to_fixed (0), { 0x0000, 0x0000, 0xffff, 0xffff } }, 19 | { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0xffff } } 20 | }; 21 | pixman_point_fixed_t p1 = { pixman_double_to_fixed (50), 0 }; 22 | pixman_point_fixed_t p2 = { pixman_double_to_fixed (200), 0 }; 23 | #if 0 24 | pixman_transform_t trans = { 25 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, 26 | { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, 27 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 28 | } 29 | }; 30 | #else 31 | pixman_transform_t trans = { 32 | { { pixman_fixed_1, 0, 0 }, 33 | { 0, pixman_fixed_1, 0 }, 34 | { 0, 0, pixman_fixed_1 } } 35 | }; 36 | #endif 37 | 38 | #if 0 39 | pixman_point_fixed_t c_inner; 40 | pixman_point_fixed_t c_outer; 41 | pixman_fixed_t r_inner; 42 | pixman_fixed_t r_outer; 43 | #endif 44 | 45 | for (i = 0; i < WIDTH * HEIGHT; ++i) 46 | dest[i] = 0xff00ff00; 47 | 48 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 49 | WIDTH, HEIGHT, 50 | dest, 51 | WIDTH * 4); 52 | 53 | #if 0 54 | c_inner.x = pixman_double_to_fixed (50.0); 55 | c_inner.y = pixman_double_to_fixed (50.0); 56 | c_outer.x = pixman_double_to_fixed (50.0); 57 | c_outer.y = pixman_double_to_fixed (50.0); 58 | r_inner = 0; 59 | r_outer = pixman_double_to_fixed (50.0); 60 | 61 | src_img = pixman_image_create_conical_gradient (&c_inner, r_inner, 62 | stops, 2); 63 | #endif 64 | #if 0 65 | src_img = pixman_image_create_conical_gradient (&c_inner, r_inner, 66 | stops, 2); 67 | src_img = pixman_image_create_linear_gradient (&c_inner, &c_outer, 68 | r_inner, r_outer, 69 | stops, 2); 70 | #endif 71 | 72 | src_img = pixman_image_create_linear_gradient (&p1, &p2, 73 | stops, 2); 74 | 75 | pixman_image_set_transform (src_img, &trans); 76 | pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE); 77 | 78 | pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img, 79 | 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); 80 | 81 | printf ("0, 0: %x\n", dest[0]); 82 | printf ("10, 10: %x\n", dest[10 * 10 + 10]); 83 | printf ("w, h: %x\n", dest[(HEIGHT - 1) * 100 + (WIDTH - 1)]); 84 | 85 | show_image (dest_img); 86 | 87 | pixman_image_unref (src_img); 88 | pixman_image_unref (dest_img); 89 | free (dest); 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /demos/conical-test.c: -------------------------------------------------------------------------------- 1 | #include "../test/utils.h" 2 | #include "gtk-utils.h" 3 | 4 | #define SIZE 128 5 | #define GRADIENTS_PER_ROW 7 6 | #define NUM_ROWS ((NUM_GRADIENTS + GRADIENTS_PER_ROW - 1) / GRADIENTS_PER_ROW) 7 | #define WIDTH (SIZE * GRADIENTS_PER_ROW) 8 | #define HEIGHT (SIZE * NUM_ROWS) 9 | #define NUM_GRADIENTS 35 10 | 11 | #define double_to_color(x) \ 12 | (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16)) 13 | 14 | #define PIXMAN_STOP(offset,r,g,b,a) \ 15 | { pixman_double_to_fixed (offset), \ 16 | { \ 17 | double_to_color (r), \ 18 | double_to_color (g), \ 19 | double_to_color (b), \ 20 | double_to_color (a) \ 21 | } \ 22 | } 23 | 24 | 25 | static const pixman_gradient_stop_t stops[] = { 26 | PIXMAN_STOP (0.25, 1, 0, 0, 0.7), 27 | PIXMAN_STOP (0.5, 1, 1, 0, 0.7), 28 | PIXMAN_STOP (0.75, 0, 1, 0, 0.7), 29 | PIXMAN_STOP (1.0, 0, 0, 1, 0.7) 30 | }; 31 | 32 | #define NUM_STOPS (sizeof (stops) / sizeof (stops[0])) 33 | 34 | static pixman_image_t * 35 | create_conical (int index) 36 | { 37 | pixman_point_fixed_t c; 38 | double angle; 39 | 40 | c.x = pixman_double_to_fixed (0); 41 | c.y = pixman_double_to_fixed (0); 42 | 43 | angle = (0.5 / NUM_GRADIENTS + index / (double)NUM_GRADIENTS) * 720 - 180; 44 | 45 | return pixman_image_create_conical_gradient ( 46 | &c, pixman_double_to_fixed (angle), stops, NUM_STOPS); 47 | } 48 | 49 | int 50 | main (int argc, char **argv) 51 | { 52 | pixman_transform_t transform; 53 | pixman_image_t *src_img, *dest_img; 54 | int i; 55 | 56 | enable_divbyzero_exceptions (); 57 | 58 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 59 | WIDTH, HEIGHT, 60 | NULL, 0); 61 | 62 | draw_checkerboard (dest_img, 25, 0xffaaaaaa, 0xff888888); 63 | 64 | pixman_transform_init_identity (&transform); 65 | 66 | pixman_transform_translate (NULL, &transform, 67 | pixman_double_to_fixed (0.5), 68 | pixman_double_to_fixed (0.5)); 69 | 70 | pixman_transform_scale (NULL, &transform, 71 | pixman_double_to_fixed (SIZE), 72 | pixman_double_to_fixed (SIZE)); 73 | pixman_transform_translate (NULL, &transform, 74 | pixman_double_to_fixed (0.5), 75 | pixman_double_to_fixed (0.5)); 76 | 77 | for (i = 0; i < NUM_GRADIENTS; i++) 78 | { 79 | int column = i % GRADIENTS_PER_ROW; 80 | int row = i / GRADIENTS_PER_ROW; 81 | 82 | src_img = create_conical (i); 83 | pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); 84 | 85 | pixman_image_set_transform (src_img, &transform); 86 | 87 | pixman_image_composite32 ( 88 | PIXMAN_OP_OVER, src_img, NULL,dest_img, 89 | 0, 0, 0, 0, column * SIZE, row * SIZE, 90 | SIZE, SIZE); 91 | 92 | pixman_image_unref (src_img); 93 | } 94 | 95 | show_image (dest_img); 96 | 97 | pixman_image_unref (dest_img); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /test/filter-reduction-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | static const pixman_fixed_t entries[] = 6 | { 7 | pixman_double_to_fixed (-1.0), 8 | pixman_double_to_fixed (-0.5), 9 | pixman_double_to_fixed (-1/3.0), 10 | pixman_double_to_fixed (0.0), 11 | pixman_double_to_fixed (0.5), 12 | pixman_double_to_fixed (1.0), 13 | pixman_double_to_fixed (1.5), 14 | pixman_double_to_fixed (2.0), 15 | pixman_double_to_fixed (3.0), 16 | }; 17 | 18 | #define SIZE 12 19 | 20 | static uint32_t 21 | test_scale (const pixman_transform_t *xform, uint32_t crc) 22 | { 23 | uint32_t *srcbuf, *dstbuf; 24 | pixman_image_t *src, *dest; 25 | 26 | srcbuf = malloc (SIZE * SIZE * 4); 27 | prng_randmemset (srcbuf, SIZE * SIZE * 4, 0); 28 | src = pixman_image_create_bits ( 29 | PIXMAN_a8r8g8b8, SIZE, SIZE, srcbuf, SIZE * 4); 30 | 31 | dstbuf = malloc (SIZE * SIZE * 4); 32 | prng_randmemset (dstbuf, SIZE * SIZE * 4, 0); 33 | dest = pixman_image_create_bits ( 34 | PIXMAN_a8r8g8b8, SIZE, SIZE, dstbuf, SIZE * 4); 35 | 36 | pixman_image_set_transform (src, xform); 37 | pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL); 38 | pixman_image_set_filter (src, PIXMAN_FILTER_BILINEAR, NULL, 0); 39 | 40 | image_endian_swap (src); 41 | image_endian_swap (dest); 42 | 43 | pixman_image_composite (PIXMAN_OP_SRC, 44 | src, NULL, dest, 45 | 0, 0, 0, 0, 0, 0, 46 | SIZE, SIZE); 47 | 48 | crc = compute_crc32_for_image (crc, dest); 49 | 50 | pixman_image_unref (src); 51 | pixman_image_unref (dest); 52 | 53 | free (srcbuf); 54 | free (dstbuf); 55 | 56 | return crc; 57 | } 58 | 59 | #if BILINEAR_INTERPOLATION_BITS == 7 60 | #define CHECKSUM 0x02169677 61 | #elif BILINEAR_INTERPOLATION_BITS == 4 62 | #define CHECKSUM 0xE44B29AC 63 | #else 64 | #define CHECKSUM 0x00000000 65 | #endif 66 | 67 | int 68 | main (int argc, const char *argv[]) 69 | { 70 | const pixman_fixed_t *end = entries + ARRAY_LENGTH (entries); 71 | const pixman_fixed_t *t0, *t1, *t2, *t3, *t4, *t5; 72 | uint32_t crc = 0; 73 | 74 | prng_srand (0x56EA1DBD); 75 | 76 | for (t0 = entries; t0 < end; ++t0) 77 | { 78 | for (t1 = entries; t1 < end; ++t1) 79 | { 80 | for (t2 = entries; t2 < end; ++t2) 81 | { 82 | for (t3 = entries; t3 < end; ++t3) 83 | { 84 | for (t4 = entries; t4 < end; ++t4) 85 | { 86 | for (t5 = entries; t5 < end; ++t5) 87 | { 88 | pixman_transform_t xform = { 89 | { { *t0, *t1, *t2 }, 90 | { *t3, *t4, *t5 }, 91 | { 0, 0, pixman_fixed_1 } } 92 | }; 93 | 94 | crc = test_scale (&xform, crc); 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | if (crc != CHECKSUM) 103 | { 104 | printf ("filter-reduction-test failed! (checksum=0x%08X, expected 0x%08X)\n", crc, CHECKSUM); 105 | return 1; 106 | } 107 | else 108 | { 109 | printf ("filter-reduction-test passed (checksum=0x%08X)\n", crc); 110 | return 0; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /demos/clip-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | #define WIDTH 200 7 | #define HEIGHT 200 8 | 9 | static pixman_image_t * 10 | create_solid_bits (uint32_t pixel) 11 | { 12 | uint32_t *pixels = malloc (WIDTH * HEIGHT * 4); 13 | int i; 14 | 15 | for (i = 0; i < WIDTH * HEIGHT; ++i) 16 | pixels[i] = pixel; 17 | 18 | return pixman_image_create_bits (PIXMAN_a8r8g8b8, 19 | WIDTH, HEIGHT, 20 | pixels, 21 | WIDTH * 4); 22 | } 23 | 24 | int 25 | main (int argc, char **argv) 26 | { 27 | pixman_image_t *gradient_img; 28 | pixman_image_t *src_img, *dst_img; 29 | pixman_gradient_stop_t stops[2] = 30 | { 31 | { pixman_int_to_fixed (0), { 0xffff, 0x0000, 0x0000, 0xffff } }, 32 | { pixman_int_to_fixed (1), { 0xffff, 0xffff, 0x0000, 0xffff } } 33 | }; 34 | #if 0 35 | pixman_point_fixed_t p1 = { 0, 0 }; 36 | pixman_point_fixed_t p2 = { pixman_int_to_fixed (WIDTH), 37 | pixman_int_to_fixed (HEIGHT) }; 38 | #endif 39 | pixman_point_fixed_t c_inner; 40 | pixman_point_fixed_t c_outer; 41 | pixman_fixed_t r_inner; 42 | pixman_fixed_t r_outer; 43 | pixman_region32_t clip_region; 44 | pixman_transform_t trans = { 45 | { { pixman_double_to_fixed (1.3), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.5), }, 46 | { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.5), }, 47 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } 48 | } 49 | }; 50 | 51 | src_img = create_solid_bits (0xff0000ff); 52 | 53 | c_inner.x = pixman_double_to_fixed (100.0); 54 | c_inner.y = pixman_double_to_fixed (100.0); 55 | c_outer.x = pixman_double_to_fixed (100.0); 56 | c_outer.y = pixman_double_to_fixed (100.0); 57 | r_inner = 0; 58 | r_outer = pixman_double_to_fixed (100.0); 59 | 60 | gradient_img = pixman_image_create_radial_gradient (&c_inner, &c_outer, 61 | r_inner, r_outer, 62 | stops, 2); 63 | 64 | #if 0 65 | gradient_img = pixman_image_create_linear_gradient (&p1, &p2, 66 | stops, 2); 67 | 68 | #endif 69 | 70 | pixman_image_composite (PIXMAN_OP_OVER, gradient_img, NULL, src_img, 71 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 72 | 73 | pixman_region32_init_rect (&clip_region, 50, 0, 100, 200); 74 | pixman_image_set_clip_region32 (src_img, &clip_region); 75 | pixman_image_set_source_clipping (src_img, TRUE); 76 | pixman_image_set_has_client_clip (src_img, TRUE); 77 | pixman_image_set_transform (src_img, &trans); 78 | pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); 79 | 80 | dst_img = create_solid_bits (0xffff0000); 81 | pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dst_img, 82 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 83 | 84 | 85 | #if 0 86 | printf ("0, 0: %x\n", src[0]); 87 | printf ("10, 10: %x\n", src[10 * 10 + 10]); 88 | printf ("w, h: %x\n", src[(HEIGHT - 1) * 100 + (WIDTH - 1)]); 89 | #endif 90 | 91 | show_image (dst_img); 92 | 93 | pixman_image_unref (gradient_img); 94 | pixman_image_unref (src_img); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /test/rotate-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | #define WIDTH 32 5 | #define HEIGHT 32 6 | 7 | static const pixman_format_code_t formats[] = 8 | { 9 | PIXMAN_a8r8g8b8, 10 | PIXMAN_a8b8g8r8, 11 | PIXMAN_x8r8g8b8, 12 | PIXMAN_x8b8g8r8, 13 | PIXMAN_r5g6b5, 14 | PIXMAN_b5g6r5, 15 | PIXMAN_a8, 16 | PIXMAN_a1, 17 | }; 18 | 19 | static const pixman_op_t ops[] = 20 | { 21 | PIXMAN_OP_OVER, 22 | PIXMAN_OP_SRC, 23 | PIXMAN_OP_ADD, 24 | }; 25 | 26 | #define TRANSFORM(v00, v01, v10, v11) \ 27 | { { { v00, v01, WIDTH * pixman_fixed_1 / 2 }, \ 28 | { v10, v11, HEIGHT * pixman_fixed_1 / 2 }, \ 29 | { 0, 0, pixman_fixed_1 } } } 30 | 31 | #define F1 pixman_fixed_1 32 | 33 | static const pixman_transform_t transforms[] = 34 | { 35 | TRANSFORM (0, -1, 1, 0), /* wrong 90 degree rotation */ 36 | TRANSFORM (0, 1, -1, 0), /* wrong 270 degree rotation */ 37 | TRANSFORM (1, 0, 0, 1), /* wrong identity */ 38 | TRANSFORM (-1, 0, 0, -1), /* wrong 180 degree rotation */ 39 | TRANSFORM (0, -F1, F1, 0), /* correct 90 degree rotation */ 40 | TRANSFORM (0, F1, -F1, 0), /* correct 270 degree rotation */ 41 | TRANSFORM (F1, 0, 0, F1), /* correct identity */ 42 | TRANSFORM (-F1, 0, 0, -F1), /* correct 180 degree rotation */ 43 | }; 44 | 45 | #define RANDOM_FORMAT() \ 46 | (formats[prng_rand_n (ARRAY_LENGTH (formats))]) 47 | 48 | #define RANDOM_OP() \ 49 | (ops[prng_rand_n (ARRAY_LENGTH (ops))]) 50 | 51 | #define RANDOM_TRANSFORM() \ 52 | (&(transforms[prng_rand_n (ARRAY_LENGTH (transforms))])) 53 | 54 | static void 55 | on_destroy (pixman_image_t *image, void *data) 56 | { 57 | free (data); 58 | } 59 | 60 | static pixman_image_t * 61 | make_image (void) 62 | { 63 | pixman_format_code_t format = RANDOM_FORMAT(); 64 | uint32_t *bytes, *orig; 65 | pixman_image_t *image; 66 | int stride; 67 | 68 | orig = bytes = malloc (WIDTH * HEIGHT * 4); 69 | prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0); 70 | 71 | stride = WIDTH * 4; 72 | if (prng_rand_n (2) == 0) 73 | { 74 | bytes += (stride / 4) * (HEIGHT - 1); 75 | stride = - stride; 76 | } 77 | 78 | image = pixman_image_create_bits ( 79 | format, WIDTH, HEIGHT, bytes, stride); 80 | 81 | pixman_image_set_transform (image, RANDOM_TRANSFORM()); 82 | pixman_image_set_destroy_function (image, on_destroy, orig); 83 | pixman_image_set_repeat (image, PIXMAN_REPEAT_NORMAL); 84 | 85 | image_endian_swap (image); 86 | 87 | return image; 88 | } 89 | 90 | static uint32_t 91 | test_transform (int testnum, int verbose) 92 | { 93 | pixman_image_t *src, *dest; 94 | uint32_t crc; 95 | 96 | prng_srand (testnum); 97 | 98 | src = make_image (); 99 | dest = make_image (); 100 | 101 | pixman_image_composite (RANDOM_OP(), 102 | src, NULL, dest, 103 | 0, 0, 0, 0, WIDTH / 2, HEIGHT / 2, 104 | WIDTH, HEIGHT); 105 | 106 | crc = compute_crc32_for_image (0, dest); 107 | 108 | pixman_image_unref (src); 109 | pixman_image_unref (dest); 110 | 111 | return crc; 112 | } 113 | 114 | int 115 | main (int argc, const char *argv[]) 116 | { 117 | return fuzzer_test_main ("rotate", 15000, 118 | 0x81E9EC2F, 119 | test_transform, argc, argv); 120 | } 121 | -------------------------------------------------------------------------------- /pixman/pixman-mips.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2000 SuSE, Inc. 3 | * Copyright © 2007 Red Hat, Inc. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of SuSE not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. SuSE makes no representations about the 12 | * suitability of this software for any purpose. It is provided "as is" 13 | * without express or implied warranty. 14 | * 15 | * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 | * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 | */ 22 | #ifdef HAVE_CONFIG_H 23 | #include 24 | #endif 25 | 26 | #include "pixman-private.h" 27 | 28 | #if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI) 29 | 30 | #include 31 | #include 32 | 33 | static pixman_bool_t 34 | have_feature (const char *search_string) 35 | { 36 | #if defined (__linux__) /* linux ELF */ 37 | /* Simple detection of MIPS features at runtime for Linux. 38 | * It is based on /proc/cpuinfo, which reveals hardware configuration 39 | * to user-space applications. According to MIPS (early 2010), no similar 40 | * facility is universally available on the MIPS architectures, so it's up 41 | * to individual OSes to provide such. 42 | */ 43 | const char *file_name = "/proc/cpuinfo"; 44 | char cpuinfo_line[256]; 45 | FILE *f = NULL; 46 | 47 | if ((f = fopen (file_name, "r")) == NULL) 48 | return FALSE; 49 | 50 | while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL) 51 | { 52 | if (strstr (cpuinfo_line, search_string) != NULL) 53 | { 54 | fclose (f); 55 | return TRUE; 56 | } 57 | } 58 | 59 | fclose (f); 60 | #endif 61 | 62 | /* Did not find string in the proc file, or not Linux ELF. */ 63 | return FALSE; 64 | } 65 | 66 | #endif 67 | 68 | pixman_implementation_t * 69 | _pixman_mips_get_implementations (pixman_implementation_t *imp) 70 | { 71 | #ifdef USE_LOONGSON_MMI 72 | /* I really don't know if some Loongson CPUs don't have MMI. */ 73 | if (!_pixman_disabled ("loongson-mmi") && have_feature ("Loongson")) 74 | imp = _pixman_implementation_create_mmx (imp); 75 | #endif 76 | 77 | #ifdef USE_MIPS_DSPR2 78 | if (!_pixman_disabled ("mips-dspr2")) 79 | { 80 | int already_compiling_everything_for_dspr2 = 0; 81 | #if defined(__mips_dsp) && (__mips_dsp_rev >= 2) 82 | already_compiling_everything_for_dspr2 = 1; 83 | #endif 84 | if (already_compiling_everything_for_dspr2 || 85 | /* Only currently available MIPS core that supports DSPr2 is 74K. */ 86 | have_feature ("MIPS 74K")) 87 | { 88 | imp = _pixman_implementation_create_mips_dspr2 (imp); 89 | } 90 | } 91 | #endif 92 | 93 | return imp; 94 | } 95 | -------------------------------------------------------------------------------- /demos/srgb-trap-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pixman.h" 3 | #include "gtk-utils.h" 4 | 5 | #define F(x) \ 6 | pixman_double_to_fixed (x) 7 | 8 | #define WIDTH 600 9 | #define HEIGHT 300 10 | 11 | static uint16_t 12 | convert_to_srgb (uint16_t in) 13 | { 14 | double d = in * (1/65535.0); 15 | double a = 0.055; 16 | 17 | if (d < 0.0031308) 18 | d = 12.92 * d; 19 | else 20 | d = (1 + a) * pow (d, 1 / 2.4) - a; 21 | 22 | return (d * 65535.0) + 0.5; 23 | } 24 | 25 | static void 26 | convert_color (pixman_color_t *dest_srgb, pixman_color_t *linear) 27 | { 28 | dest_srgb->alpha = convert_to_srgb (linear->alpha); 29 | dest_srgb->red = convert_to_srgb (linear->red); 30 | dest_srgb->green = convert_to_srgb (linear->green); 31 | dest_srgb->blue = convert_to_srgb (linear->blue); 32 | } 33 | 34 | int 35 | main (int argc, char **argv) 36 | { 37 | static const pixman_trapezoid_t traps[] = 38 | { 39 | { F(10.10), F(280.0), 40 | { { F(20.0), F(10.10) }, 41 | { F(5.3), F(280.0) } }, 42 | { { F(20.3), F(10.10) }, 43 | { F(5.6), F(280.0) } } 44 | }, 45 | { F(10.10), F(280.0), 46 | { { F(40.0), F(10.10) }, 47 | { F(15.3), F(280.0) } }, 48 | { { F(41.0), F(10.10) }, 49 | { F(16.3), F(280.0) } } 50 | }, 51 | { F(10.10), F(280.0), 52 | { { F(120.0), F(10.10) }, 53 | { F(5.3), F(280.0) } }, 54 | { { F(128.3), F(10.10) }, 55 | { F(6.6), F(280.0) } } 56 | }, 57 | { F(10.10), F(280.0), 58 | { { F(60.0), F(10.10) }, 59 | { F(25.3), F(280.0) } }, 60 | { { F(61.0), F(10.10) }, 61 | { F(26.3), F(280.0) } } 62 | }, 63 | { F(10.10), F(280.0), 64 | { { F(90.0), F(10.10) }, 65 | { F(55.3), F(280.0) } }, 66 | { { F(93.0), F(10.10) }, 67 | { F(58.3), F(280.0) } } 68 | }, 69 | { F(130.10), F(150.0), 70 | { { F(100.0), F(130.10) }, 71 | { F(250.3), F(150.0) } }, 72 | { { F(110.0), F(130.10) }, 73 | { F(260.3), F(150.0) } } 74 | }, 75 | { F(170.10), F(240.0), 76 | { { F(100.0), F(170.10) }, 77 | { F(120.3), F(240.0) } }, 78 | { { F(250.0), F(170.10) }, 79 | { F(250.3), F(240.0) } } 80 | }, 81 | }; 82 | 83 | pixman_image_t *src, *dest_srgb, *dest_linear; 84 | pixman_color_t bg = { 0x0000, 0x0000, 0x0000, 0xffff }; 85 | pixman_color_t fg = { 0xffff, 0xffff, 0xffff, 0xffff }; 86 | pixman_color_t fg_srgb; 87 | uint32_t *d; 88 | 89 | d = malloc (WIDTH * HEIGHT * 4); 90 | 91 | dest_srgb = pixman_image_create_bits ( 92 | PIXMAN_a8r8g8b8_sRGB, WIDTH, HEIGHT, d, WIDTH * 4); 93 | dest_linear = pixman_image_create_bits ( 94 | PIXMAN_a8r8g8b8, WIDTH, HEIGHT, d, WIDTH * 4); 95 | 96 | src = pixman_image_create_solid_fill (&bg); 97 | pixman_image_composite32 (PIXMAN_OP_SRC, 98 | src, NULL, dest_srgb, 99 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 100 | 101 | src = pixman_image_create_solid_fill (&fg); 102 | 103 | pixman_composite_trapezoids (PIXMAN_OP_OVER, 104 | src, dest_srgb, PIXMAN_a8, 105 | 0, 0, 10, 10, G_N_ELEMENTS (traps), traps); 106 | 107 | convert_color (&fg_srgb, &fg); 108 | src = pixman_image_create_solid_fill (&fg_srgb); 109 | 110 | pixman_composite_trapezoids (PIXMAN_OP_OVER, 111 | src, dest_linear, PIXMAN_a8, 112 | 0, 0, 310, 10, G_N_ELEMENTS (traps), traps); 113 | 114 | show_image (dest_linear); 115 | pixman_image_unref(dest_linear); 116 | free(d); 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /test/region-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | 6 | int 7 | main () 8 | { 9 | pixman_region32_t r1; 10 | pixman_region32_t r2; 11 | pixman_region32_t r3; 12 | pixman_box32_t boxes[] = { 13 | { 10, 10, 20, 20 }, 14 | { 30, 30, 30, 40 }, 15 | { 50, 45, 60, 44 }, 16 | }; 17 | pixman_box32_t boxes2[] = { 18 | { 2, 6, 7, 6 }, 19 | { 4, 1, 6, 7 }, 20 | }; 21 | pixman_box32_t boxes3[] = { 22 | { 2, 6, 7, 6 }, 23 | { 4, 1, 6, 1 }, 24 | }; 25 | int i, j; 26 | pixman_box32_t *b; 27 | pixman_image_t *image, *fill; 28 | pixman_color_t white = { 29 | 0xffff, 30 | 0xffff, 31 | 0xffff, 32 | 0xffff 33 | }; 34 | 35 | prng_srand (0); 36 | 37 | /* This used to go into an infinite loop before pixman-region.c 38 | * was fixed to not use explict "short" variables 39 | */ 40 | pixman_region32_init_rect (&r1, 0, 0, 20, 64000); 41 | pixman_region32_init_rect (&r2, 0, 0, 20, 64000); 42 | pixman_region32_init_rect (&r3, 0, 0, 20, 64000); 43 | 44 | pixman_region32_subtract (&r1, &r2, &r3); 45 | 46 | 47 | /* This would produce a region containing an empty 48 | * rectangle in it. Such regions are considered malformed, 49 | * but using an empty rectangle for initialization should 50 | * work. 51 | */ 52 | pixman_region32_init_rects (&r1, boxes, 3); 53 | 54 | b = pixman_region32_rectangles (&r1, &i); 55 | 56 | assert (i == 1); 57 | 58 | while (i--) 59 | { 60 | assert (b[i].x1 < b[i].x2); 61 | assert (b[i].y1 < b[i].y2); 62 | } 63 | 64 | /* This would produce a rectangle containing the bounding box 65 | * of the two rectangles. The correct result is to eliminate 66 | * the broken rectangle. 67 | */ 68 | pixman_region32_init_rects (&r1, boxes2, 2); 69 | 70 | b = pixman_region32_rectangles (&r1, &i); 71 | 72 | assert (i == 1); 73 | 74 | assert (b[0].x1 == 4); 75 | assert (b[0].y1 == 1); 76 | assert (b[0].x2 == 6); 77 | assert (b[0].y2 == 7); 78 | 79 | /* This should produce an empty region */ 80 | pixman_region32_init_rects (&r1, boxes3, 2); 81 | 82 | b = pixman_region32_rectangles (&r1, &i); 83 | 84 | assert (i == 0); 85 | 86 | fill = pixman_image_create_solid_fill (&white); 87 | for (i = 0; i < 100; i++) 88 | { 89 | int image_size = 128; 90 | 91 | pixman_region32_init (&r1); 92 | 93 | /* Add some random rectangles */ 94 | for (j = 0; j < 64; j++) 95 | pixman_region32_union_rect (&r1, &r1, 96 | prng_rand_n (image_size), 97 | prng_rand_n (image_size), 98 | prng_rand_n (25), 99 | prng_rand_n (25)); 100 | 101 | /* Clip to image size */ 102 | pixman_region32_init_rect (&r2, 0, 0, image_size, image_size); 103 | pixman_region32_intersect (&r1, &r1, &r2); 104 | pixman_region32_fini (&r2); 105 | 106 | /* render region to a1 mask */ 107 | image = pixman_image_create_bits (PIXMAN_a1, image_size, image_size, NULL, 0); 108 | pixman_image_set_clip_region32 (image, &r1); 109 | pixman_image_composite32 (PIXMAN_OP_SRC, 110 | fill, NULL, image, 111 | 0, 0, 0, 0, 0, 0, 112 | image_size, image_size); 113 | pixman_region32_init_from_image (&r2, image); 114 | 115 | pixman_image_unref (image); 116 | 117 | assert (pixman_region32_equal (&r1, &r2)); 118 | pixman_region32_fini (&r1); 119 | pixman_region32_fini (&r2); 120 | 121 | } 122 | pixman_image_unref (fill); 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /test/combiner-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | #include 5 | #include "pixman-private.h" 6 | 7 | static const pixman_op_t op_list[] = 8 | { 9 | PIXMAN_OP_SRC, 10 | PIXMAN_OP_OVER, 11 | PIXMAN_OP_ADD, 12 | PIXMAN_OP_CLEAR, 13 | PIXMAN_OP_SRC, 14 | PIXMAN_OP_DST, 15 | PIXMAN_OP_OVER, 16 | PIXMAN_OP_OVER_REVERSE, 17 | PIXMAN_OP_IN, 18 | PIXMAN_OP_IN_REVERSE, 19 | PIXMAN_OP_OUT, 20 | PIXMAN_OP_OUT_REVERSE, 21 | PIXMAN_OP_ATOP, 22 | PIXMAN_OP_ATOP_REVERSE, 23 | PIXMAN_OP_XOR, 24 | PIXMAN_OP_ADD, 25 | PIXMAN_OP_SATURATE, 26 | PIXMAN_OP_DISJOINT_CLEAR, 27 | PIXMAN_OP_DISJOINT_SRC, 28 | PIXMAN_OP_DISJOINT_DST, 29 | PIXMAN_OP_DISJOINT_OVER, 30 | PIXMAN_OP_DISJOINT_OVER_REVERSE, 31 | PIXMAN_OP_DISJOINT_IN, 32 | PIXMAN_OP_DISJOINT_IN_REVERSE, 33 | PIXMAN_OP_DISJOINT_OUT, 34 | PIXMAN_OP_DISJOINT_OUT_REVERSE, 35 | PIXMAN_OP_DISJOINT_ATOP, 36 | PIXMAN_OP_DISJOINT_ATOP_REVERSE, 37 | PIXMAN_OP_DISJOINT_XOR, 38 | PIXMAN_OP_CONJOINT_CLEAR, 39 | PIXMAN_OP_CONJOINT_SRC, 40 | PIXMAN_OP_CONJOINT_DST, 41 | PIXMAN_OP_CONJOINT_OVER, 42 | PIXMAN_OP_CONJOINT_OVER_REVERSE, 43 | PIXMAN_OP_CONJOINT_IN, 44 | PIXMAN_OP_CONJOINT_IN_REVERSE, 45 | PIXMAN_OP_CONJOINT_OUT, 46 | PIXMAN_OP_CONJOINT_OUT_REVERSE, 47 | PIXMAN_OP_CONJOINT_ATOP, 48 | PIXMAN_OP_CONJOINT_ATOP_REVERSE, 49 | PIXMAN_OP_CONJOINT_XOR, 50 | PIXMAN_OP_MULTIPLY, 51 | PIXMAN_OP_SCREEN, 52 | PIXMAN_OP_OVERLAY, 53 | PIXMAN_OP_DARKEN, 54 | PIXMAN_OP_LIGHTEN, 55 | PIXMAN_OP_COLOR_DODGE, 56 | PIXMAN_OP_COLOR_BURN, 57 | PIXMAN_OP_HARD_LIGHT, 58 | PIXMAN_OP_DIFFERENCE, 59 | PIXMAN_OP_EXCLUSION, 60 | PIXMAN_OP_SOFT_LIGHT, 61 | PIXMAN_OP_HSL_HUE, 62 | PIXMAN_OP_HSL_SATURATION, 63 | PIXMAN_OP_HSL_COLOR, 64 | PIXMAN_OP_HSL_LUMINOSITY, 65 | }; 66 | 67 | static float 68 | rand_float (void) 69 | { 70 | uint32_t u = prng_rand(); 71 | 72 | return *(float *)&u; 73 | } 74 | 75 | static void 76 | random_floats (argb_t *argb, int width) 77 | { 78 | int i; 79 | 80 | for (i = 0; i < width; ++i) 81 | { 82 | argb_t *p = argb + i; 83 | 84 | p->a = rand_float(); 85 | p->r = rand_float(); 86 | p->g = rand_float(); 87 | p->b = rand_float(); 88 | } 89 | } 90 | 91 | #define WIDTH 512 92 | 93 | static pixman_combine_float_func_t 94 | lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, 95 | pixman_bool_t component_alpha) 96 | { 97 | pixman_combine_float_func_t f; 98 | 99 | do 100 | { 101 | if (component_alpha) 102 | f = imp->combine_float_ca[op]; 103 | else 104 | f = imp->combine_float[op]; 105 | 106 | imp = imp->fallback; 107 | } 108 | while (!f); 109 | 110 | return f; 111 | } 112 | 113 | int 114 | main () 115 | { 116 | pixman_implementation_t *impl; 117 | argb_t *src_bytes = malloc (WIDTH * sizeof (argb_t)); 118 | argb_t *mask_bytes = malloc (WIDTH * sizeof (argb_t)); 119 | argb_t *dest_bytes = malloc (WIDTH * sizeof (argb_t)); 120 | int i; 121 | 122 | enable_divbyzero_exceptions(); 123 | 124 | impl = _pixman_internal_only_get_implementation(); 125 | 126 | prng_srand (0); 127 | 128 | for (i = 0; i < ARRAY_LENGTH (op_list); ++i) 129 | { 130 | pixman_op_t op = op_list[i]; 131 | pixman_combine_float_func_t combiner; 132 | int ca; 133 | 134 | for (ca = 0; ca < 2; ++ca) 135 | { 136 | combiner = lookup_combiner (impl, op, ca); 137 | 138 | random_floats (src_bytes, WIDTH); 139 | random_floats (mask_bytes, WIDTH); 140 | random_floats (dest_bytes, WIDTH); 141 | 142 | combiner (impl, op, 143 | (float *)dest_bytes, 144 | (float *)mask_bytes, 145 | (float *)src_bytes, 146 | WIDTH); 147 | } 148 | } 149 | 150 | return 0; 151 | } 152 | -------------------------------------------------------------------------------- /demos/alpha-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pixman.h" 4 | #include "gtk-utils.h" 5 | 6 | int 7 | main (int argc, char **argv) 8 | { 9 | #define WIDTH 400 10 | #define HEIGHT 200 11 | 12 | uint32_t *alpha = malloc (WIDTH * HEIGHT * 4); 13 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 14 | uint32_t *src = malloc (WIDTH * HEIGHT * 4); 15 | pixman_image_t *grad_img; 16 | pixman_image_t *alpha_img; 17 | pixman_image_t *dest_img; 18 | pixman_image_t *src_img; 19 | int i; 20 | pixman_gradient_stop_t stops[2] = 21 | { 22 | { pixman_int_to_fixed (0), { 0x0000, 0x0000, 0x0000, 0x0000 } }, 23 | { pixman_int_to_fixed (1), { 0xffff, 0x0000, 0x1111, 0xffff } } 24 | }; 25 | pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 }; 26 | pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH), 27 | pixman_int_to_fixed (0) }; 28 | #if 0 29 | pixman_transform_t trans = { 30 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, 31 | { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, 32 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 33 | } 34 | }; 35 | #else 36 | pixman_transform_t trans = { 37 | { { pixman_fixed_1, 0, 0 }, 38 | { 0, pixman_fixed_1, 0 }, 39 | { 0, 0, pixman_fixed_1 } } 40 | }; 41 | #endif 42 | 43 | #if 0 44 | pixman_point_fixed_t c_inner; 45 | pixman_point_fixed_t c_outer; 46 | pixman_fixed_t r_inner; 47 | pixman_fixed_t r_outer; 48 | #endif 49 | 50 | for (i = 0; i < WIDTH * HEIGHT; ++i) 51 | alpha[i] = 0x4f00004f; /* pale blue */ 52 | 53 | alpha_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 54 | WIDTH, HEIGHT, 55 | alpha, 56 | WIDTH * 4); 57 | 58 | for (i = 0; i < WIDTH * HEIGHT; ++i) 59 | dest[i] = 0xffffff00; /* yellow */ 60 | 61 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 62 | WIDTH, HEIGHT, 63 | dest, 64 | WIDTH * 4); 65 | 66 | for (i = 0; i < WIDTH * HEIGHT; ++i) 67 | src[i] = 0xffff0000; 68 | 69 | src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 70 | WIDTH, HEIGHT, 71 | src, 72 | WIDTH * 4); 73 | 74 | #if 0 75 | c_inner.x = pixman_double_to_fixed (50.0); 76 | c_inner.y = pixman_double_to_fixed (50.0); 77 | c_outer.x = pixman_double_to_fixed (50.0); 78 | c_outer.y = pixman_double_to_fixed (50.0); 79 | r_inner = 0; 80 | r_outer = pixman_double_to_fixed (50.0); 81 | 82 | grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner, 83 | stops, 2); 84 | #endif 85 | #if 0 86 | grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner, 87 | stops, 2); 88 | grad_img = pixman_image_create_linear_gradient (&c_inner, &c_outer, 89 | r_inner, r_outer, 90 | stops, 2); 91 | #endif 92 | 93 | grad_img = pixman_image_create_linear_gradient (&p1, &p2, 94 | stops, 2); 95 | 96 | pixman_image_set_transform (grad_img, &trans); 97 | pixman_image_set_repeat (grad_img, PIXMAN_REPEAT_PAD); 98 | 99 | pixman_image_composite (PIXMAN_OP_OVER, grad_img, NULL, alpha_img, 100 | 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); 101 | 102 | pixman_image_set_alpha_map (src_img, alpha_img, 10, 10); 103 | 104 | pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img, 105 | 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); 106 | 107 | printf ("0, 0: %x\n", dest[0]); 108 | printf ("10, 10: %x\n", dest[10 * 10 + 10]); 109 | printf ("w, h: %x\n", dest[(HEIGHT - 1) * 100 + (WIDTH - 1)]); 110 | 111 | show_image (dest_img); 112 | 113 | pixman_image_unref (src_img); 114 | pixman_image_unref (grad_img); 115 | pixman_image_unref (alpha_img); 116 | free (dest); 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Pixman is a library that provides low-level pixel manipulation 2 | features such as image compositing and trapezoid rasterization. 3 | 4 | Questions, bug reports and patches should be directed to the pixman 5 | mailing list: 6 | 7 | http://lists.freedesktop.org/mailman/listinfo/pixman 8 | 9 | You can also file bugs at 10 | 11 | https://bugs.freedesktop.org/enter_bug.cgi?product=pixman 12 | 13 | For real time discussions about pixman, feel free to join the IRC 14 | channels #cairo and #xorg-devel on the FreeNode IRC network. 15 | 16 | 17 | Contributing 18 | ------------ 19 | 20 | In order to contribute to pixman, you will need a working knowledge of 21 | the git version control system. For a quick getting started guide, 22 | there is the "Everyday Git With 20 Commands Or So guide" 23 | 24 | http://www.kernel.org/pub/software/scm/git/docs/everyday.html 25 | 26 | from the Git homepage. For more in depth git documentation, see the 27 | resources on the Git community documentation page: 28 | 29 | http://git-scm.com/documentation 30 | 31 | Pixman uses the infrastructure from the freedesktop.org umbrella 32 | project. For instructions about how to use the git service on 33 | freedesktop.org, see: 34 | 35 | http://www.freedesktop.org/wiki/Infrastructure/git/Developers 36 | 37 | The Pixman master repository can be found at: 38 | 39 | git://anongit.freedesktop.org/git/pixman 40 | 41 | and browsed on the web here: 42 | 43 | http://cgit.freedesktop.org/pixman/ 44 | 45 | 46 | Sending patches 47 | --------------- 48 | 49 | The general workflow for sending patches is to first make sure that 50 | git can send mail on your system. Then, 51 | 52 | - create a branch off of master in your local git repository 53 | 54 | - make your changes as one or more commits 55 | 56 | - use the 57 | 58 | git send-email 59 | 60 | command to send the patch series to pixman@lists.freedesktop.org. 61 | 62 | In order for your patches to be accepted, please consider the 63 | following guidelines: 64 | 65 | - This link: 66 | 67 | http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#patch-series 68 | 69 | describes how what a good patch series is, and to create one with 70 | git. 71 | 72 | - At each point in the series, pixman should compile and the test 73 | suite should pass. 74 | 75 | The exception here is if you are changing the test suite to 76 | demonstrate a bug. In this case, make one commit that makes the 77 | test suite fail due to the bug, and then another commit that fixes 78 | the bug. 79 | 80 | You can run the test suite with 81 | 82 | make check 83 | 84 | It will take around two minutes to run on a modern PC. 85 | 86 | - Follow the coding style described in the CODING_STYLE file 87 | 88 | - For bug fixes, include an update to the test suite to make sure 89 | the bug doesn't reappear. 90 | 91 | - For new features, add tests of the feature to the test 92 | suite. Also, add a program demonstrating the new feature to the 93 | demos/ directory. 94 | 95 | - Write descriptive commit messages. Useful information to include: 96 | - Benchmark results, before and after 97 | - Description of the bug that was fixed 98 | - Detailed rationale for any new API 99 | - Alternative approaches that were rejected (and why they 100 | don't work) 101 | - If review comments were incorporated, a brief version 102 | history describing what those changes were. 103 | 104 | - For big patch series, send an introductory email with an overall 105 | description of the patch series, including benchmarks and 106 | motivation. Each commit message should still be descriptive and 107 | include enough information to understand why this particular commit 108 | was necessary. 109 | 110 | Pixman has high standards for code quality and so almost everybody 111 | should expect to have the first versions of their patches rejected. 112 | 113 | If you think that the reviewers are wrong about something, or that the 114 | guidelines above are wrong, feel free to discuss the issue on the 115 | list. The purpose of the guidelines and code review is to ensure high 116 | code quality; it is not an exercise in compliance. 117 | -------------------------------------------------------------------------------- /test/thread-test.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #ifndef HAVE_PTHREADS 4 | 5 | int main () 6 | { 7 | printf ("Skipped thread-test - pthreads not supported\n"); 8 | return 0; 9 | } 10 | 11 | #else 12 | 13 | #include 14 | #include 15 | 16 | typedef struct 17 | { 18 | int thread_no; 19 | uint32_t *dst_buf; 20 | prng_t prng_state; 21 | } info_t; 22 | 23 | static const pixman_op_t operators[] = 24 | { 25 | PIXMAN_OP_SRC, 26 | PIXMAN_OP_OVER, 27 | PIXMAN_OP_ADD, 28 | PIXMAN_OP_CLEAR, 29 | PIXMAN_OP_SRC, 30 | PIXMAN_OP_DST, 31 | PIXMAN_OP_OVER, 32 | PIXMAN_OP_OVER_REVERSE, 33 | PIXMAN_OP_IN, 34 | PIXMAN_OP_IN_REVERSE, 35 | PIXMAN_OP_OUT, 36 | PIXMAN_OP_OUT_REVERSE, 37 | PIXMAN_OP_ATOP, 38 | PIXMAN_OP_ATOP_REVERSE, 39 | PIXMAN_OP_XOR, 40 | PIXMAN_OP_ADD, 41 | PIXMAN_OP_MULTIPLY, 42 | PIXMAN_OP_SCREEN, 43 | PIXMAN_OP_OVERLAY, 44 | PIXMAN_OP_DARKEN, 45 | PIXMAN_OP_LIGHTEN, 46 | PIXMAN_OP_HARD_LIGHT, 47 | PIXMAN_OP_DIFFERENCE, 48 | PIXMAN_OP_EXCLUSION, 49 | }; 50 | 51 | static const pixman_format_code_t formats[] = 52 | { 53 | PIXMAN_a8r8g8b8, 54 | PIXMAN_r5g6b5, 55 | PIXMAN_a8, 56 | PIXMAN_a4, 57 | PIXMAN_a1, 58 | PIXMAN_b5g6r5, 59 | PIXMAN_r8g8b8a8, 60 | PIXMAN_a4r4g4b4 61 | }; 62 | 63 | #define N_ROUNDS 8192 64 | 65 | #define RAND_ELT(arr) \ 66 | arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)] 67 | 68 | #define DEST_WIDTH (7) 69 | 70 | static void * 71 | thread (void *data) 72 | { 73 | info_t *info = data; 74 | uint32_t crc32 = 0x0; 75 | uint32_t src_buf[64]; 76 | pixman_image_t *dst_img, *src_img; 77 | int i; 78 | 79 | prng_srand_r (&info->prng_state, info->thread_no); 80 | 81 | for (i = 0; i < N_ROUNDS; ++i) 82 | { 83 | pixman_op_t op; 84 | int rand1, rand2; 85 | 86 | prng_randmemset_r (&info->prng_state, info->dst_buf, 87 | DEST_WIDTH * sizeof (uint32_t), 0); 88 | prng_randmemset_r (&info->prng_state, src_buf, 89 | sizeof (src_buf), 0); 90 | 91 | src_img = pixman_image_create_bits ( 92 | RAND_ELT (formats), 4, 4, src_buf, 16); 93 | dst_img = pixman_image_create_bits ( 94 | RAND_ELT (formats), DEST_WIDTH, 1, info->dst_buf, 95 | DEST_WIDTH * sizeof (uint32_t)); 96 | 97 | image_endian_swap (src_img); 98 | image_endian_swap (dst_img); 99 | 100 | rand2 = prng_rand_r (&info->prng_state) % 4; 101 | rand1 = prng_rand_r (&info->prng_state) % 4; 102 | op = RAND_ELT (operators); 103 | 104 | pixman_image_composite32 ( 105 | op, 106 | src_img, NULL, dst_img, 107 | rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1); 108 | 109 | crc32 = compute_crc32_for_image (crc32, dst_img); 110 | 111 | pixman_image_unref (src_img); 112 | pixman_image_unref (dst_img); 113 | } 114 | 115 | return (void *)(uintptr_t)crc32; 116 | } 117 | 118 | static inline uint32_t 119 | byteswap32 (uint32_t x) 120 | { 121 | return ((x & ((uint32_t)0xFF << 24)) >> 24) | 122 | ((x & ((uint32_t)0xFF << 16)) >> 8) | 123 | ((x & ((uint32_t)0xFF << 8)) << 8) | 124 | ((x & ((uint32_t)0xFF << 0)) << 24); 125 | } 126 | 127 | int 128 | main (void) 129 | { 130 | uint32_t dest[16 * DEST_WIDTH]; 131 | info_t info[16] = { { 0 } }; 132 | pthread_t threads[16]; 133 | void *retvals[16]; 134 | uint32_t crc32s[16], crc32; 135 | int i; 136 | 137 | for (i = 0; i < 16; ++i) 138 | { 139 | info[i].thread_no = i; 140 | info[i].dst_buf = &dest[i * DEST_WIDTH]; 141 | } 142 | 143 | for (i = 0; i < 16; ++i) 144 | pthread_create (&threads[i], NULL, thread, &info[i]); 145 | 146 | for (i = 0; i < 16; ++i) 147 | pthread_join (threads[i], &retvals[i]); 148 | 149 | for (i = 0; i < 16; ++i) 150 | { 151 | crc32s[i] = (uintptr_t)retvals[i]; 152 | 153 | if (is_little_endian()) 154 | crc32s[i] = byteswap32 (crc32s[i]); 155 | } 156 | 157 | crc32 = compute_crc32 (0, crc32s, sizeof crc32s); 158 | 159 | #define EXPECTED 0x82C4D9FB 160 | 161 | if (crc32 != EXPECTED) 162 | { 163 | printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n", 164 | crc32, EXPECTED); 165 | return 1; 166 | } 167 | 168 | return 0; 169 | } 170 | 171 | #endif 172 | 173 | -------------------------------------------------------------------------------- /test/region-contains-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | static void 6 | make_random_region (pixman_region32_t *region) 7 | { 8 | int n_boxes; 9 | 10 | pixman_region32_init (region); 11 | 12 | n_boxes = prng_rand_n (64); 13 | while (n_boxes--) 14 | { 15 | int32_t x, y; 16 | uint32_t w, h; 17 | 18 | x = (int32_t)prng_rand() >> 2; 19 | y = (int32_t)prng_rand() >> 2; 20 | w = prng_rand() >> 2; 21 | h = prng_rand() >> 2; 22 | 23 | pixman_region32_union_rect (region, region, x, y, w, h); 24 | } 25 | } 26 | 27 | static void 28 | print_box (pixman_box32_t *box) 29 | { 30 | printf (" %d %d %d %d\n", box->x1, box->y1, box->x2, box->y2); 31 | } 32 | 33 | static int32_t 34 | random_coord (pixman_region32_t *region, pixman_bool_t x) 35 | { 36 | pixman_box32_t *b, *bb; 37 | int n_boxes; 38 | int begin, end; 39 | 40 | if (prng_rand_n (14)) 41 | { 42 | bb = pixman_region32_rectangles (region, &n_boxes); 43 | if (n_boxes == 0) 44 | goto use_extent; 45 | b = bb + prng_rand_n (n_boxes); 46 | } 47 | else 48 | { 49 | use_extent: 50 | b = pixman_region32_extents (region); 51 | n_boxes = 1; 52 | } 53 | 54 | if (x) 55 | { 56 | begin = b->x1; 57 | end = b->x2; 58 | } 59 | else 60 | { 61 | begin = b->y1; 62 | end = b->y2; 63 | } 64 | 65 | switch (prng_rand_n (5)) 66 | { 67 | case 0: 68 | return begin - prng_rand(); 69 | case 1: 70 | return end + prng_rand (); 71 | case 2: 72 | return end; 73 | case 3: 74 | return begin; 75 | default: 76 | return (end - begin) / 2 + begin; 77 | } 78 | return 0; 79 | } 80 | 81 | static uint32_t 82 | compute_crc32_u32 (uint32_t crc32, uint32_t v) 83 | { 84 | if (!is_little_endian()) 85 | { 86 | v = ((v & 0xff000000) >> 24) | 87 | ((v & 0x00ff0000) >> 8) | 88 | ((v & 0x0000ff00) << 8) | 89 | ((v & 0x000000ff) << 24); 90 | } 91 | 92 | return compute_crc32 (crc32, &v, sizeof (int32_t)); 93 | } 94 | 95 | static uint32_t 96 | crc32_box32 (uint32_t crc32, pixman_box32_t *box) 97 | { 98 | crc32 = compute_crc32_u32 (crc32, box->x1); 99 | crc32 = compute_crc32_u32 (crc32, box->y1); 100 | crc32 = compute_crc32_u32 (crc32, box->x2); 101 | crc32 = compute_crc32_u32 (crc32, box->y2); 102 | 103 | return crc32; 104 | } 105 | 106 | static uint32_t 107 | test_region_contains_rectangle (int i, int verbose) 108 | { 109 | pixman_box32_t box; 110 | pixman_box32_t rbox = { 0, 0, 0, 0 }; 111 | pixman_region32_t region; 112 | uint32_t r, r1, r2, r3, r4, crc32; 113 | 114 | prng_srand (i); 115 | 116 | make_random_region (®ion); 117 | 118 | box.x1 = random_coord (®ion, TRUE); 119 | box.x2 = box.x1 + prng_rand (); 120 | box.y1 = random_coord (®ion, FALSE); 121 | box.y2 = box.y1 + prng_rand (); 122 | 123 | if (verbose) 124 | { 125 | int n_rects; 126 | pixman_box32_t *boxes; 127 | 128 | boxes = pixman_region32_rectangles (®ion, &n_rects); 129 | 130 | printf ("region:\n"); 131 | while (n_rects--) 132 | print_box (boxes++); 133 | printf ("box:\n"); 134 | print_box (&box); 135 | } 136 | 137 | crc32 = 0; 138 | 139 | r1 = pixman_region32_contains_point (®ion, box.x1, box.y1, &rbox); 140 | crc32 = crc32_box32 (crc32, &rbox); 141 | r2 = pixman_region32_contains_point (®ion, box.x1, box.y2, &rbox); 142 | crc32 = crc32_box32 (crc32, &rbox); 143 | r3 = pixman_region32_contains_point (®ion, box.x2, box.y1, &rbox); 144 | crc32 = crc32_box32 (crc32, &rbox); 145 | r4 = pixman_region32_contains_point (®ion, box.x2, box.y2, &rbox); 146 | crc32 = crc32_box32 (crc32, &rbox); 147 | 148 | r = pixman_region32_contains_rectangle (®ion, &box); 149 | r = (i << 8) | (r << 4) | (r1 << 3) | (r2 << 2) | (r3 << 1) | (r4 << 0); 150 | 151 | crc32 = compute_crc32_u32 (crc32, r); 152 | 153 | if (verbose) 154 | printf ("results: %d %d %d %d %d\n", (r & 0xf0) >> 4, r1, r2, r3, r4); 155 | 156 | pixman_region32_fini (®ion); 157 | 158 | return crc32; 159 | } 160 | 161 | int 162 | main (int argc, const char *argv[]) 163 | { 164 | return fuzzer_test_main ("region_contains", 165 | 1000000, 166 | 0x548E0F3F, 167 | test_region_contains_rectangle, 168 | argc, argv); 169 | } 170 | -------------------------------------------------------------------------------- /pixman/pixman-ppc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2000 SuSE, Inc. 3 | * Copyright © 2007 Red Hat, Inc. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of SuSE not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. SuSE makes no representations about the 12 | * suitability of this software for any purpose. It is provided "as is" 13 | * without express or implied warranty. 14 | * 15 | * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 | * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 | */ 22 | #ifdef HAVE_CONFIG_H 23 | #include 24 | #endif 25 | 26 | #include "pixman-private.h" 27 | 28 | #ifdef USE_VMX 29 | 30 | /* The CPU detection code needs to be in a file not compiled with 31 | * "-maltivec -mabi=altivec", as gcc would try to save vector register 32 | * across function calls causing SIGILL on cpus without Altivec/vmx. 33 | */ 34 | #ifdef __APPLE__ 35 | #include 36 | 37 | static pixman_bool_t 38 | pixman_have_vmx (void) 39 | { 40 | int error, have_vmx; 41 | size_t length = sizeof(have_vmx); 42 | 43 | error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0); 44 | 45 | if (error) 46 | return FALSE; 47 | 48 | return have_vmx; 49 | } 50 | 51 | #elif defined (__OpenBSD__) 52 | #include 53 | #include 54 | #include 55 | 56 | static pixman_bool_t 57 | pixman_have_vmx (void) 58 | { 59 | int error, have_vmx; 60 | int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC }; 61 | size_t length = sizeof(have_vmx); 62 | 63 | error = sysctl (mib, 2, &have_vmx, &length, NULL, 0); 64 | 65 | if (error != 0) 66 | return FALSE; 67 | 68 | return have_vmx; 69 | } 70 | 71 | #elif defined (__linux__) 72 | 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | 81 | static pixman_bool_t 82 | pixman_have_vmx (void) 83 | { 84 | int have_vmx = FALSE; 85 | int fd; 86 | struct 87 | { 88 | unsigned long type; 89 | unsigned long value; 90 | } aux; 91 | 92 | fd = open ("/proc/self/auxv", O_RDONLY); 93 | if (fd >= 0) 94 | { 95 | while (read (fd, &aux, sizeof (aux)) == sizeof (aux)) 96 | { 97 | if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC)) 98 | { 99 | have_vmx = TRUE; 100 | break; 101 | } 102 | } 103 | 104 | close (fd); 105 | } 106 | 107 | return have_vmx; 108 | } 109 | 110 | #else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */ 111 | #include 112 | #include 113 | 114 | static jmp_buf jump_env; 115 | 116 | static void 117 | vmx_test (int sig, 118 | siginfo_t *si, 119 | void * unused) 120 | { 121 | longjmp (jump_env, 1); 122 | } 123 | 124 | static pixman_bool_t 125 | pixman_have_vmx (void) 126 | { 127 | struct sigaction sa, osa; 128 | int jmp_result; 129 | 130 | sa.sa_flags = SA_SIGINFO; 131 | sigemptyset (&sa.sa_mask); 132 | sa.sa_sigaction = vmx_test; 133 | sigaction (SIGILL, &sa, &osa); 134 | jmp_result = setjmp (jump_env); 135 | if (jmp_result == 0) 136 | { 137 | asm volatile ( "vor 0, 0, 0" ); 138 | } 139 | sigaction (SIGILL, &osa, NULL); 140 | return (jmp_result == 0); 141 | } 142 | 143 | #endif /* __APPLE__ */ 144 | #endif /* USE_VMX */ 145 | 146 | pixman_implementation_t * 147 | _pixman_ppc_get_implementations (pixman_implementation_t *imp) 148 | { 149 | #ifdef USE_VMX 150 | if (!_pixman_disabled ("vmx") && pixman_have_vmx ()) 151 | imp = _pixman_implementation_create_vmx (imp); 152 | #endif 153 | 154 | return imp; 155 | } 156 | -------------------------------------------------------------------------------- /test/fetch-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | 6 | #define SIZE 1024 7 | 8 | static pixman_indexed_t mono_palette = 9 | { 10 | 0, { 0x00000000, 0x00ffffff }, 11 | }; 12 | 13 | 14 | typedef struct { 15 | pixman_format_code_t format; 16 | int width, height; 17 | int stride; 18 | uint32_t src[SIZE]; 19 | uint32_t dst[SIZE]; 20 | pixman_indexed_t *indexed; 21 | } testcase_t; 22 | 23 | static testcase_t testcases[] = 24 | { 25 | { 26 | PIXMAN_a8r8g8b8, 27 | 2, 2, 28 | 8, 29 | { 0x00112233, 0x44556677, 30 | 0x8899aabb, 0xccddeeff }, 31 | { 0x00112233, 0x44556677, 32 | 0x8899aabb, 0xccddeeff }, 33 | NULL, 34 | }, 35 | { 36 | PIXMAN_r8g8b8a8, 37 | 2, 2, 38 | 8, 39 | { 0x11223300, 0x55667744, 40 | 0x99aabb88, 0xddeeffcc }, 41 | { 0x00112233, 0x44556677, 42 | 0x8899aabb, 0xccddeeff }, 43 | NULL, 44 | }, 45 | { 46 | PIXMAN_g1, 47 | 8, 2, 48 | 4, 49 | #ifdef WORDS_BIGENDIAN 50 | { 51 | 0xaa000000, 52 | 0x55000000 53 | }, 54 | #else 55 | { 56 | 0x00000055, 57 | 0x000000aa 58 | }, 59 | #endif 60 | { 61 | 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 62 | 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff 63 | }, 64 | &mono_palette, 65 | }, 66 | #if 0 67 | { 68 | PIXMAN_g8, 69 | 4, 2, 70 | 4, 71 | { 0x01234567, 72 | 0x89abcdef }, 73 | { 0x00010101, 0x00232323, 0x00454545, 0x00676767, 74 | 0x00898989, 0x00ababab, 0x00cdcdcd, 0x00efefef, }, 75 | }, 76 | #endif 77 | /* FIXME: make this work on big endian */ 78 | { 79 | PIXMAN_yv12, 80 | 8, 2, 81 | 8, 82 | #ifdef WORDS_BIGENDIAN 83 | { 84 | 0x00ff00ff, 0x00ff00ff, 85 | 0xff00ff00, 0xff00ff00, 86 | 0x80ff8000, 87 | 0x800080ff 88 | }, 89 | #else 90 | { 91 | 0xff00ff00, 0xff00ff00, 92 | 0x00ff00ff, 0x00ff00ff, 93 | 0x0080ff80, 94 | 0xff800080 95 | }, 96 | #endif 97 | { 98 | 0xff000000, 0xffffffff, 0xffb80000, 0xffffe113, 99 | 0xff000000, 0xffffffff, 0xff0023ee, 0xff4affff, 100 | 0xffffffff, 0xff000000, 0xffffe113, 0xffb80000, 101 | 0xffffffff, 0xff000000, 0xff4affff, 0xff0023ee, 102 | }, 103 | }, 104 | }; 105 | 106 | int n_test_cases = ARRAY_LENGTH (testcases); 107 | 108 | 109 | static uint32_t 110 | reader (const void *src, int size) 111 | { 112 | switch (size) 113 | { 114 | case 1: 115 | return *(uint8_t *)src; 116 | case 2: 117 | return *(uint16_t *)src; 118 | case 4: 119 | return *(uint32_t *)src; 120 | default: 121 | assert(0); 122 | return 0; /* silence MSVC */ 123 | } 124 | } 125 | 126 | 127 | static void 128 | writer (void *src, uint32_t value, int size) 129 | { 130 | switch (size) 131 | { 132 | case 1: 133 | *(uint8_t *)src = value; 134 | break; 135 | case 2: 136 | *(uint16_t *)src = value; 137 | break; 138 | case 4: 139 | *(uint32_t *)src = value; 140 | break; 141 | default: 142 | assert(0); 143 | } 144 | } 145 | 146 | 147 | int 148 | main (int argc, char **argv) 149 | { 150 | uint32_t dst[SIZE]; 151 | pixman_image_t *src_img; 152 | pixman_image_t *dst_img; 153 | int i, j, x, y; 154 | int ret = 0; 155 | 156 | for (i = 0; i < n_test_cases; ++i) 157 | { 158 | for (j = 0; j < 2; ++j) 159 | { 160 | src_img = pixman_image_create_bits (testcases[i].format, 161 | testcases[i].width, 162 | testcases[i].height, 163 | testcases[i].src, 164 | testcases[i].stride); 165 | pixman_image_set_indexed(src_img, testcases[i].indexed); 166 | 167 | dst_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 168 | testcases[i].width, 169 | testcases[i].height, 170 | dst, 171 | testcases[i].width*4); 172 | 173 | if (j) 174 | { 175 | pixman_image_set_accessors (src_img, reader, writer); 176 | pixman_image_set_accessors (dst_img, reader, writer); 177 | } 178 | 179 | pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, 180 | 0, 0, 0, 0, 0, 0, testcases[i].width, testcases[i].height); 181 | 182 | pixman_image_unref (src_img); 183 | pixman_image_unref (dst_img); 184 | 185 | for (y = 0; y < testcases[i].height; ++y) 186 | { 187 | for (x = 0; x < testcases[i].width; ++x) 188 | { 189 | int offset = y * testcases[i].width + x; 190 | 191 | if (dst[offset] != testcases[i].dst[offset]) 192 | { 193 | printf ("test %i%c: pixel mismatch at (x=%d,y=%d): %08x expected, %08x obtained\n", 194 | i + 1, 'a' + j, 195 | x, y, 196 | testcases[i].dst[offset], dst[offset]); 197 | ret = 1; 198 | } 199 | } 200 | } 201 | } 202 | } 203 | 204 | return ret; 205 | } 206 | -------------------------------------------------------------------------------- /pixman/Makefile.am: -------------------------------------------------------------------------------- 1 | include $(top_srcdir)/pixman/Makefile.sources 2 | 3 | lib_LTLIBRARIES = libpixman-1.la 4 | 5 | libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@ 6 | libpixman_1_la_LIBADD = @PTHREAD_LIBS@ -lm 7 | libpixman_1_la_SOURCES = $(libpixman_sources) $(libpixman_headers) 8 | 9 | libpixmanincludedir = $(includedir)/pixman-1 10 | libpixmaninclude_HEADERS = pixman.h pixman-version.h 11 | noinst_LTLIBRARIES = 12 | 13 | EXTRA_DIST = \ 14 | Makefile.win32 \ 15 | pixman-region.c \ 16 | solaris-hwcap.mapfile \ 17 | $(NULL) 18 | 19 | # mmx code 20 | if USE_X86_MMX 21 | noinst_LTLIBRARIES += libpixman-mmx.la 22 | libpixman_mmx_la_SOURCES = \ 23 | pixman-mmx.c 24 | libpixman_mmx_la_CFLAGS = $(MMX_CFLAGS) 25 | libpixman_1_la_LDFLAGS += $(MMX_LDFLAGS) 26 | libpixman_1_la_LIBADD += libpixman-mmx.la 27 | 28 | ASM_CFLAGS_mmx=$(MMX_CFLAGS) 29 | endif 30 | 31 | # vmx code 32 | if USE_VMX 33 | noinst_LTLIBRARIES += libpixman-vmx.la 34 | libpixman_vmx_la_SOURCES = \ 35 | pixman-vmx.c \ 36 | pixman-combine32.h 37 | libpixman_vmx_la_CFLAGS = $(VMX_CFLAGS) 38 | libpixman_1_la_LIBADD += libpixman-vmx.la 39 | 40 | ASM_CFLAGS_vmx=$(VMX_CFLAGS) 41 | endif 42 | 43 | # sse2 code 44 | if USE_SSE2 45 | noinst_LTLIBRARIES += libpixman-sse2.la 46 | libpixman_sse2_la_SOURCES = \ 47 | pixman-sse2.c 48 | libpixman_sse2_la_CFLAGS = $(SSE2_CFLAGS) 49 | libpixman_1_la_LDFLAGS += $(SSE2_LDFLAGS) 50 | libpixman_1_la_LIBADD += libpixman-sse2.la 51 | 52 | ASM_CFLAGS_sse2=$(SSE2_CFLAGS) 53 | endif 54 | 55 | # ssse3 code 56 | if USE_SSSE3 57 | noinst_LTLIBRARIES += libpixman-ssse3.la 58 | libpixman_ssse3_la_SOURCES = \ 59 | pixman-ssse3.c 60 | libpixman_ssse3_la_CFLAGS = $(SSSE3_CFLAGS) 61 | libpixman_1_la_LDFLAGS += $(SSSE3_LDFLAGS) 62 | libpixman_1_la_LIBADD += libpixman-ssse3.la 63 | 64 | ASM_CFLAGS_ssse3=$(SSSE3_CFLAGS) 65 | endif 66 | 67 | # arm simd code 68 | if USE_ARM_SIMD 69 | noinst_LTLIBRARIES += libpixman-arm-simd.la 70 | libpixman_arm_simd_la_SOURCES = \ 71 | pixman-arm-simd.c \ 72 | pixman-arm-common.h \ 73 | pixman-arm-simd-asm.S \ 74 | pixman-arm-simd-asm-scaled.S \ 75 | pixman-arm-asm.h \ 76 | pixman-arm-simd-asm.h 77 | libpixman_1_la_LIBADD += libpixman-arm-simd.la 78 | 79 | ASM_CFLAGS_arm_simd= 80 | endif 81 | 82 | # arm neon code 83 | if USE_ARM_NEON 84 | noinst_LTLIBRARIES += libpixman-arm-neon.la 85 | libpixman_arm_neon_la_SOURCES = \ 86 | pixman-arm-neon.c \ 87 | pixman-arm-common.h \ 88 | pixman-arm-neon-asm.S \ 89 | pixman-arm-neon-asm-bilinear.S \ 90 | pixman-arm-asm.h \ 91 | pixman-arm-neon-asm.h 92 | libpixman_1_la_LIBADD += libpixman-arm-neon.la 93 | 94 | ASM_CFLAGS_arm_neon= 95 | endif 96 | 97 | # iwmmxt code 98 | if USE_ARM_IWMMXT 99 | libpixman_iwmmxt_la_SOURCES = pixman-mmx.c 100 | noinst_LTLIBRARIES += libpixman-iwmmxt.la 101 | libpixman_1_la_LIBADD += libpixman-iwmmxt.la 102 | 103 | libpixman_iwmmxt_la-pixman-mmx.lo: pixman-mmx.c 104 | $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(IWMMXT_CFLAGS) -MT libpixman_iwmmxt_la-pixman-mmx.lo -MD -MP -MF $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo -c -o libpixman_iwmmxt_la-pixman-mmx.lo `test -f 'pixman-mmx.c' || echo '$(srcdir)/'`pixman-mmx.c 105 | $(AM_V_at)$(am__mv) $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Plo 106 | 107 | libpixman_iwmmxt_la_DEPENDENCIES = $(am__DEPENDENCIES_1) 108 | libpixman_iwmmxt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ 109 | $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ 110 | $(CFLAGS) $(IWMMXT_CFLAGS) $(AM_LDFLAGS) \ 111 | $(LDFLAGS) -o $@ 112 | 113 | libpixman-iwmmxt.la: libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_DEPENDENCIES) 114 | $(AM_V_CCLD)$(libpixman_iwmmxt_la_LINK) libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_LIBADD) $(LIBS) 115 | endif 116 | 117 | # mips dspr2 code 118 | if USE_MIPS_DSPR2 119 | noinst_LTLIBRARIES += libpixman-mips-dspr2.la 120 | libpixman_mips_dspr2_la_SOURCES = \ 121 | pixman-mips-dspr2.c \ 122 | pixman-mips-dspr2.h \ 123 | pixman-mips-dspr2-asm.S \ 124 | pixman-mips-dspr2-asm.h \ 125 | pixman-mips-memcpy-asm.S 126 | libpixman_1_la_LIBADD += libpixman-mips-dspr2.la 127 | 128 | ASM_CFLAGS_mips_dspr2= 129 | endif 130 | 131 | # loongson code 132 | if USE_LOONGSON_MMI 133 | noinst_LTLIBRARIES += libpixman-loongson-mmi.la 134 | libpixman_loongson_mmi_la_SOURCES = pixman-mmx.c loongson-mmintrin.h 135 | libpixman_loongson_mmi_la_CFLAGS = $(LS_CFLAGS) 136 | libpixman_1_la_LDFLAGS += $(LS_LDFLAGS) 137 | libpixman_1_la_LIBADD += libpixman-loongson-mmi.la 138 | endif 139 | 140 | .c.s : $(libpixmaninclude_HEADERS) 141 | $(CC) $(CFLAGS) $(ASM_CFLAGS_$(@:pixman-%.s=%)) $(ASM_CFLAGS_$(@:pixman-arm-%.s=arm_%)) -DHAVE_CONFIG_H -I$(srcdir) -I$(builddir) -I$(top_builddir) -S -o $@ $< 142 | -------------------------------------------------------------------------------- /demos/gtk-utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../test/utils.h" 4 | #include "gtk-utils.h" 5 | 6 | pixman_image_t * 7 | pixman_image_from_file (const char *filename, pixman_format_code_t format) 8 | { 9 | GdkPixbuf *pixbuf; 10 | pixman_image_t *image; 11 | int width, height; 12 | uint32_t *data, *d; 13 | uint8_t *gdk_data; 14 | int n_channels; 15 | int j, i; 16 | int stride; 17 | 18 | if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL))) 19 | return NULL; 20 | 21 | image = NULL; 22 | 23 | width = gdk_pixbuf_get_width (pixbuf); 24 | height = gdk_pixbuf_get_height (pixbuf); 25 | n_channels = gdk_pixbuf_get_n_channels (pixbuf); 26 | gdk_data = gdk_pixbuf_get_pixels (pixbuf); 27 | stride = gdk_pixbuf_get_rowstride (pixbuf); 28 | 29 | if (!(data = malloc (width * height * sizeof (uint32_t)))) 30 | goto out; 31 | 32 | d = data; 33 | for (j = 0; j < height; ++j) 34 | { 35 | uint8_t *gdk_line = gdk_data; 36 | 37 | for (i = 0; i < width; ++i) 38 | { 39 | int r, g, b, a; 40 | uint32_t pixel; 41 | 42 | r = gdk_line[0]; 43 | g = gdk_line[1]; 44 | b = gdk_line[2]; 45 | 46 | if (n_channels == 4) 47 | a = gdk_line[3]; 48 | else 49 | a = 0xff; 50 | 51 | r = (r * a + 127) / 255; 52 | g = (g * a + 127) / 255; 53 | b = (b * a + 127) / 255; 54 | 55 | pixel = (a << 24) | (r << 16) | (g << 8) | b; 56 | 57 | *d++ = pixel; 58 | gdk_line += n_channels; 59 | } 60 | 61 | gdk_data += stride; 62 | } 63 | 64 | image = pixman_image_create_bits ( 65 | format, width, height, data, width * 4); 66 | 67 | out: 68 | g_object_unref (pixbuf); 69 | return image; 70 | } 71 | 72 | GdkPixbuf * 73 | pixbuf_from_argb32 (uint32_t *bits, 74 | int width, 75 | int height, 76 | int stride) 77 | { 78 | GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 79 | 8, width, height); 80 | int p_stride = gdk_pixbuf_get_rowstride (pixbuf); 81 | guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf); 82 | int i; 83 | 84 | for (i = 0; i < height; ++i) 85 | { 86 | uint32_t *src_row = &bits[i * (stride / 4)]; 87 | uint32_t *dst_row = p_bits + i * (p_stride / 4); 88 | 89 | a8r8g8b8_to_rgba_np (dst_row, src_row, width); 90 | } 91 | 92 | return pixbuf; 93 | } 94 | 95 | static gboolean 96 | on_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data) 97 | { 98 | pixman_image_t *pimage = data; 99 | int width = pixman_image_get_width (pimage); 100 | int height = pixman_image_get_height (pimage); 101 | int stride = pixman_image_get_stride (pimage); 102 | cairo_surface_t *cimage; 103 | cairo_format_t format; 104 | cairo_t *cr; 105 | 106 | if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8) 107 | format = CAIRO_FORMAT_RGB24; 108 | else 109 | format = CAIRO_FORMAT_ARGB32; 110 | 111 | cimage = cairo_image_surface_create_for_data ( 112 | (uint8_t *)pixman_image_get_data (pimage), 113 | format, width, height, stride); 114 | 115 | cr = gdk_cairo_create (widget->window); 116 | 117 | cairo_rectangle (cr, 0, 0, width, height); 118 | cairo_set_source_surface (cr, cimage, 0, 0); 119 | cairo_fill (cr); 120 | 121 | cairo_destroy (cr); 122 | cairo_surface_destroy (cimage); 123 | 124 | return TRUE; 125 | } 126 | 127 | void 128 | show_image (pixman_image_t *image) 129 | { 130 | GtkWidget *window; 131 | int width, height; 132 | int argc; 133 | char **argv; 134 | char *arg0 = g_strdup ("pixman-test-program"); 135 | pixman_format_code_t format; 136 | pixman_image_t *copy; 137 | 138 | argc = 1; 139 | argv = (char **)&arg0; 140 | 141 | gtk_init (&argc, &argv); 142 | 143 | window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 144 | width = pixman_image_get_width (image); 145 | height = pixman_image_get_height (image); 146 | 147 | gtk_window_set_default_size (GTK_WINDOW (window), width, height); 148 | 149 | format = pixman_image_get_format (image); 150 | 151 | /* We always display the image as if it contains sRGB data. That 152 | * means that no conversion should take place when the image 153 | * has the a8r8g8b8_sRGB format. 154 | */ 155 | switch (format) 156 | { 157 | case PIXMAN_a8r8g8b8_sRGB: 158 | case PIXMAN_a8r8g8b8: 159 | case PIXMAN_x8r8g8b8: 160 | copy = pixman_image_ref (image); 161 | break; 162 | 163 | default: 164 | copy = pixman_image_create_bits (PIXMAN_a8r8g8b8, 165 | width, height, NULL, -1); 166 | pixman_image_composite32 (PIXMAN_OP_SRC, 167 | image, NULL, copy, 168 | 0, 0, 0, 0, 0, 0, 169 | width, height); 170 | break; 171 | } 172 | 173 | g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), copy); 174 | g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL); 175 | 176 | gtk_widget_show (window); 177 | 178 | gtk_main (); 179 | } 180 | -------------------------------------------------------------------------------- /CODING_STYLE: -------------------------------------------------------------------------------- 1 | Pixman coding style. 2 | ==================== 3 | 4 | The pixman coding style is close to cairo's with one exception: braces 5 | go on their own line, rather than on the line of the if/while/for: 6 | 7 | if (condition) 8 | { 9 | do_something(); 10 | do_something_else(); 11 | } 12 | 13 | not 14 | 15 | if (condition) { 16 | do_something(); 17 | do_something_else(); 18 | } 19 | 20 | 21 | 22 | Indentation 23 | =========== 24 | 25 | Each new level is indented four spaces: 26 | 27 | if (condition) 28 | do_something(); 29 | 30 | This may be achieved with space characters or with a combination of 31 | tab characters and space characters. Tab characters are interpreted as 32 | 33 | Advance to the next column which is a multiple of 8. 34 | 35 | 36 | Names 37 | ===== 38 | 39 | In all names, words are separated with underscores. Do not use 40 | CamelCase for any names. 41 | 42 | Macros have ALL_CAPITAL_NAMES 43 | 44 | Type names are in lower case and end with "_t". For example 45 | pixman_image_t. 46 | 47 | Labels, functions and variables have lower case names. 48 | 49 | 50 | Braces 51 | ====== 52 | 53 | Braces always go on their own line: 54 | 55 | if (condition) 56 | { 57 | do_this (); 58 | do_that (); 59 | } 60 | else 61 | { 62 | do_the_other (); 63 | } 64 | 65 | Rules for braces and substatements of if/while/for/do: 66 | 67 | * If a substatement spans multiple lines, then there must be braces 68 | around it. 69 | 70 | * If the condition of an if/while/for spans multiple lines, then 71 | braces must be used for the substatements. 72 | 73 | * If one substatement of an if statement has braces, then the other 74 | must too. 75 | 76 | * Otherwise, don't add braces. 77 | 78 | 79 | Comments 80 | ======== 81 | 82 | For comments either like this: 83 | 84 | /* One line comment */ 85 | 86 | or like this: 87 | 88 | /* This is a multi-line comment 89 | * 90 | * It extends over multiple lines 91 | */ 92 | 93 | Generally comments should say things that aren't clear from the code 94 | itself. If too many comments say obvious things, then people will just 95 | stop reading all comments, including the good ones. 96 | 97 | 98 | Whitespace 99 | ========== 100 | 101 | * Put a single space after commas 102 | 103 | * Put spaces around arithmetic operators such a +, -, *, /: 104 | 105 | y * stride + x 106 | 107 | x / unit_x 108 | 109 | * Do not put spaces after the address-of operator, the * when used as 110 | a pointer derefernce or the ! and ~ operators: 111 | 112 | &foo; 113 | 114 | ~0x00000000 115 | 116 | !condition 117 | 118 | *result = 100 119 | 120 | * Break up long lines (> ~80 characters) and use whitespace to align 121 | things nicely. This is one way: 122 | 123 | some_very_long_function name ( 124 | implementation, op, src, mask, dest, 125 | src_x, src_y, mask_x, mask_y, dest_x, dest_y, 126 | width, height); 127 | 128 | This is another: 129 | 130 | some_very_long_function_name (implementation, op, 131 | src, mask, dest, 132 | src_x, src_y, 133 | mask_x, mask_y, 134 | dest_x, dest_y, 135 | width, height); 136 | 137 | * Separate logically distinct chunks with a single newline. This 138 | obviously applies between functions, but also applies within a 139 | function or block or structure definition. 140 | 141 | * Use a newline after a block of variable declarations. 142 | 143 | * Use a single space before a left parenthesis, except where the 144 | standard will not allow it, (eg. when defining a parameterized macro). 145 | 146 | * Don't eliminate newlines just because things would still fit on one 147 | line. This breaks the expected visual structure of the code making 148 | it much harder to read and understand: 149 | 150 | if (condition) foo (); else bar (); /* Yuck! */ 151 | 152 | 153 | Function Definitions 154 | ==================== 155 | 156 | Function definitions should take the following form: 157 | 158 | void 159 | my_function (int argument) 160 | { 161 | do_my_things (); 162 | } 163 | 164 | If all the parameters to a function fit naturally on one line, format 165 | them that way. Otherwise, put one argument on each line, adding 166 | whitespace so that the parameter names are aligned with each other. 167 | 168 | I.e., do either this: 169 | 170 | void 171 | short_arguments (const char *str, int x, int y, int z) 172 | { 173 | } 174 | 175 | or this: 176 | 177 | void 178 | long_arguments (const char *char_star_arg, 179 | int int_arg, 180 | double *double_star_arg, 181 | double double_arg) 182 | { 183 | } 184 | 185 | 186 | Mode lines 187 | ========== 188 | 189 | Given the rules above, what is the best way to simplify one's life as 190 | a code monkey? Get your editor to do most of the tedious work of 191 | beautifying your code! 192 | 193 | As a reward for reading this far, here are some mode lines for the more 194 | popular editors: 195 | /* 196 | * vim:sw=4:sts=4:ts=8:tw=78:fo=tcroq:cindent:cino=\:0,(0 197 | * vim:isk=a-z,A-Z,48-57,_,.,-,> 198 | */ 199 | 200 | -------------------------------------------------------------------------------- /pixman/pixman-noop.c: -------------------------------------------------------------------------------- 1 | /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ 2 | /* 3 | * Copyright © 2011 Red Hat, Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice (including the next 13 | * paragraph) shall be included in all copies or substantial portions of the 14 | * Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | * DEALINGS IN THE SOFTWARE. 23 | */ 24 | #ifdef HAVE_CONFIG_H 25 | #include 26 | #endif 27 | #include 28 | #include 29 | #include "pixman-private.h" 30 | #include "pixman-combine32.h" 31 | #include "pixman-inlines.h" 32 | 33 | static void 34 | noop_composite (pixman_implementation_t *imp, 35 | pixman_composite_info_t *info) 36 | { 37 | return; 38 | } 39 | 40 | static uint32_t * 41 | noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask) 42 | { 43 | uint32_t *result = iter->buffer; 44 | 45 | iter->buffer += iter->image->bits.rowstride; 46 | 47 | return result; 48 | } 49 | 50 | static void 51 | noop_init_solid_narrow (pixman_iter_t *iter, 52 | const pixman_iter_info_t *info) 53 | { 54 | pixman_image_t *image = iter->image; 55 | uint32_t *buffer = iter->buffer; 56 | uint32_t *end = buffer + iter->width; 57 | uint32_t color; 58 | 59 | if (iter->image->type == SOLID) 60 | color = image->solid.color_32; 61 | else 62 | color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); 63 | 64 | while (buffer < end) 65 | *(buffer++) = color; 66 | } 67 | 68 | static void 69 | noop_init_solid_wide (pixman_iter_t *iter, 70 | const pixman_iter_info_t *info) 71 | { 72 | pixman_image_t *image = iter->image; 73 | argb_t *buffer = (argb_t *)iter->buffer; 74 | argb_t *end = buffer + iter->width; 75 | argb_t color; 76 | 77 | if (iter->image->type == SOLID) 78 | color = image->solid.color_float; 79 | else 80 | color = image->bits.fetch_pixel_float (&image->bits, 0, 0); 81 | 82 | while (buffer < end) 83 | *(buffer++) = color; 84 | } 85 | 86 | static void 87 | noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info) 88 | { 89 | pixman_image_t *image = iter->image; 90 | 91 | iter->buffer = 92 | image->bits.bits + iter->y * image->bits.rowstride + iter->x; 93 | } 94 | 95 | static void 96 | dest_write_back_direct (pixman_iter_t *iter) 97 | { 98 | iter->buffer += iter->image->bits.rowstride; 99 | } 100 | 101 | static const pixman_iter_info_t noop_iters[] = 102 | { 103 | /* Source iters */ 104 | { PIXMAN_any, 105 | 0, ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_SRC, 106 | NULL, 107 | _pixman_iter_get_scanline_noop, 108 | NULL 109 | }, 110 | { PIXMAN_solid, 111 | FAST_PATH_NO_ALPHA_MAP, ITER_NARROW | ITER_SRC, 112 | noop_init_solid_narrow, 113 | _pixman_iter_get_scanline_noop, 114 | NULL, 115 | }, 116 | { PIXMAN_solid, 117 | FAST_PATH_NO_ALPHA_MAP, ITER_WIDE | ITER_SRC, 118 | noop_init_solid_wide, 119 | _pixman_iter_get_scanline_noop, 120 | NULL 121 | }, 122 | { PIXMAN_a8r8g8b8, 123 | FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | 124 | FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, 125 | ITER_NARROW | ITER_SRC, 126 | noop_init_direct_buffer, 127 | noop_get_scanline, 128 | NULL 129 | }, 130 | /* Dest iters */ 131 | { PIXMAN_a8r8g8b8, 132 | FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST, 133 | noop_init_direct_buffer, 134 | _pixman_iter_get_scanline_noop, 135 | dest_write_back_direct 136 | }, 137 | { PIXMAN_x8r8g8b8, 138 | FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST | ITER_LOCALIZED_ALPHA, 139 | noop_init_direct_buffer, 140 | _pixman_iter_get_scanline_noop, 141 | dest_write_back_direct 142 | }, 143 | { PIXMAN_null }, 144 | }; 145 | 146 | static const pixman_fast_path_t noop_fast_paths[] = 147 | { 148 | { PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite }, 149 | { PIXMAN_OP_NONE }, 150 | }; 151 | 152 | pixman_implementation_t * 153 | _pixman_implementation_create_noop (pixman_implementation_t *fallback) 154 | { 155 | pixman_implementation_t *imp = 156 | _pixman_implementation_create (fallback, noop_fast_paths); 157 | 158 | imp->iter_info = noop_iters; 159 | 160 | return imp; 161 | } 162 | -------------------------------------------------------------------------------- /pixman/pixman-edge-imp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2004 Keith Packard 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that 7 | * copyright notice and this permission notice appear in supporting 8 | * documentation, and that the name of Keith Packard not be used in 9 | * advertising or publicity pertaining to distribution of the software without 10 | * specific, written prior permission. Keith Packard makes no 11 | * representations about the suitability of this software for any purpose. It 12 | * is provided "as is" without express or implied warranty. 13 | * 14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 | * PERFORMANCE OF THIS SOFTWARE. 21 | */ 22 | 23 | #ifndef rasterize_span 24 | #endif 25 | 26 | static void 27 | RASTERIZE_EDGES (pixman_image_t *image, 28 | pixman_edge_t *l, 29 | pixman_edge_t *r, 30 | pixman_fixed_t t, 31 | pixman_fixed_t b) 32 | { 33 | pixman_fixed_t y = t; 34 | uint32_t *line; 35 | uint32_t *buf = (image)->bits.bits; 36 | int stride = (image)->bits.rowstride; 37 | int width = (image)->bits.width; 38 | 39 | line = buf + pixman_fixed_to_int (y) * stride; 40 | 41 | for (;;) 42 | { 43 | pixman_fixed_t lx; 44 | pixman_fixed_t rx; 45 | int lxi; 46 | int rxi; 47 | 48 | lx = l->x; 49 | rx = r->x; 50 | #if N_BITS == 1 51 | /* For the non-antialiased case, round the coordinates up, in effect 52 | * sampling just slightly to the left of the pixel. This is so that 53 | * when the sample point lies exactly on the line, we round towards 54 | * north-west. 55 | * 56 | * (The AA case does a similar adjustment in RENDER_SAMPLES_X) 57 | */ 58 | lx += X_FRAC_FIRST(1) - pixman_fixed_e; 59 | rx += X_FRAC_FIRST(1) - pixman_fixed_e; 60 | #endif 61 | /* clip X */ 62 | if (lx < 0) 63 | lx = 0; 64 | if (pixman_fixed_to_int (rx) >= width) 65 | #if N_BITS == 1 66 | rx = pixman_int_to_fixed (width); 67 | #else 68 | /* Use the last pixel of the scanline, covered 100%. 69 | * We can't use the first pixel following the scanline, 70 | * because accessing it could result in a buffer overrun. 71 | */ 72 | rx = pixman_int_to_fixed (width) - 1; 73 | #endif 74 | 75 | /* Skip empty (or backwards) sections */ 76 | if (rx > lx) 77 | { 78 | 79 | /* Find pixel bounds for span */ 80 | lxi = pixman_fixed_to_int (lx); 81 | rxi = pixman_fixed_to_int (rx); 82 | 83 | #if N_BITS == 1 84 | { 85 | 86 | #define LEFT_MASK(x) \ 87 | (((x) & 0x1f) ? \ 88 | SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0) 89 | #define RIGHT_MASK(x) \ 90 | (((32 - (x)) & 0x1f) ? \ 91 | SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0) 92 | 93 | #define MASK_BITS(x,w,l,n,r) { \ 94 | n = (w); \ 95 | r = RIGHT_MASK ((x) + n); \ 96 | l = LEFT_MASK (x); \ 97 | if (l) { \ 98 | n -= 32 - ((x) & 0x1f); \ 99 | if (n < 0) { \ 100 | n = 0; \ 101 | l &= r; \ 102 | r = 0; \ 103 | } \ 104 | } \ 105 | n >>= 5; \ 106 | } 107 | 108 | uint32_t *a = line; 109 | uint32_t startmask; 110 | uint32_t endmask; 111 | int nmiddle; 112 | int width = rxi - lxi; 113 | int x = lxi; 114 | 115 | a += x >> 5; 116 | x &= 0x1f; 117 | 118 | MASK_BITS (x, width, startmask, nmiddle, endmask); 119 | 120 | if (startmask) { 121 | WRITE(image, a, READ(image, a) | startmask); 122 | a++; 123 | } 124 | while (nmiddle--) 125 | WRITE(image, a++, 0xffffffff); 126 | if (endmask) 127 | WRITE(image, a, READ(image, a) | endmask); 128 | } 129 | #else 130 | { 131 | DEFINE_ALPHA(line,lxi); 132 | int lxs; 133 | int rxs; 134 | 135 | /* Sample coverage for edge pixels */ 136 | lxs = RENDER_SAMPLES_X (lx, N_BITS); 137 | rxs = RENDER_SAMPLES_X (rx, N_BITS); 138 | 139 | /* Add coverage across row */ 140 | if (lxi == rxi) 141 | { 142 | ADD_ALPHA (rxs - lxs); 143 | } 144 | else 145 | { 146 | int xi; 147 | 148 | ADD_ALPHA (N_X_FRAC(N_BITS) - lxs); 149 | STEP_ALPHA; 150 | for (xi = lxi + 1; xi < rxi; xi++) 151 | { 152 | ADD_ALPHA (N_X_FRAC(N_BITS)); 153 | STEP_ALPHA; 154 | } 155 | ADD_ALPHA (rxs); 156 | } 157 | } 158 | #endif 159 | } 160 | 161 | if (y == b) 162 | break; 163 | 164 | #if N_BITS > 1 165 | if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS)) 166 | { 167 | RENDER_EDGE_STEP_SMALL (l); 168 | RENDER_EDGE_STEP_SMALL (r); 169 | y += STEP_Y_SMALL(N_BITS); 170 | } 171 | else 172 | #endif 173 | { 174 | RENDER_EDGE_STEP_BIG (l); 175 | RENDER_EDGE_STEP_BIG (r); 176 | y += STEP_Y_BIG(N_BITS); 177 | line += stride; 178 | } 179 | } 180 | } 181 | 182 | #undef rasterize_span 183 | -------------------------------------------------------------------------------- /pixman/pixman-arm-simd-asm-scaled.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Mozilla Corporation 3 | * Copyright © 2010 Nokia Corporation 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of Mozilla Corporation not be used in 10 | * advertising or publicity pertaining to distribution of the software without 11 | * specific, written prior permission. Mozilla Corporation makes no 12 | * representations about the suitability of this software for any purpose. It 13 | * is provided "as is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 20 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 21 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 22 | * SOFTWARE. 23 | * 24 | * Author: Jeff Muizelaar (jeff@infidigm.net) 25 | * 26 | */ 27 | 28 | /* Prevent the stack from becoming executable */ 29 | #if defined(__linux__) && defined(__ELF__) 30 | .section .note.GNU-stack,"",%progbits 31 | #endif 32 | 33 | .text 34 | .arch armv6 35 | .object_arch armv4 36 | .arm 37 | .altmacro 38 | .p2align 2 39 | 40 | #include "pixman-arm-asm.h" 41 | 42 | /* 43 | * Note: This code is only using armv5te instructions (not even armv6), 44 | * but is scheduled for ARM Cortex-A8 pipeline. So it might need to 45 | * be split into a few variants, tuned for each microarchitecture. 46 | * 47 | * TODO: In order to get good performance on ARM9/ARM11 cores (which don't 48 | * have efficient write combining), it needs to be changed to use 16-byte 49 | * aligned writes using STM instruction. 50 | * 51 | * Nearest scanline scaler macro template uses the following arguments: 52 | * fname - name of the function to generate 53 | * bpp_shift - (1 << bpp_shift) is the size of pixel in bytes 54 | * t - type suffix for LDR/STR instructions 55 | * prefetch_distance - prefetch in the source image by that many 56 | * pixels ahead 57 | * prefetch_braking_distance - stop prefetching when that many pixels are 58 | * remaining before the end of scanline 59 | */ 60 | 61 | .macro generate_nearest_scanline_func fname, bpp_shift, t, \ 62 | prefetch_distance, \ 63 | prefetch_braking_distance 64 | 65 | pixman_asm_function fname 66 | W .req r0 67 | DST .req r1 68 | SRC .req r2 69 | VX .req r3 70 | UNIT_X .req ip 71 | TMP1 .req r4 72 | TMP2 .req r5 73 | VXMASK .req r6 74 | PF_OFFS .req r7 75 | SRC_WIDTH_FIXED .req r8 76 | 77 | ldr UNIT_X, [sp] 78 | push {r4, r5, r6, r7, r8, r10} 79 | mvn VXMASK, #((1 << bpp_shift) - 1) 80 | ldr SRC_WIDTH_FIXED, [sp, #28] 81 | 82 | /* define helper macro */ 83 | .macro scale_2_pixels 84 | ldr&t TMP1, [SRC, TMP1] 85 | and TMP2, VXMASK, VX, asr #(16 - bpp_shift) 86 | adds VX, VX, UNIT_X 87 | str&t TMP1, [DST], #(1 << bpp_shift) 88 | 9: subpls VX, VX, SRC_WIDTH_FIXED 89 | bpl 9b 90 | 91 | ldr&t TMP2, [SRC, TMP2] 92 | and TMP1, VXMASK, VX, asr #(16 - bpp_shift) 93 | adds VX, VX, UNIT_X 94 | str&t TMP2, [DST], #(1 << bpp_shift) 95 | 9: subpls VX, VX, SRC_WIDTH_FIXED 96 | bpl 9b 97 | .endm 98 | 99 | /* now do the scaling */ 100 | and TMP1, VXMASK, VX, asr #(16 - bpp_shift) 101 | adds VX, VX, UNIT_X 102 | 9: subpls VX, VX, SRC_WIDTH_FIXED 103 | bpl 9b 104 | subs W, W, #(8 + prefetch_braking_distance) 105 | blt 2f 106 | /* calculate prefetch offset */ 107 | mov PF_OFFS, #prefetch_distance 108 | mla PF_OFFS, UNIT_X, PF_OFFS, VX 109 | 1: /* main loop, process 8 pixels per iteration with prefetch */ 110 | pld [SRC, PF_OFFS, asr #(16 - bpp_shift)] 111 | add PF_OFFS, UNIT_X, lsl #3 112 | scale_2_pixels 113 | scale_2_pixels 114 | scale_2_pixels 115 | scale_2_pixels 116 | subs W, W, #8 117 | bge 1b 118 | 2: 119 | subs W, W, #(4 - 8 - prefetch_braking_distance) 120 | blt 2f 121 | 1: /* process the remaining pixels */ 122 | scale_2_pixels 123 | scale_2_pixels 124 | subs W, W, #4 125 | bge 1b 126 | 2: 127 | tst W, #2 128 | beq 2f 129 | scale_2_pixels 130 | 2: 131 | tst W, #1 132 | ldrne&t TMP1, [SRC, TMP1] 133 | strne&t TMP1, [DST] 134 | /* cleanup helper macro */ 135 | .purgem scale_2_pixels 136 | .unreq DST 137 | .unreq SRC 138 | .unreq W 139 | .unreq VX 140 | .unreq UNIT_X 141 | .unreq TMP1 142 | .unreq TMP2 143 | .unreq VXMASK 144 | .unreq PF_OFFS 145 | .unreq SRC_WIDTH_FIXED 146 | /* return */ 147 | pop {r4, r5, r6, r7, r8, r10} 148 | bx lr 149 | .endfunc 150 | .endm 151 | 152 | generate_nearest_scanline_func \ 153 | pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6, 1, h, 80, 32 154 | 155 | generate_nearest_scanline_func \ 156 | pixman_scaled_nearest_scanline_8888_8888_SRC_asm_armv6, 2, , 48, 32 157 | -------------------------------------------------------------------------------- /test/gradient-crash-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | int 6 | main (int argc, char **argv) 7 | { 8 | #define WIDTH 400 9 | #define HEIGHT 200 10 | 11 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 12 | pixman_image_t *src_img; 13 | pixman_image_t *dest_img; 14 | int i, j, k, p; 15 | 16 | typedef struct 17 | { 18 | pixman_point_fixed_t p0; 19 | pixman_point_fixed_t p1; 20 | } point_pair_t; 21 | 22 | pixman_gradient_stop_t onestop[1] = 23 | { 24 | { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, 25 | }; 26 | 27 | pixman_gradient_stop_t subsetstops[2] = 28 | { 29 | { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, 30 | { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, 31 | }; 32 | 33 | pixman_gradient_stop_t stops01[2] = 34 | { 35 | { pixman_int_to_fixed (0), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, 36 | { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } } 37 | }; 38 | 39 | point_pair_t point_pairs [] = 40 | { { { pixman_double_to_fixed (0), 0 }, 41 | { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } }, 42 | { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) }, 43 | { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } } 44 | }; 45 | 46 | pixman_transform_t transformations[] = { 47 | { 48 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, 49 | { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, 50 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 51 | } 52 | }, 53 | { 54 | { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), }, 55 | { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 56 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 57 | } 58 | }, 59 | { 60 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 61 | { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 62 | { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) } 63 | } 64 | }, 65 | { 66 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 67 | { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 68 | { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) } 69 | } 70 | }, 71 | { 72 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 73 | { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 74 | { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 75 | } 76 | }, 77 | { 78 | { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (3), }, 79 | { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, 80 | { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 81 | } 82 | }, 83 | }; 84 | 85 | pixman_fixed_t r_inner; 86 | pixman_fixed_t r_outer; 87 | 88 | enable_divbyzero_exceptions(); 89 | 90 | for (i = 0; i < WIDTH * HEIGHT; ++i) 91 | dest[i] = 0x4f00004f; /* pale blue */ 92 | 93 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 94 | WIDTH, HEIGHT, 95 | dest, 96 | WIDTH * 4); 97 | 98 | r_inner = 0; 99 | r_outer = pixman_double_to_fixed (50.0); 100 | 101 | for (i = 0; i < 3; ++i) 102 | { 103 | pixman_gradient_stop_t *stops; 104 | int num_stops; 105 | 106 | if (i == 0) 107 | { 108 | stops = onestop; 109 | num_stops = ARRAY_LENGTH (onestop); 110 | } 111 | else if (i == 1) 112 | { 113 | stops = subsetstops; 114 | num_stops = ARRAY_LENGTH (subsetstops); 115 | } 116 | else 117 | { 118 | stops = stops01; 119 | num_stops = ARRAY_LENGTH (stops01); 120 | } 121 | 122 | for (j = 0; j < 3; ++j) 123 | { 124 | for (p = 0; p < ARRAY_LENGTH (point_pairs); ++p) 125 | { 126 | point_pair_t *pair = &(point_pairs[p]); 127 | 128 | if (j == 0) 129 | src_img = pixman_image_create_conical_gradient (&(pair->p0), r_inner, 130 | stops, num_stops); 131 | else if (j == 1) 132 | src_img = pixman_image_create_radial_gradient (&(pair->p0), &(pair->p1), 133 | r_inner, r_outer, 134 | stops, num_stops); 135 | else 136 | src_img = pixman_image_create_linear_gradient (&(pair->p0), &(pair->p1), 137 | stops, num_stops); 138 | 139 | for (k = 0; k < ARRAY_LENGTH (transformations); ++k) 140 | { 141 | pixman_image_set_transform (src_img, &transformations[k]); 142 | 143 | pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE); 144 | pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img, 145 | 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); 146 | } 147 | 148 | pixman_image_unref (src_img); 149 | } 150 | 151 | } 152 | } 153 | 154 | pixman_image_unref (dest_img); 155 | free (dest); 156 | 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = pixman demos test 2 | 3 | pkgconfigdir=$(libdir)/pkgconfig 4 | pkgconfig_DATA=pixman-1.pc 5 | 6 | $(pkgconfig_DATA): pixman-1.pc.in 7 | 8 | snapshot: 9 | distdir="$(distdir)-`date '+%Y%m%d'`"; \ 10 | test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \ 11 | $(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist 12 | 13 | GPGKEY=3892336E 14 | USERNAME=$$USER 15 | RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi) 16 | RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org 17 | RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s 18 | RELEASE_CAIRO_URL = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s 19 | RELEASE_XORG_URL = http://xorg.freedesktop.org/archive/individual/lib 20 | RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org 21 | RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib 22 | RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org 23 | 24 | EXTRA_DIST = \ 25 | Makefile.win32 \ 26 | Makefile.win32.common 27 | 28 | tar_gz = $(PACKAGE)-$(VERSION).tar.gz 29 | tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 30 | 31 | sha1_tgz = $(tar_gz).sha1 32 | md5_tgz = $(tar_gz).md5 33 | 34 | sha1_tbz2 = $(tar_bz2).sha1 35 | md5_tbz2 = $(tar_bz2).md5 36 | 37 | gpg_file = $(sha1_tgz).asc 38 | 39 | $(sha1_tgz): $(tar_gz) 40 | sha1sum $^ > $@ 41 | 42 | $(md5_tgz): $(tar_gz) 43 | md5sum $^ > $@ 44 | 45 | $(sha1_tbz2): $(tar_bz2) 46 | sha1sum $^ > $@ 47 | 48 | $(md5_tbz2): $(tar_bz2) 49 | md5sum $^ > $@ 50 | 51 | $(gpg_file): $(sha1_tgz) 52 | @echo "Please enter your GPG password to sign the checksum." 53 | gpg --armor --sign $^ 54 | 55 | HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2) 56 | 57 | release-verify-newer: 58 | @echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..." 59 | @ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \ 60 | || (echo "Ouch." && echo "Found: $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)/$(tar_gz)" \ 61 | && echo "Refusing to try to generate a new release of the same name." \ 62 | && false) 63 | @ssh $(RELEASE_CAIRO_HOST) test ! -e $(RELEASE_CAIRO_DIR)/$(tar_gz) \ 64 | || (echo "Ouch." && echo "Found: $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)/$(tar_gz)" \ 65 | && echo "Refusing to try to generate a new release of the same name." \ 66 | && false) 67 | @echo "Good." 68 | 69 | release-remove-old: 70 | $(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file) 71 | 72 | ensure-prev: 73 | @if [[ "$(PREV)" == "" ]]; then \ 74 | echo "" && \ 75 | echo "You must set the PREV variable on the make command line to" && \ 76 | echo "the last version." && \ 77 | echo "" && \ 78 | echo "For example:" && \ 79 | echo " make PREV=0.7.3" && \ 80 | echo "" && \ 81 | false; \ 82 | fi 83 | 84 | release-check: ensure-prev release-verify-newer release-remove-old distcheck 85 | 86 | release-tag: 87 | git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION) 88 | 89 | release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(gpg_file) 90 | scp $(tar_gz) $(sha1_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) 91 | scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) 92 | ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)" 93 | 94 | 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) 95 | 96 | release-publish-message: $(HASHFILES) ensure-prev 97 | @echo "Please follow the instructions in RELEASING to push stuff out and" 98 | @echo "send out the announcement mails. Here is the excerpt you need:" 99 | @echo "" 100 | @echo "Lists: $(RELEASE_ANNOUNCE_LIST)" 101 | @echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available" 102 | @echo "============================== CUT HERE ==============================" 103 | @echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)" 104 | @echo "" 105 | @echo "tar.gz:" 106 | @echo " $(RELEASE_CAIRO_URL)/$(tar_gz)" 107 | @echo " $(RELEASE_XORG_URL)/$(tar_gz)" 108 | @echo "" 109 | @echo "tar.bz2:" 110 | @echo " $(RELEASE_XORG_URL)/$(tar_bz2)" 111 | @echo "" 112 | @echo "Hashes:" 113 | @echo -n " MD5: " 114 | @cat $(md5_tgz) 115 | @echo -n " MD5: " 116 | @cat $(md5_tbz2) 117 | @echo -n " SHA1: " 118 | @cat $(sha1_tgz) 119 | @echo -n " SHA1: " 120 | @cat $(sha1_tbz2) 121 | @echo "" 122 | @echo "GPG signature:" 123 | @echo " $(RELEASE_CAIRO_URL)/$(gpg_file)" 124 | @echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)" 125 | @echo "" 126 | @echo "Git:" 127 | @echo " git://git.freedesktop.org/git/pixman" 128 | @echo " tag: $(PACKAGE)-$(VERSION)" 129 | @echo "" 130 | @echo "Log:" 131 | @git log --no-merges "$(PACKAGE)-$(PREV)".."$(PACKAGE)-$(VERSION)" | git shortlog | awk '{ printf "\t"; print ; }' | cut -b1-80 132 | @echo "============================== CUT HERE ==============================" 133 | @echo "" 134 | 135 | release-publish: release-upload release-tag release-publish-message 136 | 137 | .PHONY: release-upload release-publish release-publish-message release-tag 138 | -------------------------------------------------------------------------------- /pixman/rounding.txt: -------------------------------------------------------------------------------- 1 | *** General notes about rounding 2 | 3 | Suppose a function is sampled at positions [k + o] where k is an 4 | integer and o is a fractional offset 0 <= o < 1. 5 | 6 | To round a value to the nearest sample, breaking ties by rounding up, 7 | we can do this: 8 | 9 | round(x) = floor(x - o + 0.5) + o 10 | 11 | That is, first subtract o to let us pretend that the samples are at 12 | integer coordinates, then add 0.5 and floor to round to nearest 13 | integer, then add the offset back in. 14 | 15 | To break ties by rounding down: 16 | 17 | round(x) = ceil(x - o - 0.5) + o 18 | 19 | or if we have an epsilon value: 20 | 21 | round(x) = floor(x - o + 0.5 - e) + o 22 | 23 | To always round *up* to the next sample: 24 | 25 | round_up(x) = ceil(x - o) + o 26 | 27 | To always round *down* to the previous sample: 28 | 29 | round_down(x) = floor(x - o) + o 30 | 31 | If a set of samples is stored in an array, you get from the sample 32 | position to an index by subtracting the position of the first sample 33 | in the array: 34 | 35 | index(s) = s - first_sample 36 | 37 | 38 | *** Application to pixman 39 | 40 | In pixman, images are sampled with o = 0.5, that is, pixels are 41 | located midways between integers. We usually break ties by rounding 42 | down (i.e., "round towards north-west"). 43 | 44 | 45 | -- NEAREST filtering: 46 | 47 | The NEAREST filter simply picks the closest pixel to the given 48 | position: 49 | 50 | round(x) = floor(x - 0.5 + 0.5 - e) + 0.5 = floor (x - e) + 0.5 51 | 52 | The first sample of a pixman image has position 0.5, so to find the 53 | index in the pixel array, we have to subtract 0.5: 54 | 55 | floor (x - e) + 0.5 - 0.5 = floor (x - e). 56 | 57 | Therefore a 16.16 fixed-point image location is turned into a pixel 58 | value with NEAREST filtering by doing this: 59 | 60 | pixels[((y - e) >> 16) * stride + ((x - e) >> 16)] 61 | 62 | where stride is the number of pixels allocated per scanline and e = 63 | 0x0001. 64 | 65 | 66 | -- CONVOLUTION filtering: 67 | 68 | A convolution matrix is considered a sampling of a function f at 69 | values surrounding 0. For example, this convolution matrix: 70 | 71 | [a, b, c, d] 72 | 73 | is interpreted as the values of a function f: 74 | 75 | a = f(-1.5) 76 | b = f(-0.5) 77 | c = f(0.5) 78 | d = f(1.5) 79 | 80 | The sample offset in this case is o = 0.5 and the first sample has 81 | position s0 = -1.5. If the matrix is: 82 | 83 | [a, b, c, d, e] 84 | 85 | the sample offset is o = 0 and the first sample has position s0 = 86 | -2.0. In general we have 87 | 88 | s0 = (- width / 2.0 + 0.5). 89 | 90 | and 91 | 92 | o = frac (s0) 93 | 94 | To evaluate f at a position between the samples, we round to the 95 | closest sample, and then we subtract the position of the first sample 96 | to get the index in the matrix: 97 | 98 | f(t) = matrix[floor(t - o + 0.5) + o - s0] 99 | 100 | Note that in this case we break ties by rounding up. 101 | 102 | If we write s0 = m + o, where m is an integer, this is equivalent to 103 | 104 | f(t) = matrix[floor(t - o + 0.5) + o - (m + o)] 105 | = matrix[floor(t - o + 0.5 - m) + o - o] 106 | = matrix[floor(t - s0 + 0.5)] 107 | 108 | The convolution filter in pixman positions f such that 0 aligns with 109 | the given position x. For a given pixel x0 in the image, the closest 110 | sample of f is then computed by taking (x - x0) and rounding that to 111 | the closest index: 112 | 113 | i = floor ((x0 - x) - s0 + 0.5) 114 | 115 | To perform the convolution, we have to find the first pixel x0 whose 116 | corresponding sample has index 0. We can write x0 = k + 0.5, where k 117 | is an integer: 118 | 119 | 0 = floor(k + 0.5 - x - s0 + 0.5) 120 | 121 | = k + floor(1 - x - s0) 122 | 123 | = k - ceil(x + s0 - 1) 124 | 125 | = k - floor(x + s0 - e) 126 | 127 | = k - floor(x - (width - 1) / 2.0 - e) 128 | 129 | And so the final formula for the index k of x0 in the image is: 130 | 131 | k = floor(x - (width - 1) / 2.0 - e) 132 | 133 | Computing the result is then simply a matter of convolving all the 134 | pixels starting at k with all the samples in the matrix. 135 | 136 | 137 | --- SEPARABLE_CONVOLUTION 138 | 139 | For this filter, x is first rounded to one of n regularly spaced 140 | subpixel positions. This subpixel position determines which of n 141 | convolution matrices is being used. 142 | 143 | Then, as in a regular convolution filter, the first pixel to be used 144 | is determined: 145 | 146 | k = floor (x - (width - 1) / 2.0 - e) 147 | 148 | and then the image pixels starting there are convolved with the chosen 149 | matrix. If we write x = xi + frac, where xi is an integer, we get 150 | 151 | k = xi + floor (frac - (width - 1) / 2.0 - e) 152 | 153 | so the location of k relative to x is given by: 154 | 155 | (k + 0.5 - x) = xi + floor (frac - (width - 1) / 2.0 - e) + 0.5 - x 156 | 157 | = floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac 158 | 159 | which means the contents of the matrix corresponding to (frac) should 160 | contain width samplings of the function, with the first sample at: 161 | 162 | floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac 163 | = ceil (frac - width / 2.0 - 0.5) + 0.5 - frac 164 | 165 | This filter is called separable because each of the k x k convolution 166 | matrices is specified with two k-wide vectors, one for each dimension, 167 | where each entry in the matrix is computed as the product of the 168 | corresponding entries in the vectors. 169 | -------------------------------------------------------------------------------- /test/check-formats.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | static int 5 | check_op (pixman_op_t op, 6 | pixman_format_code_t src_format, 7 | pixman_format_code_t dest_format) 8 | { 9 | uint32_t src_alpha_mask, src_green_mask; 10 | uint32_t dest_alpha_mask, dest_green_mask; 11 | pixel_checker_t src_checker, dest_checker; 12 | pixman_image_t *si, *di; 13 | uint32_t sa, sg, da, dg; 14 | uint32_t s, d; 15 | int retval = 0; 16 | 17 | pixel_checker_init (&src_checker, src_format); 18 | pixel_checker_init (&dest_checker, dest_format); 19 | 20 | pixel_checker_get_masks ( 21 | &src_checker, &src_alpha_mask, NULL, &src_green_mask, NULL); 22 | pixel_checker_get_masks ( 23 | &dest_checker, &dest_alpha_mask, NULL, &dest_green_mask, NULL); 24 | 25 | /* printf ("masks: %x %x %x %x\n", */ 26 | /* src_alpha_mask, src_green_mask, */ 27 | /* dest_alpha_mask, dest_green_mask); */ 28 | 29 | si = pixman_image_create_bits (src_format, 1, 1, &s, 4); 30 | di = pixman_image_create_bits (dest_format, 1, 1, &d, 4); 31 | 32 | sa = 0; 33 | do 34 | { 35 | sg = 0; 36 | do 37 | { 38 | da = 0; 39 | do 40 | { 41 | dg = 0; 42 | do 43 | { 44 | color_t src_color, dest_color, result_color; 45 | uint32_t orig_d; 46 | 47 | s = sa | sg; 48 | d = da | dg; 49 | 50 | orig_d = d; 51 | 52 | pixel_checker_convert_pixel_to_color (&src_checker, s, &src_color); 53 | pixel_checker_convert_pixel_to_color (&dest_checker, d, &dest_color); 54 | 55 | do_composite (op, &src_color, NULL, &dest_color, &result_color, FALSE); 56 | 57 | 58 | if (!is_little_endian()) 59 | { 60 | s <<= 32 - PIXMAN_FORMAT_BPP (src_format); 61 | d <<= 32 - PIXMAN_FORMAT_BPP (dest_format); 62 | } 63 | 64 | pixman_image_composite32 (op, si, NULL, di, 65 | 0, 0, 0, 0, 0, 0, 1, 1); 66 | 67 | if (!is_little_endian()) 68 | d >>= (32 - PIXMAN_FORMAT_BPP (dest_format)); 69 | 70 | if (!pixel_checker_check (&dest_checker, d, &result_color)) 71 | { 72 | printf ("---- test failed ----\n"); 73 | printf ("operator: %-32s\n", operator_name (op)); 74 | printf ("source: %-12s pixel: %08x\n", format_name (src_format), s); 75 | printf ("dest: %-12s pixel: %08x\n", format_name (dest_format), orig_d); 76 | printf ("got: %-12s pixel: %08x\n", format_name (dest_format), d); 77 | 78 | retval = 1; 79 | } 80 | 81 | dg -= dest_green_mask; 82 | dg &= dest_green_mask; 83 | } 84 | while (dg != 0); 85 | 86 | da -= dest_alpha_mask; 87 | da &= dest_alpha_mask; 88 | } 89 | while (da != 0); 90 | 91 | sg -= src_green_mask; 92 | sg &= src_green_mask; 93 | } 94 | while (sg != 0); 95 | 96 | sa -= src_alpha_mask; 97 | sa &= src_alpha_mask; 98 | } 99 | while (sa != 0); 100 | 101 | pixman_image_unref (si); 102 | pixman_image_unref (di); 103 | 104 | return retval; 105 | } 106 | 107 | int 108 | main (int argc, char **argv) 109 | { 110 | enum { OPTION_OP, OPTION_SRC, OPTION_DEST, LAST_OPTION } option; 111 | pixman_format_code_t src_fmt, dest_fmt; 112 | pixman_op_t op; 113 | 114 | op = PIXMAN_OP_NONE; 115 | src_fmt = PIXMAN_null; 116 | dest_fmt = PIXMAN_null; 117 | 118 | argc--; 119 | argv++; 120 | 121 | for (option = OPTION_OP; option < LAST_OPTION; ++option) 122 | { 123 | char *arg = NULL; 124 | 125 | if (argc) 126 | { 127 | argc--; 128 | arg = *argv++; 129 | } 130 | 131 | switch (option) 132 | { 133 | case OPTION_OP: 134 | if (!arg) 135 | printf (" - missing operator\n"); 136 | else if ((op = operator_from_string (arg)) == PIXMAN_OP_NONE) 137 | printf (" - unknown operator %s\n", arg); 138 | break; 139 | 140 | case OPTION_SRC: 141 | if (!arg) 142 | printf (" - missing source format\n"); 143 | else if ((src_fmt = format_from_string (arg)) == PIXMAN_null) 144 | printf (" - unknown source format %s\n", arg); 145 | break; 146 | 147 | case OPTION_DEST: 148 | if (!arg) 149 | printf (" - missing destination format\n"); 150 | else if ((dest_fmt = format_from_string (arg)) == PIXMAN_null) 151 | printf (" - unknown destination format %s\n", arg); 152 | break; 153 | 154 | default: 155 | assert (0); 156 | break; 157 | } 158 | } 159 | 160 | while (argc--) 161 | { 162 | op = PIXMAN_OP_NONE; 163 | printf (" - unexpected argument: %s\n", *argv++); 164 | } 165 | 166 | if (op == PIXMAN_OP_NONE || src_fmt == PIXMAN_null || dest_fmt == PIXMAN_null) 167 | { 168 | printf ("\nUsage:\n check-formats \n\n"); 169 | list_operators(); 170 | list_formats(); 171 | 172 | return -1; 173 | } 174 | 175 | return check_op (op, src_fmt, dest_fmt); 176 | } 177 | -------------------------------------------------------------------------------- /demos/composite-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pixman.h" 5 | #include "gtk-utils.h" 6 | #include "parrot.c" 7 | 8 | #define WIDTH 80 9 | #define HEIGHT 80 10 | 11 | typedef struct { 12 | const char *name; 13 | pixman_op_t op; 14 | } operator_t; 15 | 16 | static const operator_t operators[] = { 17 | { "CLEAR", PIXMAN_OP_CLEAR }, 18 | { "SRC", PIXMAN_OP_SRC }, 19 | { "DST", PIXMAN_OP_DST }, 20 | { "OVER", PIXMAN_OP_OVER }, 21 | { "OVER_REVERSE", PIXMAN_OP_OVER_REVERSE }, 22 | { "IN", PIXMAN_OP_IN }, 23 | { "IN_REVERSE", PIXMAN_OP_IN_REVERSE }, 24 | { "OUT", PIXMAN_OP_OUT }, 25 | { "OUT_REVERSE", PIXMAN_OP_OUT_REVERSE }, 26 | { "ATOP", PIXMAN_OP_ATOP }, 27 | { "ATOP_REVERSE", PIXMAN_OP_ATOP_REVERSE }, 28 | { "XOR", PIXMAN_OP_XOR }, 29 | { "ADD", PIXMAN_OP_ADD }, 30 | { "SATURATE", PIXMAN_OP_SATURATE }, 31 | 32 | { "MULTIPLY", PIXMAN_OP_MULTIPLY }, 33 | { "SCREEN", PIXMAN_OP_SCREEN }, 34 | { "OVERLAY", PIXMAN_OP_OVERLAY }, 35 | { "DARKEN", PIXMAN_OP_DARKEN }, 36 | { "LIGHTEN", PIXMAN_OP_LIGHTEN }, 37 | { "COLOR_DODGE", PIXMAN_OP_COLOR_DODGE }, 38 | { "COLOR_BURN", PIXMAN_OP_COLOR_BURN }, 39 | { "HARD_LIGHT", PIXMAN_OP_HARD_LIGHT }, 40 | { "SOFT_LIGHT", PIXMAN_OP_SOFT_LIGHT }, 41 | { "DIFFERENCE", PIXMAN_OP_DIFFERENCE }, 42 | { "EXCLUSION", PIXMAN_OP_EXCLUSION }, 43 | { "HSL_HUE", PIXMAN_OP_HSL_HUE }, 44 | { "HSL_SATURATION", PIXMAN_OP_HSL_SATURATION }, 45 | { "HSL_COLOR", PIXMAN_OP_HSL_COLOR }, 46 | { "HSL_LUMINOSITY", PIXMAN_OP_HSL_LUMINOSITY }, 47 | }; 48 | 49 | static uint32_t 50 | reader (const void *src, int size) 51 | { 52 | switch (size) 53 | { 54 | case 1: 55 | return *(uint8_t *)src; 56 | case 2: 57 | return *(uint16_t *)src; 58 | case 4: 59 | return *(uint32_t *)src; 60 | default: 61 | g_assert_not_reached(); 62 | } 63 | } 64 | 65 | static void 66 | writer (void *src, uint32_t value, int size) 67 | { 68 | switch (size) 69 | { 70 | case 1: 71 | *(uint8_t *)src = value; 72 | break; 73 | 74 | case 2: 75 | *(uint16_t *)src = value; 76 | break; 77 | 78 | case 4: 79 | *(uint32_t *)src = value; 80 | break; 81 | 82 | default: 83 | break; 84 | } 85 | } 86 | 87 | int 88 | main (int argc, char **argv) 89 | { 90 | #define d2f pixman_double_to_fixed 91 | 92 | GtkWidget *window, *swindow; 93 | GtkWidget *table; 94 | uint32_t *dest = malloc (WIDTH * HEIGHT * 4); 95 | uint32_t *src = malloc (WIDTH * HEIGHT * 4); 96 | pixman_image_t *gradient, *parrot; 97 | pixman_image_t *dest_img; 98 | pixman_point_fixed_t p1 = { -10 << 16, 10 << 16 }; 99 | pixman_point_fixed_t p2 = { (WIDTH + 10) << 16, (HEIGHT - 10) << 16 }; 100 | uint16_t alpha = 0xdddd; 101 | pixman_gradient_stop_t stops[6] = 102 | { 103 | { d2f (0.0), { 0xf2f2, 0x8787, 0x7d7d, alpha } }, 104 | { d2f (0.22), { 0xf3f3, 0xeaea, 0x8383, alpha } }, 105 | { d2f (0.42), { 0x6b6b, 0xc0c0, 0x7777, alpha } }, 106 | { d2f (0.57), { 0x4b4b, 0xc9c9, 0xf5f5, alpha } }, 107 | { d2f (0.75), { 0x6a6a, 0x7f7f, 0xbebe, alpha } }, 108 | { d2f (1.0), { 0xeded, 0x8282, 0xb0b0, alpha } }, 109 | }; 110 | 111 | int i; 112 | 113 | gtk_init (&argc, &argv); 114 | 115 | window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 116 | 117 | gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); 118 | 119 | g_signal_connect (window, "delete-event", 120 | G_CALLBACK (gtk_main_quit), 121 | NULL); 122 | table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE); 123 | 124 | gradient = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops)); 125 | parrot = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, (uint32_t *)parrot_bits, WIDTH * 4); 126 | 127 | pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD); 128 | 129 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 130 | WIDTH, HEIGHT, 131 | NULL, 132 | WIDTH * 4); 133 | pixman_image_set_accessors (dest_img, reader, writer); 134 | 135 | for (i = 0; i < G_N_ELEMENTS (operators); ++i) 136 | { 137 | GtkWidget *image; 138 | GdkPixbuf *pixbuf; 139 | GtkWidget *vbox; 140 | GtkWidget *label; 141 | 142 | vbox = gtk_vbox_new (FALSE, 0); 143 | 144 | label = gtk_label_new (operators[i].name); 145 | gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6); 146 | gtk_widget_show (label); 147 | 148 | pixman_image_composite (PIXMAN_OP_SRC, gradient, NULL, dest_img, 149 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 150 | pixman_image_composite (operators[i].op, parrot, NULL, dest_img, 151 | 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 152 | pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), 153 | WIDTH, HEIGHT, WIDTH * 4); 154 | image = gtk_image_new_from_pixbuf (pixbuf); 155 | gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0); 156 | gtk_widget_show (image); 157 | 158 | gtk_table_attach_defaults (GTK_TABLE (table), vbox, 159 | i % 6, (i % 6) + 1, i / 6, (i / 6) + 1); 160 | gtk_widget_show (vbox); 161 | 162 | g_object_unref (pixbuf); 163 | } 164 | 165 | pixman_image_unref (gradient); 166 | free (src); 167 | pixman_image_unref (dest_img); 168 | free (dest); 169 | 170 | swindow = gtk_scrolled_window_new (NULL, NULL); 171 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), 172 | GTK_POLICY_AUTOMATIC, 173 | GTK_POLICY_AUTOMATIC); 174 | 175 | gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table); 176 | gtk_widget_show (table); 177 | 178 | gtk_container_add (GTK_CONTAINER (window), swindow); 179 | gtk_widget_show (swindow); 180 | 181 | gtk_widget_show (window); 182 | 183 | gtk_main (); 184 | 185 | return 0; 186 | } 187 | -------------------------------------------------------------------------------- /test/prng-test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Siarhei Siamashka 3 | * 4 | * Based on the public domain implementation of small noncryptographic PRNG 5 | * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice (including the next 15 | * paragraph) shall be included in all copies or substantial portions of the 16 | * Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include "utils-prng.h" 30 | #include "utils.h" 31 | 32 | /* The original code from http://www.burtleburtle.net/bob/rand/smallprng.html */ 33 | 34 | typedef uint32_t u4; 35 | typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx; 36 | 37 | #define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) 38 | u4 ranval( ranctx *x ) { 39 | u4 e = x->a - rot(x->b, 27); 40 | x->a = x->b ^ rot(x->c, 17); 41 | x->b = x->c + x->d; 42 | x->c = x->d + e; 43 | x->d = e + x->a; 44 | return x->d; 45 | } 46 | 47 | void raninit( ranctx *x, u4 seed ) { 48 | u4 i; 49 | x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; 50 | for (i=0; i<20; ++i) { 51 | (void)ranval(x); 52 | } 53 | } 54 | 55 | /*****************************************************************************/ 56 | 57 | #define BUFSIZE (8 * 1024 * 1024) 58 | #define N 50 59 | 60 | void bench (void) 61 | { 62 | double t1, t2; 63 | int i; 64 | prng_t prng; 65 | uint8_t *buf = aligned_malloc (16, BUFSIZE + 1); 66 | 67 | prng_srand_r (&prng, 1234); 68 | t1 = gettime(); 69 | for (i = 0; i < N; i++) 70 | prng_randmemset_r (&prng, buf, BUFSIZE, 0); 71 | t2 = gettime(); 72 | printf ("aligned randmemset : %.2f MB/s\n", 73 | (double)BUFSIZE * N / 1000000. / (t2 - t1)); 74 | 75 | t1 = gettime(); 76 | for (i = 0; i < N; i++) 77 | prng_randmemset_r (&prng, buf + 1, BUFSIZE, 0); 78 | t2 = gettime(); 79 | printf ("unaligned randmemset : %.2f MB/s\n", 80 | (double)BUFSIZE * N / 1000000. / (t2 - t1)); 81 | 82 | t1 = gettime(); 83 | for (i = 0; i < N; i++) 84 | { 85 | prng_randmemset_r (&prng, buf, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); 86 | } 87 | t2 = gettime (); 88 | printf ("aligned randmemset (more 00 and FF) : %.2f MB/s\n", 89 | (double)BUFSIZE * N / 1000000. / (t2 - t1)); 90 | 91 | t1 = gettime(); 92 | for (i = 0; i < N; i++) 93 | { 94 | prng_randmemset_r (&prng, buf + 1, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); 95 | } 96 | t2 = gettime (); 97 | printf ("unaligned randmemset (more 00 and FF) : %.2f MB/s\n", 98 | (double)BUFSIZE * N / 1000000. / (t2 - t1)); 99 | 100 | free (buf); 101 | } 102 | 103 | #define SMALLBUFSIZE 100 104 | 105 | int main (int argc, char *argv[]) 106 | { 107 | const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] = 108 | { 109 | 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39, 110 | 0xD2321099, 0xFD8C5420, 0xD3B7C42A, 0xFC098093, 111 | 0x85E01DE0, 0x6680F8F7, 0x4D32DD3C, 0xAE52382B, 112 | 0x149E6CB5, 0x8B336987, 0x15DCB2B3, 0x8A71B781 113 | }; 114 | uint32_t crc1, crc2; 115 | uint32_t ref, seed, seed0, seed1, seed2, seed3; 116 | prng_rand_128_data_t buf; 117 | uint8_t *bytebuf = aligned_malloc(16, SMALLBUFSIZE + 1); 118 | ranctx x; 119 | prng_t prng; 120 | prng_randmemset_flags_t flags; 121 | 122 | if (argc > 1 && strcmp(argv[1], "-bench") == 0) 123 | { 124 | bench (); 125 | return 0; 126 | } 127 | 128 | /* basic test */ 129 | raninit (&x, 0); 130 | prng_srand_r (&prng, 0); 131 | assert (ranval (&x) == prng_rand_r (&prng)); 132 | 133 | /* test for simd code */ 134 | seed = 0; 135 | prng_srand_r (&prng, seed); 136 | seed0 = (seed = seed * 1103515245 + 12345); 137 | seed1 = (seed = seed * 1103515245 + 12345); 138 | seed2 = (seed = seed * 1103515245 + 12345); 139 | seed3 = (seed = seed * 1103515245 + 12345); 140 | prng_rand_128_r (&prng, &buf); 141 | 142 | raninit (&x, seed0); 143 | ref = ranval (&x); 144 | assert (ref == buf.w[0]); 145 | 146 | raninit (&x, seed1); 147 | ref = ranval (&x); 148 | assert (ref == buf.w[1]); 149 | 150 | raninit (&x, seed2); 151 | ref = ranval (&x); 152 | assert (ref == buf.w[2]); 153 | 154 | raninit (&x, seed3); 155 | ref = ranval (&x); 156 | assert (ref == buf.w[3]); 157 | 158 | /* test for randmemset */ 159 | for (flags = 0; flags <= RANDMEMSET_MORE_00_AND_FF; flags++) 160 | { 161 | prng_srand_r (&prng, 1234); 162 | prng_randmemset_r (&prng, bytebuf, 16, flags); 163 | prng_randmemset_r (&prng, bytebuf + 16, SMALLBUFSIZE - 17, flags); 164 | crc1 = compute_crc32 (0, bytebuf, SMALLBUFSIZE - 1); 165 | prng_srand_r (&prng, 1234); 166 | prng_randmemset_r (&prng, bytebuf + 1, SMALLBUFSIZE - 1, flags); 167 | crc2 = compute_crc32 (0, bytebuf + 1, SMALLBUFSIZE - 1); 168 | assert (ref_crc[flags] == crc1); 169 | assert (ref_crc[flags] == crc2); 170 | } 171 | 172 | free (bytebuf); 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /pixman/pixman-conical-gradient.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2000 SuSE, Inc. 3 | * Copyright © 2007 Red Hat, Inc. 4 | * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 5 | * 2005 Lars Knoll & Zack Rusin, Trolltech 6 | * 7 | * Permission to use, copy, modify, distribute, and sell this software and its 8 | * documentation for any purpose is hereby granted without fee, provided that 9 | * the above copyright notice appear in all copies and that both that 10 | * copyright notice and this permission notice appear in supporting 11 | * documentation, and that the name of Keith Packard not be used in 12 | * advertising or publicity pertaining to distribution of the software without 13 | * specific, written prior permission. Keith Packard makes no 14 | * representations about the suitability of this software for any purpose. It 15 | * is provided "as is" without express or implied warranty. 16 | * 17 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 18 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 22 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 23 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 24 | * SOFTWARE. 25 | */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include 29 | #endif 30 | 31 | #include 32 | #include 33 | #include "pixman-private.h" 34 | 35 | static force_inline double 36 | coordinates_to_parameter (double x, double y, double angle) 37 | { 38 | double t; 39 | 40 | t = atan2 (y, x) + angle; 41 | 42 | while (t < 0) 43 | t += 2 * M_PI; 44 | 45 | while (t >= 2 * M_PI) 46 | t -= 2 * M_PI; 47 | 48 | return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and 49 | * make rotation CCW 50 | */ 51 | } 52 | 53 | static uint32_t * 54 | conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) 55 | { 56 | pixman_image_t *image = iter->image; 57 | int x = iter->x; 58 | int y = iter->y; 59 | int width = iter->width; 60 | uint32_t *buffer = iter->buffer; 61 | 62 | gradient_t *gradient = (gradient_t *)image; 63 | conical_gradient_t *conical = (conical_gradient_t *)image; 64 | uint32_t *end = buffer + width; 65 | pixman_gradient_walker_t walker; 66 | pixman_bool_t affine = TRUE; 67 | double cx = 1.; 68 | double cy = 0.; 69 | double cz = 0.; 70 | double rx = x + 0.5; 71 | double ry = y + 0.5; 72 | double rz = 1.; 73 | 74 | _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); 75 | 76 | if (image->common.transform) 77 | { 78 | pixman_vector_t v; 79 | 80 | /* reference point is the center of the pixel */ 81 | v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; 82 | v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; 83 | v.vector[2] = pixman_fixed_1; 84 | 85 | if (!pixman_transform_point_3d (image->common.transform, &v)) 86 | return iter->buffer; 87 | 88 | cx = image->common.transform->matrix[0][0] / 65536.; 89 | cy = image->common.transform->matrix[1][0] / 65536.; 90 | cz = image->common.transform->matrix[2][0] / 65536.; 91 | 92 | rx = v.vector[0] / 65536.; 93 | ry = v.vector[1] / 65536.; 94 | rz = v.vector[2] / 65536.; 95 | 96 | affine = 97 | image->common.transform->matrix[2][0] == 0 && 98 | v.vector[2] == pixman_fixed_1; 99 | } 100 | 101 | if (affine) 102 | { 103 | rx -= conical->center.x / 65536.; 104 | ry -= conical->center.y / 65536.; 105 | 106 | while (buffer < end) 107 | { 108 | if (!mask || *mask++) 109 | { 110 | double t = coordinates_to_parameter (rx, ry, conical->angle); 111 | 112 | *buffer = _pixman_gradient_walker_pixel ( 113 | &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); 114 | } 115 | 116 | ++buffer; 117 | 118 | rx += cx; 119 | ry += cy; 120 | } 121 | } 122 | else 123 | { 124 | while (buffer < end) 125 | { 126 | double x, y; 127 | 128 | if (!mask || *mask++) 129 | { 130 | double t; 131 | 132 | if (rz != 0) 133 | { 134 | x = rx / rz; 135 | y = ry / rz; 136 | } 137 | else 138 | { 139 | x = y = 0.; 140 | } 141 | 142 | x -= conical->center.x / 65536.; 143 | y -= conical->center.y / 65536.; 144 | 145 | t = coordinates_to_parameter (x, y, conical->angle); 146 | 147 | *buffer = _pixman_gradient_walker_pixel ( 148 | &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); 149 | } 150 | 151 | ++buffer; 152 | 153 | rx += cx; 154 | ry += cy; 155 | rz += cz; 156 | } 157 | } 158 | 159 | iter->y++; 160 | return iter->buffer; 161 | } 162 | 163 | static uint32_t * 164 | conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) 165 | { 166 | uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); 167 | 168 | pixman_expand_to_float ( 169 | (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); 170 | 171 | return buffer; 172 | } 173 | 174 | void 175 | _pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) 176 | { 177 | if (iter->iter_flags & ITER_NARROW) 178 | iter->get_scanline = conical_get_scanline_narrow; 179 | else 180 | iter->get_scanline = conical_get_scanline_wide; 181 | } 182 | 183 | PIXMAN_EXPORT pixman_image_t * 184 | pixman_image_create_conical_gradient (const pixman_point_fixed_t * center, 185 | pixman_fixed_t angle, 186 | const pixman_gradient_stop_t *stops, 187 | int n_stops) 188 | { 189 | pixman_image_t *image = _pixman_image_allocate (); 190 | conical_gradient_t *conical; 191 | 192 | if (!image) 193 | return NULL; 194 | 195 | conical = &image->conical; 196 | 197 | if (!_pixman_init_gradient (&conical->common, stops, n_stops)) 198 | { 199 | free (image); 200 | return NULL; 201 | } 202 | 203 | angle = MOD (angle, pixman_int_to_fixed (360)); 204 | 205 | image->type = CONICAL; 206 | 207 | conical->center = *center; 208 | conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI; 209 | 210 | return image; 211 | } 212 | 213 | -------------------------------------------------------------------------------- /test/scaling-crash-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "utils.h" 6 | 7 | /* 8 | * We have a source image filled with solid color, set NORMAL or PAD repeat, 9 | * and some transform which results in nearest neighbour scaling. 10 | * 11 | * The expected result is either that the destination image filled with this solid 12 | * color or, if the transformation is such that we can't composite anything at 13 | * all, that nothing has changed in the destination. 14 | * 15 | * The surrounding memory of the source image is a different solid color so that 16 | * we are sure to get failures if we access it. 17 | */ 18 | static int 19 | run_test (int32_t dst_width, 20 | int32_t dst_height, 21 | int32_t src_width, 22 | int32_t src_height, 23 | int32_t src_x, 24 | int32_t src_y, 25 | int32_t scale_x, 26 | int32_t scale_y, 27 | pixman_filter_t filter, 28 | pixman_repeat_t repeat) 29 | { 30 | pixman_image_t * src_img; 31 | pixman_image_t * dst_img; 32 | pixman_transform_t transform; 33 | uint32_t * srcbuf; 34 | uint32_t * dstbuf; 35 | pixman_color_t color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc }; 36 | pixman_image_t * solid; 37 | int result; 38 | int i; 39 | 40 | static const pixman_fixed_t kernel[] = 41 | { 42 | #define D(f) (pixman_double_to_fixed (f) + 0x0001) 43 | 44 | pixman_int_to_fixed (5), 45 | pixman_int_to_fixed (5), 46 | D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 47 | D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 48 | D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 49 | D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 50 | D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0) 51 | }; 52 | 53 | result = 0; 54 | 55 | srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4); 56 | dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4); 57 | 58 | memset (srcbuf, 0x88, src_width * src_height * 4); 59 | memset (dstbuf, 0x33, dst_width * dst_height * 4); 60 | 61 | src_img = pixman_image_create_bits ( 62 | PIXMAN_a8r8g8b8, src_width, src_height, 63 | srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4); 64 | 65 | solid = pixman_image_create_solid_fill (&color_cc); 66 | pixman_image_composite32 (PIXMAN_OP_SRC, solid, NULL, src_img, 67 | 0, 0, 0, 0, 0, 0, src_width, src_height); 68 | pixman_image_unref (solid); 69 | 70 | dst_img = pixman_image_create_bits ( 71 | PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4); 72 | 73 | pixman_transform_init_scale (&transform, scale_x, scale_y); 74 | pixman_image_set_transform (src_img, &transform); 75 | pixman_image_set_repeat (src_img, repeat); 76 | if (filter == PIXMAN_FILTER_CONVOLUTION) 77 | pixman_image_set_filter (src_img, filter, kernel, 27); 78 | else 79 | pixman_image_set_filter (src_img, filter, NULL, 0); 80 | 81 | pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, 82 | src_x, src_y, 0, 0, 0, 0, dst_width, dst_height); 83 | 84 | pixman_image_unref (src_img); 85 | pixman_image_unref (dst_img); 86 | 87 | for (i = 0; i < dst_width * dst_height; i++) 88 | { 89 | if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333) 90 | { 91 | result = 1; 92 | break; 93 | } 94 | } 95 | 96 | free (srcbuf); 97 | free (dstbuf); 98 | return result; 99 | } 100 | 101 | typedef struct filter_info_t filter_info_t; 102 | struct filter_info_t 103 | { 104 | pixman_filter_t value; 105 | char name[28]; 106 | }; 107 | 108 | static const filter_info_t filters[] = 109 | { 110 | { PIXMAN_FILTER_NEAREST, "NEAREST" }, 111 | { PIXMAN_FILTER_BILINEAR, "BILINEAR" }, 112 | { PIXMAN_FILTER_CONVOLUTION, "CONVOLUTION" }, 113 | }; 114 | 115 | typedef struct repeat_info_t repeat_info_t; 116 | struct repeat_info_t 117 | { 118 | pixman_repeat_t value; 119 | char name[28]; 120 | }; 121 | 122 | 123 | static const repeat_info_t repeats[] = 124 | { 125 | { PIXMAN_REPEAT_PAD, "PAD" }, 126 | { PIXMAN_REPEAT_REFLECT, "REFLECT" }, 127 | { PIXMAN_REPEAT_NORMAL, "NORMAL" } 128 | }; 129 | 130 | static int 131 | do_test (int32_t dst_size, 132 | int32_t src_size, 133 | int32_t src_offs, 134 | int32_t scale_factor) 135 | { 136 | int i, j; 137 | 138 | for (i = 0; i < ARRAY_LENGTH (filters); ++i) 139 | { 140 | for (j = 0; j < ARRAY_LENGTH (repeats); ++j) 141 | { 142 | /* horizontal test */ 143 | if (run_test (dst_size, 1, 144 | src_size, 1, 145 | src_offs, 0, 146 | scale_factor, 65536, 147 | filters[i].value, 148 | repeats[j].value) != 0) 149 | { 150 | printf ("Vertical test failed with %s filter and repeat mode %s\n", 151 | filters[i].name, repeats[j].name); 152 | 153 | return 1; 154 | } 155 | 156 | /* vertical test */ 157 | if (run_test (1, dst_size, 158 | 1, src_size, 159 | 0, src_offs, 160 | 65536, scale_factor, 161 | filters[i].value, 162 | repeats[j].value) != 0) 163 | { 164 | printf ("Vertical test failed with %s filter and repeat mode %s\n", 165 | filters[i].name, repeats[j].name); 166 | 167 | return 1; 168 | } 169 | } 170 | } 171 | 172 | return 0; 173 | } 174 | 175 | int 176 | main (int argc, char *argv[]) 177 | { 178 | int i; 179 | 180 | pixman_disable_out_of_bounds_workaround (); 181 | 182 | /* can potentially crash */ 183 | assert (do_test ( 184 | 48000, 32767, 1, 65536 * 128) == 0); 185 | 186 | /* can potentially get into a deadloop */ 187 | assert (do_test ( 188 | 16384, 65536, 32, 32768) == 0); 189 | 190 | /* can potentially access memory outside source image buffer */ 191 | assert (do_test ( 192 | 10, 10, 0, 1) == 0); 193 | assert (do_test ( 194 | 10, 10, 0, 0) == 0); 195 | 196 | for (i = 0; i < 100; ++i) 197 | { 198 | pixman_fixed_t one_seventh = 199 | (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (7 << 16); 200 | 201 | assert (do_test ( 202 | 1, 7, 3, one_seventh + i - 50) == 0); 203 | } 204 | 205 | for (i = 0; i < 100; ++i) 206 | { 207 | pixman_fixed_t scale = 208 | (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (32767 << 16); 209 | 210 | assert (do_test ( 211 | 1, 32767, 16383, scale + i - 50) == 0); 212 | } 213 | 214 | /* can potentially provide invalid results (out of range matrix stuff) */ 215 | assert (do_test ( 216 | 48000, 32767, 16384, 65536 * 128) == 0); 217 | 218 | return 0; 219 | } 220 | -------------------------------------------------------------------------------- /pixman/pixman-arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2000 SuSE, Inc. 3 | * Copyright © 2007 Red Hat, Inc. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of SuSE not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. SuSE makes no representations about the 12 | * suitability of this software for any purpose. It is provided "as is" 13 | * without express or implied warranty. 14 | * 15 | * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 | * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 | */ 22 | #ifdef HAVE_CONFIG_H 23 | #include 24 | #endif 25 | 26 | #include "pixman-private.h" 27 | 28 | typedef enum 29 | { 30 | ARM_V7 = (1 << 0), 31 | ARM_V6 = (1 << 1), 32 | ARM_VFP = (1 << 2), 33 | ARM_NEON = (1 << 3), 34 | ARM_IWMMXT = (1 << 4) 35 | } arm_cpu_features_t; 36 | 37 | #if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT) 38 | 39 | #if defined(_MSC_VER) 40 | 41 | /* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */ 42 | #include 43 | 44 | extern int pixman_msvc_try_arm_neon_op (); 45 | extern int pixman_msvc_try_arm_simd_op (); 46 | 47 | static arm_cpu_features_t 48 | detect_cpu_features (void) 49 | { 50 | arm_cpu_features_t features = 0; 51 | 52 | __try 53 | { 54 | pixman_msvc_try_arm_simd_op (); 55 | features |= ARM_V6; 56 | } 57 | __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) 58 | { 59 | } 60 | 61 | __try 62 | { 63 | pixman_msvc_try_arm_neon_op (); 64 | features |= ARM_NEON; 65 | } 66 | __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) 67 | { 68 | } 69 | 70 | return features; 71 | } 72 | 73 | #elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */ 74 | 75 | #include "TargetConditionals.h" 76 | 77 | static arm_cpu_features_t 78 | detect_cpu_features (void) 79 | { 80 | arm_cpu_features_t features = 0; 81 | 82 | features |= ARM_V6; 83 | 84 | /* Detection of ARM NEON on iOS is fairly simple because iOS binaries 85 | * contain separate executable images for each processor architecture. 86 | * So all we have to do is detect the armv7 architecture build. The 87 | * operating system automatically runs the armv7 binary for armv7 devices 88 | * and the armv6 binary for armv6 devices. 89 | */ 90 | #if defined(__ARM_NEON__) 91 | features |= ARM_NEON; 92 | #endif 93 | 94 | return features; 95 | } 96 | 97 | #elif defined(__ANDROID__) || defined(ANDROID) /* Android */ 98 | 99 | #include 100 | 101 | static arm_cpu_features_t 102 | detect_cpu_features (void) 103 | { 104 | arm_cpu_features_t features = 0; 105 | AndroidCpuFamily cpu_family; 106 | uint64_t cpu_features; 107 | 108 | cpu_family = android_getCpuFamily(); 109 | cpu_features = android_getCpuFeatures(); 110 | 111 | if (cpu_family == ANDROID_CPU_FAMILY_ARM) 112 | { 113 | if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7) 114 | features |= ARM_V7; 115 | 116 | if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3) 117 | features |= ARM_VFP; 118 | 119 | if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) 120 | features |= ARM_NEON; 121 | } 122 | 123 | return features; 124 | } 125 | 126 | #elif defined (__linux__) /* linux ELF */ 127 | 128 | #include 129 | #include 130 | #include 131 | #include 132 | #include 133 | #include 134 | #include 135 | 136 | static arm_cpu_features_t 137 | detect_cpu_features (void) 138 | { 139 | arm_cpu_features_t features = 0; 140 | Elf32_auxv_t aux; 141 | int fd; 142 | 143 | fd = open ("/proc/self/auxv", O_RDONLY); 144 | if (fd >= 0) 145 | { 146 | while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) 147 | { 148 | if (aux.a_type == AT_HWCAP) 149 | { 150 | uint32_t hwcap = aux.a_un.a_val; 151 | 152 | /* hardcode these values to avoid depending on specific 153 | * versions of the hwcap header, e.g. HWCAP_NEON 154 | */ 155 | if ((hwcap & 64) != 0) 156 | features |= ARM_VFP; 157 | if ((hwcap & 512) != 0) 158 | features |= ARM_IWMMXT; 159 | /* this flag is only present on kernel 2.6.29 */ 160 | if ((hwcap & 4096) != 0) 161 | features |= ARM_NEON; 162 | } 163 | else if (aux.a_type == AT_PLATFORM) 164 | { 165 | const char *plat = (const char*) aux.a_un.a_val; 166 | 167 | if (strncmp (plat, "v7l", 3) == 0) 168 | features |= (ARM_V7 | ARM_V6); 169 | else if (strncmp (plat, "v6l", 3) == 0) 170 | features |= ARM_V6; 171 | } 172 | } 173 | close (fd); 174 | } 175 | 176 | return features; 177 | } 178 | 179 | #else /* Unknown */ 180 | 181 | static arm_cpu_features_t 182 | detect_cpu_features (void) 183 | { 184 | return 0; 185 | } 186 | 187 | #endif /* Linux elf */ 188 | 189 | static pixman_bool_t 190 | have_feature (arm_cpu_features_t feature) 191 | { 192 | static pixman_bool_t initialized; 193 | static arm_cpu_features_t features; 194 | 195 | if (!initialized) 196 | { 197 | features = detect_cpu_features(); 198 | initialized = TRUE; 199 | } 200 | 201 | return (features & feature) == feature; 202 | } 203 | 204 | #endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */ 205 | 206 | pixman_implementation_t * 207 | _pixman_arm_get_implementations (pixman_implementation_t *imp) 208 | { 209 | #ifdef USE_ARM_SIMD 210 | if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6)) 211 | imp = _pixman_implementation_create_arm_simd (imp); 212 | #endif 213 | 214 | #ifdef USE_ARM_IWMMXT 215 | if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT)) 216 | imp = _pixman_implementation_create_mmx (imp); 217 | #endif 218 | 219 | #ifdef USE_ARM_NEON 220 | if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON)) 221 | imp = _pixman_implementation_create_arm_neon (imp); 222 | #endif 223 | 224 | return imp; 225 | } 226 | -------------------------------------------------------------------------------- /demos/radial-test.c: -------------------------------------------------------------------------------- 1 | #include "../test/utils.h" 2 | #include "gtk-utils.h" 3 | 4 | #define NUM_GRADIENTS 9 5 | #define NUM_STOPS 3 6 | #define NUM_REPEAT 4 7 | #define SIZE 128 8 | #define WIDTH (SIZE * NUM_GRADIENTS) 9 | #define HEIGHT (SIZE * NUM_REPEAT) 10 | 11 | /* 12 | * We want to test all the possible relative positions of the start 13 | * and end circle: 14 | * 15 | * - The start circle can be smaller/equal/bigger than the end 16 | * circle. A radial gradient can be classified in one of these 17 | * three cases depending on the sign of dr. 18 | * 19 | * - The smaller circle can be completely inside/internally 20 | * tangent/outside (at least in part) of the bigger circle. This 21 | * classification is the same as the one which can be computed by 22 | * examining the sign of a = (dx^2 + dy^2 - dr^2). 23 | * 24 | * - If the two circles have the same size, neither can be inside or 25 | * internally tangent 26 | * 27 | * This test draws radial gradients whose circles always have the same 28 | * centers (0, 0) and (1, 0), but with different radiuses. From left 29 | * to right: 30 | * 31 | * - Degenerate start circle completely inside the end circle 32 | * 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0 33 | * 34 | * - Small start circle completely inside the end circle 35 | * 0.25 -> 1.75; dr = 1.5 > 0; a = 1 - 1.50^2 < 0 36 | * 37 | * - Small start circle internally tangent to the end circle 38 | * 0.50 -> 1.50; dr = 1.0 > 0; a = 1 - 1.00^2 = 0 39 | * 40 | * - Small start circle outside of the end circle 41 | * 0.50 -> 1.00; dr = 0.5 > 0; a = 1 - 0.50^2 > 0 42 | * 43 | * - Start circle with the same size as the end circle 44 | * 1.00 -> 1.00; dr = 0.0 = 0; a = 1 - 0.00^2 > 0 45 | * 46 | * - Small end circle outside of the start circle 47 | * 1.00 -> 0.50; dr = -0.5 > 0; a = 1 - 0.50^2 > 0 48 | * 49 | * - Small end circle internally tangent to the start circle 50 | * 1.50 -> 0.50; dr = -1.0 > 0; a = 1 - 1.00^2 = 0 51 | * 52 | * - Small end circle completely inside the start circle 53 | * 1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0 54 | * 55 | * - Degenerate end circle completely inside the start circle 56 | * 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0 57 | * 58 | */ 59 | 60 | const static double radiuses[NUM_GRADIENTS] = { 61 | 0.00, 62 | 0.25, 63 | 0.50, 64 | 0.50, 65 | 1.00, 66 | 1.00, 67 | 1.50, 68 | 1.75, 69 | 1.75 70 | }; 71 | 72 | #define double_to_color(x) \ 73 | (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16)) 74 | 75 | #define PIXMAN_STOP(offset,r,g,b,a) \ 76 | { pixman_double_to_fixed (offset), \ 77 | { \ 78 | double_to_color (r), \ 79 | double_to_color (g), \ 80 | double_to_color (b), \ 81 | double_to_color (a) \ 82 | } \ 83 | } 84 | 85 | static const pixman_gradient_stop_t stops[NUM_STOPS] = { 86 | PIXMAN_STOP (0.0, 1, 0, 0, 0.75), 87 | PIXMAN_STOP (0.70710678, 0, 1, 0, 0), 88 | PIXMAN_STOP (1.0, 0, 0, 1, 1) 89 | }; 90 | 91 | static pixman_image_t * 92 | create_radial (int index) 93 | { 94 | pixman_point_fixed_t p0, p1; 95 | pixman_fixed_t r0, r1; 96 | double x0, x1, radius0, radius1, left, right, center; 97 | 98 | x0 = 0; 99 | x1 = 1; 100 | radius0 = radiuses[index]; 101 | radius1 = radiuses[NUM_GRADIENTS - index - 1]; 102 | 103 | /* center the gradient */ 104 | left = MIN (x0 - radius0, x1 - radius1); 105 | right = MAX (x0 + radius0, x1 + radius1); 106 | center = (left + right) * 0.5; 107 | x0 -= center; 108 | x1 -= center; 109 | 110 | /* scale to make it fit within a 1x1 rect centered in (0,0) */ 111 | x0 *= 0.25; 112 | x1 *= 0.25; 113 | radius0 *= 0.25; 114 | radius1 *= 0.25; 115 | 116 | p0.x = pixman_double_to_fixed (x0); 117 | p0.y = pixman_double_to_fixed (0); 118 | 119 | p1.x = pixman_double_to_fixed (x1); 120 | p1.y = pixman_double_to_fixed (0); 121 | 122 | r0 = pixman_double_to_fixed (radius0); 123 | r1 = pixman_double_to_fixed (radius1); 124 | 125 | return pixman_image_create_radial_gradient (&p0, &p1, 126 | r0, r1, 127 | stops, NUM_STOPS); 128 | } 129 | 130 | static const pixman_repeat_t repeat[NUM_REPEAT] = { 131 | PIXMAN_REPEAT_NONE, 132 | PIXMAN_REPEAT_NORMAL, 133 | PIXMAN_REPEAT_REFLECT, 134 | PIXMAN_REPEAT_PAD 135 | }; 136 | 137 | int 138 | main (int argc, char **argv) 139 | { 140 | pixman_transform_t transform; 141 | pixman_image_t *src_img, *dest_img; 142 | int i, j; 143 | 144 | enable_divbyzero_exceptions (); 145 | 146 | dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 147 | WIDTH, HEIGHT, 148 | NULL, 0); 149 | 150 | draw_checkerboard (dest_img, 25, 0xffaaaaaa, 0xffbbbbbb); 151 | 152 | pixman_transform_init_identity (&transform); 153 | 154 | /* 155 | * The create_radial() function returns gradients centered in the 156 | * origin and whose interesting part fits a 1x1 square. We want to 157 | * paint these gradients on a SIZExSIZE square and to make things 158 | * easier we want the origin in the top-left corner of the square 159 | * we want to see. 160 | */ 161 | pixman_transform_translate (NULL, &transform, 162 | pixman_double_to_fixed (0.5), 163 | pixman_double_to_fixed (0.5)); 164 | 165 | pixman_transform_scale (NULL, &transform, 166 | pixman_double_to_fixed (SIZE), 167 | pixman_double_to_fixed (SIZE)); 168 | 169 | /* 170 | * Gradients are evaluated at the center of each pixel, so we need 171 | * to translate by half a pixel to trigger some interesting 172 | * cornercases. In particular, the original implementation of PDF 173 | * radial gradients tried to divide by 0 when using this transform 174 | * on the "tangent circles" cases. 175 | */ 176 | pixman_transform_translate (NULL, &transform, 177 | pixman_double_to_fixed (0.5), 178 | pixman_double_to_fixed (0.5)); 179 | 180 | for (i = 0; i < NUM_GRADIENTS; i++) 181 | { 182 | src_img = create_radial (i); 183 | pixman_image_set_transform (src_img, &transform); 184 | 185 | for (j = 0; j < NUM_REPEAT; j++) 186 | { 187 | pixman_image_set_repeat (src_img, repeat[j]); 188 | 189 | pixman_image_composite32 (PIXMAN_OP_OVER, 190 | src_img, 191 | NULL, 192 | dest_img, 193 | 0, 0, 194 | 0, 0, 195 | i * SIZE, j * SIZE, 196 | SIZE, SIZE); 197 | 198 | } 199 | 200 | pixman_image_unref (src_img); 201 | } 202 | 203 | show_image (dest_img); 204 | 205 | pixman_image_unref (dest_img); 206 | 207 | return 0; 208 | } 209 | -------------------------------------------------------------------------------- /pixman/pixman-gradient-walker.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 4 | * 2005 Lars Knoll & Zack Rusin, Trolltech 5 | * 6 | * Permission to use, copy, modify, distribute, and sell this software and its 7 | * documentation for any purpose is hereby granted without fee, provided that 8 | * the above copyright notice appear in all copies and that both that 9 | * copyright notice and this permission notice appear in supporting 10 | * documentation, and that the name of Keith Packard not be used in 11 | * advertising or publicity pertaining to distribution of the software without 12 | * specific, written prior permission. Keith Packard makes no 13 | * representations about the suitability of this software for any purpose. It 14 | * is provided "as is" without express or implied warranty. 15 | * 16 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 17 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 21 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 22 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 23 | * SOFTWARE. 24 | */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include 28 | #endif 29 | #include "pixman-private.h" 30 | 31 | void 32 | _pixman_gradient_walker_init (pixman_gradient_walker_t *walker, 33 | gradient_t * gradient, 34 | pixman_repeat_t repeat) 35 | { 36 | walker->num_stops = gradient->n_stops; 37 | walker->stops = gradient->stops; 38 | walker->left_x = 0; 39 | walker->right_x = 0x10000; 40 | walker->a_s = 0.0f; 41 | walker->a_b = 0.0f; 42 | walker->r_s = 0.0f; 43 | walker->r_b = 0.0f; 44 | walker->g_s = 0.0f; 45 | walker->g_b = 0.0f; 46 | walker->b_s = 0.0f; 47 | walker->b_b = 0.0f; 48 | walker->repeat = repeat; 49 | 50 | walker->need_reset = TRUE; 51 | } 52 | 53 | static void 54 | gradient_walker_reset (pixman_gradient_walker_t *walker, 55 | pixman_fixed_48_16_t pos) 56 | { 57 | int64_t x, left_x, right_x; 58 | pixman_color_t *left_c, *right_c; 59 | int n, count = walker->num_stops; 60 | pixman_gradient_stop_t *stops = walker->stops; 61 | float la, lr, lg, lb; 62 | float ra, rr, rg, rb; 63 | float lx, rx; 64 | 65 | if (walker->repeat == PIXMAN_REPEAT_NORMAL) 66 | { 67 | x = (int32_t)pos & 0xffff; 68 | } 69 | else if (walker->repeat == PIXMAN_REPEAT_REFLECT) 70 | { 71 | x = (int32_t)pos & 0xffff; 72 | if ((int32_t)pos & 0x10000) 73 | x = 0x10000 - x; 74 | } 75 | else 76 | { 77 | x = pos; 78 | } 79 | 80 | for (n = 0; n < count; n++) 81 | { 82 | if (x < stops[n].x) 83 | break; 84 | } 85 | 86 | left_x = stops[n - 1].x; 87 | left_c = &stops[n - 1].color; 88 | 89 | right_x = stops[n].x; 90 | right_c = &stops[n].color; 91 | 92 | if (walker->repeat == PIXMAN_REPEAT_NORMAL) 93 | { 94 | left_x += (pos - x); 95 | right_x += (pos - x); 96 | } 97 | else if (walker->repeat == PIXMAN_REPEAT_REFLECT) 98 | { 99 | if ((int32_t)pos & 0x10000) 100 | { 101 | pixman_color_t *tmp_c; 102 | int32_t tmp_x; 103 | 104 | tmp_x = 0x10000 - right_x; 105 | right_x = 0x10000 - left_x; 106 | left_x = tmp_x; 107 | 108 | tmp_c = right_c; 109 | right_c = left_c; 110 | left_c = tmp_c; 111 | 112 | x = 0x10000 - x; 113 | } 114 | left_x += (pos - x); 115 | right_x += (pos - x); 116 | } 117 | else if (walker->repeat == PIXMAN_REPEAT_NONE) 118 | { 119 | if (n == 0) 120 | right_c = left_c; 121 | else if (n == count) 122 | left_c = right_c; 123 | } 124 | 125 | /* The alpha channel is scaled to be in the [0, 255] interval, 126 | * and the red/green/blue channels are scaled to be in [0, 1]. 127 | * This ensures that after premultiplication all channels will 128 | * be in the [0, 255] interval. 129 | */ 130 | la = (left_c->alpha * (1.0f/257.0f)); 131 | lr = (left_c->red * (1.0f/257.0f)); 132 | lg = (left_c->green * (1.0f/257.0f)); 133 | lb = (left_c->blue * (1.0f/257.0f)); 134 | 135 | ra = (right_c->alpha * (1.0f/257.0f)); 136 | rr = (right_c->red * (1.0f/257.0f)); 137 | rg = (right_c->green * (1.0f/257.0f)); 138 | rb = (right_c->blue * (1.0f/257.0f)); 139 | 140 | lx = left_x * (1.0f/65536.0f); 141 | rx = right_x * (1.0f/65536.0f); 142 | 143 | if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX) 144 | { 145 | walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f; 146 | walker->a_b = (la + ra) / 2.0f; 147 | walker->r_b = (lr + rr) / 510.0f; 148 | walker->g_b = (lg + rg) / 510.0f; 149 | walker->b_b = (lb + rb) / 510.0f; 150 | } 151 | else 152 | { 153 | float w_rec = 1.0f / (rx - lx); 154 | 155 | walker->a_b = (la * rx - ra * lx) * w_rec; 156 | walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f); 157 | walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f); 158 | walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f); 159 | 160 | walker->a_s = (ra - la) * w_rec; 161 | walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f); 162 | walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f); 163 | walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f); 164 | } 165 | 166 | walker->left_x = left_x; 167 | walker->right_x = right_x; 168 | 169 | walker->need_reset = FALSE; 170 | } 171 | 172 | uint32_t 173 | _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, 174 | pixman_fixed_48_16_t x) 175 | { 176 | float a, r, g, b; 177 | uint8_t a8, r8, g8, b8; 178 | uint32_t v; 179 | float y; 180 | 181 | if (walker->need_reset || x < walker->left_x || x >= walker->right_x) 182 | gradient_walker_reset (walker, x); 183 | 184 | y = x * (1.0f / 65536.0f); 185 | 186 | a = walker->a_s * y + walker->a_b; 187 | r = a * (walker->r_s * y + walker->r_b); 188 | g = a * (walker->g_s * y + walker->g_b); 189 | b = a * (walker->b_s * y + walker->b_b); 190 | 191 | a8 = a + 0.5f; 192 | r8 = r + 0.5f; 193 | g8 = g + 0.5f; 194 | b8 = b + 0.5f; 195 | 196 | v = ((a8 << 24) & 0xff000000) | 197 | ((r8 << 16) & 0x00ff0000) | 198 | ((g8 << 8) & 0x0000ff00) | 199 | ((b8 >> 0) & 0x000000ff); 200 | 201 | return v; 202 | } 203 | --------------------------------------------------------------------------------