< prev index next >

src/share/native/sun/awt/libpng/pngrtran.c

Print this page
rev 13657 : 8217676: Upgrade libpng to 1.6.37
Reviewed-by: prr, jdv, kcr


  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /* pngrtran.c - transforms the data in a row for PNG readers
  26  *
  27  * This file is available under and governed by the GNU General Public
  28  * License version 2 only, as published by the Free Software Foundation.
  29  * However, the following notice accompanied the original version of this
  30  * file and, per its terms, should not be removed:
  31  *
  32  * Last changed in libpng 1.6.35 [July 15, 2018]
  33  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  34  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  35  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  36  *
  37  * This code is released under the libpng license.
  38  * For conditions of distribution and use, see the disclaimer
  39  * and license in png.h
  40  *
  41  * This file contains functions optionally called by an application
  42  * in order to tell libpng how to handle data when reading a PNG.
  43  * Transformations that are used in both reading and writing are
  44  * in pngtrans.c.
  45  */
  46 
  47 #include "pngpriv.h"
  48 











  49 #ifdef PNG_READ_SUPPORTED
  50 
  51 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
  52 void PNGAPI
  53 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
  54 {
  55    png_debug(1, "in png_set_crc_action");
  56 
  57    if (png_ptr == NULL)
  58       return;
  59 
  60    /* Tell libpng how we react to CRC errors in critical chunks */
  61    switch (crit_action)
  62    {
  63       case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
  64          break;
  65 
  66       case PNG_CRC_WARN_USE:                               /* Warn/use data */
  67          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  68          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;


1191        (png_ptr->transformations & PNG_EXPAND) != 0)
1192    {
1193       {
1194          png_ptr->background.red   =
1195              png_ptr->palette[png_ptr->background.index].red;
1196          png_ptr->background.green =
1197              png_ptr->palette[png_ptr->background.index].green;
1198          png_ptr->background.blue  =
1199              png_ptr->palette[png_ptr->background.index].blue;
1200 
1201 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1202         if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
1203         {
1204            if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1205            {
1206               /* Invert the alpha channel (in tRNS) unless the pixels are
1207                * going to be expanded, in which case leave it for later
1208                */
1209               int i, istop = png_ptr->num_trans;
1210 
1211               for (i=0; i<istop; i++)
1212                  png_ptr->trans_alpha[i] = (png_byte)(255 -
1213                     png_ptr->trans_alpha[i]);
1214            }
1215         }
1216 #endif /* READ_INVERT_ALPHA */
1217       }
1218    } /* background expand and (therefore) no alpha association. */
1219 #endif /* READ_EXPAND && READ_BACKGROUND */
1220 }
1221 
1222 static void /* PRIVATE */
1223 png_init_rgb_transformations(png_structrp png_ptr)
1224 {
1225    /* Added to libpng-1.5.4: check the color type to determine whether there
1226     * is any alpha or transparency in the image and simply cancel the
1227     * background and alpha mode stuff if there isn't.
1228     */
1229    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1230    int input_has_transparency = png_ptr->num_trans > 0;
1231 
1232    /* If no alpha we can optimize. */
1233    if (input_has_alpha == 0)


2997  *  libpng uses, instead, the closest non-overflowing approximation:
2998  *
2999  *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
3000  *
3001  *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
3002  *  (including an sRGB chunk) then the chromaticities are used to calculate the
3003  *  coefficients.  See the chunk handling in pngrutil.c for more information.
3004  *
3005  *  In all cases the calculation is to be done in a linear colorspace.  If no
3006  *  gamma information is available to correct the encoding of the original RGB
3007  *  values this results in an implicit assumption that the original PNG RGB
3008  *  values were linear.
3009  *
3010  *  Other integer coefficients can be used via png_set_rgb_to_gray().  Because
3011  *  the API takes just red and green coefficients the blue coefficient is
3012  *  calculated to make the sum 32768.  This will result in different rounding
3013  *  to that used above.
3014  */
3015 static int
3016 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
3017 
3018 {
3019    int rgb_error = 0;
3020 
3021    png_debug(1, "in png_do_rgb_to_gray");
3022 
3023    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
3024        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
3025    {
3026       PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3027       PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3028       PNG_CONST png_uint_32 bc = 32768 - rc - gc;
3029       PNG_CONST png_uint_32 row_width = row_info->width;
3030       PNG_CONST int have_alpha =
3031          (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3032 
3033       if (row_info->bit_depth == 8)
3034       {
3035 #ifdef PNG_READ_GAMMA_SUPPORTED
3036          /* Notice that gamma to/from 1 are not necessarily inverses (if
3037           * there is an overall gamma correction).  Prior to 1.5.5 this code
3038           * checked the linearized values for equality; this doesn't match
3039           * the documentation, the original values must be checked.
3040           */
3041          if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3042          {
3043             png_bytep sp = row;
3044             png_bytep dp = row;
3045             png_uint_32 i;
3046 
3047             for (i = 0; i < row_width; i++)
3048             {
3049                png_byte red   = *(sp++);
3050                png_byte green = *(sp++);
3051                png_byte blue  = *(sp++);


4154    }
4155 }
4156 #endif
4157 
4158 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4159 /* Encode the alpha channel to the output gamma (the input channel is always
4160  * linear.)  Called only with color types that have an alpha channel.  Needs the
4161  * from_1 tables.
4162  */
4163 static void
4164 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4165 {
4166    png_uint_32 row_width = row_info->width;
4167 
4168    png_debug(1, "in png_do_encode_alpha");
4169 
4170    if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4171    {
4172       if (row_info->bit_depth == 8)
4173       {
4174          PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4175 
4176          if (table != NULL)
4177          {
4178             PNG_CONST int step =
4179                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4180 
4181             /* The alpha channel is the last component: */
4182             row += step - 1;
4183 
4184             for (; row_width > 0; --row_width, row += step)
4185                *row = table[*row];
4186 
4187             return;
4188          }
4189       }
4190 
4191       else if (row_info->bit_depth == 16)
4192       {
4193          PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4194          PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4195 
4196          if (table != NULL)
4197          {
4198             PNG_CONST int step =
4199                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4200 
4201             /* The alpha channel is the last component: */
4202             row += step - 2;
4203 
4204             for (; row_width > 0; --row_width, row += step)
4205             {
4206                png_uint_16 v;
4207 
4208                v = table[*(row + 1) >> gamma_shift][*row];
4209                *row = (png_byte)((v >> 8) & 0xff);
4210                *(row + 1) = (png_byte)(v & 0xff);
4211             }
4212 
4213             return;
4214          }
4215       }
4216    }
4217 
4218    /* Only get to here if called with a weird row_info; no harm has been done,
4219     * so just issue a warning.
4220     */
4221    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4222 }
4223 #endif
4224 
4225 #ifdef PNG_READ_EXPAND_SUPPORTED
4226 /* Expands a palette row to an RGB or RGBA row depending
4227  * upon whether you supply trans and num_trans.
4228  */
4229 static void
4230 png_do_expand_palette(png_row_infop row_info, png_bytep row,
4231     png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)

4232 {
4233    int shift, value;
4234    png_bytep sp, dp;
4235    png_uint_32 i;
4236    png_uint_32 row_width=row_info->width;
4237 
4238    png_debug(1, "in png_do_expand_palette");
4239 
4240    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4241    {
4242       if (row_info->bit_depth < 8)
4243       {
4244          switch (row_info->bit_depth)
4245          {
4246             case 1:
4247             {
4248                sp = row + (size_t)((row_width - 1) >> 3);
4249                dp = row + (size_t)row_width - 1;
4250                shift = 7 - (int)((row_width + 7) & 0x07);
4251                for (i = 0; i < row_width; i++)


4315                }
4316                break;
4317             }
4318 
4319             default:
4320                break;
4321          }
4322          row_info->bit_depth = 8;
4323          row_info->pixel_depth = 8;
4324          row_info->rowbytes = row_width;
4325       }
4326 
4327       if (row_info->bit_depth == 8)
4328       {
4329          {
4330             if (num_trans > 0)
4331             {
4332                sp = row + (size_t)row_width - 1;
4333                dp = row + ((size_t)row_width << 2) - 1;
4334 
4335                for (i = 0; i < row_width; i++)















4336                {
4337                   if ((int)(*sp) >= num_trans)
4338                      *dp-- = 0xff;
4339 
4340                   else
4341                      *dp-- = trans_alpha[*sp];
4342 
4343                   *dp-- = palette[*sp].blue;
4344                   *dp-- = palette[*sp].green;
4345                   *dp-- = palette[*sp].red;
4346                   sp--;
4347                }
4348                row_info->bit_depth = 8;
4349                row_info->pixel_depth = 32;
4350                row_info->rowbytes = row_width * 4;
4351                row_info->color_type = 6;
4352                row_info->channels = 4;
4353             }
4354 
4355             else
4356             {
4357                sp = row + (size_t)row_width - 1;
4358                dp = row + (size_t)(row_width * 3) - 1;







4359 
4360                for (i = 0; i < row_width; i++)
4361                {
4362                   *dp-- = palette[*sp].blue;
4363                   *dp-- = palette[*sp].green;
4364                   *dp-- = palette[*sp].red;
4365                   sp--;
4366                }
4367 
4368                row_info->bit_depth = 8;
4369                row_info->pixel_depth = 24;
4370                row_info->rowbytes = row_width * 3;
4371                row_info->color_type = 2;
4372                row_info->channels = 3;
4373             }
4374          }
4375       }
4376    }
4377 }
4378 
4379 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
4380  * expanded transparency value is supplied, an alpha channel is built.


4754     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
4755     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
4756     * all transformations, however in practice the ROW_INIT always gets done on
4757     * demand, if necessary.
4758     */
4759    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4760        (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4761    {
4762       /* Application has failed to call either png_read_start_image() or
4763        * png_read_update_info() after setting transforms that expand pixels.
4764        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
4765        */
4766       png_error(png_ptr, "Uninitialized row");
4767    }
4768 
4769 #ifdef PNG_READ_EXPAND_SUPPORTED
4770    if ((png_ptr->transformations & PNG_EXPAND) != 0)
4771    {
4772       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4773       {
4774          png_do_expand_palette(row_info, png_ptr->row_buf + 1,












4775              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4776       }
4777 
4778       else
4779       {
4780          if (png_ptr->num_trans != 0 &&
4781              (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4782             png_do_expand(row_info, png_ptr->row_buf + 1,
4783                 &(png_ptr->trans_color));
4784 
4785          else
4786             png_do_expand(row_info, png_ptr->row_buf + 1, NULL);
4787       }
4788    }
4789 #endif
4790 
4791 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4792    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4793        (png_ptr->transformations & PNG_COMPOSE) == 0 &&
4794        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||




  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /* pngrtran.c - transforms the data in a row for PNG readers
  26  *
  27  * This file is available under and governed by the GNU General Public
  28  * License version 2 only, as published by the Free Software Foundation.
  29  * However, the following notice accompanied the original version of this
  30  * file and, per its terms, should not be removed:
  31  *
  32  * Copyright (c) 2018-2019 Cosmin Truta
  33  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  34  * Copyright (c) 1996-1997 Andreas Dilger
  35  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  36  *
  37  * This code is released under the libpng license.
  38  * For conditions of distribution and use, see the disclaimer
  39  * and license in png.h
  40  *
  41  * This file contains functions optionally called by an application
  42  * in order to tell libpng how to handle data when reading a PNG.
  43  * Transformations that are used in both reading and writing are
  44  * in pngtrans.c.
  45  */
  46 
  47 #include "pngpriv.h"
  48 
  49 #ifdef PNG_ARM_NEON_IMPLEMENTATION
  50 #  if PNG_ARM_NEON_IMPLEMENTATION == 1
  51 #    define PNG_ARM_NEON_INTRINSICS_AVAILABLE
  52 #    if defined(_MSC_VER) && defined(_M_ARM64)
  53 #      include <arm64_neon.h>
  54 #    else
  55 #      include <arm_neon.h>
  56 #    endif
  57 #  endif
  58 #endif
  59 
  60 #ifdef PNG_READ_SUPPORTED
  61 
  62 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
  63 void PNGAPI
  64 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
  65 {
  66    png_debug(1, "in png_set_crc_action");
  67 
  68    if (png_ptr == NULL)
  69       return;
  70 
  71    /* Tell libpng how we react to CRC errors in critical chunks */
  72    switch (crit_action)
  73    {
  74       case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
  75          break;
  76 
  77       case PNG_CRC_WARN_USE:                               /* Warn/use data */
  78          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  79          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;


1202        (png_ptr->transformations & PNG_EXPAND) != 0)
1203    {
1204       {
1205          png_ptr->background.red   =
1206              png_ptr->palette[png_ptr->background.index].red;
1207          png_ptr->background.green =
1208              png_ptr->palette[png_ptr->background.index].green;
1209          png_ptr->background.blue  =
1210              png_ptr->palette[png_ptr->background.index].blue;
1211 
1212 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1213          if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
1214          {
1215             if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1216             {
1217                /* Invert the alpha channel (in tRNS) unless the pixels are
1218                 * going to be expanded, in which case leave it for later
1219                 */
1220                int i, istop = png_ptr->num_trans;
1221 
1222                for (i = 0; i < istop; i++)
1223                   png_ptr->trans_alpha[i] =
1224                       (png_byte)(255 - png_ptr->trans_alpha[i]);
1225             }
1226          }
1227 #endif /* READ_INVERT_ALPHA */
1228       }
1229    } /* background expand and (therefore) no alpha association. */
1230 #endif /* READ_EXPAND && READ_BACKGROUND */
1231 }
1232 
1233 static void /* PRIVATE */
1234 png_init_rgb_transformations(png_structrp png_ptr)
1235 {
1236    /* Added to libpng-1.5.4: check the color type to determine whether there
1237     * is any alpha or transparency in the image and simply cancel the
1238     * background and alpha mode stuff if there isn't.
1239     */
1240    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1241    int input_has_transparency = png_ptr->num_trans > 0;
1242 
1243    /* If no alpha we can optimize. */
1244    if (input_has_alpha == 0)


3008  *  libpng uses, instead, the closest non-overflowing approximation:
3009  *
3010  *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
3011  *
3012  *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
3013  *  (including an sRGB chunk) then the chromaticities are used to calculate the
3014  *  coefficients.  See the chunk handling in pngrutil.c for more information.
3015  *
3016  *  In all cases the calculation is to be done in a linear colorspace.  If no
3017  *  gamma information is available to correct the encoding of the original RGB
3018  *  values this results in an implicit assumption that the original PNG RGB
3019  *  values were linear.
3020  *
3021  *  Other integer coefficients can be used via png_set_rgb_to_gray().  Because
3022  *  the API takes just red and green coefficients the blue coefficient is
3023  *  calculated to make the sum 32768.  This will result in different rounding
3024  *  to that used above.
3025  */
3026 static int
3027 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)

3028 {
3029    int rgb_error = 0;
3030 
3031    png_debug(1, "in png_do_rgb_to_gray");
3032 
3033    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
3034        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
3035    {
3036       png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3037       png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3038       png_uint_32 bc = 32768 - rc - gc;
3039       png_uint_32 row_width = row_info->width;
3040       int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;

3041 
3042       if (row_info->bit_depth == 8)
3043       {
3044 #ifdef PNG_READ_GAMMA_SUPPORTED
3045          /* Notice that gamma to/from 1 are not necessarily inverses (if
3046           * there is an overall gamma correction).  Prior to 1.5.5 this code
3047           * checked the linearized values for equality; this doesn't match
3048           * the documentation, the original values must be checked.
3049           */
3050          if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3051          {
3052             png_bytep sp = row;
3053             png_bytep dp = row;
3054             png_uint_32 i;
3055 
3056             for (i = 0; i < row_width; i++)
3057             {
3058                png_byte red   = *(sp++);
3059                png_byte green = *(sp++);
3060                png_byte blue  = *(sp++);


4163    }
4164 }
4165 #endif
4166 
4167 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4168 /* Encode the alpha channel to the output gamma (the input channel is always
4169  * linear.)  Called only with color types that have an alpha channel.  Needs the
4170  * from_1 tables.
4171  */
4172 static void
4173 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4174 {
4175    png_uint_32 row_width = row_info->width;
4176 
4177    png_debug(1, "in png_do_encode_alpha");
4178 
4179    if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4180    {
4181       if (row_info->bit_depth == 8)
4182       {
4183          png_bytep table = png_ptr->gamma_from_1;
4184 
4185          if (table != NULL)
4186          {
4187             int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;

4188 
4189             /* The alpha channel is the last component: */
4190             row += step - 1;
4191 
4192             for (; row_width > 0; --row_width, row += step)
4193                *row = table[*row];
4194 
4195             return;
4196          }
4197       }
4198 
4199       else if (row_info->bit_depth == 16)
4200       {
4201          png_uint_16pp table = png_ptr->gamma_16_from_1;
4202          int gamma_shift = png_ptr->gamma_shift;
4203 
4204          if (table != NULL)
4205          {
4206             int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;

4207 
4208             /* The alpha channel is the last component: */
4209             row += step - 2;
4210 
4211             for (; row_width > 0; --row_width, row += step)
4212             {
4213                png_uint_16 v;
4214 
4215                v = table[*(row + 1) >> gamma_shift][*row];
4216                *row = (png_byte)((v >> 8) & 0xff);
4217                *(row + 1) = (png_byte)(v & 0xff);
4218             }
4219 
4220             return;
4221          }
4222       }
4223    }
4224 
4225    /* Only get to here if called with a weird row_info; no harm has been done,
4226     * so just issue a warning.
4227     */
4228    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4229 }
4230 #endif
4231 
4232 #ifdef PNG_READ_EXPAND_SUPPORTED
4233 /* Expands a palette row to an RGB or RGBA row depending
4234  * upon whether you supply trans and num_trans.
4235  */
4236 static void
4237 png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
4238     png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
4239     int num_trans)
4240 {
4241    int shift, value;
4242    png_bytep sp, dp;
4243    png_uint_32 i;
4244    png_uint_32 row_width=row_info->width;
4245 
4246    png_debug(1, "in png_do_expand_palette");
4247 
4248    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4249    {
4250       if (row_info->bit_depth < 8)
4251       {
4252          switch (row_info->bit_depth)
4253          {
4254             case 1:
4255             {
4256                sp = row + (size_t)((row_width - 1) >> 3);
4257                dp = row + (size_t)row_width - 1;
4258                shift = 7 - (int)((row_width + 7) & 0x07);
4259                for (i = 0; i < row_width; i++)


4323                }
4324                break;
4325             }
4326 
4327             default:
4328                break;
4329          }
4330          row_info->bit_depth = 8;
4331          row_info->pixel_depth = 8;
4332          row_info->rowbytes = row_width;
4333       }
4334 
4335       if (row_info->bit_depth == 8)
4336       {
4337          {
4338             if (num_trans > 0)
4339             {
4340                sp = row + (size_t)row_width - 1;
4341                dp = row + ((size_t)row_width << 2) - 1;
4342 
4343                i = 0;
4344 #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4345                if (png_ptr->riffled_palette != NULL)
4346                {
4347                   /* The RGBA optimization works with png_ptr->bit_depth == 8
4348                    * but sometimes row_info->bit_depth has been changed to 8.
4349                    * In these cases, the palette hasn't been riffled.
4350                    */
4351                   i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row,
4352                       &sp, &dp);
4353                }
4354 #else
4355                PNG_UNUSED(png_ptr)
4356 #endif
4357 
4358                for (; i < row_width; i++)
4359                {
4360                   if ((int)(*sp) >= num_trans)
4361                      *dp-- = 0xff;

4362                   else
4363                      *dp-- = trans_alpha[*sp];

4364                   *dp-- = palette[*sp].blue;
4365                   *dp-- = palette[*sp].green;
4366                   *dp-- = palette[*sp].red;
4367                   sp--;
4368                }
4369                row_info->bit_depth = 8;
4370                row_info->pixel_depth = 32;
4371                row_info->rowbytes = row_width * 4;
4372                row_info->color_type = 6;
4373                row_info->channels = 4;
4374             }
4375 
4376             else
4377             {
4378                sp = row + (size_t)row_width - 1;
4379                dp = row + (size_t)(row_width * 3) - 1;
4380                i = 0;
4381 #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4382                i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row,
4383                    &sp, &dp);
4384 #else
4385                PNG_UNUSED(png_ptr)
4386 #endif
4387 
4388                for (; i < row_width; i++)
4389                {
4390                   *dp-- = palette[*sp].blue;
4391                   *dp-- = palette[*sp].green;
4392                   *dp-- = palette[*sp].red;
4393                   sp--;
4394                }
4395 
4396                row_info->bit_depth = 8;
4397                row_info->pixel_depth = 24;
4398                row_info->rowbytes = row_width * 3;
4399                row_info->color_type = 2;
4400                row_info->channels = 3;
4401             }
4402          }
4403       }
4404    }
4405 }
4406 
4407 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
4408  * expanded transparency value is supplied, an alpha channel is built.


4782     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
4783     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
4784     * all transformations, however in practice the ROW_INIT always gets done on
4785     * demand, if necessary.
4786     */
4787    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4788        (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4789    {
4790       /* Application has failed to call either png_read_start_image() or
4791        * png_read_update_info() after setting transforms that expand pixels.
4792        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
4793        */
4794       png_error(png_ptr, "Uninitialized row");
4795    }
4796 
4797 #ifdef PNG_READ_EXPAND_SUPPORTED
4798    if ((png_ptr->transformations & PNG_EXPAND) != 0)
4799    {
4800       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4801       {
4802 #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4803          if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8))
4804          {
4805             if (png_ptr->riffled_palette == NULL)
4806             {
4807                /* Initialize the accelerated palette expansion. */
4808                png_ptr->riffled_palette =
4809                    (png_bytep)png_malloc(png_ptr, 256 * 4);
4810                png_riffle_palette_neon(png_ptr);
4811             }
4812          }
4813 #endif
4814          png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
4815              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4816       }
4817 
4818       else
4819       {
4820          if (png_ptr->num_trans != 0 &&
4821              (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4822             png_do_expand(row_info, png_ptr->row_buf + 1,
4823                 &(png_ptr->trans_color));
4824 
4825          else
4826             png_do_expand(row_info, png_ptr->row_buf + 1, NULL);
4827       }
4828    }
4829 #endif
4830 
4831 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4832    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4833        (png_ptr->transformations & PNG_COMPOSE) == 0 &&
4834        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||


< prev index next >