Update to 2.0.0 tree from current Fremantle build
[opencv] / src / highgui / grfmt_sunras.cpp
diff --git a/src/highgui/grfmt_sunras.cpp b/src/highgui/grfmt_sunras.cpp
new file mode 100644 (file)
index 0000000..88712a9
--- /dev/null
@@ -0,0 +1,425 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+//  By downloading, copying, installing or using the software you agree to this license.\r
+//  If you do not agree to this license, do not download, install,\r
+//  copy or use the software.\r
+//\r
+//\r
+//                           License Agreement\r
+//                For Open Source Computer Vision Library\r
+//\r
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.\r
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+//   * Redistribution's of source code must retain the above copyright notice,\r
+//     this list of conditions and the following disclaimer.\r
+//\r
+//   * Redistribution's in binary form must reproduce the above copyright notice,\r
+//     this list of conditions and the following disclaimer in the documentation\r
+//     and/or other materials provided with the distribution.\r
+//\r
+//   * The name of the copyright holders may not be used to endorse or promote products\r
+//     derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+#include "_highgui.h"\r
+#include "grfmt_sunras.h"\r
+\r
+namespace cv\r
+{\r
+\r
+static const char* fmtSignSunRas = "\x59\xA6\x6A\x95";\r
+\r
+/************************ Sun Raster reader *****************************/\r
+\r
+SunRasterDecoder::SunRasterDecoder()\r
+{\r
+    m_offset = -1;\r
+    m_signature = fmtSignSunRas;\r
+}\r
+\r
+\r
+SunRasterDecoder::~SunRasterDecoder()\r
+{\r
+}\r
+\r
+ImageDecoder SunRasterDecoder::newDecoder() const\r
+{\r
+    return new SunRasterDecoder;\r
+}\r
+\r
+void  SunRasterDecoder::close()\r
+{\r
+    m_strm.close();\r
+}\r
+\r
+\r
+bool  SunRasterDecoder::readHeader()\r
+{\r
+    bool result = false;\r
+\r
+    if( !m_strm.open( m_filename )) return false;\r
+\r
+    try\r
+    {\r
+        m_strm.skip( 4 );\r
+        m_width  = m_strm.getDWord();\r
+        m_height = m_strm.getDWord();\r
+        m_bpp    = m_strm.getDWord();\r
+        int palSize = 3*(1 << m_bpp);\r
+\r
+        m_strm.skip( 4 );\r
+        m_encoding = (SunRasType)m_strm.getDWord();\r
+        m_maptype = (SunRasMapType)m_strm.getDWord();\r
+        m_maplength = m_strm.getDWord();\r
+\r
+        if( m_width > 0 && m_height > 0 &&\r
+            (m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) &&\r
+            (m_type == RAS_OLD || m_type == RAS_STANDARD ||\r
+             (m_type == RAS_BYTE_ENCODED && m_bpp == 8) || m_type == RAS_FORMAT_RGB) &&\r
+            ((m_maptype == RMT_NONE && m_maplength == 0) ||\r
+             (m_maptype == RMT_EQUAL_RGB && m_maplength <= palSize && m_bpp <= 8)))\r
+        {\r
+            memset( m_palette, 0, sizeof(m_palette));\r
+\r
+            if( m_maplength != 0 )\r
+            {\r
+                uchar buffer[256*3];\r
+\r
+                if( m_strm.getBytes( buffer, m_maplength ) == m_maplength )\r
+                {\r
+                    int i;\r
+                    palSize = m_maplength/3;\r
+\r
+                    for( i = 0; i < palSize; i++ )\r
+                    {\r
+                        m_palette[i].b = buffer[i + 2*palSize];\r
+                        m_palette[i].g = buffer[i + palSize];\r
+                        m_palette[i].r = buffer[i];\r
+                        m_palette[i].a = 0;\r
+                    }\r
+\r
+                    m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1;\r
+                    m_offset = m_strm.getPos();\r
+\r
+                    assert( m_offset == 32 + m_maplength );\r
+                    result = true;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;\r
+\r
+                if( CV_MAT_CN(m_type) == 1 )\r
+                    FillGrayPalette( m_palette, m_bpp );\r
+\r
+                m_offset = m_strm.getPos();\r
+\r
+                assert( m_offset == 32 + m_maplength );\r
+                result = true;\r
+            }\r
+        }\r
+    }\r
+    catch(...)\r
+    {\r
+    }\r
+\r
+    if( !result )\r
+    {\r
+        m_offset = -1;\r
+        m_width = m_height = -1;\r
+        m_strm.close();\r
+    }\r
+    return result;\r
+}\r
+\r
+\r
+bool  SunRasterDecoder::readData( Mat& img )\r
+{\r
+    int color = img.channels() > 1;\r
+    uchar* data = img.data;\r
+    int step = img.step;\r
+    uchar  gray_palette[256];\r
+    bool   result = false;\r
+    int  src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2;\r
+    int  nch = color ? 3 : 1;\r
+    int  width3 = m_width*nch;\r
+    int  y;\r
+\r
+    if( m_offset < 0 || !m_strm.isOpened())\r
+        return false;\r
+\r
+    AutoBuffer<uchar> _src(src_pitch + 32);\r
+    uchar* src = _src;\r
+    AutoBuffer<uchar> _bgr(m_width*3 + 32);\r
+    uchar* bgr = _bgr;\r
+\r
+    if( !color && m_maptype == RMT_EQUAL_RGB )\r
+        CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );\r
+\r
+    try\r
+    {\r
+        m_strm.setPos( m_offset );\r
+\r
+        switch( m_bpp )\r
+        {\r
+        /************************* 1 BPP ************************/\r
+        case 1:\r
+            if( m_type != RAS_BYTE_ENCODED )\r
+            {\r
+                for( y = 0; y < m_height; y++, data += step )\r
+                {\r
+                    m_strm.getBytes( src, src_pitch );\r
+                    if( color )\r
+                        FillColorRow1( data, src, m_width, m_palette );\r
+                    else\r
+                        FillGrayRow1( data, src, m_width, gray_palette );\r
+                }\r
+                result = true;\r
+            }\r
+            else\r
+            {\r
+                uchar* line_end = src + (m_width*m_bpp + 7)/8;\r
+                uchar* tsrc = src;\r
+                y = 0;\r
+\r
+                for(;;)\r
+                {\r
+                    int max_count = (int)(line_end - tsrc);\r
+                    int code = 0, len = 0, len1 = 0;\r
+\r
+                    do\r
+                    {\r
+                        code = m_strm.getByte();\r
+                        if( code == 0x80 )\r
+                        {\r
+                            len = m_strm.getByte();\r
+                            if( len != 0 ) break;\r
+                        }\r
+                        tsrc[len1] = (uchar)code;\r
+                    }\r
+                    while( ++len1 < max_count );\r
+\r
+                    tsrc += len1;\r
+\r
+                    if( len > 0 ) // encoded mode\r
+                    {\r
+                        ++len;\r
+                        code = m_strm.getByte();\r
+                        if( len > line_end - tsrc )\r
+                        {\r
+                            assert(0);\r
+                            goto bad_decoding_1bpp;\r
+                        }\r
+\r
+                        memset( tsrc, code, len );\r
+                        tsrc += len;\r
+                    }\r
+\r
+                    if( tsrc >= line_end )\r
+                    {\r
+                        tsrc = src;\r
+                        if( color )\r
+                            FillColorRow1( data, src, m_width, m_palette );\r
+                        else\r
+                            FillGrayRow1( data, src, m_width, gray_palette );\r
+                        data += step;\r
+                        if( ++y >= m_height ) break;\r
+                    }\r
+                }\r
+                result = true;\r
+bad_decoding_1bpp:\r
+                ;\r
+            }\r
+            break;\r
+        /************************* 8 BPP ************************/\r
+        case 8:\r
+            if( m_type != RAS_BYTE_ENCODED )\r
+            {\r
+                for( y = 0; y < m_height; y++, data += step )\r
+                {\r
+                    m_strm.getBytes( src, src_pitch );\r
+                    if( color )\r
+                        FillColorRow8( data, src, m_width, m_palette );\r
+                    else\r
+                        FillGrayRow8( data, src, m_width, gray_palette );\r
+                }\r
+                result = true;\r
+            }\r
+            else // RLE-encoded\r
+            {\r
+                uchar* line_end = data + width3;\r
+                y = 0;\r
+\r
+                for(;;)\r
+                {\r
+                    int max_count = (int)(line_end - data);\r
+                    int code = 0, len = 0, len1;\r
+                    uchar* tsrc = src;\r
+\r
+                    do\r
+                    {\r
+                        code = m_strm.getByte();\r
+                        if( code == 0x80 )\r
+                        {\r
+                            len = m_strm.getByte();\r
+                            if( len != 0 ) break;\r
+                        }\r
+                        *tsrc++ = (uchar)code;\r
+                    }\r
+                    while( (max_count -= nch) > 0 );\r
+\r
+                    len1 = (int)(tsrc - src);\r
+\r
+                    if( len1 > 0 )\r
+                    {\r
+                        if( color )\r
+                            FillColorRow8( data, src, len1, m_palette );\r
+                        else\r
+                            FillGrayRow8( data, src, len1, gray_palette );\r
+                        data += len1*nch;\r
+                    }\r
+\r
+                    if( len > 0 ) // encoded mode\r
+                    {\r
+                        len = (len + 1)*nch;\r
+                        code = m_strm.getByte();\r
+\r
+                        if( color )\r
+                            data = FillUniColor( data, line_end, step, width3,\r
+                                                 y, m_height, len,\r
+                                                 m_palette[code] );\r
+                        else\r
+                            data = FillUniGray( data, line_end, step, width3,\r
+                                                y, m_height, len,\r
+                                                gray_palette[code] );\r
+                        if( y >= m_height )\r
+                            break;\r
+                    }\r
+\r
+                    if( data == line_end )\r
+                    {\r
+                        if( m_strm.getByte() != 0 )\r
+                            goto bad_decoding_end;\r
+                        line_end += step;\r
+                        data = line_end - width3;\r
+                        if( ++y >= m_height ) break;\r
+                    }\r
+                }\r
+\r
+                result = true;\r
+bad_decoding_end:\r
+                ;\r
+            }\r
+            break;\r
+        /************************* 24 BPP ************************/\r
+        case 24:\r
+            for( y = 0; y < m_height; y++, data += step )\r
+            {\r
+                m_strm.getBytes( color ? data : bgr, src_pitch );\r
+\r
+                if( color )\r
+                {\r
+                    if( m_type == RAS_FORMAT_RGB )\r
+                        icvCvt_RGB2BGR_8u_C3R( data, 0, data, 0, cvSize(m_width,1) );\r
+                }\r
+                else\r
+                {\r
+                    icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1),\r
+                                              m_type == RAS_FORMAT_RGB ? 2 : 0 );\r
+                }\r
+            }\r
+            result = true;\r
+            break;\r
+        /************************* 32 BPP ************************/\r
+        case 32:\r
+            for( y = 0; y < m_height; y++, data += step )\r
+            {\r
+                /* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3,\r
+                   so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */\r
+                m_strm.getBytes( src + 3, src_pitch );\r
+\r
+                if( color )\r
+                    icvCvt_BGRA2BGR_8u_C4C3R( src + 4, 0, data, 0, cvSize(m_width,1),\r
+                                              m_type == RAS_FORMAT_RGB ? 2 : 0 );\r
+                else\r
+                    icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, cvSize(m_width,1),\r
+                                               m_type == RAS_FORMAT_RGB ? 2 : 0 );\r
+            }\r
+            result = true;\r
+            break;\r
+        default:\r
+            assert(0);\r
+        }\r
+    }\r
+    catch( ... )\r
+    {\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////////////////////\r
+\r
+SunRasterEncoder::SunRasterEncoder()\r
+{\r
+    m_description = "Sun raster files (*.sr;*.ras)";\r
+}\r
+\r
+\r
+ImageEncoder SunRasterEncoder::newEncoder() const\r
+{\r
+    return new SunRasterEncoder;\r
+}\r
+\r
+SunRasterEncoder::~SunRasterEncoder()\r
+{\r
+}\r
+\r
+bool  SunRasterEncoder::write( const Mat& img, const vector<int>& )\r
+{\r
+    bool result = false;\r
+    int y, width = img.cols, height = img.rows, channels = img.channels();\r
+    int fileStep = (width*channels + 1) & -2;\r
+    WMByteStream  strm;\r
+\r
+    if( strm.open(m_filename) )\r
+    {\r
+        strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) );\r
+        strm.putDWord( width );\r
+        strm.putDWord( height );\r
+        strm.putDWord( channels*8 );\r
+        strm.putDWord( fileStep*height );\r
+        strm.putDWord( RAS_STANDARD );\r
+        strm.putDWord( RMT_NONE );\r
+        strm.putDWord( 0 );\r
+\r
+        for( y = 0; y < height; y++ )\r
+            strm.putBytes( img.data + img.step*y, fileStep );\r
+\r
+        strm.close();\r
+        result = true;\r
+    }\r
+    return result;\r
+}\r
+\r
+}\r