Back to index

plt-scheme  4.2.1
pngtrans.c
Go to the documentation of this file.
00001 
00002 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
00003  *
00004  * libpng 1.2.5 - October 3, 2002
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2002 Glenn Randers-Pehrson
00007  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00008  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00009  */
00010 
00011 #define PNG_INTERNAL
00012 #include "png.h"
00013 
00014 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
00015 /* turn on BGR-to-RGB mapping */
00016 void PNGAPI
00017 png_set_bgr(png_structp png_ptr)
00018 {
00019    png_debug(1, "in png_set_bgr\n");
00020    png_ptr->transformations |= PNG_BGR;
00021 }
00022 #endif
00023 
00024 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
00025 /* turn on 16 bit byte swapping */
00026 void PNGAPI
00027 png_set_swap(png_structp png_ptr)
00028 {
00029    png_debug(1, "in png_set_swap\n");
00030    if (png_ptr->bit_depth == 16)
00031       png_ptr->transformations |= PNG_SWAP_BYTES;
00032 }
00033 #endif
00034 
00035 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
00036 /* turn on pixel packing */
00037 void PNGAPI
00038 png_set_packing(png_structp png_ptr)
00039 {
00040    png_debug(1, "in png_set_packing\n");
00041    if (png_ptr->bit_depth < 8)
00042    {
00043       png_ptr->transformations |= PNG_PACK;
00044       png_ptr->usr_bit_depth = 8;
00045    }
00046 }
00047 #endif
00048 
00049 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00050 /* turn on packed pixel swapping */
00051 void PNGAPI
00052 png_set_packswap(png_structp png_ptr)
00053 {
00054    png_debug(1, "in png_set_packswap\n");
00055    if (png_ptr->bit_depth < 8)
00056       png_ptr->transformations |= PNG_PACKSWAP;
00057 }
00058 #endif
00059 
00060 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
00061 void PNGAPI
00062 png_set_shift(png_structp png_ptr, png_color_8p true_bits)
00063 {
00064    png_debug(1, "in png_set_shift\n");
00065    png_ptr->transformations |= PNG_SHIFT;
00066    png_ptr->shift = *true_bits;
00067 }
00068 #endif
00069 
00070 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
00071     defined(PNG_WRITE_INTERLACING_SUPPORTED)
00072 int PNGAPI
00073 png_set_interlace_handling(png_structp png_ptr)
00074 {
00075    png_debug(1, "in png_set_interlace handling\n");
00076    if (png_ptr->interlaced)
00077    {
00078       png_ptr->transformations |= PNG_INTERLACE;
00079       return (7);
00080    }
00081 
00082    return (1);
00083 }
00084 #endif
00085 
00086 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
00087 /* Add a filler byte on read, or remove a filler or alpha byte on write.
00088  * The filler type has changed in v0.95 to allow future 2-byte fillers
00089  * for 48-bit input data, as well as to avoid problems with some compilers
00090  * that don't like bytes as parameters.
00091  */
00092 void PNGAPI
00093 png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
00094 {
00095    png_debug(1, "in png_set_filler\n");
00096    png_ptr->transformations |= PNG_FILLER;
00097    png_ptr->filler = (png_byte)filler;
00098    if (filler_loc == PNG_FILLER_AFTER)
00099       png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
00100    else
00101       png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
00102 
00103    /* This should probably go in the "do_filler" routine.
00104     * I attempted to do that in libpng-1.0.1a but that caused problems
00105     * so I restored it in libpng-1.0.2a
00106    */
00107 
00108    if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
00109    {
00110       png_ptr->usr_channels = 4;
00111    }
00112 
00113    /* Also I added this in libpng-1.0.2a (what happens when we expand
00114     * a less-than-8-bit grayscale to GA? */
00115 
00116    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
00117    {
00118       png_ptr->usr_channels = 2;
00119    }
00120 }
00121 #endif
00122 
00123 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
00124     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00125 void PNGAPI
00126 png_set_swap_alpha(png_structp png_ptr)
00127 {
00128    png_debug(1, "in png_set_swap_alpha\n");
00129    png_ptr->transformations |= PNG_SWAP_ALPHA;
00130 }
00131 #endif
00132 
00133 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
00134     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00135 void PNGAPI
00136 png_set_invert_alpha(png_structp png_ptr)
00137 {
00138    png_debug(1, "in png_set_invert_alpha\n");
00139    png_ptr->transformations |= PNG_INVERT_ALPHA;
00140 }
00141 #endif
00142 
00143 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
00144 void PNGAPI
00145 png_set_invert_mono(png_structp png_ptr)
00146 {
00147    png_debug(1, "in png_set_invert_mono\n");
00148    png_ptr->transformations |= PNG_INVERT_MONO;
00149 }
00150 
00151 /* invert monochrome grayscale data */
00152 void /* PRIVATE */
00153 png_do_invert(png_row_infop row_info, png_bytep row)
00154 {
00155    png_debug(1, "in png_do_invert\n");
00156   /* This test removed from libpng version 1.0.13 and 1.2.0:
00157    *   if (row_info->bit_depth == 1 &&
00158    */
00159 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00160    if (row == NULL || row_info == NULL)
00161      return;
00162 #endif
00163    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
00164    {
00165       png_bytep rp = row;
00166       png_uint_32 i;
00167       png_uint_32 istop = row_info->rowbytes;
00168 
00169       for (i = 0; i < istop; i++)
00170       {
00171          *rp = (png_byte)(~(*rp));
00172          rp++;
00173       }
00174    }
00175    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
00176       row_info->bit_depth == 8)
00177    {
00178       png_bytep rp = row;
00179       png_uint_32 i;
00180       png_uint_32 istop = row_info->rowbytes;
00181 
00182       for (i = 0; i < istop; i+=2)
00183       {
00184          *rp = (png_byte)(~(*rp));
00185          rp+=2;
00186       }
00187    }
00188    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
00189       row_info->bit_depth == 16)
00190    {
00191       png_bytep rp = row;
00192       png_uint_32 i;
00193       png_uint_32 istop = row_info->rowbytes;
00194 
00195       for (i = 0; i < istop; i+=4)
00196       {
00197          *rp = (png_byte)(~(*rp));
00198          *(rp+1) = (png_byte)(~(*(rp+1)));
00199          rp+=4;
00200       }
00201    }
00202 }
00203 #endif
00204 
00205 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
00206 /* swaps byte order on 16 bit depth images */
00207 void /* PRIVATE */
00208 png_do_swap(png_row_infop row_info, png_bytep row)
00209 {
00210    png_debug(1, "in png_do_swap\n");
00211    if (
00212 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00213        row != NULL && row_info != NULL &&
00214 #endif
00215        row_info->bit_depth == 16)
00216    {
00217       png_bytep rp = row;
00218       png_uint_32 i;
00219       png_uint_32 istop= row_info->width * row_info->channels;
00220 
00221       for (i = 0; i < istop; i++, rp += 2)
00222       {
00223          png_byte t = *rp;
00224          *rp = *(rp + 1);
00225          *(rp + 1) = t;
00226       }
00227    }
00228 }
00229 #endif
00230 
00231 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00232 static png_byte onebppswaptable[256] = {
00233    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
00234    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
00235    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
00236    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
00237    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
00238    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
00239    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
00240    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
00241    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
00242    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
00243    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
00244    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
00245    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
00246    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
00247    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
00248    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
00249    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
00250    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
00251    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
00252    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
00253    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
00254    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
00255    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
00256    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
00257    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
00258    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
00259    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
00260    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
00261    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
00262    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
00263    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
00264    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
00265 };
00266 
00267 static png_byte twobppswaptable[256] = {
00268    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
00269    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
00270    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
00271    0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
00272    0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
00273    0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
00274    0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
00275    0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
00276    0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
00277    0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
00278    0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
00279    0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
00280    0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
00281    0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
00282    0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
00283    0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
00284    0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
00285    0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
00286    0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
00287    0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
00288    0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
00289    0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
00290    0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
00291    0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
00292    0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
00293    0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
00294    0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
00295    0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
00296    0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
00297    0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
00298    0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
00299    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
00300 };
00301 
00302 static png_byte fourbppswaptable[256] = {
00303    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
00304    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
00305    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
00306    0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
00307    0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
00308    0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
00309    0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
00310    0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
00311    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
00312    0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
00313    0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
00314    0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
00315    0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
00316    0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
00317    0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
00318    0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
00319    0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
00320    0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
00321    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
00322    0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
00323    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
00324    0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
00325    0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
00326    0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
00327    0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
00328    0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
00329    0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
00330    0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
00331    0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
00332    0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
00333    0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
00334    0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
00335 };
00336 
00337 /* swaps pixel packing order within bytes */
00338 void /* PRIVATE */
00339 png_do_packswap(png_row_infop row_info, png_bytep row)
00340 {
00341    png_debug(1, "in png_do_packswap\n");
00342    if (
00343 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00344        row != NULL && row_info != NULL &&
00345 #endif
00346        row_info->bit_depth < 8)
00347    {
00348       png_bytep rp, end, table;
00349 
00350       end = row + row_info->rowbytes;
00351 
00352       if (row_info->bit_depth == 1)
00353          table = onebppswaptable;
00354       else if (row_info->bit_depth == 2)
00355          table = twobppswaptable;
00356       else if (row_info->bit_depth == 4)
00357          table = fourbppswaptable;
00358       else
00359          return;
00360 
00361       for (rp = row; rp < end; rp++)
00362          *rp = table[*rp];
00363    }
00364 }
00365 #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
00366 
00367 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
00368     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
00369 /* remove filler or alpha byte(s) */
00370 void /* PRIVATE */
00371 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
00372 {
00373    png_debug(1, "in png_do_strip_filler\n");
00374 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00375    if (row != NULL && row_info != NULL)
00376 #endif
00377    {
00378 /*
00379       if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
00380           row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00381 */
00382       png_bytep sp=row;
00383       png_bytep dp=row;
00384       png_uint_32 row_width=row_info->width;
00385       png_uint_32 i;
00386 
00387       if (row_info->channels == 4)
00388       {
00389          if (row_info->bit_depth == 8)
00390          {
00391             /* This converts from RGBX or RGBA to RGB */
00392             if (flags & PNG_FLAG_FILLER_AFTER)
00393             {
00394                dp+=3; sp+=4;
00395                for (i = 1; i < row_width; i++)
00396                {
00397                   *dp++ = *sp++;
00398                   *dp++ = *sp++;
00399                   *dp++ = *sp++;
00400                   sp++;
00401                }
00402             }
00403             /* This converts from XRGB or ARGB to RGB */
00404             else
00405             {
00406                for (i = 0; i < row_width; i++)
00407                {
00408                   sp++;
00409                   *dp++ = *sp++;
00410                   *dp++ = *sp++;
00411                   *dp++ = *sp++;
00412                }
00413             }
00414             row_info->pixel_depth = 24;
00415             row_info->rowbytes = row_width * 3;
00416          }
00417          else /* if (row_info->bit_depth == 16) */
00418          {
00419             if (flags & PNG_FLAG_FILLER_AFTER)
00420             {
00421                /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
00422                sp += 8; dp += 6;
00423                for (i = 1; i < row_width; i++)
00424                {
00425                   /* This could be (although png_memcpy is probably slower):
00426                   png_memcpy(dp, sp, 6);
00427                   sp += 8;
00428                   dp += 6;
00429                   */
00430 
00431                   *dp++ = *sp++;
00432                   *dp++ = *sp++;
00433                   *dp++ = *sp++;
00434                   *dp++ = *sp++;
00435                   *dp++ = *sp++;
00436                   *dp++ = *sp++;
00437                   sp += 2;
00438                }
00439             }
00440             else
00441             {
00442                /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
00443                for (i = 0; i < row_width; i++)
00444                {
00445                   /* This could be (although png_memcpy is probably slower):
00446                   png_memcpy(dp, sp, 6);
00447                   sp += 8;
00448                   dp += 6;
00449                   */
00450 
00451                   sp+=2;
00452                   *dp++ = *sp++;
00453                   *dp++ = *sp++;
00454                   *dp++ = *sp++;
00455                   *dp++ = *sp++;
00456                   *dp++ = *sp++;
00457                   *dp++ = *sp++;
00458                }
00459             }
00460             row_info->pixel_depth = 48;
00461             row_info->rowbytes = row_width * 6;
00462          }
00463          row_info->channels = 3;
00464          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
00465       }
00466 /*
00467       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
00468                row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00469 */
00470       else if (row_info->channels == 2)
00471       {
00472          if (row_info->bit_depth == 8)
00473          {
00474             /* This converts from GX or GA to G */
00475             if (flags & PNG_FLAG_FILLER_AFTER)
00476             {
00477                for (i = 0; i < row_width; i++)
00478                {
00479                   *dp++ = *sp++;
00480                   sp++;
00481                }
00482             }
00483             /* This converts from XG or AG to G */
00484             else
00485             {
00486                for (i = 0; i < row_width; i++)
00487                {
00488                   sp++;
00489                   *dp++ = *sp++;
00490                }
00491             }
00492             row_info->pixel_depth = 8;
00493             row_info->rowbytes = row_width;
00494          }
00495          else /* if (row_info->bit_depth == 16) */
00496          {
00497             if (flags & PNG_FLAG_FILLER_AFTER)
00498             {
00499                /* This converts from GGXX or GGAA to GG */
00500                sp += 4; dp += 2;
00501                for (i = 1; i < row_width; i++)
00502                {
00503                   *dp++ = *sp++;
00504                   *dp++ = *sp++;
00505                   sp += 2;
00506                }
00507             }
00508             else
00509             {
00510                /* This converts from XXGG or AAGG to GG */
00511                for (i = 0; i < row_width; i++)
00512                {
00513                   sp += 2;
00514                   *dp++ = *sp++;
00515                   *dp++ = *sp++;
00516                }
00517             }
00518             row_info->pixel_depth = 16;
00519             row_info->rowbytes = row_width * 2;
00520          }
00521          row_info->channels = 1;
00522          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
00523       }
00524    }
00525 }
00526 #endif
00527 
00528 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
00529 /* swaps red and blue bytes within a pixel */
00530 void /* PRIVATE */
00531 png_do_bgr(png_row_infop row_info, png_bytep row)
00532 {
00533    png_debug(1, "in png_do_bgr\n");
00534    if (
00535 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00536        row != NULL && row_info != NULL &&
00537 #endif
00538        (row_info->color_type & PNG_COLOR_MASK_COLOR))
00539    {
00540       png_uint_32 row_width = row_info->width;
00541       if (row_info->bit_depth == 8)
00542       {
00543          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00544          {
00545             png_bytep rp;
00546             png_uint_32 i;
00547 
00548             for (i = 0, rp = row; i < row_width; i++, rp += 3)
00549             {
00550                png_byte save = *rp;
00551                *rp = *(rp + 2);
00552                *(rp + 2) = save;
00553             }
00554          }
00555          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00556          {
00557             png_bytep rp;
00558             png_uint_32 i;
00559 
00560             for (i = 0, rp = row; i < row_width; i++, rp += 4)
00561             {
00562                png_byte save = *rp;
00563                *rp = *(rp + 2);
00564                *(rp + 2) = save;
00565             }
00566          }
00567       }
00568       else if (row_info->bit_depth == 16)
00569       {
00570          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00571          {
00572             png_bytep rp;
00573             png_uint_32 i;
00574 
00575             for (i = 0, rp = row; i < row_width; i++, rp += 6)
00576             {
00577                png_byte save = *rp;
00578                *rp = *(rp + 4);
00579                *(rp + 4) = save;
00580                save = *(rp + 1);
00581                *(rp + 1) = *(rp + 5);
00582                *(rp + 5) = save;
00583             }
00584          }
00585          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00586          {
00587             png_bytep rp;
00588             png_uint_32 i;
00589 
00590             for (i = 0, rp = row; i < row_width; i++, rp += 8)
00591             {
00592                png_byte save = *rp;
00593                *rp = *(rp + 4);
00594                *(rp + 4) = save;
00595                save = *(rp + 1);
00596                *(rp + 1) = *(rp + 5);
00597                *(rp + 5) = save;
00598             }
00599          }
00600       }
00601    }
00602 }
00603 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
00604 
00605 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
00606     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
00607     defined(PNG_LEGACY_SUPPORTED)
00608 void PNGAPI
00609 png_set_user_transform_info(png_structp png_ptr, png_voidp
00610    user_transform_ptr, int user_transform_depth, int user_transform_channels)
00611 {
00612    png_debug(1, "in png_set_user_transform_info\n");
00613 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
00614    png_ptr->user_transform_ptr = user_transform_ptr;
00615    png_ptr->user_transform_depth = (png_byte)user_transform_depth;
00616    png_ptr->user_transform_channels = (png_byte)user_transform_channels;
00617 #else
00618    if(user_transform_ptr || user_transform_depth || user_transform_channels)
00619       png_warning(png_ptr,
00620         "This version of libpng does not support user transform info");
00621 #endif
00622 }
00623 #endif
00624 
00625 /* This function returns a pointer to the user_transform_ptr associated with
00626  * the user transform functions.  The application should free any memory
00627  * associated with this pointer before png_write_destroy and png_read_destroy
00628  * are called.
00629  */
00630 png_voidp PNGAPI
00631 png_get_user_transform_ptr(png_structp png_ptr)
00632 {
00633 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
00634    return ((png_voidp)png_ptr->user_transform_ptr);
00635 #else
00636    if(png_ptr)
00637      return (NULL);
00638    return (NULL);
00639 #endif
00640 }