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