*** /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 ! #ifdef Q_OS_TEMP #define CALLBACK_CALL_TYPE __cdecl --- 46,52 ---- #include "qiodevice.h" #include ! #include #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; ywidth; 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; ipalette[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> 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