16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_highgui.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef HAVE_PNG
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    This part of the file implements PNG codec on base of libpng library,
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    in particular, this code is based on example.c from libpng
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (see otherlibs/_graphics/readme.txt for copyright notice)
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    and png2bmp sample from libpng distribution (Copyright (C) 1999-2001 MIYASAKA Masaru)
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 || defined HAVE_PNG_H
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <png.h>
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <libpng/png.h>
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "grfmt_png.h"
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// PNG Filter Factory
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPng::GrFmtPng()
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_sign_len = 8;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_signature = "\x89\x50\x4e\x47\xd\xa\x1a\xa";
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_description = "Portable Network Graphics files (*.png)";
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPng::~GrFmtPng()
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtReader* GrFmtPng::NewReader( const char* filename )
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return new GrFmtPngReader( filename );
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtWriter* GrFmtPng::NewWriter( const char* filename )
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return new GrFmtPngWriter( filename );
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  GrFmtPng::CheckSignature( const char* signature )
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return png_check_sig( (uchar*)signature, m_sign_len ) != 0;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////// GrFmtPngReader ///////////////////
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPngReader::GrFmtPngReader( const char* filename ) : GrFmtReader( filename )
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_color_type = m_bit_depth = 0;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_png_ptr = 0;
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_info_ptr = m_end_info = 0;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_f = 0;
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPngReader::~GrFmtPngReader()
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid  GrFmtPngReader::Close()
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_f )
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        fclose( m_f );
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_f = 0;
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_png_ptr )
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_structp png_ptr = (png_structp)m_png_ptr;
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop info_ptr = (png_infop)m_info_ptr;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop end_info = (png_infop)m_end_info;
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_png_ptr = m_info_ptr = m_end_info = 0;
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    GrFmtReader::Close();
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  GrFmtPngReader::ReadHeader()
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool result = false;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Close();
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( png_ptr )
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop info_ptr = png_create_info_struct( png_ptr );
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop end_info = png_create_info_struct( png_ptr );
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_png_ptr = png_ptr;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_info_ptr = info_ptr;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_end_info = end_info;
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( info_ptr && end_info )
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( setjmp( png_ptr->jmpbuf ) == 0 )
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                m_f = fopen( m_filename, "rb" );
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( m_f )
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_uint_32 width, height;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int bit_depth, color_type;
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_init_io( png_ptr, m_f );
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_read_info( png_ptr, info_ptr );
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_get_IHDR( png_ptr, info_ptr, &width, &height,
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  &bit_depth, &color_type, 0, 0, 0 );
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m_iscolor = color_type == PNG_COLOR_TYPE_RGB ||
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                color_type == PNG_COLOR_TYPE_PALETTE;
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m_width = (int)width;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m_height = (int)height;
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m_color_type = color_type;
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m_bit_depth = bit_depth;
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    result = true;
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !result )
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Close();
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return result;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  GrFmtPngReader::ReadData( uchar* data, int step, int color )
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool result = false;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar** buffer = 0;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    color = color > 0 || ( m_iscolor && color < 0 );
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height )
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_structp png_ptr = (png_structp)m_png_ptr;
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop info_ptr = (png_infop)m_info_ptr;
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        png_infop end_info = (png_infop)m_end_info;
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( setjmp(png_ptr->jmpbuf) == 0 )
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int y;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m_bit_depth > 8 && !m_native_depth )
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_strip_16( png_ptr );
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( !isBigEndian() )
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_swap( png_ptr );
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* observation: png_read_image() writes 400 bytes beyond
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * end of data when reading a 400x118 color png
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * "mpplus_sand.png".  OpenCV crashes even with demo
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * programs.  Looking at the loaded image I'd say we get 4
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * bytes per pixel instead of 3 bytes per pixel.  Test
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * indicate that it is a good idea to always ask for
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             * stripping alpha..  18.11.2004 Axel Walthelm
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             */
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            png_set_strip_alpha( png_ptr );
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m_color_type == PNG_COLOR_TYPE_PALETTE )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_palette_to_rgb( png_ptr );
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m_color_type == PNG_COLOR_TYPE_GRAY && m_bit_depth < 8 )
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_gray_1_2_4_to_8( png_ptr );
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m_iscolor && color )
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_bgr( png_ptr ); // convert RGB to BGR
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( color )
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_gray_to_rgb( png_ptr ); // Gray->RGB
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                png_set_rgb_to_gray( png_ptr, 1, -1, -1 ); // RGB->Gray
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            png_read_update_info( png_ptr, info_ptr );
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer = new uchar*[m_height];
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( y = 0; y < m_height; y++ )
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buffer[y] = data + y*step;
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            png_read_image( png_ptr, buffer );
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            png_read_end( png_ptr, end_info );
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            result = true;
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Close();
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delete[] buffer;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return result;
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////// GrFmtPngWriter ///////////////////
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPngWriter::GrFmtPngWriter( const char* filename ) : GrFmtWriter( filename )
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtPngWriter::~GrFmtPngWriter()
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  GrFmtPngWriter::IsFormatSupported( int depth )
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return depth == IPL_DEPTH_8U || depth == IPL_DEPTH_16U;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  GrFmtPngWriter::WriteImage( const uchar* data, int step,
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int width, int height, int depth, int channels )
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    png_infop info_ptr = 0;
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    FILE* f = 0;
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar** buffer = 0;
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool result = false;
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( depth != IPL_DEPTH_8U && depth != IPL_DEPTH_16U )
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( png_ptr )
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        info_ptr = png_create_info_struct( png_ptr );
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( info_ptr )
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( setjmp( png_ptr->jmpbuf ) == 0 )
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                f = fopen( m_filename, "wb" );
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( f )
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_init_io( png_ptr, f );
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_set_compression_mem_level( png_ptr, MAX_MEM_LEVEL );
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_set_IHDR( png_ptr, info_ptr, width, height, depth,
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        channels == 1 ? PNG_COLOR_TYPE_GRAY :
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        channels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA,
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        PNG_FILTER_TYPE_DEFAULT );
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_write_info( png_ptr, info_ptr );
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_set_bgr( png_ptr );
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !isBigEndian() )
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        png_set_swap( png_ptr );
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buffer = new uchar*[height];
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( y = 0; y < height; y++ )
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        buffer[y] = (uchar*)(data + y*step);
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_write_image( png_ptr, buffer );
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    png_write_end( png_ptr, info_ptr );
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    delete[] buffer;
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    result = true;
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    png_destroy_write_struct( &png_ptr, &info_ptr );
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if(f) fclose( f );
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return result;
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
334