Home | History | Annotate | Download | only in powerpc
      1 /*
      2  * jsimd_powerpc.c
      3  *
      4  * Copyright 2009 Pierre Ossman <ossman (at) cendio.se> for Cendio AB
      5  * Copyright (C) 2009-2011, 2014-2016, 2018, D. R. Commander.
      6  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
      7  *
      8  * Based on the x86 SIMD extension for IJG JPEG library,
      9  * Copyright (C) 1999-2006, MIYASAKA Masaru.
     10  * For conditions of distribution and use, see copyright notice in jsimdext.inc
     11  *
     12  * This file contains the interface between the "normal" portions
     13  * of the library and the SIMD implementations when running on a
     14  * PowerPC architecture.
     15  */
     16 
     17 #ifdef __amigaos4__
     18 /* This must be defined first as it re-defines GLOBAL otherwise */
     19 #include <proto/exec.h>
     20 #endif
     21 
     22 #define JPEG_INTERNALS
     23 #include "../../jinclude.h"
     24 #include "../../jpeglib.h"
     25 #include "../../jsimd.h"
     26 #include "../../jdct.h"
     27 #include "../../jsimddct.h"
     28 #include "../jsimd.h"
     29 
     30 #include <stdio.h>
     31 #include <string.h>
     32 #include <ctype.h>
     33 
     34 #if defined(__OpenBSD__)
     35 #include <sys/param.h>
     36 #include <sys/sysctl.h>
     37 #include <machine/cpu.h>
     38 #endif
     39 
     40 static unsigned int simd_support = ~0;
     41 
     42 #if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
     43 
     44 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
     45 
     46 LOCAL(int)
     47 check_feature(char *buffer, char *feature)
     48 {
     49   char *p;
     50 
     51   if (*feature == 0)
     52     return 0;
     53   if (strncmp(buffer, "cpu", 3) != 0)
     54     return 0;
     55   buffer += 3;
     56   while (isspace(*buffer))
     57     buffer++;
     58 
     59   /* Check if 'feature' is present in the buffer as a separate word */
     60   while ((p = strstr(buffer, feature))) {
     61     if (p > buffer && !isspace(*(p - 1))) {
     62       buffer++;
     63       continue;
     64     }
     65     p += strlen(feature);
     66     if (*p != 0 && !isspace(*p)) {
     67       buffer++;
     68       continue;
     69     }
     70     return 1;
     71   }
     72   return 0;
     73 }
     74 
     75 LOCAL(int)
     76 parse_proc_cpuinfo(int bufsize)
     77 {
     78   char *buffer = (char *)malloc(bufsize);
     79   FILE *fd;
     80 
     81   simd_support = 0;
     82 
     83   if (!buffer)
     84     return 0;
     85 
     86   fd = fopen("/proc/cpuinfo", "r");
     87   if (fd) {
     88     while (fgets(buffer, bufsize, fd)) {
     89       if (!strchr(buffer, '\n') && !feof(fd)) {
     90         /* "impossible" happened - insufficient size of the buffer! */
     91         fclose(fd);
     92         free(buffer);
     93         return 0;
     94       }
     95       if (check_feature(buffer, "altivec"))
     96         simd_support |= JSIMD_ALTIVEC;
     97     }
     98     fclose(fd);
     99   }
    100   free(buffer);
    101   return 1;
    102 }
    103 
    104 #endif
    105 
    106 /*
    107  * Check what SIMD accelerations are supported.
    108  *
    109  * FIXME: This code is racy under a multi-threaded environment.
    110  */
    111 LOCAL(void)
    112 init_simd(void)
    113 {
    114 #ifndef NO_GETENV
    115   char *env = NULL;
    116 #endif
    117 #if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
    118   int bufsize = 1024; /* an initial guess for the line buffer size limit */
    119 #elif defined(__amigaos4__)
    120   uint32 altivec = 0;
    121 #elif defined(__OpenBSD__)
    122   int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
    123   int altivec;
    124   size_t len = sizeof(altivec);
    125 #endif
    126 
    127   if (simd_support != ~0U)
    128     return;
    129 
    130   simd_support = 0;
    131 
    132 #if defined(__ALTIVEC__) || defined(__APPLE__)
    133   simd_support |= JSIMD_ALTIVEC;
    134 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
    135   while (!parse_proc_cpuinfo(bufsize)) {
    136     bufsize *= 2;
    137     if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
    138       break;
    139   }
    140 #elif defined(__amigaos4__)
    141   IExec->GetCPUInfoTags(GCIT_VectorUnit, &altivec, TAG_DONE);
    142   if (altivec == VECTORTYPE_ALTIVEC)
    143     simd_support |= JSIMD_ALTIVEC;
    144 #elif defined(__OpenBSD__)
    145   if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0)
    146     simd_support |= JSIMD_ALTIVEC;
    147 #endif
    148 
    149 #ifndef NO_GETENV
    150   /* Force different settings through environment variables */
    151   env = getenv("JSIMD_FORCEALTIVEC");
    152   if ((env != NULL) && (strcmp(env, "1") == 0))
    153     simd_support = JSIMD_ALTIVEC;
    154   env = getenv("JSIMD_FORCENONE");
    155   if ((env != NULL) && (strcmp(env, "1") == 0))
    156     simd_support = 0;
    157 #endif
    158 }
    159 
    160 GLOBAL(int)
    161 jsimd_can_rgb_ycc(void)
    162 {
    163   init_simd();
    164 
    165   /* The code is optimised for these values only */
    166   if (BITS_IN_JSAMPLE != 8)
    167     return 0;
    168   if (sizeof(JDIMENSION) != 4)
    169     return 0;
    170   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    171     return 0;
    172 
    173   if (simd_support & JSIMD_ALTIVEC)
    174     return 1;
    175 
    176   return 0;
    177 }
    178 
    179 GLOBAL(int)
    180 jsimd_can_rgb_gray(void)
    181 {
    182   init_simd();
    183 
    184   /* The code is optimised for these values only */
    185   if (BITS_IN_JSAMPLE != 8)
    186     return 0;
    187   if (sizeof(JDIMENSION) != 4)
    188     return 0;
    189   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    190     return 0;
    191 
    192   if (simd_support & JSIMD_ALTIVEC)
    193     return 1;
    194 
    195   return 0;
    196 }
    197 
    198 GLOBAL(int)
    199 jsimd_can_ycc_rgb(void)
    200 {
    201   init_simd();
    202 
    203   /* The code is optimised for these values only */
    204   if (BITS_IN_JSAMPLE != 8)
    205     return 0;
    206   if (sizeof(JDIMENSION) != 4)
    207     return 0;
    208   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    209     return 0;
    210 
    211   if (simd_support & JSIMD_ALTIVEC)
    212     return 1;
    213 
    214   return 0;
    215 }
    216 
    217 GLOBAL(int)
    218 jsimd_can_ycc_rgb565(void)
    219 {
    220   return 0;
    221 }
    222 
    223 GLOBAL(void)
    224 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
    225                       JSAMPIMAGE output_buf, JDIMENSION output_row,
    226                       int num_rows)
    227 {
    228   void (*altivecfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
    229 
    230   switch (cinfo->in_color_space) {
    231   case JCS_EXT_RGB:
    232     altivecfct = jsimd_extrgb_ycc_convert_altivec;
    233     break;
    234   case JCS_EXT_RGBX:
    235   case JCS_EXT_RGBA:
    236     altivecfct = jsimd_extrgbx_ycc_convert_altivec;
    237     break;
    238   case JCS_EXT_BGR:
    239     altivecfct = jsimd_extbgr_ycc_convert_altivec;
    240     break;
    241   case JCS_EXT_BGRX:
    242   case JCS_EXT_BGRA:
    243     altivecfct = jsimd_extbgrx_ycc_convert_altivec;
    244     break;
    245   case JCS_EXT_XBGR:
    246   case JCS_EXT_ABGR:
    247     altivecfct = jsimd_extxbgr_ycc_convert_altivec;
    248     break;
    249   case JCS_EXT_XRGB:
    250   case JCS_EXT_ARGB:
    251     altivecfct = jsimd_extxrgb_ycc_convert_altivec;
    252     break;
    253   default:
    254     altivecfct = jsimd_rgb_ycc_convert_altivec;
    255     break;
    256   }
    257 
    258   altivecfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
    259 }
    260 
    261 GLOBAL(void)
    262 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
    263                        JSAMPIMAGE output_buf, JDIMENSION output_row,
    264                        int num_rows)
    265 {
    266   void (*altivecfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
    267 
    268   switch (cinfo->in_color_space) {
    269   case JCS_EXT_RGB:
    270     altivecfct = jsimd_extrgb_gray_convert_altivec;
    271     break;
    272   case JCS_EXT_RGBX:
    273   case JCS_EXT_RGBA:
    274     altivecfct = jsimd_extrgbx_gray_convert_altivec;
    275     break;
    276   case JCS_EXT_BGR:
    277     altivecfct = jsimd_extbgr_gray_convert_altivec;
    278     break;
    279   case JCS_EXT_BGRX:
    280   case JCS_EXT_BGRA:
    281     altivecfct = jsimd_extbgrx_gray_convert_altivec;
    282     break;
    283   case JCS_EXT_XBGR:
    284   case JCS_EXT_ABGR:
    285     altivecfct = jsimd_extxbgr_gray_convert_altivec;
    286     break;
    287   case JCS_EXT_XRGB:
    288   case JCS_EXT_ARGB:
    289     altivecfct = jsimd_extxrgb_gray_convert_altivec;
    290     break;
    291   default:
    292     altivecfct = jsimd_rgb_gray_convert_altivec;
    293     break;
    294   }
    295 
    296   altivecfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
    297 }
    298 
    299 GLOBAL(void)
    300 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    301                       JDIMENSION input_row, JSAMPARRAY output_buf,
    302                       int num_rows)
    303 {
    304   void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
    305 
    306   switch (cinfo->out_color_space) {
    307   case JCS_EXT_RGB:
    308     altivecfct = jsimd_ycc_extrgb_convert_altivec;
    309     break;
    310   case JCS_EXT_RGBX:
    311   case JCS_EXT_RGBA:
    312     altivecfct = jsimd_ycc_extrgbx_convert_altivec;
    313     break;
    314   case JCS_EXT_BGR:
    315     altivecfct = jsimd_ycc_extbgr_convert_altivec;
    316     break;
    317   case JCS_EXT_BGRX:
    318   case JCS_EXT_BGRA:
    319     altivecfct = jsimd_ycc_extbgrx_convert_altivec;
    320     break;
    321   case JCS_EXT_XBGR:
    322   case JCS_EXT_ABGR:
    323     altivecfct = jsimd_ycc_extxbgr_convert_altivec;
    324     break;
    325   case JCS_EXT_XRGB:
    326   case JCS_EXT_ARGB:
    327     altivecfct = jsimd_ycc_extxrgb_convert_altivec;
    328     break;
    329   default:
    330     altivecfct = jsimd_ycc_rgb_convert_altivec;
    331     break;
    332   }
    333 
    334   altivecfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
    335 }
    336 
    337 GLOBAL(void)
    338 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    339                          JDIMENSION input_row, JSAMPARRAY output_buf,
    340                          int num_rows)
    341 {
    342 }
    343 
    344 GLOBAL(int)
    345 jsimd_can_h2v2_downsample(void)
    346 {
    347   init_simd();
    348 
    349   /* The code is optimised for these values only */
    350   if (BITS_IN_JSAMPLE != 8)
    351     return 0;
    352   if (sizeof(JDIMENSION) != 4)
    353     return 0;
    354 
    355   if (simd_support & JSIMD_ALTIVEC)
    356     return 1;
    357 
    358   return 0;
    359 }
    360 
    361 GLOBAL(int)
    362 jsimd_can_h2v1_downsample(void)
    363 {
    364   init_simd();
    365 
    366   /* The code is optimised for these values only */
    367   if (BITS_IN_JSAMPLE != 8)
    368     return 0;
    369   if (sizeof(JDIMENSION) != 4)
    370     return 0;
    371 
    372   if (simd_support & JSIMD_ALTIVEC)
    373     return 1;
    374 
    375   return 0;
    376 }
    377 
    378 GLOBAL(void)
    379 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
    380                       JSAMPARRAY input_data, JSAMPARRAY output_data)
    381 {
    382   jsimd_h2v2_downsample_altivec(cinfo->image_width, cinfo->max_v_samp_factor,
    383                                 compptr->v_samp_factor,
    384                                 compptr->width_in_blocks, input_data,
    385                                 output_data);
    386 }
    387 
    388 GLOBAL(void)
    389 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
    390                       JSAMPARRAY input_data, JSAMPARRAY output_data)
    391 {
    392   jsimd_h2v1_downsample_altivec(cinfo->image_width, cinfo->max_v_samp_factor,
    393                                 compptr->v_samp_factor,
    394                                 compptr->width_in_blocks, input_data,
    395                                 output_data);
    396 }
    397 
    398 GLOBAL(int)
    399 jsimd_can_h2v2_upsample(void)
    400 {
    401   init_simd();
    402 
    403   /* The code is optimised for these values only */
    404   if (BITS_IN_JSAMPLE != 8)
    405     return 0;
    406   if (sizeof(JDIMENSION) != 4)
    407     return 0;
    408 
    409   if (simd_support & JSIMD_ALTIVEC)
    410     return 1;
    411 
    412   return 0;
    413 }
    414 
    415 GLOBAL(int)
    416 jsimd_can_h2v1_upsample(void)
    417 {
    418   init_simd();
    419 
    420   /* The code is optimised for these values only */
    421   if (BITS_IN_JSAMPLE != 8)
    422     return 0;
    423   if (sizeof(JDIMENSION) != 4)
    424     return 0;
    425 
    426   if (simd_support & JSIMD_ALTIVEC)
    427     return 1;
    428 
    429   return 0;
    430 }
    431 
    432 GLOBAL(void)
    433 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    434                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    435 {
    436   jsimd_h2v2_upsample_altivec(cinfo->max_v_samp_factor, cinfo->output_width,
    437                               input_data, output_data_ptr);
    438 }
    439 
    440 GLOBAL(void)
    441 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    442                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    443 {
    444   jsimd_h2v1_upsample_altivec(cinfo->max_v_samp_factor, cinfo->output_width,
    445                               input_data, output_data_ptr);
    446 }
    447 
    448 GLOBAL(int)
    449 jsimd_can_h2v2_fancy_upsample(void)
    450 {
    451   init_simd();
    452 
    453   /* The code is optimised for these values only */
    454   if (BITS_IN_JSAMPLE != 8)
    455     return 0;
    456   if (sizeof(JDIMENSION) != 4)
    457     return 0;
    458 
    459   if (simd_support & JSIMD_ALTIVEC)
    460     return 1;
    461 
    462   return 0;
    463 }
    464 
    465 GLOBAL(int)
    466 jsimd_can_h2v1_fancy_upsample(void)
    467 {
    468   init_simd();
    469 
    470   /* The code is optimised for these values only */
    471   if (BITS_IN_JSAMPLE != 8)
    472     return 0;
    473   if (sizeof(JDIMENSION) != 4)
    474     return 0;
    475 
    476   if (simd_support & JSIMD_ALTIVEC)
    477     return 1;
    478 
    479   return 0;
    480 }
    481 
    482 GLOBAL(void)
    483 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    484                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    485 {
    486   jsimd_h2v2_fancy_upsample_altivec(cinfo->max_v_samp_factor,
    487                                     compptr->downsampled_width, input_data,
    488                                     output_data_ptr);
    489 }
    490 
    491 GLOBAL(void)
    492 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    493                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    494 {
    495   jsimd_h2v1_fancy_upsample_altivec(cinfo->max_v_samp_factor,
    496                                     compptr->downsampled_width, input_data,
    497                                     output_data_ptr);
    498 }
    499 
    500 GLOBAL(int)
    501 jsimd_can_h2v2_merged_upsample(void)
    502 {
    503   init_simd();
    504 
    505   /* The code is optimised for these values only */
    506   if (BITS_IN_JSAMPLE != 8)
    507     return 0;
    508   if (sizeof(JDIMENSION) != 4)
    509     return 0;
    510 
    511   if (simd_support & JSIMD_ALTIVEC)
    512     return 1;
    513 
    514   return 0;
    515 }
    516 
    517 GLOBAL(int)
    518 jsimd_can_h2v1_merged_upsample(void)
    519 {
    520   init_simd();
    521 
    522   /* The code is optimised for these values only */
    523   if (BITS_IN_JSAMPLE != 8)
    524     return 0;
    525   if (sizeof(JDIMENSION) != 4)
    526     return 0;
    527 
    528   if (simd_support & JSIMD_ALTIVEC)
    529     return 1;
    530 
    531   return 0;
    532 }
    533 
    534 GLOBAL(void)
    535 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    536                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
    537 {
    538   void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
    539 
    540   switch (cinfo->out_color_space) {
    541   case JCS_EXT_RGB:
    542     altivecfct = jsimd_h2v2_extrgb_merged_upsample_altivec;
    543     break;
    544   case JCS_EXT_RGBX:
    545   case JCS_EXT_RGBA:
    546     altivecfct = jsimd_h2v2_extrgbx_merged_upsample_altivec;
    547     break;
    548   case JCS_EXT_BGR:
    549     altivecfct = jsimd_h2v2_extbgr_merged_upsample_altivec;
    550     break;
    551   case JCS_EXT_BGRX:
    552   case JCS_EXT_BGRA:
    553     altivecfct = jsimd_h2v2_extbgrx_merged_upsample_altivec;
    554     break;
    555   case JCS_EXT_XBGR:
    556   case JCS_EXT_ABGR:
    557     altivecfct = jsimd_h2v2_extxbgr_merged_upsample_altivec;
    558     break;
    559   case JCS_EXT_XRGB:
    560   case JCS_EXT_ARGB:
    561     altivecfct = jsimd_h2v2_extxrgb_merged_upsample_altivec;
    562     break;
    563   default:
    564     altivecfct = jsimd_h2v2_merged_upsample_altivec;
    565     break;
    566   }
    567 
    568   altivecfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
    569 }
    570 
    571 GLOBAL(void)
    572 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    573                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
    574 {
    575   void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
    576 
    577   switch (cinfo->out_color_space) {
    578   case JCS_EXT_RGB:
    579     altivecfct = jsimd_h2v1_extrgb_merged_upsample_altivec;
    580     break;
    581   case JCS_EXT_RGBX:
    582   case JCS_EXT_RGBA:
    583     altivecfct = jsimd_h2v1_extrgbx_merged_upsample_altivec;
    584     break;
    585   case JCS_EXT_BGR:
    586     altivecfct = jsimd_h2v1_extbgr_merged_upsample_altivec;
    587     break;
    588   case JCS_EXT_BGRX:
    589   case JCS_EXT_BGRA:
    590     altivecfct = jsimd_h2v1_extbgrx_merged_upsample_altivec;
    591     break;
    592   case JCS_EXT_XBGR:
    593   case JCS_EXT_ABGR:
    594     altivecfct = jsimd_h2v1_extxbgr_merged_upsample_altivec;
    595     break;
    596   case JCS_EXT_XRGB:
    597   case JCS_EXT_ARGB:
    598     altivecfct = jsimd_h2v1_extxrgb_merged_upsample_altivec;
    599     break;
    600   default:
    601     altivecfct = jsimd_h2v1_merged_upsample_altivec;
    602     break;
    603   }
    604 
    605   altivecfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
    606 }
    607 
    608 GLOBAL(int)
    609 jsimd_can_convsamp(void)
    610 {
    611   init_simd();
    612 
    613   /* The code is optimised for these values only */
    614   if (DCTSIZE != 8)
    615     return 0;
    616   if (BITS_IN_JSAMPLE != 8)
    617     return 0;
    618   if (sizeof(JDIMENSION) != 4)
    619     return 0;
    620   if (sizeof(DCTELEM) != 2)
    621     return 0;
    622 
    623   if (simd_support & JSIMD_ALTIVEC)
    624     return 1;
    625 
    626   return 0;
    627 }
    628 
    629 GLOBAL(int)
    630 jsimd_can_convsamp_float(void)
    631 {
    632   return 0;
    633 }
    634 
    635 GLOBAL(void)
    636 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
    637                DCTELEM *workspace)
    638 {
    639   jsimd_convsamp_altivec(sample_data, start_col, workspace);
    640 }
    641 
    642 GLOBAL(void)
    643 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
    644                      FAST_FLOAT *workspace)
    645 {
    646 }
    647 
    648 GLOBAL(int)
    649 jsimd_can_fdct_islow(void)
    650 {
    651   init_simd();
    652 
    653   /* The code is optimised for these values only */
    654   if (DCTSIZE != 8)
    655     return 0;
    656   if (sizeof(DCTELEM) != 2)
    657     return 0;
    658 
    659   if (simd_support & JSIMD_ALTIVEC)
    660     return 1;
    661 
    662   return 0;
    663 }
    664 
    665 GLOBAL(int)
    666 jsimd_can_fdct_ifast(void)
    667 {
    668   init_simd();
    669 
    670   /* The code is optimised for these values only */
    671   if (DCTSIZE != 8)
    672     return 0;
    673   if (sizeof(DCTELEM) != 2)
    674     return 0;
    675 
    676   if (simd_support & JSIMD_ALTIVEC)
    677     return 1;
    678 
    679   return 0;
    680 }
    681 
    682 GLOBAL(int)
    683 jsimd_can_fdct_float(void)
    684 {
    685   return 0;
    686 }
    687 
    688 GLOBAL(void)
    689 jsimd_fdct_islow(DCTELEM *data)
    690 {
    691   jsimd_fdct_islow_altivec(data);
    692 }
    693 
    694 GLOBAL(void)
    695 jsimd_fdct_ifast(DCTELEM *data)
    696 {
    697   jsimd_fdct_ifast_altivec(data);
    698 }
    699 
    700 GLOBAL(void)
    701 jsimd_fdct_float(FAST_FLOAT *data)
    702 {
    703 }
    704 
    705 GLOBAL(int)
    706 jsimd_can_quantize(void)
    707 {
    708   init_simd();
    709 
    710   /* The code is optimised for these values only */
    711   if (DCTSIZE != 8)
    712     return 0;
    713   if (sizeof(JCOEF) != 2)
    714     return 0;
    715   if (sizeof(DCTELEM) != 2)
    716     return 0;
    717 
    718   if (simd_support & JSIMD_ALTIVEC)
    719     return 1;
    720 
    721   return 0;
    722 }
    723 
    724 GLOBAL(int)
    725 jsimd_can_quantize_float(void)
    726 {
    727   return 0;
    728 }
    729 
    730 GLOBAL(void)
    731 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
    732 {
    733   jsimd_quantize_altivec(coef_block, divisors, workspace);
    734 }
    735 
    736 GLOBAL(void)
    737 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
    738                      FAST_FLOAT *workspace)
    739 {
    740 }
    741 
    742 GLOBAL(int)
    743 jsimd_can_idct_2x2(void)
    744 {
    745   return 0;
    746 }
    747 
    748 GLOBAL(int)
    749 jsimd_can_idct_4x4(void)
    750 {
    751   return 0;
    752 }
    753 
    754 GLOBAL(void)
    755 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    756                JCOEFPTR coef_block, JSAMPARRAY output_buf,
    757                JDIMENSION output_col)
    758 {
    759 }
    760 
    761 GLOBAL(void)
    762 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    763                JCOEFPTR coef_block, JSAMPARRAY output_buf,
    764                JDIMENSION output_col)
    765 {
    766 }
    767 
    768 GLOBAL(int)
    769 jsimd_can_idct_islow(void)
    770 {
    771   init_simd();
    772 
    773   /* The code is optimised for these values only */
    774   if (DCTSIZE != 8)
    775     return 0;
    776   if (sizeof(JCOEF) != 2)
    777     return 0;
    778 
    779   if (simd_support & JSIMD_ALTIVEC)
    780     return 1;
    781 
    782   return 0;
    783 }
    784 
    785 GLOBAL(int)
    786 jsimd_can_idct_ifast(void)
    787 {
    788   init_simd();
    789 
    790   /* The code is optimised for these values only */
    791   if (DCTSIZE != 8)
    792     return 0;
    793   if (sizeof(JCOEF) != 2)
    794     return 0;
    795 
    796   if (simd_support & JSIMD_ALTIVEC)
    797     return 1;
    798 
    799   return 0;
    800 }
    801 
    802 GLOBAL(int)
    803 jsimd_can_idct_float(void)
    804 {
    805   return 0;
    806 }
    807 
    808 GLOBAL(void)
    809 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    810                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
    811                  JDIMENSION output_col)
    812 {
    813   jsimd_idct_islow_altivec(compptr->dct_table, coef_block, output_buf,
    814                            output_col);
    815 }
    816 
    817 GLOBAL(void)
    818 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    819                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
    820                  JDIMENSION output_col)
    821 {
    822   jsimd_idct_ifast_altivec(compptr->dct_table, coef_block, output_buf,
    823                            output_col);
    824 }
    825 
    826 GLOBAL(void)
    827 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    828                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
    829                  JDIMENSION output_col)
    830 {
    831 }
    832 
    833 GLOBAL(int)
    834 jsimd_can_huff_encode_one_block(void)
    835 {
    836   return 0;
    837 }
    838 
    839 GLOBAL(JOCTET *)
    840 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
    841                             int last_dc_val, c_derived_tbl *dctbl,
    842                             c_derived_tbl *actbl)
    843 {
    844   return NULL;
    845 }
    846 
    847 GLOBAL(int)
    848 jsimd_can_encode_mcu_AC_first_prepare(void)
    849 {
    850   return 0;
    851 }
    852 
    853 GLOBAL(void)
    854 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
    855                                   const int *jpeg_natural_order_start, int Sl,
    856                                   int Al, JCOEF *values, size_t *zerobits)
    857 {
    858 }
    859 
    860 GLOBAL(int)
    861 jsimd_can_encode_mcu_AC_refine_prepare(void)
    862 {
    863   return 0;
    864 }
    865 
    866 GLOBAL(int)
    867 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
    868                                    const int *jpeg_natural_order_start, int Sl,
    869                                    int Al, JCOEF *absvalues, size_t *bits)
    870 {
    871   return 0;
    872 }
    873