1 /*M///////////////////////////////////////////////////////////////////////////////////////
\r
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
\r
5 // By downloading, copying, installing or using the software you agree to this license.
\r
6 // If you do not agree to this license, do not download, install,
\r
7 // copy or use the software.
\r
10 // License Agreement
\r
11 // For Open Source Computer Vision Library
\r
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
\r
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
\r
15 // Third party copyrights are property of their respective owners.
\r
17 // Redistribution and use in source and binary forms, with or without modification,
\r
18 // are permitted provided that the following conditions are met:
\r
20 // * Redistribution's of source code must retain the above copyright notice,
\r
21 // this list of conditions and the following disclaimer.
\r
23 // * Redistribution's in binary form must reproduce the above copyright notice,
\r
24 // this list of conditions and the following disclaimer in the documentation
\r
25 // and/or other materials provided with the distribution.
\r
27 // * The name of the copyright holders may not be used to endorse or promote products
\r
28 // derived from this software without specific prior written permission.
\r
30 // This software is provided by the copyright holders and contributors "as is" and
\r
31 // any express or implied warranties, including, but not limited to, the implied
\r
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
\r
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
\r
34 // indirect, incidental, special, exemplary, or consequential damages
\r
35 // (including, but not limited to, procurement of substitute goods or services;
\r
36 // loss of use, data, or profits; or business interruption) however caused
\r
37 // and on any theory of liability, whether in contract, strict liability,
\r
38 // or tort (including negligence or otherwise) arising in any way out of
\r
39 // the use of this software, even if advised of the possibility of such damage.
\r
43 #include "_highgui.h"
\r
44 #include "grfmt_sunras.h"
\r
49 static const char* fmtSignSunRas = "\x59\xA6\x6A\x95";
\r
51 /************************ Sun Raster reader *****************************/
\r
53 SunRasterDecoder::SunRasterDecoder()
\r
56 m_signature = fmtSignSunRas;
\r
60 SunRasterDecoder::~SunRasterDecoder()
\r
64 ImageDecoder SunRasterDecoder::newDecoder() const
\r
66 return new SunRasterDecoder;
\r
69 void SunRasterDecoder::close()
\r
75 bool SunRasterDecoder::readHeader()
\r
77 bool result = false;
\r
79 if( !m_strm.open( m_filename )) return false;
\r
84 m_width = m_strm.getDWord();
\r
85 m_height = m_strm.getDWord();
\r
86 m_bpp = m_strm.getDWord();
\r
87 int palSize = 3*(1 << m_bpp);
\r
90 m_encoding = (SunRasType)m_strm.getDWord();
\r
91 m_maptype = (SunRasMapType)m_strm.getDWord();
\r
92 m_maplength = m_strm.getDWord();
\r
94 if( m_width > 0 && m_height > 0 &&
\r
95 (m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) &&
\r
96 (m_type == RAS_OLD || m_type == RAS_STANDARD ||
\r
97 (m_type == RAS_BYTE_ENCODED && m_bpp == 8) || m_type == RAS_FORMAT_RGB) &&
\r
98 ((m_maptype == RMT_NONE && m_maplength == 0) ||
\r
99 (m_maptype == RMT_EQUAL_RGB && m_maplength <= palSize && m_bpp <= 8)))
\r
101 memset( m_palette, 0, sizeof(m_palette));
\r
103 if( m_maplength != 0 )
\r
105 uchar buffer[256*3];
\r
107 if( m_strm.getBytes( buffer, m_maplength ) == m_maplength )
\r
110 palSize = m_maplength/3;
\r
112 for( i = 0; i < palSize; i++ )
\r
114 m_palette[i].b = buffer[i + 2*palSize];
\r
115 m_palette[i].g = buffer[i + palSize];
\r
116 m_palette[i].r = buffer[i];
\r
117 m_palette[i].a = 0;
\r
120 m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1;
\r
121 m_offset = m_strm.getPos();
\r
123 assert( m_offset == 32 + m_maplength );
\r
129 m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
\r
131 if( CV_MAT_CN(m_type) == 1 )
\r
132 FillGrayPalette( m_palette, m_bpp );
\r
134 m_offset = m_strm.getPos();
\r
136 assert( m_offset == 32 + m_maplength );
\r
148 m_width = m_height = -1;
\r
155 bool SunRasterDecoder::readData( Mat& img )
\r
157 int color = img.channels() > 1;
\r
158 uchar* data = img.data;
\r
159 int step = img.step;
\r
160 uchar gray_palette[256];
\r
161 bool result = false;
\r
162 int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2;
\r
163 int nch = color ? 3 : 1;
\r
164 int width3 = m_width*nch;
\r
167 if( m_offset < 0 || !m_strm.isOpened())
\r
170 AutoBuffer<uchar> _src(src_pitch + 32);
\r
172 AutoBuffer<uchar> _bgr(m_width*3 + 32);
\r
175 if( !color && m_maptype == RMT_EQUAL_RGB )
\r
176 CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
\r
180 m_strm.setPos( m_offset );
\r
184 /************************* 1 BPP ************************/
\r
186 if( m_type != RAS_BYTE_ENCODED )
\r
188 for( y = 0; y < m_height; y++, data += step )
\r
190 m_strm.getBytes( src, src_pitch );
\r
192 FillColorRow1( data, src, m_width, m_palette );
\r
194 FillGrayRow1( data, src, m_width, gray_palette );
\r
200 uchar* line_end = src + (m_width*m_bpp + 7)/8;
\r
206 int max_count = (int)(line_end - tsrc);
\r
207 int code = 0, len = 0, len1 = 0;
\r
211 code = m_strm.getByte();
\r
214 len = m_strm.getByte();
\r
215 if( len != 0 ) break;
\r
217 tsrc[len1] = (uchar)code;
\r
219 while( ++len1 < max_count );
\r
223 if( len > 0 ) // encoded mode
\r
226 code = m_strm.getByte();
\r
227 if( len > line_end - tsrc )
\r
230 goto bad_decoding_1bpp;
\r
233 memset( tsrc, code, len );
\r
237 if( tsrc >= line_end )
\r
241 FillColorRow1( data, src, m_width, m_palette );
\r
243 FillGrayRow1( data, src, m_width, gray_palette );
\r
245 if( ++y >= m_height ) break;
\r
253 /************************* 8 BPP ************************/
\r
255 if( m_type != RAS_BYTE_ENCODED )
\r
257 for( y = 0; y < m_height; y++, data += step )
\r
259 m_strm.getBytes( src, src_pitch );
\r
261 FillColorRow8( data, src, m_width, m_palette );
\r
263 FillGrayRow8( data, src, m_width, gray_palette );
\r
267 else // RLE-encoded
\r
269 uchar* line_end = data + width3;
\r
274 int max_count = (int)(line_end - data);
\r
275 int code = 0, len = 0, len1;
\r
280 code = m_strm.getByte();
\r
283 len = m_strm.getByte();
\r
284 if( len != 0 ) break;
\r
286 *tsrc++ = (uchar)code;
\r
288 while( (max_count -= nch) > 0 );
\r
290 len1 = (int)(tsrc - src);
\r
295 FillColorRow8( data, src, len1, m_palette );
\r
297 FillGrayRow8( data, src, len1, gray_palette );
\r
301 if( len > 0 ) // encoded mode
\r
303 len = (len + 1)*nch;
\r
304 code = m_strm.getByte();
\r
307 data = FillUniColor( data, line_end, step, width3,
\r
311 data = FillUniGray( data, line_end, step, width3,
\r
313 gray_palette[code] );
\r
314 if( y >= m_height )
\r
318 if( data == line_end )
\r
320 if( m_strm.getByte() != 0 )
\r
321 goto bad_decoding_end;
\r
323 data = line_end - width3;
\r
324 if( ++y >= m_height ) break;
\r
333 /************************* 24 BPP ************************/
\r
335 for( y = 0; y < m_height; y++, data += step )
\r
337 m_strm.getBytes( color ? data : bgr, src_pitch );
\r
341 if( m_type == RAS_FORMAT_RGB )
\r
342 icvCvt_RGB2BGR_8u_C3R( data, 0, data, 0, cvSize(m_width,1) );
\r
346 icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1),
\r
347 m_type == RAS_FORMAT_RGB ? 2 : 0 );
\r
352 /************************* 32 BPP ************************/
\r
354 for( y = 0; y < m_height; y++, data += step )
\r
356 /* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3,
\r
357 so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */
\r
358 m_strm.getBytes( src + 3, src_pitch );
\r
361 icvCvt_BGRA2BGR_8u_C4C3R( src + 4, 0, data, 0, cvSize(m_width,1),
\r
362 m_type == RAS_FORMAT_RGB ? 2 : 0 );
\r
364 icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, cvSize(m_width,1),
\r
365 m_type == RAS_FORMAT_RGB ? 2 : 0 );
\r
381 //////////////////////////////////////////////////////////////////////////////////////////
\r
383 SunRasterEncoder::SunRasterEncoder()
\r
385 m_description = "Sun raster files (*.sr;*.ras)";
\r
389 ImageEncoder SunRasterEncoder::newEncoder() const
\r
391 return new SunRasterEncoder;
\r
394 SunRasterEncoder::~SunRasterEncoder()
\r
398 bool SunRasterEncoder::write( const Mat& img, const vector<int>& )
\r
400 bool result = false;
\r
401 int y, width = img.cols, height = img.rows, channels = img.channels();
\r
402 int fileStep = (width*channels + 1) & -2;
\r
405 if( strm.open(m_filename) )
\r
407 strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) );
\r
408 strm.putDWord( width );
\r
409 strm.putDWord( height );
\r
410 strm.putDWord( channels*8 );
\r
411 strm.putDWord( fileStep*height );
\r
412 strm.putDWord( RAS_STANDARD );
\r
413 strm.putDWord( RMT_NONE );
\r
414 strm.putDWord( 0 );
\r
416 for( y = 0; y < height; y++ )
\r
417 strm.putBytes( img.data + img.step*y, fileStep );
\r