1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
26 #include "png_bitmap.hpp"
29 PngBitmap::PngBitmap( intf_thread_t *pIntf, string fileName,
31 GenericBitmap( pIntf ), m_width( 0 ), m_height( 0 ), m_pData( NULL )
34 FILE *pFile = fopen( fileName.c_str(), "rb" );
37 msg_Err( getIntf(), "Cannot open bitmap %s", fileName.c_str() );
41 // Create the PNG structures
42 png_structp pReadStruct = png_create_read_struct( PNG_LIBPNG_VER_STRING,
44 if ( pReadStruct == NULL )
46 msg_Err( getIntf(), "Failed to create PNG read struct" );
49 png_infop pInfo = png_create_info_struct( pReadStruct );
52 png_destroy_read_struct( &pReadStruct, NULL, NULL );
53 msg_Err( getIntf(), "Failed to create PNG info struct" );
56 png_infop pEndInfo = png_create_info_struct( pReadStruct );
57 if( pEndInfo == NULL )
59 png_destroy_read_struct( &pReadStruct, NULL, NULL );
60 msg_Err( getIntf(), "Failed to create PNG end info struct" );
64 // Initialize the PNG reader
65 png_init_io( pReadStruct, pFile );
67 // Read the image header
68 png_read_info( pReadStruct, pInfo );
69 m_width = png_get_image_width( pReadStruct, pInfo );
70 m_height = png_get_image_height( pReadStruct, pInfo );
71 int depth = png_get_bit_depth( pReadStruct, pInfo );
72 int colorType = png_get_color_type( pReadStruct, pInfo );
74 // Convert paletted images to RGB
75 if( colorType == PNG_COLOR_TYPE_PALETTE )
77 png_set_palette_to_rgb( pReadStruct );
79 // Strip to 8 bits per channel
82 png_set_strip_16( pReadStruct );
85 if( !(colorType & PNG_COLOR_MASK_ALPHA ) )
87 png_set_filler( pReadStruct, 0xff, PNG_FILLER_AFTER );
90 if( colorType & PNG_COLOR_MASK_COLOR )
92 png_set_bgr( pReadStruct );
94 png_read_update_info( pReadStruct, pInfo );
96 // Allocate memory for the buffers
97 m_pData = new uint8_t[m_height * m_width * 4];
98 uint8_t** pRows = new uint8_t*[m_height];
99 for( int i = 0; i < m_height; i++ )
101 pRows[i] = m_pData + (i * m_width * 4);
105 png_read_image( pReadStruct, pRows );
106 png_read_end( pReadStruct, pEndInfo );
108 // Compute the alpha layer
109 uint8_t *pData = m_pData;
110 for( int y = 0; y < m_height; y++ )
112 for( int x = 0; x < m_width; x++ )
114 uint32_t b = (uint32_t)*(pData++);
115 uint32_t g = (uint32_t)*(pData++);
116 uint32_t r = (uint32_t)*(pData++);
117 // Transparent pixel ?
118 if( aColor == (r<<16 | g<<8 | b) )
126 // Free the structures
127 png_destroy_read_struct( &pReadStruct, &pInfo, &pEndInfo );
135 PngBitmap::~PngBitmap()
144 uint8_t *PngBitmap::getData() const
146 if( m_pData == NULL )
148 msg_Warn( getIntf(), "PngBitmap::getData() returns NULL" );