176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* pngwtran.c - transforms the data in a row for PNG writers
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Last changed in libpng 1.2.43 [February 25, 2010]
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 1998-2010 Glenn Randers-Pehrson
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This code is released under the libpng license.
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * For conditions of distribution and use, see the disclaimer
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and license in png.h
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_INTERNAL
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_NO_PEDANTIC_WARNINGS
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "png.h"
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SUPPORTED
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transform the data according to the user's wishes.  The order of
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * transformations is significant.
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_write_transformations(png_structp png_ptr)
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_write_transformations");
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_USER_TRANSFORM)
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->write_user_transform_fn != NULL)
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        (*(png_ptr->write_user_transform_fn)) /* User write transform
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                                 function */
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          (png_ptr,                    /* png_ptr */
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman           &(png_ptr->row_info),       /* row_info:     */
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_uint_32 width;          width of row */
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_uint_32 rowbytes;       number of bytes in row */
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_byte color_type;        color type of pixels */
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_byte bit_depth;         bit depth of samples */
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_byte channels;          number of channels (1-4) */
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman           png_ptr->row_buf + 1);      /* start of pixel data for row */
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_FILLER_SUPPORTED
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_FILLER)
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->flags);
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_PACKSWAP)
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_PACK_SUPPORTED
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_PACK)
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (png_uint_32)png_ptr->bit_depth);
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SWAP_SUPPORTED
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_SWAP_BYTES)
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SHIFT_SUPPORTED
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_SHIFT)
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         &(png_ptr->shift));
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_SWAP_ALPHA)
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_INVERT_ALPHA)
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_BGR_SUPPORTED
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_BGR)
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_INVERT_SUPPORTED
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations & PNG_INVERT_MONO)
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_PACK_SUPPORTED
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * row_info bit depth should be 8 (one pixel per byte).  The channels
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * should be 1 (this only happens on grayscale and paletted images).
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_pack");
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (row_info->bit_depth == 8 &&
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USELESS_TESTS_SUPPORTED
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       row != NULL && row_info != NULL &&
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      row_info->channels == 1)
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      switch ((int)bit_depth)
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 1:
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int mask, v;
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            sp = row;
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            dp = row;
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            mask = 0x80;
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = 0;
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < row_width; i++)
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (*sp != 0)
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  v |= mask;
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp++;
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (mask > 1)
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  mask >>= 1;
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  mask = 0x80;
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *dp = (png_byte)v;
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  dp++;
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  v = 0;
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (mask != 0x80)
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *dp = (png_byte)v;
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 2:
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int shift, v;
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            sp = row;
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            dp = row;
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            shift = 6;
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = 0;
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < row_width; i++)
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte value;
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               value = (png_byte)(*sp & 0x03);
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               v |= (value << shift);
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (shift == 0)
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  shift = 6;
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *dp = (png_byte)v;
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  dp++;
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  v = 0;
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  shift -= 2;
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp++;
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (shift != 6)
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *dp = (png_byte)v;
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 4:
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int shift, v;
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            sp = row;
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            dp = row;
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            shift = 4;
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = 0;
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < row_width; i++)
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte value;
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               value = (png_byte)(*sp & 0x0f);
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               v |= (value << shift);
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (shift == 0)
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  shift = 4;
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *dp = (png_byte)v;
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  dp++;
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  v = 0;
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  shift -= 4;
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp++;
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (shift != 4)
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *dp = (png_byte)v;
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      row_info->bit_depth = (png_byte)bit_depth;
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         row_info->width);
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SHIFT_SUPPORTED
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Shift pixel values to take advantage of whole range.  Pass the
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * true number of bits in bit_depth.  The row should be packed
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * according to row_info->bit_depth.  Thus, if you had a row of
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * bit depth 4, but the pixels only had values from 0 to 7, you
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * would pass 3 as bit_depth, and this routine would translate the
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * data to 0 to 15.
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_shift");
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USELESS_TESTS_SUPPORTED
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (row != NULL && row_info != NULL &&
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int shift_start[4], shift_dec[4];
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int channels = 0;
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_start[channels] = row_info->bit_depth - bit_depth->red;
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_dec[channels] = bit_depth->red;
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         channels++;
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_start[channels] = row_info->bit_depth - bit_depth->green;
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_dec[channels] = bit_depth->green;
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         channels++;
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_dec[channels] = bit_depth->blue;
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         channels++;
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_dec[channels] = bit_depth->gray;
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         channels++;
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         shift_dec[channels] = bit_depth->alpha;
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         channels++;
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* With low row depths, could only be grayscale, so one channel */
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->bit_depth < 8)
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep bp = row;
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 i;
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_byte mask;
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 row_bytes = row_info->rowbytes;
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            mask = 0x55;
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            mask = 0x11;
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            mask = 0xff;
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (i = 0; i < row_bytes; i++, bp++)
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_16 v;
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int j;
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = *bp;
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *bp = 0;
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (j > 0)
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *bp |= (png_byte)((v << j) & 0xff);
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *bp |= (png_byte)((v >> (-j)) & mask);
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (row_info->bit_depth == 8)
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep bp = row;
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 i;
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 istop = channels * row_info->width;
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (i = 0; i < istop; i++, bp++)
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_16 v;
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int j;
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int c = (int)(i%channels);
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = *bp;
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *bp = 0;
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (j > 0)
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *bp |= (png_byte)((v << j) & 0xff);
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  *bp |= (png_byte)((v >> (-j)) & 0xff);
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep bp;
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 i;
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 istop = channels * row_info->width;
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (bp = row, i = 0; i < istop; i++)
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int c = (int)(i%channels);
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_16 value, v;
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int j;
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            value = 0;
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (j > 0)
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               else
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *bp++ = (png_byte)(value >> 8);
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *bp++ = (png_byte)(value & 0xff);
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_write_swap_alpha");
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USELESS_TESTS_SUPPORTED
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (row != NULL && row_info != NULL)
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This converts from ARGB to RGBA */
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->bit_depth == 8)
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte save = *(sp++);
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save;
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This converts from AARRGGBB to RRGGBBAA */
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte save[2];
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               save[0] = *(sp++);
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               save[1] = *(sp++);
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save[0];
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save[1];
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This converts from AG to GA */
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->bit_depth == 8)
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte save = *(sp++);
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save;
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This converts from AAGG to GGAA */
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_byte save[2];
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               save[0] = *(sp++);
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               save[1] = *(sp++);
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save[0];
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = save[1];
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_write_invert_alpha");
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USELESS_TESTS_SUPPORTED
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (row != NULL && row_info != NULL)
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This inverts the alpha channel in RGBA */
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->bit_depth == 8)
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               /* Does nothing
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               */
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp+=3; dp = sp;
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This inverts the alpha channel in RRGGBBAA */
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               /* Does nothing
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               */
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp+=6; dp = sp;
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This inverts the alpha channel in GA */
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->bit_depth == 8)
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This inverts the alpha channel in GGAA */
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_bytep sp, dp;
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 i;
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 row_width = row_info->width;
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0, sp = dp = row; i < row_width; i++)
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               /* Does nothing
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = *(sp++);
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               */
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               sp+=2; dp = sp;
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(dp++) = (png_byte)(255 - *(sp++));
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MNG_FEATURES_SUPPORTED
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Undoes intrapixel differencing  */
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_do_write_intrapixel(png_row_infop row_info, png_bytep row)
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_debug(1, "in png_do_write_intrapixel");
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USELESS_TESTS_SUPPORTED
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       row != NULL && row_info != NULL &&
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       (row_info->color_type & PNG_COLOR_MASK_COLOR))
53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int bytes_per_pixel;
53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_uint_32 row_width = row_info->width;
53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (row_info->bit_depth == 8)
53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep rp;
53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 i;
54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            bytes_per_pixel = 3;
54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            bytes_per_pixel = 4;
54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            return;
54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp)   = (png_byte)((*rp     - *(rp+1))&0xff);
55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (row_info->bit_depth == 16)
55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep rp;
55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_uint_32 i;
55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            bytes_per_pixel = 6;
56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            bytes_per_pixel = 8;
56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            return;
56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp  ) = (png_byte)((red >> 8) & 0xff);
57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp+1) = (png_byte)(red & 0xff);
57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *(rp+5) = (png_byte)(blue & 0xff);
57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_MNG_FEATURES_SUPPORTED */
58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_WRITE_SUPPORTED */
583