pngtrans.c 20.8 KB
Newer Older
D
duke 已提交
1 2 3 4 5
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
6
 * published by the Free Software Foundation.  Oracle designates this
D
duke 已提交
7
 * particular file as subject to the "Classpath" exception as provided
8
 * by Oracle in the LICENSE file that accompanied this code.
D
duke 已提交
9 10 11 12 13 14 15 16 17 18 19
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
20 21 22
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
23 24 25 26 27 28 29 30 31
 */

/* pngtrans.c - transforms the data in a row (used by both readers and writers)
 *
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file and, per its terms, should not be removed:
 *
B
bae 已提交
32 33
 * Last changed in libpng 1.5.4 [July 7, 2011]
 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
D
duke 已提交
34 35
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
B
bae 已提交
36 37 38 39
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
D
duke 已提交
40 41
 */

B
bae 已提交
42
#include "pngpriv.h"
D
duke 已提交
43 44

#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
B
bae 已提交
45

D
duke 已提交
46
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
B
bae 已提交
47
/* Turn on BGR-to-RGB mapping */
D
duke 已提交
48 49 50
void PNGAPI
png_set_bgr(png_structp png_ptr)
{
B
bae 已提交
51 52 53 54 55
   png_debug(1, "in png_set_bgr");

   if (png_ptr == NULL)
      return;

D
duke 已提交
56 57 58 59 60
   png_ptr->transformations |= PNG_BGR;
}
#endif

#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
B
bae 已提交
61
/* Turn on 16 bit byte swapping */
D
duke 已提交
62 63 64
void PNGAPI
png_set_swap(png_structp png_ptr)
{
B
bae 已提交
65 66 67 68 69
   png_debug(1, "in png_set_swap");

   if (png_ptr == NULL)
      return;

D
duke 已提交
70 71 72 73 74 75
   if (png_ptr->bit_depth == 16)
      png_ptr->transformations |= PNG_SWAP_BYTES;
}
#endif

#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
B
bae 已提交
76
/* Turn on pixel packing */
D
duke 已提交
77 78 79
void PNGAPI
png_set_packing(png_structp png_ptr)
{
B
bae 已提交
80 81 82 83 84
   png_debug(1, "in png_set_packing");

   if (png_ptr == NULL)
      return;

D
duke 已提交
85 86 87 88 89 90 91 92 93
   if (png_ptr->bit_depth < 8)
   {
      png_ptr->transformations |= PNG_PACK;
      png_ptr->usr_bit_depth = 8;
   }
}
#endif

#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
B
bae 已提交
94
/* Turn on packed pixel swapping */
D
duke 已提交
95 96 97
void PNGAPI
png_set_packswap(png_structp png_ptr)
{
B
bae 已提交
98 99 100 101 102
   png_debug(1, "in png_set_packswap");

   if (png_ptr == NULL)
      return;

D
duke 已提交
103 104 105 106 107 108 109
   if (png_ptr->bit_depth < 8)
      png_ptr->transformations |= PNG_PACKSWAP;
}
#endif

#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void PNGAPI
B
bae 已提交
110
png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
D
duke 已提交
111
{
B
bae 已提交
112 113 114 115 116
   png_debug(1, "in png_set_shift");

   if (png_ptr == NULL)
      return;

D
duke 已提交
117 118 119 120 121 122 123 124 125 126
   png_ptr->transformations |= PNG_SHIFT;
   png_ptr->shift = *true_bits;
}
#endif

#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
    defined(PNG_WRITE_INTERLACING_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structp png_ptr)
{
B
bae 已提交
127 128
   png_debug(1, "in png_set_interlace handling");

D
duke 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
   if (png_ptr && png_ptr->interlaced)
   {
      png_ptr->transformations |= PNG_INTERLACE;
      return (7);
   }

   return (1);
}
#endif

#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte on read, or remove a filler or alpha byte on write.
 * The filler type has changed in v0.95 to allow future 2-byte fillers
 * for 48-bit input data, as well as to avoid problems with some compilers
 * that don't like bytes as parameters.
 */
void PNGAPI
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
B
bae 已提交
148 149 150 151 152
   png_debug(1, "in png_set_filler");

   if (png_ptr == NULL)
      return;

D
duke 已提交
153
   png_ptr->transformations |= PNG_FILLER;
B
bae 已提交
154 155
   png_ptr->filler = (png_uint_16)filler;

D
duke 已提交
156 157
   if (filler_loc == PNG_FILLER_AFTER)
      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
B
bae 已提交
158

D
duke 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171 172
   else
      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;

   /* This should probably go in the "do_read_filler" routine.
    * I attempted to do that in libpng-1.0.1a but that caused problems
    * so I restored it in libpng-1.0.2a
   */

   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   {
      png_ptr->usr_channels = 4;
   }

   /* Also I added this in libpng-1.0.2a (what happens when we expand
B
bae 已提交
173
    * a less-than-8-bit grayscale to GA?) */
D
duke 已提交
174 175 176 177 178 179 180 181 182 183 184

   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
   {
      png_ptr->usr_channels = 2;
   }
}

/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
B
bae 已提交
185 186 187 188 189
   png_debug(1, "in png_set_add_alpha");

   if (png_ptr == NULL)
      return;

D
duke 已提交
190 191 192 193 194 195 196 197 198 199 200
   png_set_filler(png_ptr, filler, filler_loc);
   png_ptr->transformations |= PNG_ADD_ALPHA;
}

#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void PNGAPI
png_set_swap_alpha(png_structp png_ptr)
{
B
bae 已提交
201 202 203 204 205
   png_debug(1, "in png_set_swap_alpha");

   if (png_ptr == NULL)
      return;

D
duke 已提交
206 207 208 209 210 211 212 213 214
   png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif

#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void PNGAPI
png_set_invert_alpha(png_structp png_ptr)
{
B
bae 已提交
215 216 217 218 219
   png_debug(1, "in png_set_invert_alpha");

   if (png_ptr == NULL)
      return;

D
duke 已提交
220 221 222 223 224 225 226 227
   png_ptr->transformations |= PNG_INVERT_ALPHA;
}
#endif

#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void PNGAPI
png_set_invert_mono(png_structp png_ptr)
{
B
bae 已提交
228 229 230 231 232
   png_debug(1, "in png_set_invert_mono");

   if (png_ptr == NULL)
      return;

D
duke 已提交
233 234 235
   png_ptr->transformations |= PNG_INVERT_MONO;
}

B
bae 已提交
236
/* Invert monochrome grayscale data */
D
duke 已提交
237 238 239
void /* PRIVATE */
png_do_invert(png_row_infop row_info, png_bytep row)
{
B
bae 已提交
240 241
   png_debug(1, "in png_do_invert");

D
duke 已提交
242 243 244 245 246 247
  /* This test removed from libpng version 1.0.13 and 1.2.0:
   *   if (row_info->bit_depth == 1 &&
   */
   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   {
      png_bytep rp = row;
B
bae 已提交
248 249
      png_size_t i;
      png_size_t istop = row_info->rowbytes;
D
duke 已提交
250 251 252 253 254 255 256

      for (i = 0; i < istop; i++)
      {
         *rp = (png_byte)(~(*rp));
         rp++;
      }
   }
B
bae 已提交
257

D
duke 已提交
258 259 260 261
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
      row_info->bit_depth == 8)
   {
      png_bytep rp = row;
B
bae 已提交
262 263
      png_size_t i;
      png_size_t istop = row_info->rowbytes;
D
duke 已提交
264

B
bae 已提交
265
      for (i = 0; i < istop; i += 2)
D
duke 已提交
266 267
      {
         *rp = (png_byte)(~(*rp));
B
bae 已提交
268
         rp += 2;
D
duke 已提交
269 270
      }
   }
B
bae 已提交
271 272

#ifdef PNG_16BIT_SUPPORTED
D
duke 已提交
273 274 275 276
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
      row_info->bit_depth == 16)
   {
      png_bytep rp = row;
B
bae 已提交
277 278
      png_size_t i;
      png_size_t istop = row_info->rowbytes;
D
duke 已提交
279

B
bae 已提交
280
      for (i = 0; i < istop; i += 4)
D
duke 已提交
281 282
      {
         *rp = (png_byte)(~(*rp));
B
bae 已提交
283 284
         *(rp + 1) = (png_byte)(~(*(rp + 1)));
         rp += 4;
D
duke 已提交
285 286
      }
   }
B
bae 已提交
287
#endif
D
duke 已提交
288 289 290
}
#endif

B
bae 已提交
291
#ifdef PNG_16BIT_SUPPORTED
D
duke 已提交
292
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
B
bae 已提交
293
/* Swaps byte order on 16 bit depth images */
D
duke 已提交
294 295 296
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
B
bae 已提交
297 298 299
   png_debug(1, "in png_do_swap");

   if (row_info->bit_depth == 16)
D
duke 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313
   {
      png_bytep rp = row;
      png_uint_32 i;
      png_uint_32 istop= row_info->width * row_info->channels;

      for (i = 0; i < istop; i++, rp += 2)
      {
         png_byte t = *rp;
         *rp = *(rp + 1);
         *(rp + 1) = t;
      }
   }
}
#endif
B
bae 已提交
314
#endif
D
duke 已提交
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421

#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static PNG_CONST png_byte onebppswaptable[256] = {
   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};

static PNG_CONST png_byte twobppswaptable[256] = {
   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};

static PNG_CONST png_byte fourbppswaptable[256] = {
   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
};

B
bae 已提交
422
/* Swaps pixel packing order within bytes */
D
duke 已提交
423 424 425
void /* PRIVATE */
png_do_packswap(png_row_infop row_info, png_bytep row)
{
B
bae 已提交
426 427 428
   png_debug(1, "in png_do_packswap");

   if (row_info->bit_depth < 8)
D
duke 已提交
429
   {
B
bae 已提交
430 431
      png_bytep rp;
      png_const_bytep end, table;
D
duke 已提交
432 433 434 435

      end = row + row_info->rowbytes;

      if (row_info->bit_depth == 1)
B
bae 已提交
436 437
         table = onebppswaptable;

D
duke 已提交
438
      else if (row_info->bit_depth == 2)
B
bae 已提交
439 440
         table = twobppswaptable;

D
duke 已提交
441
      else if (row_info->bit_depth == 4)
B
bae 已提交
442 443
         table = fourbppswaptable;

D
duke 已提交
444 445 446 447 448 449 450 451 452 453 454
      else
         return;

      for (rp = row; rp < end; rp++)
         *rp = table[*rp];
   }
}
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */

#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
B
bae 已提交
455 456 457 458 459 460 461 462
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
 * somewhat weird combination of flags to determine what to do.  All the calls
 * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
 * correct arguments.
 *
 * The routine isn't general - the channel must be the channel at the start or
 * end (not in the middle) of each pixel.
 */
D
duke 已提交
463
void /* PRIVATE */
B
bae 已提交
464
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
D
duke 已提交
465
{
B
bae 已提交
466 467 468 469 470 471 472 473 474 475 476 477 478 479
   png_bytep sp = row; /* source pointer */
   png_bytep dp = row; /* destination pointer */
   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */

   /* At the start sp will point to the first byte to copy and dp to where
    * it is copied to.  ep always points just beyond the end of the row, so
    * the loop simply copies (channels-1) channels until sp reaches ep.
    *
    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
    */

   /* GA, GX, XG cases */
   if (row_info->channels == 2)
D
duke 已提交
480
   {
B
bae 已提交
481 482 483 484 485 486 487 488 489 490 491 492 493
      if (row_info->bit_depth == 8)
      {
         if (at_start) /* Skip initial filler */
            ++sp;
         else          /* Skip initial channel and, for sp, the filler */
            sp += 2, ++dp;

         /* For a 1 pixel wide image there is nothing to do */
         while (sp < ep)
            *dp++ = *sp, sp += 2;

         row_info->pixel_depth = 8;
      }
D
duke 已提交
494

B
bae 已提交
495
      else if (row_info->bit_depth == 16)
D
duke 已提交
496
      {
B
bae 已提交
497 498 499 500 501 502 503 504 505
         if (at_start) /* Skip initial filler */
            sp += 2;
         else          /* Skip initial channel and, for sp, the filler */
            sp += 4, dp += 2;

         while (sp < ep)
            *dp++ = *sp++, *dp++ = *sp, sp += 3;

         row_info->pixel_depth = 16;
D
duke 已提交
506
      }
B
bae 已提交
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521

      else
         return; /* bad bit depth */

      row_info->channels = 1;

      /* Finally fix the color type if it records an alpha channel */
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
         row_info->color_type = PNG_COLOR_TYPE_GRAY;
   }

   /* RGBA, RGBX, XRGB cases */
   else if (row_info->channels == 4)
   {
      if (row_info->bit_depth == 8)
D
duke 已提交
522
      {
B
bae 已提交
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
         if (at_start) /* Skip initial filler */
            ++sp;
         else          /* Skip initial channels and, for sp, the filler */
            sp += 4, dp += 3;

         /* Note that the loop adds 3 to dp and 4 to sp each time. */
         while (sp < ep)
            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;

         row_info->pixel_depth = 24;
      }

      else if (row_info->bit_depth == 16)
      {
         if (at_start) /* Skip initial filler */
            sp += 2;
         else          /* Skip initial channels and, for sp, the filler */
            sp += 8, dp += 6;

         while (sp < ep)
D
duke 已提交
543
         {
B
bae 已提交
544 545 546 547
            /* Copy 6 bytes, skip 2 */
            *dp++ = *sp++, *dp++ = *sp++;
            *dp++ = *sp++, *dp++ = *sp++;
            *dp++ = *sp++, *dp++ = *sp, sp += 3;
D
duke 已提交
548
         }
B
bae 已提交
549 550

         row_info->pixel_depth = 48;
D
duke 已提交
551
      }
B
bae 已提交
552 553 554 555 556 557 558 559 560

      else
         return; /* bad bit depth */

      row_info->channels = 3;

      /* Finally fix the color type if it records an alpha channel */
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
         row_info->color_type = PNG_COLOR_TYPE_RGB;
D
duke 已提交
561
   }
B
bae 已提交
562 563 564 565 566 567

   else
      return; /* The filler channel has gone already */

   /* Fix the rowbytes value. */
   row_info->rowbytes = dp-row;
D
duke 已提交
568 569 570 571
}
#endif

#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
B
bae 已提交
572
/* Swaps red and blue bytes within a pixel */
D
duke 已提交
573 574 575
void /* PRIVATE */
png_do_bgr(png_row_infop row_info, png_bytep row)
{
B
bae 已提交
576 577 578
   png_debug(1, "in png_do_bgr");

   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
D
duke 已提交
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
   {
      png_uint_32 row_width = row_info->width;
      if (row_info->bit_depth == 8)
      {
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
         {
            png_bytep rp;
            png_uint_32 i;

            for (i = 0, rp = row; i < row_width; i++, rp += 3)
            {
               png_byte save = *rp;
               *rp = *(rp + 2);
               *(rp + 2) = save;
            }
         }
B
bae 已提交
595

D
duke 已提交
596 597 598 599 600 601 602 603 604 605 606 607 608
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
         {
            png_bytep rp;
            png_uint_32 i;

            for (i = 0, rp = row; i < row_width; i++, rp += 4)
            {
               png_byte save = *rp;
               *rp = *(rp + 2);
               *(rp + 2) = save;
            }
         }
      }
B
bae 已提交
609 610

#ifdef PNG_16BIT_SUPPORTED
D
duke 已提交
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
      else if (row_info->bit_depth == 16)
      {
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
         {
            png_bytep rp;
            png_uint_32 i;

            for (i = 0, rp = row; i < row_width; i++, rp += 6)
            {
               png_byte save = *rp;
               *rp = *(rp + 4);
               *(rp + 4) = save;
               save = *(rp + 1);
               *(rp + 1) = *(rp + 5);
               *(rp + 5) = save;
            }
         }
B
bae 已提交
628

D
duke 已提交
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
         {
            png_bytep rp;
            png_uint_32 i;

            for (i = 0, rp = row; i < row_width; i++, rp += 8)
            {
               png_byte save = *rp;
               *rp = *(rp + 4);
               *(rp + 4) = save;
               save = *(rp + 1);
               *(rp + 1) = *(rp + 5);
               *(rp + 5) = save;
            }
         }
      }
B
bae 已提交
645
#endif
D
duke 已提交
646 647 648 649 650
   }
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */

#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
B
bae 已提交
651 652
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
D
duke 已提交
653 654 655 656
void PNGAPI
png_set_user_transform_info(png_structp png_ptr, png_voidp
   user_transform_ptr, int user_transform_depth, int user_transform_channels)
{
B
bae 已提交
657 658 659 660
   png_debug(1, "in png_set_user_transform_info");

   if (png_ptr == NULL)
      return;
D
duke 已提交
661 662 663 664 665 666 667 668 669 670 671
   png_ptr->user_transform_ptr = user_transform_ptr;
   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
}
#endif

/* This function returns a pointer to the user_transform_ptr associated with
 * the user transform functions.  The application should free any memory
 * associated with this pointer before png_write_destroy and png_read_destroy
 * are called.
 */
B
bae 已提交
672
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
D
duke 已提交
673
png_voidp PNGAPI
B
bae 已提交
674
png_get_user_transform_ptr(png_const_structp png_ptr)
D
duke 已提交
675
{
B
bae 已提交
676 677 678
   if (png_ptr == NULL)
      return (NULL);

D
duke 已提交
679
   return ((png_voidp)png_ptr->user_transform_ptr);
B
bae 已提交
680
}
D
duke 已提交
681
#endif
B
bae 已提交
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701

#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structp png_ptr)
{
   /* See the comments in png.h - this is the sub-image row when reading and
    * interlaced image.
    */
   if (png_ptr != NULL)
      return png_ptr->row_number;

   return PNG_UINT_32_MAX; /* help the app not to fail silently */
}

png_byte PNGAPI
png_get_current_pass_number(png_const_structp png_ptr)
{
   if (png_ptr != NULL)
      return png_ptr->pass;
   return 8; /* invalid */
D
duke 已提交
702
}
B
bae 已提交
703 704 705
#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
          PNG_WRITE_USER_TRANSFORM_SUPPORTED */
D
duke 已提交
706
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */