git: f908d134485c - main - devel/juce: fix build on powerpc64le

From: Piotr Kubaj <pkubaj_at_FreeBSD.org>
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