fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_PNG_Image.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_PNG_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Fl_PNG_Image routines.
00005 //
00006 // Copyright 1997-2010 by Easy Software Products.
00007 // Image support by Matthias Melcher, Copyright 2000-2009.
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Library General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Library General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00022 // USA.
00023 //
00024 // Please report all bugs and problems on the following page:
00025 //
00026 //     http://www.fltk.org/str.php
00027 //
00028 // Contents:
00029 
00030 //
00031 //   Fl_PNG_Image::Fl_PNG_Image() - Load a PNG image file.
00032 //
00033 
00034 //
00035 // Include necessary header files...
00036 //
00037 
00038 #include <FL/Fl.H>
00039 #include <FL/Fl_PNG_Image.H>
00040 #include <config.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <FL/fl_utf8.h>
00044 
00045 extern "C"
00046 {
00047 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
00048 #  include <zlib.h>
00049 #  ifdef HAVE_PNG_H
00050 #    include <png.h>
00051 #  else
00052 #    include <libpng/png.h>
00053 #  endif // HAVE_PNG_H
00054 #endif // HAVE_LIBPNG && HAVE_LIBZ
00055 }
00056 
00057 
00063 Fl_PNG_Image::Fl_PNG_Image(const char *png) // I - File to read
00064   : Fl_RGB_Image(0,0,0) {
00065 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
00066   int           i;                      // Looping var
00067   FILE          *fp;                    // File pointer
00068   int           channels;               // Number of color channels
00069   png_structp   pp;                     // PNG read pointer
00070   png_infop     info;                   // PNG info pointers
00071   png_bytep     *rows;                  // PNG row pointers
00072 
00073 
00074   // Open the PNG file...
00075   if ((fp = fl_fopen(png, "rb")) == NULL) return;
00076 
00077   // Setup the PNG data structures...
00078   pp   = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00079   info = png_create_info_struct(pp);
00080 
00081   if (setjmp(png_jmpbuf(pp)))
00082   {
00083     Fl::warning("PNG file \"%s\" contains errors!\n", png);
00084     return;
00085   }
00086 
00087   // Initialize the PNG read "engine"...
00088   png_init_io(pp, fp);
00089 
00090   // Get the image dimensions and convert to grayscale or RGB...
00091   png_read_info(pp, info);
00092 
00093   if (png_get_color_type(pp, info) == PNG_COLOR_TYPE_PALETTE)
00094     png_set_expand(pp);
00095 
00096   if (png_get_color_type(pp, info) & PNG_COLOR_MASK_COLOR)
00097     channels = 3;
00098   else
00099     channels = 1;
00100 
00101   int num_trans = 0;
00102   png_get_tRNS(pp, info, 0, &num_trans, 0);
00103   if ((png_get_color_type(pp, info) & PNG_COLOR_MASK_ALPHA) || (num_trans != 0))
00104       channels ++;
00105 
00106   w((int)(png_get_image_width(pp, info)));
00107   h((int)(png_get_image_height(pp, info)));
00108   d(channels);
00109 
00110   if (png_get_bit_depth(pp, info) < 8)
00111   {
00112     png_set_packing(pp);
00113     png_set_expand(pp);
00114   }
00115   else if (png_get_bit_depth(pp, info) == 16)
00116     png_set_strip_16(pp);
00117 
00118 #  if defined(HAVE_PNG_GET_VALID) && defined(HAVE_PNG_SET_TRNS_TO_ALPHA)
00119   // Handle transparency...
00120   if (png_get_valid(pp, info, PNG_INFO_tRNS))
00121     png_set_tRNS_to_alpha(pp);
00122 #  endif // HAVE_PNG_GET_VALID && HAVE_PNG_SET_TRNS_TO_ALPHA
00123 
00124   array = new uchar[w() * h() * d()];
00125   alloc_array = 1;
00126 
00127   // Allocate pointers...
00128   rows = new png_bytep[h()];
00129 
00130   for (i = 0; i < h(); i ++)
00131     rows[i] = (png_bytep)(array + i * w() * d());
00132 
00133   // Read the image, handling interlacing as needed...
00134   for (i = png_set_interlace_handling(pp); i > 0; i --)
00135     png_read_rows(pp, rows, NULL, h());
00136 
00137 #ifdef WIN32
00138   // Some Windows graphics drivers don't honor transparency when RGB == white
00139   if (channels == 4) {
00140     // Convert RGB to 0 when alpha == 0...
00141     uchar *ptr = (uchar *)array;
00142     for (i = w() * h(); i > 0; i --, ptr += 4)
00143       if (!ptr[3]) ptr[0] = ptr[1] = ptr[2] = 0;
00144   }
00145 #endif // WIN32
00146 
00147   // Free memory and return...
00148   delete[] rows;
00149 
00150   png_read_end(pp, info);
00151   png_destroy_read_struct(&pp, &info, NULL);
00152 
00153   fclose(fp);
00154 #endif // HAVE_LIBPNG && HAVE_LIBZ
00155 }
00156 
00157 
00158 //
00159 // End of "$Id: Fl_PNG_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
00160 //