]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/png_bitmap.cpp
* skins2/src/skin_main.cpp: New demux2 module to load automatically a skin.
[vlc] / modules / gui / skins2 / src / png_bitmap.cpp
1 /*****************************************************************************
2  * png_bitmap.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *
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.
14  *
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.
19  *
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  *****************************************************************************/
24
25 #include <png.h>
26 #include "png_bitmap.hpp"
27
28
29 PngBitmap::PngBitmap( intf_thread_t *pIntf, string fileName,
30                       uint32_t aColor ):
31     GenericBitmap( pIntf ), m_width( 0 ), m_height( 0 ), m_pData( NULL )
32 {
33     // Open the PNG file
34     FILE *pFile = fopen( fileName.c_str(), "rb" );
35     if( pFile == NULL )
36     {
37         msg_Err( getIntf(), "Cannot open bitmap %s", fileName.c_str() );
38         return;
39     }
40
41     // Create the PNG structures
42     png_structp pReadStruct = png_create_read_struct( PNG_LIBPNG_VER_STRING,
43         NULL, NULL, NULL );
44     if ( pReadStruct == NULL )
45     {
46         msg_Err( getIntf(), "Failed to create PNG read struct" );
47         return;
48     }
49     png_infop pInfo = png_create_info_struct( pReadStruct );
50     if( pInfo == NULL )
51     {
52         png_destroy_read_struct( &pReadStruct, NULL, NULL );
53         msg_Err( getIntf(), "Failed to create PNG info struct" );
54         return;
55     }
56     png_infop pEndInfo = png_create_info_struct( pReadStruct );
57     if( pEndInfo == NULL )
58     {
59         png_destroy_read_struct( &pReadStruct, NULL, NULL );
60         msg_Err( getIntf(), "Failed to create PNG end info struct" );
61         return;
62     }
63
64     // Initialize the PNG reader
65     png_init_io( pReadStruct, pFile );
66
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 );
73
74     // Convert paletted images to RGB
75     if( colorType == PNG_COLOR_TYPE_PALETTE )
76     {
77         png_set_palette_to_rgb( pReadStruct );
78     }
79     // Strip to 8 bits per channel
80     if( depth == 16 )
81     {
82         png_set_strip_16( pReadStruct );
83     }
84     // 4 bytes per pixel
85     if( !(colorType & PNG_COLOR_MASK_ALPHA ) )
86     {
87         png_set_filler( pReadStruct, 0xff, PNG_FILLER_AFTER );
88     }
89     // Invert colors
90     if( colorType & PNG_COLOR_MASK_COLOR )
91     {
92         png_set_bgr( pReadStruct );
93     }
94     png_read_update_info( pReadStruct, pInfo );
95
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++ )
100     {
101         pRows[i] = m_pData + (i * m_width * 4);
102     }
103
104     // Read the image
105     png_read_image( pReadStruct, pRows );
106     png_read_end( pReadStruct, pEndInfo );
107
108     // Compute the alpha layer
109     uint8_t *pData = m_pData;
110     for( int y = 0; y < m_height; y++ )
111     {
112         for( int x = 0; x < m_width; x++ )
113         {
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) )
119             {
120                 *pData = 0;
121             }
122             pData++;
123         }
124     }
125
126     // Free the structures
127     png_destroy_read_struct( &pReadStruct, &pInfo, &pEndInfo );
128     delete[] pRows;
129
130     // Close the file
131     fclose( pFile );
132 }
133
134
135 PngBitmap::~PngBitmap()
136 {
137     if( m_pData )
138     {
139         delete[] m_pData;
140     }
141 }
142
143
144 uint8_t *PngBitmap::getData() const
145 {
146     if( m_pData == NULL )
147     {
148         msg_Warn( getIntf(), "PngBitmap::getData() returns NULL" );
149     }
150     return m_pData;
151 }