Back to index

tetex-bin  3.0
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.8 - December 3, 2004
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2004 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_read_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 
00122 #if !defined(PNG_1_0_X)
00123 /* Added to libpng-1.2.7 */
00124 void PNGAPI
00125 png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
00126 {
00127    png_debug(1, "in png_set_add_alpha\n");
00128    png_set_filler(png_ptr, filler, filler_loc);
00129    png_ptr->transformations |= PNG_ADD_ALPHA;
00130 }
00131 #endif
00132 
00133 #endif
00134 
00135 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
00136     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00137 void PNGAPI
00138 png_set_swap_alpha(png_structp png_ptr)
00139 {
00140    png_debug(1, "in png_set_swap_alpha\n");
00141    png_ptr->transformations |= PNG_SWAP_ALPHA;
00142 }
00143 #endif
00144 
00145 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
00146     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00147 void PNGAPI
00148 png_set_invert_alpha(png_structp png_ptr)
00149 {
00150    png_debug(1, "in png_set_invert_alpha\n");
00151    png_ptr->transformations |= PNG_INVERT_ALPHA;
00152 }
00153 #endif
00154 
00155 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
00156 void PNGAPI
00157 png_set_invert_mono(png_structp png_ptr)
00158 {
00159    png_debug(1, "in png_set_invert_mono\n");
00160    png_ptr->transformations |= PNG_INVERT_MONO;
00161 }
00162 
00163 /* invert monochrome grayscale data */
00164 void /* PRIVATE */
00165 png_do_invert(png_row_infop row_info, png_bytep row)
00166 {
00167    png_debug(1, "in png_do_invert\n");
00168   /* This test removed from libpng version 1.0.13 and 1.2.0:
00169    *   if (row_info->bit_depth == 1 &&
00170    */
00171 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00172    if (row == NULL || row_info == NULL)
00173      return;
00174 #endif
00175    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
00176    {
00177       png_bytep rp = row;
00178       png_uint_32 i;
00179       png_uint_32 istop = row_info->rowbytes;
00180 
00181       for (i = 0; i < istop; i++)
00182       {
00183          *rp = (png_byte)(~(*rp));
00184          rp++;
00185       }
00186    }
00187    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
00188       row_info->bit_depth == 8)
00189    {
00190       png_bytep rp = row;
00191       png_uint_32 i;
00192       png_uint_32 istop = row_info->rowbytes;
00193 
00194       for (i = 0; i < istop; i+=2)
00195       {
00196          *rp = (png_byte)(~(*rp));
00197          rp+=2;
00198       }
00199    }
00200    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
00201       row_info->bit_depth == 16)
00202    {
00203       png_bytep rp = row;
00204       png_uint_32 i;
00205       png_uint_32 istop = row_info->rowbytes;
00206 
00207       for (i = 0; i < istop; i+=4)
00208       {
00209          *rp = (png_byte)(~(*rp));
00210          *(rp+1) = (png_byte)(~(*(rp+1)));
00211          rp+=4;
00212       }
00213    }
00214 }
00215 #endif
00216 
00217 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
00218 /* swaps byte order on 16 bit depth images */
00219 void /* PRIVATE */
00220 png_do_swap(png_row_infop row_info, png_bytep row)
00221 {
00222    png_debug(1, "in png_do_swap\n");
00223    if (
00224 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00225        row != NULL && row_info != NULL &&
00226 #endif
00227        row_info->bit_depth == 16)
00228    {
00229       png_bytep rp = row;
00230       png_uint_32 i;
00231       png_uint_32 istop= row_info->width * row_info->channels;
00232 
00233       for (i = 0; i < istop; i++, rp += 2)
00234       {
00235          png_byte t = *rp;
00236          *rp = *(rp + 1);
00237          *(rp + 1) = t;
00238       }
00239    }
00240 }
00241 #endif
00242 
00243 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00244 static png_byte onebppswaptable[256] = {
00245    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
00246    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
00247    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
00248    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
00249    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
00250    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
00251    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
00252    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
00253    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
00254    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
00255    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
00256    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
00257    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
00258    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
00259    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
00260    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
00261    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
00262    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
00263    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
00264    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
00265    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
00266    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
00267    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
00268    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
00269    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
00270    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
00271    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
00272    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
00273    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
00274    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
00275    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
00276    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
00277 };
00278 
00279 static png_byte twobppswaptable[256] = {
00280    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
00281    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
00282    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
00283    0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
00284    0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
00285    0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
00286    0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
00287    0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
00288    0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
00289    0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
00290    0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
00291    0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
00292    0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
00293    0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
00294    0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
00295    0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
00296    0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
00297    0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
00298    0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
00299    0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
00300    0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
00301    0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
00302    0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
00303    0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
00304    0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
00305    0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
00306    0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
00307    0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
00308    0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
00309    0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
00310    0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
00311    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
00312 };
00313 
00314 static png_byte fourbppswaptable[256] = {
00315    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
00316    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
00317    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
00318    0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
00319    0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
00320    0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
00321    0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
00322    0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
00323    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
00324    0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
00325    0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
00326    0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
00327    0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
00328    0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
00329    0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
00330    0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
00331    0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
00332    0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
00333    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
00334    0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
00335    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
00336    0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
00337    0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
00338    0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
00339    0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
00340    0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
00341    0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
00342    0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
00343    0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
00344    0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
00345    0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
00346    0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
00347 };
00348 
00349 /* swaps pixel packing order within bytes */
00350 void /* PRIVATE */
00351 png_do_packswap(png_row_infop row_info, png_bytep row)
00352 {
00353    png_debug(1, "in png_do_packswap\n");
00354    if (
00355 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00356        row != NULL && row_info != NULL &&
00357 #endif
00358        row_info->bit_depth < 8)
00359    {
00360       png_bytep rp, end, table;
00361 
00362       end = row + row_info->rowbytes;
00363 
00364       if (row_info->bit_depth == 1)
00365          table = onebppswaptable;
00366       else if (row_info->bit_depth == 2)
00367          table = twobppswaptable;
00368       else if (row_info->bit_depth == 4)
00369          table = fourbppswaptable;
00370       else
00371          return;
00372 
00373       for (rp = row; rp < end; rp++)
00374          *rp = table[*rp];
00375    }
00376 }
00377 #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
00378 
00379 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
00380     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
00381 /* remove filler or alpha byte(s) */
00382 void /* PRIVATE */
00383 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
00384 {
00385    png_debug(1, "in png_do_strip_filler\n");
00386 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00387    if (row != NULL && row_info != NULL)
00388 #endif
00389    {
00390       png_bytep sp=row;
00391       png_bytep dp=row;
00392       png_uint_32 row_width=row_info->width;
00393       png_uint_32 i;
00394 
00395       if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
00396          (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
00397          (flags & PNG_FLAG_STRIP_ALPHA))) &&
00398          row_info->channels == 4)
00399       {
00400          if (row_info->bit_depth == 8)
00401          {
00402             /* This converts from RGBX or RGBA to RGB */
00403             if (flags & PNG_FLAG_FILLER_AFTER)
00404             {
00405                dp+=3; sp+=4;
00406                for (i = 1; i < row_width; i++)
00407                {
00408                   *dp++ = *sp++;
00409                   *dp++ = *sp++;
00410                   *dp++ = *sp++;
00411                   sp++;
00412                }
00413             }
00414             /* This converts from XRGB or ARGB to RGB */
00415             else
00416             {
00417                for (i = 0; i < row_width; i++)
00418                {
00419                   sp++;
00420                   *dp++ = *sp++;
00421                   *dp++ = *sp++;
00422                   *dp++ = *sp++;
00423                }
00424             }
00425             row_info->pixel_depth = 24;
00426             row_info->rowbytes = row_width * 3;
00427          }
00428          else /* if (row_info->bit_depth == 16) */
00429          {
00430             if (flags & PNG_FLAG_FILLER_AFTER)
00431             {
00432                /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
00433                sp += 8; dp += 6;
00434                for (i = 1; i < row_width; i++)
00435                {
00436                   /* This could be (although png_memcpy is probably slower):
00437                   png_memcpy(dp, sp, 6);
00438                   sp += 8;
00439                   dp += 6;
00440                   */
00441 
00442                   *dp++ = *sp++;
00443                   *dp++ = *sp++;
00444                   *dp++ = *sp++;
00445                   *dp++ = *sp++;
00446                   *dp++ = *sp++;
00447                   *dp++ = *sp++;
00448                   sp += 2;
00449                }
00450             }
00451             else
00452             {
00453                /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
00454                for (i = 0; i < row_width; i++)
00455                {
00456                   /* This could be (although png_memcpy is probably slower):
00457                   png_memcpy(dp, sp, 6);
00458                   sp += 8;
00459                   dp += 6;
00460                   */
00461 
00462                   sp+=2;
00463                   *dp++ = *sp++;
00464                   *dp++ = *sp++;
00465                   *dp++ = *sp++;
00466                   *dp++ = *sp++;
00467                   *dp++ = *sp++;
00468                   *dp++ = *sp++;
00469                }
00470             }
00471             row_info->pixel_depth = 48;
00472             row_info->rowbytes = row_width * 6;
00473          }
00474          row_info->channels = 3;
00475       }
00476       else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
00477          (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
00478          (flags & PNG_FLAG_STRIP_ALPHA))) &&
00479           row_info->channels == 2)
00480       {
00481          if (row_info->bit_depth == 8)
00482          {
00483             /* This converts from GX or GA to G */
00484             if (flags & PNG_FLAG_FILLER_AFTER)
00485             {
00486                for (i = 0; i < row_width; i++)
00487                {
00488                   *dp++ = *sp++;
00489                   sp++;
00490                }
00491             }
00492             /* This converts from XG or AG to G */
00493             else
00494             {
00495                for (i = 0; i < row_width; i++)
00496                {
00497                   sp++;
00498                   *dp++ = *sp++;
00499                }
00500             }
00501             row_info->pixel_depth = 8;
00502             row_info->rowbytes = row_width;
00503          }
00504          else /* if (row_info->bit_depth == 16) */
00505          {
00506             if (flags & PNG_FLAG_FILLER_AFTER)
00507             {
00508                /* This converts from GGXX or GGAA to GG */
00509                sp += 4; dp += 2;
00510                for (i = 1; i < row_width; i++)
00511                {
00512                   *dp++ = *sp++;
00513                   *dp++ = *sp++;
00514                   sp += 2;
00515                }
00516             }
00517             else
00518             {
00519                /* This converts from XXGG or AAGG to GG */
00520                for (i = 0; i < row_width; i++)
00521                {
00522                   sp += 2;
00523                   *dp++ = *sp++;
00524                   *dp++ = *sp++;
00525                }
00526             }
00527             row_info->pixel_depth = 16;
00528             row_info->rowbytes = row_width * 2;
00529          }
00530          row_info->channels = 1;
00531       }
00532       if (flags & PNG_FLAG_STRIP_ALPHA)
00533         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
00534    }
00535 }
00536 #endif
00537 
00538 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
00539 /* swaps red and blue bytes within a pixel */
00540 void /* PRIVATE */
00541 png_do_bgr(png_row_infop row_info, png_bytep row)
00542 {
00543    png_debug(1, "in png_do_bgr\n");
00544    if (
00545 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00546        row != NULL && row_info != NULL &&
00547 #endif
00548        (row_info->color_type & PNG_COLOR_MASK_COLOR))
00549    {
00550       png_uint_32 row_width = row_info->width;
00551       if (row_info->bit_depth == 8)
00552       {
00553          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00554          {
00555             png_bytep rp;
00556             png_uint_32 i;
00557 
00558             for (i = 0, rp = row; i < row_width; i++, rp += 3)
00559             {
00560                png_byte save = *rp;
00561                *rp = *(rp + 2);
00562                *(rp + 2) = save;
00563             }
00564          }
00565          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00566          {
00567             png_bytep rp;
00568             png_uint_32 i;
00569 
00570             for (i = 0, rp = row; i < row_width; i++, rp += 4)
00571             {
00572                png_byte save = *rp;
00573                *rp = *(rp + 2);
00574                *(rp + 2) = save;
00575             }
00576          }
00577       }
00578       else if (row_info->bit_depth == 16)
00579       {
00580          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00581          {
00582             png_bytep rp;
00583             png_uint_32 i;
00584 
00585             for (i = 0, rp = row; i < row_width; i++, rp += 6)
00586             {
00587                png_byte save = *rp;
00588                *rp = *(rp + 4);
00589                *(rp + 4) = save;
00590                save = *(rp + 1);
00591                *(rp + 1) = *(rp + 5);
00592                *(rp + 5) = save;
00593             }
00594          }
00595          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00596          {
00597             png_bytep rp;
00598             png_uint_32 i;
00599 
00600             for (i = 0, rp = row; i < row_width; i++, rp += 8)
00601             {
00602                png_byte save = *rp;
00603                *rp = *(rp + 4);
00604                *(rp + 4) = save;
00605                save = *(rp + 1);
00606                *(rp + 1) = *(rp + 5);
00607                *(rp + 5) = save;
00608             }
00609          }
00610       }
00611    }
00612 }
00613 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
00614 
00615 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
00616     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
00617     defined(PNG_LEGACY_SUPPORTED)
00618 void PNGAPI
00619 png_set_user_transform_info(png_structp png_ptr, png_voidp
00620    user_transform_ptr, int user_transform_depth, int user_transform_channels)
00621 {
00622    png_debug(1, "in png_set_user_transform_info\n");
00623 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
00624    png_ptr->user_transform_ptr = user_transform_ptr;
00625    png_ptr->user_transform_depth = (png_byte)user_transform_depth;
00626    png_ptr->user_transform_channels = (png_byte)user_transform_channels;
00627 #else
00628    if(user_transform_ptr || user_transform_depth || user_transform_channels)
00629       png_warning(png_ptr,
00630         "This version of libpng does not support user transform info");
00631 #endif
00632 }
00633 #endif
00634 
00635 /* This function returns a pointer to the user_transform_ptr associated with
00636  * the user transform functions.  The application should free any memory
00637  * associated with this pointer before png_write_destroy and png_read_destroy
00638  * are called.
00639  */
00640 png_voidp PNGAPI
00641 png_get_user_transform_ptr(png_structp png_ptr)
00642 {
00643 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
00644    return ((png_voidp)png_ptr->user_transform_ptr);
00645 #else
00646    if(png_ptr)
00647      return (NULL);
00648    return (NULL);
00649 #endif
00650 }