1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  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 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  26  *
  27  * Copyright (c) 2018 Cosmin Truta
  28  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  29  * Copyright (c) 1996-1997 Andreas Dilger
  30  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  31  *
  32  * This code is released under the libpng license.
  33  * For conditions of distribution and use, see the disclaimer
  34  * and license in png.h
  35  */
  36 
  37 #include "pngpriv.h"
  38 
  39 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  40 
  41 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
  42 /* Turn on BGR-to-RGB mapping */
  43 void PNGAPI
  44 png_set_bgr(png_structrp png_ptr)
  45 {
  46    png_debug(1, "in png_set_bgr");
  47 
  48    if (png_ptr == NULL)
  49       return;
  50 
  51    png_ptr->transformations |= PNG_BGR;
  52 }
  53 #endif
  54 
  55 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
  56 /* Turn on 16-bit byte swapping */
  57 void PNGAPI
  58 png_set_swap(png_structrp png_ptr)
  59 {
  60    png_debug(1, "in png_set_swap");
  61 
  62    if (png_ptr == NULL)
  63       return;
  64 
  65    if (png_ptr->bit_depth == 16)
  66       png_ptr->transformations |= PNG_SWAP_BYTES;
  67 }
  68 #endif
  69 
  70 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
  71 /* Turn on pixel packing */
  72 void PNGAPI
  73 png_set_packing(png_structrp png_ptr)
  74 {
  75    png_debug(1, "in png_set_packing");
  76 
  77    if (png_ptr == NULL)
  78       return;
  79 
  80    if (png_ptr->bit_depth < 8)
  81    {
  82       png_ptr->transformations |= PNG_PACK;
  83 #     ifdef PNG_WRITE_SUPPORTED
  84          png_ptr->usr_bit_depth = 8;
  85 #     endif
  86    }
  87 }
  88 #endif
  89 
  90 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
  91 /* Turn on packed pixel swapping */
  92 void PNGAPI
  93 png_set_packswap(png_structrp png_ptr)
  94 {
  95    png_debug(1, "in png_set_packswap");
  96 
  97    if (png_ptr == NULL)
  98       return;
  99 
 100    if (png_ptr->bit_depth < 8)
 101       png_ptr->transformations |= PNG_PACKSWAP;
 102 }
 103 #endif
 104 
 105 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
 106 void PNGAPI
 107 png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
 108 {
 109    png_debug(1, "in png_set_shift");
 110 
 111    if (png_ptr == NULL)
 112       return;
 113 
 114    png_ptr->transformations |= PNG_SHIFT;
 115    png_ptr->shift = *true_bits;
 116 }
 117 #endif
 118 
 119 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
 120     defined(PNG_WRITE_INTERLACING_SUPPORTED)
 121 int PNGAPI
 122 png_set_interlace_handling(png_structrp png_ptr)
 123 {
 124    png_debug(1, "in png_set_interlace handling");
 125 
 126    if (png_ptr != 0 && png_ptr->interlaced != 0)
 127    {
 128       png_ptr->transformations |= PNG_INTERLACE;
 129       return (7);
 130    }
 131 
 132    return (1);
 133 }
 134 #endif
 135 
 136 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
 137 /* Add a filler byte on read, or remove a filler or alpha byte on write.
 138  * The filler type has changed in v0.95 to allow future 2-byte fillers
 139  * for 48-bit input data, as well as to avoid problems with some compilers
 140  * that don't like bytes as parameters.
 141  */
 142 void PNGAPI
 143 png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
 144 {
 145    png_debug(1, "in png_set_filler");
 146 
 147    if (png_ptr == NULL)
 148       return;
 149 
 150    /* In libpng 1.6 it is possible to determine whether this is a read or write
 151     * operation and therefore to do more checking here for a valid call.
 152     */
 153    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
 154    {
 155 #     ifdef PNG_READ_FILLER_SUPPORTED
 156          /* On read png_set_filler is always valid, regardless of the base PNG
 157           * format, because other transformations can give a format where the
 158           * filler code can execute (basically an 8 or 16-bit component RGB or G
 159           * format.)
 160           *
 161           * NOTE: usr_channels is not used by the read code!  (This has led to
 162           * confusion in the past.)  The filler is only used in the read code.
 163           */
 164          png_ptr->filler = (png_uint_16)filler;
 165 #     else
 166          png_app_error(png_ptr, "png_set_filler not supported on read");
 167          PNG_UNUSED(filler) /* not used in the write case */
 168          return;
 169 #     endif
 170    }
 171 
 172    else /* write */
 173    {
 174 #     ifdef PNG_WRITE_FILLER_SUPPORTED
 175          /* On write the usr_channels parameter must be set correctly at the
 176           * start to record the number of channels in the app-supplied data.
 177           */
 178          switch (png_ptr->color_type)
 179          {
 180             case PNG_COLOR_TYPE_RGB:
 181                png_ptr->usr_channels = 4;
 182                break;
 183 
 184             case PNG_COLOR_TYPE_GRAY:
 185                if (png_ptr->bit_depth >= 8)
 186                {
 187                   png_ptr->usr_channels = 2;
 188                   break;
 189                }
 190 
 191                else
 192                {
 193                   /* There simply isn't any code in libpng to strip out bits
 194                    * from bytes when the components are less than a byte in
 195                    * size!
 196                    */
 197                   png_app_error(png_ptr,
 198                       "png_set_filler is invalid for"
 199                       " low bit depth gray output");
 200                   return;
 201                }
 202 
 203             default:
 204                png_app_error(png_ptr,
 205                    "png_set_filler: inappropriate color type");
 206                return;
 207          }
 208 #     else
 209          png_app_error(png_ptr, "png_set_filler not supported on write");
 210          return;
 211 #     endif
 212    }
 213 
 214    /* Here on success - libpng supports the operation, set the transformation
 215     * and the flag to say where the filler channel is.
 216     */
 217    png_ptr->transformations |= PNG_FILLER;
 218 
 219    if (filler_loc == PNG_FILLER_AFTER)
 220       png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
 221 
 222    else
 223       png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
 224 }
 225 
 226 /* Added to libpng-1.2.7 */
 227 void PNGAPI
 228 png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
 229 {
 230    png_debug(1, "in png_set_add_alpha");
 231 
 232    if (png_ptr == NULL)
 233       return;
 234 
 235    png_set_filler(png_ptr, filler, filler_loc);
 236    /* The above may fail to do anything. */
 237    if ((png_ptr->transformations & PNG_FILLER) != 0)
 238       png_ptr->transformations |= PNG_ADD_ALPHA;
 239 }
 240 
 241 #endif
 242 
 243 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
 244     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 245 void PNGAPI
 246 png_set_swap_alpha(png_structrp png_ptr)
 247 {
 248    png_debug(1, "in png_set_swap_alpha");
 249 
 250    if (png_ptr == NULL)
 251       return;
 252 
 253    png_ptr->transformations |= PNG_SWAP_ALPHA;
 254 }
 255 #endif
 256 
 257 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
 258     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 259 void PNGAPI
 260 png_set_invert_alpha(png_structrp png_ptr)
 261 {
 262    png_debug(1, "in png_set_invert_alpha");
 263 
 264    if (png_ptr == NULL)
 265       return;
 266 
 267    png_ptr->transformations |= PNG_INVERT_ALPHA;
 268 }
 269 #endif
 270 
 271 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
 272 void PNGAPI
 273 png_set_invert_mono(png_structrp png_ptr)
 274 {
 275    png_debug(1, "in png_set_invert_mono");
 276 
 277    if (png_ptr == NULL)
 278       return;
 279 
 280    png_ptr->transformations |= PNG_INVERT_MONO;
 281 }
 282 
 283 /* Invert monochrome grayscale data */
 284 void /* PRIVATE */
 285 png_do_invert(png_row_infop row_info, png_bytep row)
 286 {
 287    png_debug(1, "in png_do_invert");
 288 
 289   /* This test removed from libpng version 1.0.13 and 1.2.0:
 290    *   if (row_info->bit_depth == 1 &&
 291    */
 292    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
 293    {
 294       png_bytep rp = row;
 295       size_t i;
 296       size_t istop = row_info->rowbytes;
 297 
 298       for (i = 0; i < istop; i++)
 299       {
 300          *rp = (png_byte)(~(*rp));
 301          rp++;
 302       }
 303    }
 304 
 305    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
 306       row_info->bit_depth == 8)
 307    {
 308       png_bytep rp = row;
 309       size_t i;
 310       size_t istop = row_info->rowbytes;
 311 
 312       for (i = 0; i < istop; i += 2)
 313       {
 314          *rp = (png_byte)(~(*rp));
 315          rp += 2;
 316       }
 317    }
 318 
 319 #ifdef PNG_16BIT_SUPPORTED
 320    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
 321       row_info->bit_depth == 16)
 322    {
 323       png_bytep rp = row;
 324       size_t i;
 325       size_t istop = row_info->rowbytes;
 326 
 327       for (i = 0; i < istop; i += 4)
 328       {
 329          *rp = (png_byte)(~(*rp));
 330          *(rp + 1) = (png_byte)(~(*(rp + 1)));
 331          rp += 4;
 332       }
 333    }
 334 #endif
 335 }
 336 #endif
 337 
 338 #ifdef PNG_16BIT_SUPPORTED
 339 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
 340 /* Swaps byte order on 16-bit depth images */
 341 void /* PRIVATE */
 342 png_do_swap(png_row_infop row_info, png_bytep row)
 343 {
 344    png_debug(1, "in png_do_swap");
 345 
 346    if (row_info->bit_depth == 16)
 347    {
 348       png_bytep rp = row;
 349       png_uint_32 i;
 350       png_uint_32 istop= row_info->width * row_info->channels;
 351 
 352       for (i = 0; i < istop; i++, rp += 2)
 353       {
 354 #ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
 355          /* Feature added to libpng-1.6.11 for testing purposes, not
 356           * enabled by default.
 357           */
 358          *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
 359 #else
 360          png_byte t = *rp;
 361          *rp = *(rp + 1);
 362          *(rp + 1) = t;
 363 #endif
 364       }
 365    }
 366 }
 367 #endif
 368 #endif
 369 
 370 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 371 static const png_byte onebppswaptable[256] = {
 372    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
 373    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
 374    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
 375    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
 376    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
 377    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
 378    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
 379    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
 380    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
 381    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
 382    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
 383    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
 384    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
 385    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
 386    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
 387    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
 388    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
 389    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
 390    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
 391    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
 392    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
 393    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
 394    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
 395    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
 396    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
 397    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
 398    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
 399    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
 400    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
 401    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
 402    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
 403    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 404 };
 405 
 406 static const png_byte twobppswaptable[256] = {
 407    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
 408    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
 409    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
 410    0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
 411    0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
 412    0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
 413    0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
 414    0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
 415    0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
 416    0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
 417    0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
 418    0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
 419    0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
 420    0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
 421    0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
 422    0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
 423    0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
 424    0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
 425    0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
 426    0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
 427    0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
 428    0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
 429    0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
 430    0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
 431    0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
 432    0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
 433    0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
 434    0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
 435    0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
 436    0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
 437    0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
 438    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
 439 };
 440 
 441 static const png_byte fourbppswaptable[256] = {
 442    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
 443    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
 444    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
 445    0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
 446    0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
 447    0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
 448    0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
 449    0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
 450    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
 451    0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
 452    0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
 453    0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
 454    0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
 455    0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
 456    0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
 457    0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
 458    0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
 459    0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
 460    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
 461    0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
 462    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
 463    0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
 464    0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
 465    0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
 466    0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
 467    0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
 468    0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
 469    0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
 470    0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
 471    0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
 472    0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
 473    0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
 474 };
 475 
 476 /* Swaps pixel packing order within bytes */
 477 void /* PRIVATE */
 478 png_do_packswap(png_row_infop row_info, png_bytep row)
 479 {
 480    png_debug(1, "in png_do_packswap");
 481 
 482    if (row_info->bit_depth < 8)
 483    {
 484       png_bytep rp;
 485       png_const_bytep end, table;
 486 
 487       end = row + row_info->rowbytes;
 488 
 489       if (row_info->bit_depth == 1)
 490          table = onebppswaptable;
 491 
 492       else if (row_info->bit_depth == 2)
 493          table = twobppswaptable;
 494 
 495       else if (row_info->bit_depth == 4)
 496          table = fourbppswaptable;
 497 
 498       else
 499          return;
 500 
 501       for (rp = row; rp < end; rp++)
 502          *rp = table[*rp];
 503    }
 504 }
 505 #endif /* PACKSWAP || WRITE_PACKSWAP */
 506 
 507 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
 508     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 509 /* Remove a channel - this used to be 'png_do_strip_filler' but it used a
 510  * somewhat weird combination of flags to determine what to do.  All the calls
 511  * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
 512  * correct arguments.
 513  *
 514  * The routine isn't general - the channel must be the channel at the start or
 515  * end (not in the middle) of each pixel.
 516  */
 517 void /* PRIVATE */
 518 png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
 519 {
 520    png_bytep sp = row; /* source pointer */
 521    png_bytep dp = row; /* destination pointer */
 522    png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
 523 
 524    /* At the start sp will point to the first byte to copy and dp to where
 525     * it is copied to.  ep always points just beyond the end of the row, so
 526     * the loop simply copies (channels-1) channels until sp reaches ep.
 527     *
 528     * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
 529     *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
 530     */
 531 
 532    /* GA, GX, XG cases */
 533    if (row_info->channels == 2)
 534    {
 535       if (row_info->bit_depth == 8)
 536       {
 537          if (at_start != 0) /* Skip initial filler */
 538             ++sp;
 539          else          /* Skip initial channel and, for sp, the filler */
 540          {
 541             sp += 2; ++dp;
 542          }
 543 
 544          /* For a 1 pixel wide image there is nothing to do */
 545          while (sp < ep)
 546          {
 547             *dp++ = *sp; sp += 2;
 548          }
 549 
 550          row_info->pixel_depth = 8;
 551       }
 552 
 553       else if (row_info->bit_depth == 16)
 554       {
 555          if (at_start != 0) /* Skip initial filler */
 556             sp += 2;
 557          else          /* Skip initial channel and, for sp, the filler */
 558          {
 559             sp += 4; dp += 2;
 560          }
 561 
 562          while (sp < ep)
 563          {
 564             *dp++ = *sp++; *dp++ = *sp; sp += 3;
 565          }
 566 
 567          row_info->pixel_depth = 16;
 568       }
 569 
 570       else
 571          return; /* bad bit depth */
 572 
 573       row_info->channels = 1;
 574 
 575       /* Finally fix the color type if it records an alpha channel */
 576       if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 577          row_info->color_type = PNG_COLOR_TYPE_GRAY;
 578    }
 579 
 580    /* RGBA, RGBX, XRGB cases */
 581    else if (row_info->channels == 4)
 582    {
 583       if (row_info->bit_depth == 8)
 584       {
 585          if (at_start != 0) /* Skip initial filler */
 586             ++sp;
 587          else          /* Skip initial channels and, for sp, the filler */
 588          {
 589             sp += 4; dp += 3;
 590          }
 591 
 592          /* Note that the loop adds 3 to dp and 4 to sp each time. */
 593          while (sp < ep)
 594          {
 595             *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
 596          }
 597 
 598          row_info->pixel_depth = 24;
 599       }
 600 
 601       else if (row_info->bit_depth == 16)
 602       {
 603          if (at_start != 0) /* Skip initial filler */
 604             sp += 2;
 605          else          /* Skip initial channels and, for sp, the filler */
 606          {
 607             sp += 8; dp += 6;
 608          }
 609 
 610          while (sp < ep)
 611          {
 612             /* Copy 6 bytes, skip 2 */
 613             *dp++ = *sp++; *dp++ = *sp++;
 614             *dp++ = *sp++; *dp++ = *sp++;
 615             *dp++ = *sp++; *dp++ = *sp; sp += 3;
 616          }
 617 
 618          row_info->pixel_depth = 48;
 619       }
 620 
 621       else
 622          return; /* bad bit depth */
 623 
 624       row_info->channels = 3;
 625 
 626       /* Finally fix the color type if it records an alpha channel */
 627       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 628          row_info->color_type = PNG_COLOR_TYPE_RGB;
 629    }
 630 
 631    else
 632       return; /* The filler channel has gone already */
 633 
 634    /* Fix the rowbytes value. */
 635    row_info->rowbytes = (size_t)(dp-row);
 636 }
 637 #endif
 638 
 639 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 640 /* Swaps red and blue bytes within a pixel */
 641 void /* PRIVATE */
 642 png_do_bgr(png_row_infop row_info, png_bytep row)
 643 {
 644    png_debug(1, "in png_do_bgr");
 645 
 646    if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
 647    {
 648       png_uint_32 row_width = row_info->width;
 649       if (row_info->bit_depth == 8)
 650       {
 651          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 652          {
 653             png_bytep rp;
 654             png_uint_32 i;
 655 
 656             for (i = 0, rp = row; i < row_width; i++, rp += 3)
 657             {
 658                png_byte save = *rp;
 659                *rp = *(rp + 2);
 660                *(rp + 2) = save;
 661             }
 662          }
 663 
 664          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 665          {
 666             png_bytep rp;
 667             png_uint_32 i;
 668 
 669             for (i = 0, rp = row; i < row_width; i++, rp += 4)
 670             {
 671                png_byte save = *rp;
 672                *rp = *(rp + 2);
 673                *(rp + 2) = save;
 674             }
 675          }
 676       }
 677 
 678 #ifdef PNG_16BIT_SUPPORTED
 679       else if (row_info->bit_depth == 16)
 680       {
 681          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 682          {
 683             png_bytep rp;
 684             png_uint_32 i;
 685 
 686             for (i = 0, rp = row; i < row_width; i++, rp += 6)
 687             {
 688                png_byte save = *rp;
 689                *rp = *(rp + 4);
 690                *(rp + 4) = save;
 691                save = *(rp + 1);
 692                *(rp + 1) = *(rp + 5);
 693                *(rp + 5) = save;
 694             }
 695          }
 696 
 697          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 698          {
 699             png_bytep rp;
 700             png_uint_32 i;
 701 
 702             for (i = 0, rp = row; i < row_width; i++, rp += 8)
 703             {
 704                png_byte save = *rp;
 705                *rp = *(rp + 4);
 706                *(rp + 4) = save;
 707                save = *(rp + 1);
 708                *(rp + 1) = *(rp + 5);
 709                *(rp + 5) = save;
 710             }
 711          }
 712       }
 713 #endif
 714    }
 715 }
 716 #endif /* READ_BGR || WRITE_BGR */
 717 
 718 #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
 719     defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
 720 /* Added at libpng-1.5.10 */
 721 void /* PRIVATE */
 722 png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
 723 {
 724    if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
 725       png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
 726    {
 727       /* Calculations moved outside switch in an attempt to stop different
 728        * compiler warnings.  'padding' is in *bits* within the last byte, it is
 729        * an 'int' because pixel_depth becomes an 'int' in the expression below,
 730        * and this calculation is used because it avoids warnings that other
 731        * forms produced on either GCC or MSVC.
 732        */
 733       int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
 734       png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
 735 
 736       switch (row_info->bit_depth)
 737       {
 738          case 1:
 739          {
 740             /* in this case, all bytes must be 0 so we don't need
 741              * to unpack the pixels except for the rightmost one.
 742              */
 743             for (; rp > png_ptr->row_buf; rp--)
 744             {
 745               if ((*rp >> padding) != 0)
 746                  png_ptr->num_palette_max = 1;
 747               padding = 0;
 748             }
 749 
 750             break;
 751          }
 752 
 753          case 2:
 754          {
 755             for (; rp > png_ptr->row_buf; rp--)
 756             {
 757               int i = ((*rp >> padding) & 0x03);
 758 
 759               if (i > png_ptr->num_palette_max)
 760                  png_ptr->num_palette_max = i;
 761 
 762               i = (((*rp >> padding) >> 2) & 0x03);
 763 
 764               if (i > png_ptr->num_palette_max)
 765                  png_ptr->num_palette_max = i;
 766 
 767               i = (((*rp >> padding) >> 4) & 0x03);
 768 
 769               if (i > png_ptr->num_palette_max)
 770                  png_ptr->num_palette_max = i;
 771 
 772               i = (((*rp >> padding) >> 6) & 0x03);
 773 
 774               if (i > png_ptr->num_palette_max)
 775                  png_ptr->num_palette_max = i;
 776 
 777               padding = 0;
 778             }
 779 
 780             break;
 781          }
 782 
 783          case 4:
 784          {
 785             for (; rp > png_ptr->row_buf; rp--)
 786             {
 787               int i = ((*rp >> padding) & 0x0f);
 788 
 789               if (i > png_ptr->num_palette_max)
 790                  png_ptr->num_palette_max = i;
 791 
 792               i = (((*rp >> padding) >> 4) & 0x0f);
 793 
 794               if (i > png_ptr->num_palette_max)
 795                  png_ptr->num_palette_max = i;
 796 
 797               padding = 0;
 798             }
 799 
 800             break;
 801          }
 802 
 803          case 8:
 804          {
 805             for (; rp > png_ptr->row_buf; rp--)
 806             {
 807                if (*rp > png_ptr->num_palette_max)
 808                   png_ptr->num_palette_max = (int) *rp;
 809             }
 810 
 811             break;
 812          }
 813 
 814          default:
 815             break;
 816       }
 817    }
 818 }
 819 #endif /* CHECK_FOR_INVALID_INDEX */
 820 
 821 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
 822     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 823 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
 824 void PNGAPI
 825 png_set_user_transform_info(png_structrp png_ptr, png_voidp
 826    user_transform_ptr, int user_transform_depth, int user_transform_channels)
 827 {
 828    png_debug(1, "in png_set_user_transform_info");
 829 
 830    if (png_ptr == NULL)
 831       return;
 832 
 833 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
 834    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
 835       (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
 836    {
 837       png_app_error(png_ptr,
 838           "info change after png_start_read_image or png_read_update_info");
 839       return;
 840    }
 841 #endif
 842 
 843    png_ptr->user_transform_ptr = user_transform_ptr;
 844    png_ptr->user_transform_depth = (png_byte)user_transform_depth;
 845    png_ptr->user_transform_channels = (png_byte)user_transform_channels;
 846 }
 847 #endif
 848 
 849 /* This function returns a pointer to the user_transform_ptr associated with
 850  * the user transform functions.  The application should free any memory
 851  * associated with this pointer before png_write_destroy and png_read_destroy
 852  * are called.
 853  */
 854 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
 855 png_voidp PNGAPI
 856 png_get_user_transform_ptr(png_const_structrp png_ptr)
 857 {
 858    if (png_ptr == NULL)
 859       return (NULL);
 860 
 861    return png_ptr->user_transform_ptr;
 862 }
 863 #endif
 864 
 865 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
 866 png_uint_32 PNGAPI
 867 png_get_current_row_number(png_const_structrp png_ptr)
 868 {
 869    /* See the comments in png.h - this is the sub-image row when reading an
 870     * interlaced image.
 871     */
 872    if (png_ptr != NULL)
 873       return png_ptr->row_number;
 874 
 875    return PNG_UINT_32_MAX; /* help the app not to fail silently */
 876 }
 877 
 878 png_byte PNGAPI
 879 png_get_current_pass_number(png_const_structrp png_ptr)
 880 {
 881    if (png_ptr != NULL)
 882       return png_ptr->pass;
 883    return 8; /* invalid */
 884 }
 885 #endif /* USER_TRANSFORM_INFO */
 886 #endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
 887 #endif /* READ || WRITE */