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

Fl_PNG_Image.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // Fl_PNG_Image routines.
5 //
6 // Copyright 1997-2012 by Easy Software Products.
7 // Image support by Matthias Melcher, Copyright 2000-2009.
8 //
9 // This library is free software. Distribution and use rights are outlined in
10 // the file "COPYING" which should have been included with this file. If this
11 // file is missing or damaged, see the license at:
12 //
13 // http://www.fltk.org/COPYING.php
14 //
15 // Please report all bugs and problems on the following page:
16 //
17 // http://www.fltk.org/str.php
18 //
19 // Contents:
20 
21 //
22 // Fl_PNG_Image::Fl_PNG_Image() - Load a PNG image file.
23 //
24 
25 //
26 // Include necessary header files...
27 //
28 
29 #include <FL/Fl.H>
30 #include <FL/Fl_PNG_Image.H>
31 #include <FL/Fl_Shared_Image.H>
32 #include <config.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <FL/fl_utf8.h>
36 
37 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
38 extern "C"
39 {
40 # include <zlib.h>
41 # ifdef HAVE_PNG_H
42 # include <png.h>
43 # else
44 # include <libpng/png.h>
45 # endif // HAVE_PNG_H
46 }
47 
48 typedef struct {
49  png_structp pp;
50  const unsigned char *current;
51  const unsigned char *last;
52 } fl_png_memory;
53 
54 extern "C" {
55  static void png_read_data_from_mem( png_structp png_ptr, //pointer to our data
56  png_bytep data, // where to copy the image data for libpng computing
57  png_size_t length) // length of data to copy
58  {
59  fl_png_memory *png_mem_data = (fl_png_memory*)png_get_io_ptr(png_ptr); // get the pointer to our struct
60  if (png_mem_data->current + length > png_mem_data->last) {
61  png_error(png_mem_data->pp, "Invalid attempt to read row data");
62  return;
63  }
64  /* copy data from image buffer */
65  memcpy (data, png_mem_data->current, length);
66  /* advance in the memory data */
67  png_mem_data->current += length;
68  }
69 } // extern "C"
70 #endif // HAVE_LIBPNG && HAVE_LIBZ
71 
72 
87 {
88  load_png_(filename, NULL, 0);
89 }
90 
91 
105  const char *name_png, const unsigned char *buffer, int maxsize): Fl_RGB_Image(0,0,0)
106 {
107  load_png_(name_png, buffer, maxsize);
108 }
109 
110 
111 void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_png, int maxsize)
112 {
113 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
114  int i; // Looping var
115  FILE *fp = NULL; // File pointer
116  int channels; // Number of color channels
117  png_structp pp; // PNG read pointer
118  png_infop info = 0; // PNG info pointers
119  png_bytep *rows;// PNG row pointers
120  fl_png_memory png_mem_data;
121  int from_memory = (buffer_png != NULL); // true if reading image from memory
122 
123  if (!from_memory) {
124  if ((fp = fl_fopen(name_png, "rb")) == NULL) {
126  return;
127  }
128  }
129  const char *display_name = (name_png ? name_png : "In-memory PNG data");
130 
131  // Setup the PNG data structures...
133  if (pp) info = png_create_info_struct(pp);
134  if (!pp || !info) {
135  if (pp) png_destroy_read_struct(&pp, NULL, NULL);
136  if (!from_memory) fclose(fp);
137  Fl::warning("Cannot allocate memory to read PNG file or data \"%s\".\n", display_name);
138  w(0); h(0); d(0); ld(ERR_FORMAT);
139  return;
140  }
141 
142  if (setjmp(png_jmpbuf(pp)))
143  {
145  if (!from_memory) fclose(fp);
146  Fl::warning("PNG file or data \"%s\" is too large or contains errors!\n", display_name);
147  w(0); h(0); d(0); ld(ERR_FORMAT);
148  return;
149  }
150 
151  if (from_memory) {
152  png_mem_data.current = buffer_png;
153  png_mem_data.last = buffer_png + maxsize;
154  png_mem_data.pp = pp;
155  // Initialize the function pointer to the PNG read "engine"...
156  png_set_read_fn (pp, (png_voidp) &png_mem_data, png_read_data_from_mem);
157  } else {
158  png_init_io(pp, fp); // Initialize the PNG file read "engine"...
159  }
160 
161  // Get the image dimensions and convert to grayscale or RGB...
162  png_read_info(pp, info);
163 
165  png_set_expand(pp);
166 
168  channels = 3;
169  else
170  channels = 1;
171 
172  int num_trans = 0;
173  png_get_tRNS(pp, info, 0, &num_trans, 0);
174  if ((png_get_color_type(pp, info) & PNG_COLOR_MASK_ALPHA) || (num_trans != 0))
175  channels ++;
176 
177  w((int)(png_get_image_width(pp, info)));
178  h((int)(png_get_image_height(pp, info)));
179  d(channels);
180 
181  if (png_get_bit_depth(pp, info) < 8)
182  {
183  png_set_packing(pp);
184  png_set_expand(pp);
185  }
186  else if (png_get_bit_depth(pp, info) == 16)
187  png_set_strip_16(pp);
188 
189 # if defined(HAVE_PNG_GET_VALID) && defined(HAVE_PNG_SET_TRNS_TO_ALPHA)
190  // Handle transparency...
191  if (png_get_valid(pp, info, PNG_INFO_tRNS))
193 # endif // HAVE_PNG_GET_VALID && HAVE_PNG_SET_TRNS_TO_ALPHA
194 
195  if (((size_t)w()) * h() * d() > max_size() ) longjmp(png_jmpbuf(pp), 1);
196  array = new uchar[w() * h() * d()];
197  alloc_array = 1;
198 
199  // Allocate pointers...
200  rows = new png_bytep[h()];
201 
202  for (i = 0; i < h(); i ++)
203  rows[i] = (png_bytep)(array + i * w() * d());
204 
205  // Read the image, handling interlacing as needed...
206  for (i = png_set_interlace_handling(pp); i > 0; i --)
207  png_read_rows(pp, rows, NULL, h());
208 
209 #ifdef WIN32
210  // Some Windows graphics drivers don't honor transparency when RGB == white
211  if (channels == 4) {
212  // Convert RGB to 0 when alpha == 0...
213  uchar *ptr = (uchar *)array;
214  for (i = w() * h(); i > 0; i --, ptr += 4)
215  if (!ptr[3]) ptr[0] = ptr[1] = ptr[2] = 0;
216  }
217 #endif // WIN32
218 
219  // Free memory and return...
220  delete[] rows;
221 
222  png_read_end(pp, info);
224 
225  if (from_memory) {
226  if (w() && h() && name_png) {
227  Fl_Shared_Image *si = new Fl_Shared_Image(name_png, this);
228  si->add();
229  }
230  } else {
231  fclose(fp);
232  }
233 #endif // HAVE_LIBPNG && HAVE_LIBZ
234 }
235 
236 
237 //
238 // End of "$Id$".
239 //
png_read_rows
PNG_IMPEXP void() png_read_rows(png_structrp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)
Definition: pngread.c:636
Fl.H
png_error
PNG_IMPEXP void() png_error(png_const_structrp png_ptr, png_const_charp error_message)
Definition: pngerror.c:40
png_get_valid
PNG_IMPEXP png_uint_32() png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag)
Definition: pngget.c:20
png_get_bit_depth
PNG_IMPEXP png_byte() png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngget.c:70
png_voidp
void * png_voidp
Definition: pngconf.h:598
PNG_INFO_tRNS
#define PNG_INFO_tRNS
Definition: png.h:877
Fl_Image::d
int d() const
Definition: Fl_Image.H:121
Fl_PNG_Image::load_png_
void load_png_(const char *name_png, const unsigned char *buffer_png, int datasize)
Definition: Fl_PNG_Image.cxx:111
png_set_interlace_handling
PNG_IMPEXP int() png_set_interlace_handling(png_structrp png_ptr)
Definition: pngtrans.c:99
png_bytep
png_byte * png_bytep
Definition: pngconf.h:600
NULL
#define NULL
Definition: forms.H:34
fl_fopen
FILE * fl_fopen(const char *f, const char *mode)
Definition: fl_utf8.cxx:498
png_destroy_read_struct
PNG_IMPEXP void() png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)
Definition: pngread.c:985
Fl_Image::ld
int ld() const
Definition: Fl_Image.H:126
png_read_info
PNG_IMPEXP void() png_read_info(png_structrp png_ptr, png_inforp info_ptr)
Definition: pngread.c:92
png_get_image_height
PNG_IMPEXP png_uint_32() png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngget.c:61
buffer
static char * buffer
Definition: file.cxx:215
png_set_tRNS_to_alpha
PNG_IMPEXP void() png_set_tRNS_to_alpha(png_structrp png_ptr)
Definition: pngrtran.c:909
png_get_color_type
PNG_IMPEXP png_byte() png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngget.c:79
Fl_RGB_Image::alloc_array
int alloc_array
Definition: Fl_Image.H:215
fl_utf8.h
header for Unicode and UTF-8 character handling
last
static idle_cb * last
Definition: Fl_add_idle.cxx:34
png_get_io_ptr
png_voidp png_get_io_ptr(png_const_structrp png_ptr)
Definition: png.c:641
filename
static const char * filename
Definition: fluid.cxx:119
png_info_def
Definition: pnginfo.h:56
Fl_Image::ERR_FORMAT
static const int ERR_FORMAT
Definition: Fl_Image.H:60
png_get_image_width
PNG_IMPEXP png_uint_32() png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngget.c:52
Fl_Shared_Image::add
void add()
Definition: Fl_Shared_Image.cxx:167
png_create_info_struct
png_infop png_create_info_struct(png_const_structrp png_ptr)
Definition: png.c:327
Fl_Image::h
int h() const
Definition: Fl_Image.H:115
Fl_RGB_Image::array
const uchar * array
Definition: Fl_Image.H:212
Fl_Shared_Image.H
png_struct_def
Definition: pngstruct.h:144
png_read_end
PNG_IMPEXP void() png_read_end(png_structrp png_ptr, png_inforp info_ptr)
Definition: pngread.c:757
PNG_LIBPNG_VER_STRING
#define PNG_LIBPNG_VER_STRING
Definition: png.h:426
png_set_expand
PNG_IMPEXP void() png_set_expand(png_structrp png_ptr)
Definition: pngrtran.c:855
png_size_t
size_t png_size_t
Definition: pngconf.h:543
Fl_RGB_Image::max_size
static size_t max_size()
Definition: Fl_Image.H:255
Fl_Image::w
int w() const
Definition: Fl_Image.H:111
PNG_COLOR_MASK_COLOR
#define PNG_COLOR_MASK_COLOR
Definition: png.h:805
Fl::warning
static void(* warning)(const char *,...)
Definition: Fl.H:498
png_jmpbuf
#define png_jmpbuf(png_ptr)
Definition: png.h:1090
png_create_read_struct
PNG_IMPEXP png_structp() png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn)
Definition: pngread.c:27
png_get_tRNS
PNG_IMPEXP png_uint_32() png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
Definition: pngget.c:1057
info
backing_store_ptr info
Definition: jmemsys.h:181
png_set_strip_16
PNG_IMPEXP void() png_set_strip_16(png_structrp png_ptr)
Definition: pngrtran.c:185
Fl_PNG_Image.H
length
png_uint_32 length
Definition: png.c:2173
Fl_Image::ERR_FILE_ACCESS
static const int ERR_FILE_ACCESS
Definition: Fl_Image.H:59
png.h
uchar
unsigned char uchar
Definition: fl_types.h:30
Fl_RGB_Image
Definition: Fl_Image.H:202
Fl_Shared_Image
Definition: Fl_Shared_Image.H:50
PNG_COLOR_MASK_ALPHA
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:806
png_init_io
void png_init_io(png_structrp png_ptr, png_FILE_p fp)
Definition: png.c:658
zlib.h
png_set_read_fn
PNG_IMPEXP void() png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)
Definition: pngrio.c:87
PNG_COLOR_TYPE_PALETTE
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:810
png_set_packing
PNG_IMPEXP void() png_set_packing(png_structrp png_ptr)
Definition: pngtrans.c:50
Fl_PNG_Image::Fl_PNG_Image
Fl_PNG_Image(const char *filename)
Definition: Fl_PNG_Image.cxx:86