*** /src/kernel/qpngio.cpp	Fri Feb  2 15:01:15 2007
--- /src/kernel/qpngio.cpp.new	Mon Sep 17 23:22:06 2012
***************
*** 1,37 ****
  /****************************************************************************
- ** $Id: qt/qpngio.cpp   3.3.8   edited Jan 11 14:38 $
  **
  ** Implementation of PNG QImage IOHandler
  **
  ** Created : 970521
  **
! ** Copyright (C) 1992-2007 Trolltech ASA.  All rights reserved.
  **
  ** This file is part of the kernel module of the Qt GUI Toolkit.
  **
! ** This file may be distributed under the terms of the Q Public License
! ** as defined by Trolltech ASA of Norway and appearing in the file
! ** LICENSE.QPL included in the packaging of this file.
  **
! ** This file may be distributed and/or modified under the terms of the
! ** GNU General Public License version 2 as published by the Free Software
! ** Foundation and appearing in the file LICENSE.GPL included in the
! ** packaging of this file.
  **
! ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
! ** licenses may use this file in accordance with the Qt Commercial License
! ** Agreement provided with the Software.
  **
! ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
! ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
! **
! ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
! **   information about Qt Commercial License Agreements.
! ** See http://www.trolltech.com/qpl/ for QPL licensing information.
! ** See http://www.trolltech.com/gpl/ for GPL licensing information.
! **
! ** Contact info@trolltech.com if any conditions of this licensing are
! ** not clear to you.
  **
  **********************************************************************/
  
--- 1,40 ----
  /****************************************************************************
  **
  ** Implementation of PNG QImage IOHandler
  **
  ** Created : 970521
  **
! ** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved.
  **
  ** This file is part of the kernel module of the Qt GUI Toolkit.
  **
! ** This file may be used under the terms of the GNU General
! ** Public License versions 2.0 or 3.0 as published by the Free
! ** Software Foundation and appearing in the files LICENSE.GPL2
! ** and LICENSE.GPL3 included in the packaging of this file.
! ** Alternatively you may (at your option) use any later version
! ** of the GNU General Public License if such license has been
! ** publicly approved by Trolltech ASA (or its successors, if any)
! ** and the KDE Free Qt Foundation.
  **
! ** Please review the following information to ensure GNU General
! ** Public Licensing requirements will be met:
! ** http://trolltech.com/products/qt/licenses/licensing/opensource/.
! ** If you are unsure which license is appropriate for your use, please
! ** review the following information:
! ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
! ** or contact the sales department at sales@trolltech.com.
  **
! ** This file may be used under the terms of the Q Public License as
! ** defined by Trolltech ASA and appearing in the file LICENSE.QPL
! ** included in the packaging of this file.  Licensees holding valid Qt
! ** Commercial licenses may use this file in accordance with the Qt
! ** Commercial License Agreement provided with the Software.
  **
! ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
! ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
! ** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
! ** herein.
  **
  **********************************************************************/
  
***************
*** 43,49 ****
  #include "qiodevice.h"
  
  #include <png.h>
! 
  
  #ifdef Q_OS_TEMP
  #define CALLBACK_CALL_TYPE	__cdecl
--- 46,52 ----
  #include "qiodevice.h"
  
  #include <png.h>
! #include <zlib.h>
  
  #ifdef Q_OS_TEMP
  #define CALLBACK_CALL_TYPE	__cdecl
***************
*** 125,131 ****
  
      if ( color_type == PNG_COLOR_TYPE_GRAY ) {
  	// Black & White or 8-bit grayscale
! 	if ( bit_depth == 1 && info_ptr->channels == 1 ) {
  	    png_set_invert_mono( png_ptr );
  	    png_read_update_info( png_ptr, info_ptr );
  	    if (!image.create( width, height, 1, 2, QImage::BigEndian ))
--- 128,134 ----
  
      if ( color_type == PNG_COLOR_TYPE_GRAY ) {
  	// Black & White or 8-bit grayscale
!       if ( bit_depth == 1 && png_get_channels (png_ptr, info_ptr)  == 1 ) {
  	    png_set_invert_mono( png_ptr );
  	    png_read_update_info( png_ptr, info_ptr );
  	    if (!image.create( width, height, 1, 2, QImage::BigEndian ))
***************
*** 159,220 ****
  		image.setColor( i, qRgba(c,c,c,0xff) );
  	    }
  	    if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
! 		const int g = info_ptr->trans_values.gray;
! 		if (g < ncols) {
  		    image.setAlphaBuffer(TRUE);
  		    image.setColor(g, image.color(g) & RGB_MASK);
  		}
  	    }
  	}
      } else if ( color_type == PNG_COLOR_TYPE_PALETTE
!      && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)
!      && info_ptr->num_palette <= 256 )
      {
! 	// 1-bit and 8-bit color
! 	if ( bit_depth != 1 )
  	    png_set_packing( png_ptr );
! 	png_read_update_info( png_ptr, info_ptr );
! 	png_get_IHDR(png_ptr, info_ptr,
! 	    &width, &height, &bit_depth, &color_type, 0, 0, 0);
! 	if (!image.create(width, height, bit_depth, info_ptr->num_palette,
! 	    QImage::BigEndian))
  	    return;
! 	int i = 0;
! 	if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
  	    image.setAlphaBuffer( TRUE );
! 	    while ( i < info_ptr->num_trans ) {
! 		image.setColor(i, qRgba(
! 		    info_ptr->palette[i].red,
! 		    info_ptr->palette[i].green,
! 		    info_ptr->palette[i].blue,
  		    info_ptr->trans[i]
  		    )
  		);
! 		i++;
  	    }
! 	}
! 	while ( i < info_ptr->num_palette ) {
  	    image.setColor(i, qRgba(
! 		info_ptr->palette[i].red,
! 		info_ptr->palette[i].green,
! 		info_ptr->palette[i].blue,
! 		0xff
! 		)
! 	    );
  	    i++;
! 	}
      } else {
! 	// 32-bit
! 	if ( bit_depth == 16 )
! 	    png_set_strip_16(png_ptr);
! 
! 	png_set_expand(png_ptr);
! 
! 	if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
! 	    png_set_gray_to_rgb(png_ptr);
! 
! 	if (!image.create(width, height, 32))
! 	    return;
  
  	// Only add filler if no alpha, or we can get 5 channel data.
  	if (!(color_type & PNG_COLOR_MASK_ALPHA)
--- 162,249 ----
  		image.setColor( i, qRgba(c,c,c,0xff) );
  	    }
  	    if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
! 	        png_bytep trans_alpha;
! 		int num_trans;
! 		png_color_16p trans_color;
! 
! 		if ( png_get_tRNS (png_ptr, info_ptr, &trans_alpha,
! 				   &num_trans, &trans_color) ) {
! 		  
! 		  const int g = trans_color->gray;
! 		  if (g < ncols) {
  		    image.setAlphaBuffer(TRUE);
  		    image.setColor(g, image.color(g) & RGB_MASK);
+ 		  }
  		}
  	    }
  	}
      } else if ( color_type == PNG_COLOR_TYPE_PALETTE
! 		&& png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))
      {
!         png_colorp palette;
! 	int num_palette;
! 
! 	png_get_PLTE (png_ptr, info_ptr, &palette, &num_palette);
! 
! 	if (num_palette <= 256)
! 	{
! 	  // 1-bit and 8-bit color
! 	  if ( bit_depth != 1 )
  	    png_set_packing( png_ptr );
! 	  png_read_update_info( png_ptr, info_ptr );
! 	  png_get_IHDR(png_ptr, info_ptr,
! 		       &width, &height, &bit_depth, &color_type, 0, 0, 0);
! 	  if (!image.create(width, height, bit_depth, num_palette,
! 			    QImage::BigEndian))
  	    return;
! 	  int i = 0;
! 	  if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
! 	    png_bytep trans_alpha;
! 	    int num_trans;
! 	    png_color_16p trans_color;
! 
! 	    png_get_tRNS (png_ptr, info_ptr, &trans_alpha,
! 			  &num_trans, &trans_color);
! 	    
  	    image.setAlphaBuffer( TRUE );
! 	    while ( i < num_trans ) {
! 	      image.setColor(i, qRgba(
! 		    palette[i].red,
! 		    palette[i].green,
! 		    palette[i].blue,
! #if PNG_LIBPNG_VER_MAJOR>1 || ( PNG_LIBPNG_VER_MAJOR==1 && PNG_LIBPNG_VER_MINOR>=4 )
! 		    trans_alpha[i]
! #else
  		    info_ptr->trans[i]
+ #endif
  		    )
  		);
! 	      i++;
  	    }
! 	  }
! 	  while ( i < num_palette ) {
  	    image.setColor(i, qRgba(
! 				    palette[i].red,
! 				    palette[i].green,
! 				    palette[i].blue,
! 				    0xff
! 				    )
! 			   );
  	    i++;
! 	  }
! 	} 
      } else {
!       // 32-bit
!       if ( bit_depth == 16 )
! 	png_set_strip_16(png_ptr);
!       
!       png_set_expand(png_ptr);
!       
!       if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
! 	png_set_gray_to_rgb(png_ptr);
!       
!       if (!image.create(width, height, 32))
! 	return;
  
  	// Only add filler if no alpha, or we can get 5 channel data.
  	if (!(color_type & PNG_COLOR_MASK_ALPHA)
***************
*** 284,290 ****
  	return;
      }
  
!     if (setjmp(png_ptr->jmpbuf)) {
  	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  	iio->setStatus(-4);
  	return;
--- 313,319 ----
  	return;
      }
  
!     if (setjmp(png_jmpbuf(png_ptr))) {
  	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  	iio->setStatus(-4);
  	return;
***************
*** 321,329 ****
--- 350,364 ----
  png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)
      if (image.depth()==32 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
  	QRgb trans = 0xFF000000 | qRgb(
+ #if PNG_LIBPNG_VER_MAJOR>1 || ( PNG_LIBPNG_VER_MAJOR==1 && PNG_LIBPNG_VER_MINOR>=4 )
+ 	      (info_ptr->trans_color.red << 8 >> bit_depth)&0xff,
+ 	      (info_ptr->trans_color.green << 8 >> bit_depth)&0xff,
+ 	      (info_ptr->trans_color.blue << 8 >> bit_depth)&0xff);
+ #else
  	      (info_ptr->trans_values.red << 8 >> bit_depth)&0xff,
  	      (info_ptr->trans_values.green << 8 >> bit_depth)&0xff,
  	      (info_ptr->trans_values.blue << 8 >> bit_depth)&0xff);
+ #endif
  	for (uint y=0; y<height; y++) {
  	    for (uint x=0; x<info_ptr->width; x++) {
  		if (((uint**)jt)[y][x] == trans) {
***************
*** 455,460 ****
--- 490,496 ----
      png_structp png_ptr;
      png_infop info_ptr;
      png_bytep* row_pointers;
+     png_color_8p sig_bit;
  
      png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
      if (!png_ptr) {
***************
*** 469,475 ****
  	return FALSE;
      }
  
!     if (setjmp(png_ptr->jmpbuf)) {
  	png_destroy_write_struct(&png_ptr, &info_ptr);
  	return FALSE;
      }
--- 505,511 ----
  	return FALSE;
      }
  
!     if (setjmp(png_jmpbuf(png_ptr))) {
  	png_destroy_write_struct(&png_ptr, &info_ptr);
  	return FALSE;
      }
***************
*** 491,500 ****
  
      png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);
  
!     info_ptr->channels =
  	(image.depth() == 32)
  	    ? (image.hasAlphaBuffer() ? 4 : 3)
  	    : 1;
  
      png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
  	image.depth() == 1 ? 1 : 8 /* per channel */,
--- 527,538 ----
  
      png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);
  
!       /*
!       png_get_channels(png_ptr, info_ptr) =
  	(image.depth() == 32)
  	    ? (image.hasAlphaBuffer() ? 4 : 3)
  	    : 1;
+       */
  
      png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
  	image.depth() == 1 ? 1 : 8 /* per channel */,
***************
*** 504,514 ****
  		: PNG_COLOR_TYPE_RGB
  	    : PNG_COLOR_TYPE_PALETTE, 0, 0, 0);
  
! 
!     //png_set_sBIT(png_ptr, info_ptr, 8);
!     info_ptr->sig_bit.red = 8;
!     info_ptr->sig_bit.green = 8;
!     info_ptr->sig_bit.blue = 8;
  
      if (image.depth() == 1 && image.bitOrder() == QImage::LittleEndian)
         png_set_packswap(png_ptr);
--- 542,555 ----
  		: PNG_COLOR_TYPE_RGB
  	    : PNG_COLOR_TYPE_PALETTE, 0, 0, 0);
  
!     sig_bit = new png_color_8;
!     sig_bit->red = 8;
!     sig_bit->green = 8;
!     sig_bit->blue = 8;
!     if ( image.hasAlphaBuffer() ) {
! 	sig_bit->alpha = 8;
!     }
!     png_set_sBIT(png_ptr, info_ptr, sig_bit);
  
      if (image.depth() == 1 && image.bitOrder() == QImage::LittleEndian)
         png_set_packswap(png_ptr);
***************
*** 524,532 ****
  	int num_trans = 0;
  	for (int i=0; i<num_palette; i++) {
  	    QRgb rgb=image.color(i);
! 	    info_ptr->palette[i].red = qRed(rgb);
! 	    info_ptr->palette[i].green = qGreen(rgb);
! 	    info_ptr->palette[i].blue = qBlue(rgb);
  	    if (image.hasAlphaBuffer()) {
  		trans[i] = rgb >> 24;
  		if (trans[i] < 255) {
--- 565,573 ----
  	int num_trans = 0;
  	for (int i=0; i<num_palette; i++) {
  	    QRgb rgb=image.color(i);
! 	    palette[i].red = qRed(rgb);
! 	    palette[i].green = qGreen(rgb);
! 	    palette[i].blue = qBlue(rgb);
  	    if (image.hasAlphaBuffer()) {
  		trans[i] = rgb >> 24;
  		if (trans[i] < 255) {
***************
*** 543,552 ****
  	delete [] trans;
      }
  
-     if ( image.hasAlphaBuffer() ) {
- 	info_ptr->sig_bit.alpha = 8;
-     }
- 
      // Swap ARGB to RGBA (normal PNG format) before saving on
      // BigEndian machines
      if ( QImage::systemByteOrder() == QImage::BigEndian ) {
--- 584,589 ----
***************
*** 630,635 ****
--- 667,674 ----
  	delete [] palette;
      if ( copy_trans )
  	delete [] copy_trans;
+     if ( sig_bit )
+ 	delete sig_bit;
  
      png_destroy_write_struct(&png_ptr, &info_ptr);
  
***************
*** 1030,1036 ****
  	    return -1;
  	}
  
! 	if (setjmp((png_ptr)->jmpbuf)) {
  	    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
  	    image = 0;
  	    return -1;
--- 1069,1075 ----
  	    return -1;
  	}
  
! 	if (setjmp(png_jmpbuf(png_ptr))) {
  	    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
  	    image = 0;
  	    return -1;
***************
*** 1057,1063 ****
  
      if ( !png_ptr ) return 0;
  
!     if (setjmp(png_ptr->jmpbuf)) {
  	png_destroy_read_struct(&png_ptr, &info_ptr, 0);
  	image = 0;
  	state = MovieStart;
--- 1096,1102 ----
  
      if ( !png_ptr ) return 0;
  
!     if (setjmp(png_jmpbuf(png_ptr))) {
  	png_destroy_read_struct(&png_ptr, &info_ptr, 0);
  	image = 0;
  	state = MovieStart;
***************
*** 1117,1123 ****
      consumer->frameDone(QPoint(offx,offy),r);
      consumer->end();
      state = FrameStart;
!     unused_data = (int)png->buffer_size; // Since libpng doesn't tell us
  }
  
  #ifdef PNG_USER_CHUNKS_SUPPORTED
--- 1156,1162 ----
      consumer->frameDone(QPoint(offx,offy),r);
      consumer->end();
      state = FrameStart;
!     //unused_data = (int)png->buffer_size; // Since libpng doesn't tell us
  }
  
  #ifdef PNG_USER_CHUNKS_SUPPORTED