00001 /* 00002 CLAW - a C++ Library Absolutely Wonderful 00003 00004 CLAW is a free library without any particular aim but being useful to 00005 anyone. 00006 00007 Copyright (C) 2005-2008 Julien Jorge 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 contact: julien_jorge@yahoo.fr 00024 */ 00030 #include <claw/bitmap.hpp> 00031 #include <algorithm> 00032 00033 /*----------------------------------------------------------------------------*/ 00038 claw::graphic::bitmap::writer::writer( const image& img ) 00039 : m_image(img) 00040 { 00041 00042 } // bitmap::writer::writer() 00043 00044 /*----------------------------------------------------------------------------*/ 00050 claw::graphic::bitmap::writer::writer( const image& img, std::ostream& f ) 00051 : m_image(img) 00052 { 00053 save(f); 00054 } // bitmap::writer::writer() 00055 00056 /*----------------------------------------------------------------------------*/ 00061 void claw::graphic::bitmap::writer::save( std::ostream& f ) const 00062 { 00063 header h; 00064 00065 init_header(h); 00066 00067 f.write( reinterpret_cast<char*>(&h), sizeof(header) ); 00068 00069 save_data( f ); 00070 } // bitmap::writer::save() 00071 00072 /*----------------------------------------------------------------------------*/ 00077 void claw::graphic::bitmap::writer::save_data( std::ostream& f ) const 00078 { 00079 unsigned int line; 00080 unsigned int buffer_size = m_image.width() * 3; 00081 00082 // lines are 4-bytes aligned, so adjust buffer's size. 00083 if (buffer_size % 4 != 0) 00084 buffer_size += 4 - buffer_size % 4; 00085 00086 char* buffer = new char[buffer_size]; 00087 00088 for (line = m_image.height(); line>0; ) 00089 { 00090 --line; 00091 pixel32_to_pixel24( buffer, m_image[line] ); 00092 f.write(buffer, buffer_size); 00093 } 00094 00095 delete[] buffer; 00096 } // bitmap::writer::save_data() 00097 00098 /*----------------------------------------------------------------------------*/ 00104 void claw::graphic::bitmap::writer::pixel32_to_pixel24 00105 ( char* dest, const scanline& src ) const 00106 { 00107 unsigned int i24 = 0; 00108 scanline::const_iterator first( src.begin() ); 00109 scanline::const_iterator last( src.end() ); 00110 00111 for ( ; first!=last; ++first ) 00112 { 00113 dest[i24++] = first->components.blue; 00114 dest[i24++] = first->components.green; 00115 dest[i24++] = first->components.red; 00116 } 00117 } // bitmap::writer::pixel32_to_pixel24() 00118 00119 /*----------------------------------------------------------------------------*/ 00124 void claw::graphic::bitmap::writer::init_header( header& h ) const 00125 { 00126 unsigned int adjusted_line = m_image.width() * 3; 00127 00128 if (m_image.width() % 4 != 0) 00129 adjusted_line += 4 - m_image.width() % 4; 00130 00131 // for a 24 bpp bitmap. 00132 h.id[0] = 'B'; 00133 h.id[1] = 'M'; 00134 h.file_size = adjusted_line * m_image.height() + sizeof(h); 00135 h.nop = 0; 00136 00137 // there is no color pallet, so data is just after the h 00138 h.data_offset = sizeof(h); 00139 // default value for Windows' bitmaps. 00140 h.header_size = 0x28; 00141 00142 h.width = m_image.width(); 00143 h.height = m_image.height(); 00144 h.layers = 1; 00145 h.bpp = 24; 00146 h.compression = BMP_COMPRESSION_RGB; 00147 h.image_size = adjusted_line * m_image.height(); 00148 h.ppm_x = 0x2E23; // 11811 00149 h.ppm_y = 0x2E23; 00150 h.colors_count = 0; 00151 h.importants_colors = 0; 00152 } // bitmap::writer::init_header() 00153