git: f908d134485c - main - devel/juce: fix build on powerpc64le
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Sep 2026 12:49:54 UTC
The branch main has been updated by pkubaj:
URL: https://cgit.FreeBSD.org/ports/commit/?id=f908d134485ca827af71a271ec6f1f44370aca0c
commit f908d134485ca827af71a271ec6f1f44370aca0c
Author: Piotr Kubaj <pkubaj@FreeBSD.org>
AuthorDate: 2026-08-30 10:19:57 +0000
Commit: Piotr Kubaj <pkubaj@FreeBSD.org>
CommitDate: 2026-09-11 12:48:59 +0000
devel/juce: fix build on powerpc64le
Add libpng's sources, similarly to other architectures.
---
devel/juce/Makefile | 1 +
...ormats_pnglib_powerpc_filter__vsx__intrinsics.c | 771 +++++++++++++++++++++
...s_image__formats_pnglib_powerpc_powerpc__init.c | 128 ++++
...modules_juce__graphics_juce__graphics__libpng.c | 10 +
devel/juce/pkg-plist | 2 +
5 files changed, 912 insertions(+)
diff --git a/devel/juce/Makefile b/devel/juce/Makefile
index 27c6bd2637a0..0e964577381d 100644
--- a/devel/juce/Makefile
+++ b/devel/juce/Makefile
@@ -31,6 +31,7 @@ DOS2UNIX_FILES= modules/juce_core/juce_core.h \
modules/juce_core/native/juce_SystemStats_linux.cpp \
modules/juce_audio_processors_headless/format_types/juce_VST3Headers.h \
modules/juce_dsp/containers/juce_AudioBlock_test.cpp \
+ modules/juce_graphics/juce_graphics_libpng.c \
extras/NetworkGraphicsDemo/Source/Demos.h \
extras/NetworkGraphicsDemo/Source/SharedCanvas.h
USE_GNOME= atk cairo gdkpixbuf glib20 gtk30 pango
diff --git a/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_filter__vsx__intrinsics.c b/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_filter__vsx__intrinsics.c
new file mode 100644
index 000000000000..3bc5cab21465
--- /dev/null
+++ b/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_filter__vsx__intrinsics.c
@@ -0,0 +1,771 @@
+--- /dev/null 2026-08-30 06:00:09 UTC
++++ modules/juce_graphics/image_formats/pnglib/powerpc/filter_vsx_intrinsics.c
+@@ -0,0 +1,768 @@
++/* filter_vsx_intrinsics.c - PowerPC optimised filter functions
++ *
++ * Copyright (c) 2018 Cosmin Truta
++ * Copyright (c) 2017 Glenn Randers-Pehrson
++ * Written by Vadim Barkov, 2017.
++ *
++ * This code is released under the libpng license.
++ * For conditions of distribution and use, see the disclaimer
++ * and license in png.h
++ */
++
++#include <stdio.h>
++#include <stdint.h>
++#include "../pngpriv.h"
++
++#ifdef PNG_READ_SUPPORTED
++
++/* This code requires -maltivec and -mvsx on the command line: */
++#if PNG_POWERPC_VSX_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
++
++#include <altivec.h>
++
++#if PNG_POWERPC_VSX_OPT > 0
++
++#ifndef __VSX__
++# error This code requires VSX support (POWER7 and later); please compile with -mvsx
++#endif
++
++#define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data)
++#define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data)
++
++
++/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
++ * They're positioned like this:
++ * prev: c b
++ * row: a d
++ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
++ * whichever of a, b, or c is closest to p=a+b-c.
++ * ( this is taken from ../intel/filter_sse2_intrinsics.c )
++ */
++
++#define vsx_declare_common_vars(row_info,row,prev_row,offset) \
++ png_byte i;\
++ png_bytep rp = row + offset;\
++ png_const_bytep pp = prev_row;\
++ size_t unaligned_top = 16 - (((size_t)rp % 16));\
++ size_t istop;\
++ if(unaligned_top == 16)\
++ unaligned_top = 0;\
++ istop = row_info->rowbytes;\
++ if((unaligned_top < istop))\
++ istop -= unaligned_top;\
++ else{\
++ unaligned_top = istop;\
++ istop = 0;\
++ }
++
++void png_read_filter_row_up_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ vector unsigned char rp_vec;
++ vector unsigned char pp_vec;
++ vsx_declare_common_vars(row_info,row,prev_row,0)
++
++ /* Altivec operations require 16-byte aligned data
++ * but input can be unaligned. So we calculate
++ * unaligned part as usual.
++ */
++ for (i = 0; i < unaligned_top; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
++ rp++;
++ }
++
++ /* Using SIMD while we can */
++ while( istop >= 16 )
++ {
++ rp_vec = vec_ld(0,rp);
++ vec_ld_unaligned(pp_vec,pp);
++
++ rp_vec = vec_add(rp_vec,pp_vec);
++
++ vec_st(rp_vec,0,rp);
++
++ pp += 16;
++ rp += 16;
++ istop -= 16;
++ }
++
++ if(istop > 0)
++ {
++ /* If byte count of row is not divisible by 16
++ * we will process remaining part as usual
++ */
++ for (i = 0; i < istop; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
++ rp++;
++ }
++}
++
++}
++
++static const vector unsigned char VSX_LEFTSHIFTED1_4 = {16,16,16,16, 0, 1, 2, 3,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_LEFTSHIFTED2_4 = {16,16,16,16,16,16,16,16, 4, 5, 6, 7,16,16,16,16};
++static const vector unsigned char VSX_LEFTSHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 8, 9,10,11};
++
++static const vector unsigned char VSX_LEFTSHIFTED1_3 = {16,16,16, 0, 1, 2,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_LEFTSHIFTED2_3 = {16,16,16,16,16,16, 3, 4, 5,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_LEFTSHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 6, 7, 8,16,16,16,16};
++static const vector unsigned char VSX_LEFTSHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 9,10,11,16};
++
++static const vector unsigned char VSX_NOT_SHIFTED1_4 = {16,16,16,16, 4, 5, 6, 7,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_NOT_SHIFTED2_4 = {16,16,16,16,16,16,16,16, 8, 9,10,11,16,16,16,16};
++static const vector unsigned char VSX_NOT_SHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,15};
++
++static const vector unsigned char VSX_NOT_SHIFTED1_3 = {16,16,16, 3, 4, 5,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_NOT_SHIFTED2_3 = {16,16,16,16,16,16, 6, 7, 8,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_NOT_SHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 9,10,11,16,16,16,16};
++static const vector unsigned char VSX_NOT_SHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,16};
++
++static const vector unsigned char VSX_CHAR_ZERO = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
++#ifdef __LITTLE_ENDIAN__
++
++static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = { 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = { 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {12,16,13,16,14,16,15,16,16,16,16,16,16,16,16,16};
++
++static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 0, 2, 4, 6,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 0, 2, 4, 6,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4, 6};
++
++static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = { 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = { 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = { 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {12,16,13,16,14,16,16,16,16,16,16,16,16,16,16,16};
++
++static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 0, 2, 4,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 0, 2, 4,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 0, 2, 4,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4,16};
++
++#elif defined(__BIG_ENDIAN__)
++
++static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = {16, 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = {16, 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {16,12,16,13,16,14,16,15,16,16,16,16,16,16,16,16};
++
++static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 1, 3, 5, 7,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 1, 3, 5, 7,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5, 7};
++
++static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = {16, 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = {16, 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = {16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {16,12,16,13,16,14,16,16,16,16,16,16,16,16,16,16};
++
++static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 1, 3, 5,16,16,16,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 1, 3, 5,16,16,16,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 1, 3, 5,16,16,16,16};
++static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5,16};
++
++#endif
++
++#define vsx_char_to_short(vec,offset,bpp) (vector unsigned short)vec_perm((vec),VSX_CHAR_ZERO,VSX_CHAR_TO_SHORT##offset##_##bpp)
++#define vsx_short_to_char(vec,offset,bpp) vec_perm(((vector unsigned char)(vec)),VSX_CHAR_ZERO,VSX_SHORT_TO_CHAR##offset##_##bpp)
++
++#ifdef PNG_USE_ABS
++# define vsx_abs(number) abs(number)
++#else
++# define vsx_abs(number) (number > 0) ? (number) : -(number)
++#endif
++
++void png_read_filter_row_sub4_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 4;
++
++ vector unsigned char rp_vec;
++ vector unsigned char part_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++
++ PNG_UNUSED(pp)
++
++ /* Altivec operations require 16-byte aligned data
++ * but input can be unaligned. So we calculate
++ * unaligned part as usual.
++ */
++ for (i = 0; i < unaligned_top; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++
++ /* Using SIMD while we can */
++ while( istop >= 16 )
++ {
++ for(i=0;i < bpp ; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++ rp -= bpp;
++
++ rp_vec = vec_ld(0,rp);
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ vec_st(rp_vec,0,rp);
++
++ rp += 16;
++ istop -= 16;
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp - bpp))) & 0xff);
++ rp++;
++ }
++
++}
++
++void png_read_filter_row_sub3_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 3;
++
++ vector unsigned char rp_vec;
++ vector unsigned char part_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++
++ PNG_UNUSED(pp)
++
++ /* Altivec operations require 16-byte aligned data
++ * but input can be unaligned. So we calculate
++ * unaligned part as usual.
++ */
++ for (i = 0; i < unaligned_top; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++
++ /* Using SIMD while we can */
++ while( istop >= 16 )
++ {
++ for(i=0;i < bpp ; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++ rp -= bpp;
++
++ rp_vec = vec_ld(0,rp);
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
++ rp_vec = vec_add(rp_vec,part_vec);
++
++ vec_st(rp_vec,0,rp);
++ rp += 15;
++ istop -= 16;
++
++ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
++ * be proceeded manually
++ */
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
++ rp++;
++ }
++}
++
++void png_read_filter_row_avg4_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 4;
++
++ vector unsigned char rp_vec;
++ vector unsigned char pp_vec;
++ vector unsigned char pp_part_vec;
++ vector unsigned char rp_part_vec;
++ vector unsigned char avg_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++ rp -= bpp;
++ if(istop >= bpp)
++ istop -= bpp;
++
++ for (i = 0; i < bpp; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ ((int)(*pp++) / 2 )) & 0xff);
++
++ rp++;
++ }
++
++ /* Altivec operations require 16-byte aligned data
++ * but input can be unaligned. So we calculate
++ * unaligned part as usual.
++ */
++ for (i = 0; i < unaligned_top; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++
++ /* Using SIMD while we can */
++ while( istop >= 16 )
++ {
++ for(i=0;i < bpp ; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++ rp -= bpp;
++ pp -= bpp;
++
++ vec_ld_unaligned(pp_vec,pp);
++ rp_vec = vec_ld(0,rp);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_4);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_4);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_4);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ vec_st(rp_vec,0,rp);
++
++ rp += 16;
++ pp += 16;
++ istop -= 16;
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++}
++
++void png_read_filter_row_avg3_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 3;
++
++ vector unsigned char rp_vec;
++ vector unsigned char pp_vec;
++ vector unsigned char pp_part_vec;
++ vector unsigned char rp_part_vec;
++ vector unsigned char avg_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++ rp -= bpp;
++ if(istop >= bpp)
++ istop -= bpp;
++
++ for (i = 0; i < bpp; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ ((int)(*pp++) / 2 )) & 0xff);
++
++ rp++;
++ }
++
++ /* Altivec operations require 16-byte aligned data
++ * but input can be unaligned. So we calculate
++ * unaligned part as usual.
++ */
++ for (i = 0; i < unaligned_top; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++
++ /* Using SIMD while we can */
++ while( istop >= 16 )
++ {
++ for(i=0;i < bpp ; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++ rp -= bpp;
++ pp -= bpp;
++
++ vec_ld_unaligned(pp_vec,pp);
++ rp_vec = vec_ld(0,rp);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_3);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_3);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_3);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
++ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED4_3);
++ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
++ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
++ rp_vec = vec_add(rp_vec,avg_vec);
++
++ vec_st(rp_vec,0,rp);
++
++ rp += 15;
++ pp += 15;
++ istop -= 16;
++
++ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
++ * be proceeded manually
++ */
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++ rp++;
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ *rp = (png_byte)(((int)(*rp) +
++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
++
++ rp++;
++ }
++}
++
++/* Bytewise c ? t : e. */
++#define if_then_else(c,t,e) vec_sel(e,t,c)
++
++#define vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) {\
++ c = *(pp - bpp);\
++ a = *(rp - bpp);\
++ b = *pp++;\
++ p = b - c;\
++ pc = a - c;\
++ pa = vsx_abs(p);\
++ pb = vsx_abs(pc);\
++ pc = vsx_abs(p + pc);\
++ if (pb < pa) pa = pb, a = b;\
++ if (pc < pa) a = c;\
++ a += *rp;\
++ *rp++ = (png_byte)a;\
++ }
++
++void png_read_filter_row_paeth4_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 4;
++
++ int a, b, c, pa, pb, pc, p;
++ vector unsigned char rp_vec;
++ vector unsigned char pp_vec;
++ vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
++ vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++ rp -= bpp;
++ if(istop >= bpp)
++ istop -= bpp;
++
++ /* Process the first pixel in the row completely (this is the same as 'up'
++ * because there is only one candidate predictor for the first row).
++ */
++ for(i = 0; i < bpp ; i++)
++ {
++ *rp = (png_byte)( *rp + *pp);
++ rp++;
++ pp++;
++ }
++
++ for(i = 0; i < unaligned_top ; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++
++ while( istop >= 16)
++ {
++ for(i = 0; i < bpp ; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++
++ rp -= bpp;
++ pp -= bpp;
++ rp_vec = vec_ld(0,rp);
++ vec_ld_unaligned(pp_vec,pp);
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_4),1,4);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,4)));
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_4),2,4);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,4)));
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_4),3,4);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,4)));
++
++ vec_st(rp_vec,0,rp);
++
++ rp += 16;
++ pp += 16;
++ istop -= 16;
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++}
++
++void png_read_filter_row_paeth3_vsx(png_row_infop row_info, png_bytep row,
++ png_const_bytep prev_row)
++{
++ png_byte bpp = 3;
++
++ int a, b, c, pa, pb, pc, p;
++ vector unsigned char rp_vec;
++ vector unsigned char pp_vec;
++ vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
++ vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
++
++ vsx_declare_common_vars(row_info,row,prev_row,bpp)
++ rp -= bpp;
++ if(istop >= bpp)
++ istop -= bpp;
++
++ /* Process the first pixel in the row completely (this is the same as 'up'
++ * because there is only one candidate predictor for the first row).
++ */
++ for(i = 0; i < bpp ; i++)
++ {
++ *rp = (png_byte)( *rp + *pp);
++ rp++;
++ pp++;
++ }
++
++ for(i = 0; i < unaligned_top ; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++
++ while( istop >= 16)
++ {
++ for(i = 0; i < bpp ; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++
++ rp -= bpp;
++ pp -= bpp;
++ rp_vec = vec_ld(0,rp);
++ vec_ld_unaligned(pp_vec,pp);
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_3),1,3);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,3)));
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_3),2,3);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,3)));
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_3),3,3);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,3)));
++
++ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
++ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED4_3),4,3);
++ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
++ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
++ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
++ pc_vec = vec_add(pa_vec,pb_vec);
++ pa_vec = vec_abs(pa_vec);
++ pb_vec = vec_abs(pb_vec);
++ pc_vec = vec_abs(pc_vec);
++ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
++ nearest_vec = if_then_else(
++ vec_cmpeq(pa_vec,smallest_vec),
++ a_vec,
++ if_then_else(
++ vec_cmpeq(pb_vec,smallest_vec),
++ b_vec,
++ c_vec
++ )
++ );
++ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,4,3)));
++
++ vec_st(rp_vec,0,rp);
++
++ rp += 15;
++ pp += 15;
++ istop -= 16;
++
++ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
++ * be proceeded manually
++ */
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++
++ if(istop > 0)
++ for (i = 0; i < istop % 16; i++)
++ {
++ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
++ }
++}
++
++#endif /* PNG_POWERPC_VSX_OPT > 0 */
++#endif /* PNG_POWERPC_VSX_IMPLEMENTATION == 1 (intrinsics) */
++#endif /* READ */
diff --git a/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_powerpc__init.c b/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_powerpc__init.c
new file mode 100644
index 000000000000..1e276e8905f0
--- /dev/null
+++ b/devel/juce/files/patch-modules_juce__graphics_image__formats_pnglib_powerpc_powerpc__init.c
@@ -0,0 +1,128 @@
+--- /dev/null 2026-08-30 06:00:09 UTC
++++ modules/juce_graphics/image_formats/pnglib/powerpc/powerpc_init.c
+@@ -0,0 +1,125 @@
++/* powerpc_init.c - POWERPC optimised filter functions
++ *
++ * Copyright (c) 2018 Cosmin Truta
++ * Copyright (c) 2017 Glenn Randers-Pehrson
++ * Written by Vadim Barkov, 2017.
++ *
++ * This code is released under the libpng license.
++ * For conditions of distribution and use, see the disclaimer
++ * and license in png.h
++ */
++
++/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
++ * called.
++ */
++#define _POSIX_SOURCE 1
++
++#include <stdio.h>
++#include "../pngpriv.h"
++
++#ifdef PNG_READ_SUPPORTED
++
++#if PNG_POWERPC_VSX_OPT > 0
++#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED /* Do run-time checks */
++/* WARNING: it is strongly recommended that you do not build libpng with
++ * run-time checks for CPU features if at all possible. In the case of the PowerPC
++ * VSX instructions there is no processor-specific way of detecting the
++ * presence of the required support, therefore run-time detection is extremely
++ * OS specific.
++ *
++ * You may set the macro PNG_POWERPC_VSX_FILE to the file name of file containing
++ * a fragment of C source code which defines the png_have_vsx function. There
++ * are a number of implementations in contrib/powerpc-vsx, but the only one that
++ * has partial support is contrib/powerpc-vsx/linux.c - a generic Linux
++ * implementation which reads /proc/cpufino.
++ */
++#ifndef PNG_POWERPC_VSX_FILE
++# ifdef __linux__
++# define PNG_POWERPC_VSX_FILE "contrib/powerpc-vsx/linux_aux.c"
++# endif
++#endif
++
++#ifdef PNG_POWERPC_VSX_FILE
++
++#include <signal.h> /* for sig_atomic_t */
++static int png_have_vsx(png_structp png_ptr);
++#include PNG_POWERPC_VSX_FILE
++
++#else /* PNG_POWERPC_VSX_FILE */
++# error PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks
++#endif /* PNG_POWERPC_VSX_FILE */
++#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
++
++void
++png_init_filter_functions_vsx(png_structp pp, unsigned int bpp)
++{
++ /* The switch statement is compiled in for POWERPC_VSX_API, the call to
++ * png_have_vsx is compiled in for POWERPC_VSX_CHECK. If both are defined
++ * the check is only performed if the API has not set the PowerPC option on
++ * or off explicitly. In this case the check controls what happens.
++ */
++
++#ifdef PNG_POWERPC_VSX_API_SUPPORTED
++ switch ((pp->options >> PNG_POWERPC_VSX) & 3)
++ {
++ case PNG_OPTION_UNSET:
++ /* Allow the run-time check to execute if it has been enabled -
++ * thus both API and CHECK can be turned on. If it isn't supported
++ * this case will fall through to the 'default' below, which just
++ * returns.
++ */
++#endif /* PNG_POWERPC_VSX_API_SUPPORTED */
++#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
++ {
++ static volatile sig_atomic_t no_vsx = -1; /* not checked */
++
++ if (no_vsx < 0)
++ no_vsx = !png_have_vsx(pp);
++
++ if (no_vsx)
++ return;
++ }
++#ifdef PNG_POWERPC_VSX_API_SUPPORTED
++ break;
++#endif
++#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
++
++#ifdef PNG_POWERPC_VSX_API_SUPPORTED
++ default: /* OFF or INVALID */
++ return;
++
++ case PNG_OPTION_ON:
++ /* Option turned on */
++ break;
++ }
++#endif
++
++ /* IMPORTANT: any new internal functions used here must be declared using
++ * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
++ * 'prefix' option to configure works:
++ *
++ * ./configure --with-libpng-prefix=foobar_
++ *
++ * Verify you have got this right by running the above command, doing a build
++ * and examining pngprefix.h; it must contain a #define for every external
++ * function you add. (Notice that this happens automatically for the
++ * initialization function.)
++ */
++ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_vsx;
++
++ if (bpp == 3)
++ {
++ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_vsx;
++ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_vsx;
++ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_vsx;
++ }
++
++ else if (bpp == 4)
++ {
++ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_vsx;
++ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_vsx;
++ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_vsx;
++ }
++}
++#endif /* PNG_POWERPC_VSX_OPT > 0 */
++#endif /* READ */
diff --git a/devel/juce/files/patch-modules_juce__graphics_juce__graphics__libpng.c b/devel/juce/files/patch-modules_juce__graphics_juce__graphics__libpng.c
new file mode 100644
index 000000000000..3f7acbdb8c5a
--- /dev/null
+++ b/devel/juce/files/patch-modules_juce__graphics_juce__graphics__libpng.c
@@ -0,0 +1,10 @@
+--- modules/juce_graphics/juce_graphics_libpng.c.orig 2026-08-30 05:59:56 UTC
++++ modules/juce_graphics/juce_graphics_libpng.c
+@@ -87,5 +87,7 @@ JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4146 4996)
+ #include "juce_graphics/image_formats/pnglib/arm/arm_init.c"
+ #include "juce_graphics/image_formats/pnglib/arm/filter_neon_intrinsics.c"
+ #include "juce_graphics/image_formats/pnglib/arm/palette_neon_intrinsics.c"
++#include "juce_graphics/image_formats/pnglib/powerpc/powerpc_init.c"
++#include "juce_graphics/image_formats/pnglib/powerpc/filter_vsx_intrinsics.c"
+
+ #endif
diff --git a/devel/juce/pkg-plist b/devel/juce/pkg-plist
index 77d68cee89af..84651d122819 100644
--- a/devel/juce/pkg-plist
+++ b/devel/juce/pkg-plist
@@ -2661,6 +2661,8 @@ include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/pngwio.c
include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/pngwrite.c
include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/pngwtran.c
include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/pngwutil.c
+include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/powerpc/filter_vsx_intrinsics.c
+include/JUCE-%%VERSION%%/modules/juce_graphics/image_formats/pnglib/powerpc/powerpc_init.c
include/JUCE-%%VERSION%%/modules/juce_graphics/images/juce_Image.cpp
include/JUCE-%%VERSION%%/modules/juce_graphics/images/juce_Image.h
include/JUCE-%%VERSION%%/modules/juce_graphics/images/juce_ImageCache.cpp