1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 #include "grfmt_bmp.h"
46 /************************ BMP reader *****************************/
48 GrFmtBmpReader::GrFmtBmpReader()
52 m_description = "Windows bitmap (*.bmp;*.dib)";
57 int GrFmtBmpReader::GetColor()
59 return m_bpp > 8 ? 1 : -1;
63 void GrFmtBmpReader::Close()
69 bool GrFmtBmpReader::ReadHeader()
73 assert( strlen(m_filename) != 0 );
74 if( !m_strm.Open( m_filename )) return false;
79 m_offset = m_strm.GetDWord();
81 int size = m_strm.GetDWord();
85 m_width = m_strm.GetDWord();
86 m_height = m_strm.GetDWord();
87 m_bpp = m_strm.GetDWord() >> 16;
88 m_rle_code = m_strm.GetDWord();
90 int clrused = m_strm.GetDWord();
91 m_strm.Skip( size - 36 );
93 if( m_width > 0 && m_height > 0 &&
94 (((m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
95 m_bpp == 24 || m_bpp == 32 ) && m_rle_code == 0) ||
96 (m_bpp == 4 && m_rle_code == 2) || (m_bpp == 8 && m_rle_code == 1)))
100 memset( m_palette, 0, sizeof(m_palette));
101 m_strm.GetBytes( m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
106 else if( size == 12 )
108 m_width = m_strm.GetWord();
109 m_height = m_strm.GetWord();
110 m_bpp = m_strm.GetDWord() >> 16;
113 if( m_width > 0 && m_height > 0 &&
114 (m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
115 m_bpp == 24 || m_bpp == 32 ))
120 int j, clrused = 1 << m_bpp;
121 m_strm.GetBytes( buffer, clrused*3 );
122 for( j = 0; j < clrused; j++ )
124 m_palette[j].b = buffer[3*j+0];
125 m_palette[j].g = buffer[3*j+1];
126 m_palette[j].r = buffer[3*j+2];
140 m_width = m_height = -1;
146 bool GrFmtBmpReader::ReadData( uchar* data, int step, int color )
148 const int buffer_size = 1 << 12;
149 uchar buffer[buffer_size];
150 uchar bgr_buffer[buffer_size];
151 uchar gray_palette[256];
154 uchar* bgr = bgr_buffer;
155 int src_pitch = ((m_width*m_bpp + 7)/8 + 3) & -4;
156 int nch = color ? 3 : 1;
157 int width3 = m_width*nch;
158 int delta = -(width3 + step);
161 if( m_offset < 0 || !m_strm.IsOpened())
164 data += (m_height - 1)*step;
168 if( src_pitch+32 > buffer_size ) src = new uchar[src_pitch+32];
175 CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
177 if( m_width*3 + 32 > buffer_size ) bgr = new uchar[m_width*3 + 32];
182 m_strm.SetPos( m_offset );
186 /************************* 1 BPP ************************/
188 for( y = 0; y < m_height; y++, data -= step )
190 m_strm.GetBytes( src, src_pitch );
191 FillColorRow1( color ? data : bgr, src, m_width, m_palette );
192 if( !color ) CvtBGRToGray( bgr, data, m_width );
197 /************************* 4 BPP ************************/
199 if( m_rle_code == 0 )
201 for( y = 0; y < m_height; y++, data -= step )
203 m_strm.GetBytes( src, src_pitch );
205 FillColorRow4( data, src, m_width, m_palette );
207 FillGrayRow4( data, src, m_width, gray_palette );
211 else if( m_rle_code == 2 ) // rle4 compression
213 uchar* line_end = data + width3;
218 int code = m_strm.GetWord();
219 int len = code & 255;
221 if( len != 0 ) // encoded mode
225 clr[0] = m_palette[code >> 4];
226 clr[1] = m_palette[code & 15];
227 uchar* end = data + len*nch;
228 if( end > line_end ) goto decode_rle4_bad;
233 WRITE_PIX( data, clr[t] );
237 WRITE_PIX( bgr, clr[t] );
238 CvtBGRToGray( bgr, data, 1 );
242 while( (data += nch) < end );
244 else if( code > 2 ) // absolute mode
246 if( data + code*nch > line_end ) goto decode_rle4_bad;
247 m_strm.GetBytes( src, (((code + 1)>>1) + 1) & -2 );
249 data = FillColorRow4( data, src, code, m_palette );
251 data = FillGrayRow4( data, src, code, gray_palette );
255 if( code == 0 ) // line end
257 if( data < line_end )
259 FillUni( data, line_end, width3, delta,
260 line_end - data, 0, m_palette[0], color );
262 data = line_end + delta;
263 line_end = data + width3;
264 if( ++y == m_height ) goto decode_rle4_good;
266 else if( code == 1 ) // image end
267 goto decode_rle4_good;
270 int x_shift3 = m_strm.GetByte()*nch;
271 int y_shift = m_strm.GetByte();
273 if( (y += y_shift) >= m_height ||
274 data + x_shift3 > line_end ) goto decode_rle4_bad;
276 data = FillUni( data, line_end, width3, delta,
277 x_shift3, y_shift, m_palette[0], color );
278 line_end -= step*y_shift;
288 /************************* 8 BPP ************************/
290 if( m_rle_code == 0 )
292 for( y = 0; y < m_height; y++, data -= step )
294 m_strm.GetBytes( src, src_pitch );
296 FillColorRow8( data, src, m_width, m_palette );
298 FillGrayRow8( data, src, m_width, gray_palette );
302 else if( m_rle_code == 1 ) // rle8 compression
304 uchar* line_end = data + width3;
309 int code = m_strm.GetWord();
310 int len = code & 255;
312 if( len != 0 ) // encoded mode
315 if( data + len > line_end ) goto decode_rle8_bad;
316 data = FillUni( data, line_end, width3, delta,
317 len, 0, m_palette[code], color );
319 else if( code > 2 ) // absolute mode
321 int code3 = code*nch;
322 if( data + code3 > line_end ) goto decode_rle8_bad;
323 m_strm.GetBytes( src, (code + 1) & -2 );
325 data = FillColorRow8( data, src, code, m_palette );
327 data = FillGrayRow8( data, src, code, gray_palette );
331 if( code == 0 ) // line end
333 if( data < line_end )
335 FillUni( data, line_end, width3, delta,
336 line_end - data, 0, m_palette[0], color );
338 data = line_end + delta;
339 line_end = data + width3;
340 if( ++y == m_height ) goto decode_rle8_good;
342 else if( code == 1 ) // image end
343 goto decode_rle8_good;
346 int x_shift3 = m_strm.GetByte()*nch;
347 int y_shift = m_strm.GetByte();
349 if( (y += y_shift) >= m_height ||
350 data + x_shift3 > line_end ) goto decode_rle8_bad;
352 data = FillUni( data, line_end, width3, delta,
353 x_shift3, y_shift, m_palette[0], color );
354 line_end -= step*y_shift;
363 /************************* 24 BPP ************************/
365 for( y = 0; y < m_height; y++, data -= step )
367 m_strm.GetBytes( color ? data : bgr, src_pitch );
368 if( !color ) CvtBGRToGray( bgr, data, m_width );
372 /************************* 32 BPP ************************/
374 for( y = 0; y < m_height; y++, data -= step )
376 m_strm.GetBytes( src, src_pitch );
377 FillRow32( color ? data : bgr, src, m_width );
378 if( !color ) CvtBGRToGray( bgr, data, m_width );
390 if( src != buffer ) delete src;
391 if( bgr != bgr_buffer ) delete bgr;
396 /************************ Sun Raster reader *****************************/
398 GrFmtSunRasterReader::GrFmtSunRasterReader()
401 m_signature ="\x59\xA6\x6A\x95";
402 m_description = "Sun raster files (*.sr)";
407 void GrFmtSunRasterReader::Close()
413 bool GrFmtSunRasterReader::ReadHeader()
417 assert( strlen(m_filename) != 0 );
418 if( !m_strm.Open( m_filename )) return false;
423 m_width = m_strm.GetDWord();
424 m_height = m_strm.GetDWord();
425 m_bpp = m_strm.GetDWord();
426 int palSize = 3*(1 << m_bpp);
429 m_type = (SunRasType)m_strm.GetDWord();
430 m_maptype = (SunRasMapType)m_strm.GetDWord();
431 m_maplength = m_strm.GetDWord();
433 if( m_width > 0 && m_height > 0 &&
434 (m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) &&
435 (m_type == RT_OLD || m_type == RT_STANDARD ||
436 (m_type == RT_BYTE_ENCODED && m_bpp == 8) || m_type == RT_FORMAT_RGB) &&
437 (m_maptype == RMT_NONE && m_maplength == 0 ||
438 m_maptype == RMT_EQUAL_RGB && m_maplength == palSize && m_bpp <= 8))
440 if( m_maplength != 0 )
445 m_strm.GetBytes( buffer, palSize, &readed );
446 if( readed == palSize )
451 for( i = 0; i < palSize; i++ )
453 m_palette[i].b = buffer[i*3 + 2];
454 m_palette[i].g = buffer[i*3 + 1];
455 m_palette[i].r = buffer[i*3];
459 m_offset = m_strm.GetPos();
461 assert( m_offset == 32 + m_maplength );
468 FillGrayPalette( m_palette, m_bpp );
470 m_offset = m_strm.GetPos();
472 assert( m_offset == 32 + m_maplength );
484 m_width = m_height = -1;
491 int GrFmtSunRasterReader::GetColor()
493 return m_bpp > 8 || m_maptype == RMT_EQUAL_RGB ? 1 : 0;
497 bool GrFmtSunRasterReader::ReadData( uchar* data, int step, int color )
499 const int buffer_size = 1 << 12;
500 uchar buffer[buffer_size];
501 uchar bgr_buffer[buffer_size];
502 uchar gray_palette[256];
505 uchar* bgr = bgr_buffer;
506 int src_pitch = ((m_width*m_bpp + 7)/8 + 3) & -4;
507 int nch = color ? 3 : 1;
508 int width3 = m_width*nch;
509 int delta = step - width3;
512 if( m_offset < 0 || !m_strm.IsOpened())
515 if( src_pitch+32 > buffer_size )
516 src = new uchar[src_pitch+32];
518 if( m_width*3 + 32 > buffer_size )
519 bgr = new uchar[m_width*3 + 32];
521 if( !color && m_maptype == RMT_EQUAL_RGB )
522 CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
526 m_strm.SetPos( m_offset );
530 /************************* 1 BPP ************************/
532 for( y = 0; y < m_height; y++, data += step )
534 m_strm.GetBytes( src, src_pitch );
535 FillColorRow1( color ? data : bgr, src, m_width, m_palette );
536 if( !color ) CvtBGRToGray( bgr, data, m_width );
540 /************************* 8 BPP ************************/
542 if( m_type != RT_BYTE_ENCODED )
544 for( y = 0; y < m_height; y++, data += step )
546 m_strm.GetBytes( src, src_pitch );
548 FillColorRow8( data, src, m_width, m_palette );
550 FillGrayRow8( data, src, m_width, gray_palette );
556 uchar* line_end = data + width3;
561 int max_count = line_end - data;
562 int code = 0, len = 0, len1;
567 code = m_strm.GetByte();
570 len = m_strm.GetByte();
571 if( len != 0 ) break;
573 *tsrc++ = (uchar)code;
575 while( (max_count -= nch) > 0 );
582 FillColorRow8( data, src, len1, m_palette );
584 FillGrayRow8( data, src, len1, gray_palette );
588 if( len > 0 ) // encoded mode
592 code = m_strm.GetByte();
594 CalcShifts( data, line_end, width3, y, m_height, len, y_shift );
596 data = FillUni( data, line_end, width3, delta,
597 len, y_shift, m_palette[code], color );
599 line_end += y_shift*step;
602 if( data == line_end )
606 if( ++y >= m_height ) break;
613 /************************* 24 BPP ************************/
615 for( y = 0; y < m_height; y++, data += step )
617 m_strm.GetBytes( color ? data : bgr, src_pitch );
621 if( m_type == RT_FORMAT_RGB )
622 CvtRGBToBGR( data, data, m_width );
626 if( m_type == RT_FORMAT_RGB )
627 CvtRGBToGray( bgr, data, m_width );
629 CvtBGRToGray( bgr, data, m_width );
634 /************************* 32 BPP ************************/
636 for( y = 0; y < m_height; y++, data += step )
638 /* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3,
639 so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */
640 m_strm.GetBytes( src + 3, src_pitch );
641 FillRow32( color ? data : bgr, src + 4, m_width );
645 if( m_type == RT_FORMAT_RGB )
646 CvtRGBToBGR( data, data, m_width );
650 if( m_type == RT_FORMAT_RGB )
651 CvtRGBToGray( bgr, data, m_width );
653 CvtBGRToGray( bgr, data, m_width );
666 if( src != buffer ) delete src;
667 if( bgr != bgr_buffer ) delete bgr;