bool SunRasterDecoder::readData( Mat& img ) { int color = img.channels() > 1; uchar* data = img.data; int step = img.step; uchar gray_palette[256]; bool result = false; int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2; int nch = color ? 3 : 1; int width3 = m_width*nch; int y; if( m_offset < 0 || !m_strm.isOpened()) return false; AutoBuffer<uchar> _src(src_pitch + 32); uchar* src = _src; AutoBuffer<uchar> _bgr(m_width*3 + 32); uchar* bgr = _bgr; if( !color && m_maptype == RMT_EQUAL_RGB ) CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp ); try { m_strm.setPos( m_offset ); switch( m_bpp ) { /************************* 1 BPP ************************/ case 1: if( m_type != RAS_BYTE_ENCODED ) { for( y = 0; y < m_height; y++, data += step ) { m_strm.getBytes( src, src_pitch ); if( color ) FillColorRow1( data, src, m_width, m_palette ); else FillGrayRow1( data, src, m_width, gray_palette ); } result = true; } else { uchar* line_end = src + (m_width*m_bpp + 7)/8; uchar* tsrc = src; y = 0; for(;;) { int max_count = (int)(line_end - tsrc); int code = 0, len = 0, len1 = 0; do { code = m_strm.getByte(); if( code == 0x80 ) { len = m_strm.getByte(); if( len != 0 ) break; } tsrc[len1] = (uchar)code; } while( ++len1 < max_count ); tsrc += len1; if( len > 0 ) // encoded mode { ++len; code = m_strm.getByte(); if( len > line_end - tsrc ) { assert(0); goto bad_decoding_1bpp; } memset( tsrc, code, len ); tsrc += len; } if( tsrc >= line_end ) { tsrc = src; if( color ) FillColorRow1( data, src, m_width, m_palette ); else FillGrayRow1( data, src, m_width, gray_palette ); data += step; if( ++y >= m_height ) break; } } result = true; bad_decoding_1bpp: ; } break; /************************* 8 BPP ************************/ case 8: if( m_type != RAS_BYTE_ENCODED ) { for( y = 0; y < m_height; y++, data += step ) { m_strm.getBytes( src, src_pitch ); if( color ) FillColorRow8( data, src, m_width, m_palette ); else FillGrayRow8( data, src, m_width, gray_palette ); } result = true; } else // RLE-encoded { uchar* line_end = data + width3; y = 0; for(;;) { int max_count = (int)(line_end - data); int code = 0, len = 0, len1; uchar* tsrc = src; do { code = m_strm.getByte(); if( code == 0x80 ) { len = m_strm.getByte(); if( len != 0 ) break; } *tsrc++ = (uchar)code; } while( (max_count -= nch) > 0 ); len1 = (int)(tsrc - src); if( len1 > 0 ) { if( color ) FillColorRow8( data, src, len1, m_palette ); else FillGrayRow8( data, src, len1, gray_palette ); data += len1*nch; } if( len > 0 ) // encoded mode { len = (len + 1)*nch; code = m_strm.getByte(); if( color ) data = FillUniColor( data, line_end, step, width3, y, m_height, len, m_palette[code] ); else data = FillUniGray( data, line_end, step, width3, y, m_height, len, gray_palette[code] ); if( y >= m_height ) break; } if( data == line_end ) { if( m_strm.getByte() != 0 ) goto bad_decoding_end; line_end += step; data = line_end - width3; if( ++y >= m_height ) break; } } result = true; bad_decoding_end: ; } break; /************************* 24 BPP ************************/ case 24: for( y = 0; y < m_height; y++, data += step ) { m_strm.getBytes( color ? data : bgr, src_pitch ); if( color ) { if( m_type == RAS_FORMAT_RGB ) icvCvt_RGB2BGR_8u_C3R( data, 0, data, 0, cvSize(m_width,1) ); } else { icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1), m_type == RAS_FORMAT_RGB ? 2 : 0 ); } } result = true; break; /************************* 32 BPP ************************/ case 32: for( y = 0; y < m_height; y++, data += step ) { /* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3, so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */ m_strm.getBytes( src + 3, src_pitch ); if( color ) icvCvt_BGRA2BGR_8u_C4C3R( src + 4, 0, data, 0, cvSize(m_width,1), m_type == RAS_FORMAT_RGB ? 2 : 0 ); else icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, cvSize(m_width,1), m_type == RAS_FORMAT_RGB ? 2 : 0 ); } result = true; break; default: assert(0); } } catch( ... ) { } return result; }
bool TiffDecoder::readData( Mat& img ) { bool result = false; bool color = img.channels() > 1; uchar* data = img.data; int step = (int)img.step; if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F ) return false; if( m_tif && m_width && m_height ) { TIFF* tif = (TIFF*)m_tif; int tile_width0 = m_width, tile_height0 = 0; int x, y, i; int is_tiled = TIFFIsTiled(tif); int photometric; TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ); int bpp = 8, ncn = photometric > 1 ? 3 : 1; TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); const int bitsPerByte = 8; int dst_bpp = (int)(img.elemSize1() * bitsPerByte); if(dst_bpp == 8) { char errmsg[1024]; if(!TIFFRGBAImageOK( tif, errmsg )) { close(); return false; } } if( (!is_tiled) || (is_tiled && TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) && TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))) { if(!is_tiled) TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ); if( tile_width0 <= 0 ) tile_width0 = m_width; if( tile_height0 <= 0 ) tile_height0 = m_height; AutoBuffer<uchar> _buffer(tile_height0*tile_width0*8); uchar* buffer = _buffer; ushort* buffer16 = (ushort*)buffer; float* buffer32 = (float*)buffer; double* buffer64 = (double*)buffer; int tileidx = 0; for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 ) { int tile_height = tile_height0; if( y + tile_height > m_height ) tile_height = m_height - y; for( x = 0; x < m_width; x += tile_width0, tileidx++ ) { int tile_width = tile_width0, ok; if( x + tile_width > m_width ) tile_width = m_width - x; switch(dst_bpp) { case 8: { if( !is_tiled ) ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer ); else ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer ); if( !ok ) { close(); return false; } for( i = 0; i < tile_height; i++ ) if( color ) icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, data + x*3 + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); else icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, data + x + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); break; } case 16: { if( !is_tiled ) ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; else ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; if( !ok ) { close(); return false; } for( i = 0; i < tile_height; i++ ) { if( color ) { if( ncn == 1 ) { icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1) ); } else if( ncn == 3 ) { icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1) ); } else { icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1), 2 ); } } else { if( ncn == 1 ) { memcpy((ushort*)(data + step*i)+x, buffer16 + i*tile_width*ncn, tile_width*sizeof(buffer16[0])); } else { icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x, 0, cvSize(tile_width,1), ncn, 2 ); } } } break; } case 32: case 64: { if( !is_tiled ) ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; else ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; if( !ok || ncn != 1 ) { close(); return false; } for( i = 0; i < tile_height; i++ ) { if(dst_bpp == 32) { memcpy((float*)(data + step*i)+x, buffer32 + i*tile_width*ncn, tile_width*sizeof(buffer32[0])); } else { memcpy((double*)(data + step*i)+x, buffer64 + i*tile_width*ncn, tile_width*sizeof(buffer64[0])); } } break; } default: { close(); return false; } } } } result = true; } } close(); return result; }
bool TiffDecoder::readData( Mat& img ) { bool result = false; bool color = img.channels() > 1; uchar* data = img.data; int step = img.step; if( m_tif && m_width && m_height ) { TIFF* tif = (TIFF*)m_tif; int tile_width0 = m_width, tile_height0 = 0; int x, y, i; int is_tiled = TIFFIsTiled(tif); if( (!is_tiled && TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 )) || (is_tiled && TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) && TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))) { if( tile_width0 <= 0 ) tile_width0 = m_width; if( tile_height0 <= 0 ) tile_height0 = m_height; AutoBuffer<uchar> _buffer(tile_height0*tile_width0*4); uchar* buffer = _buffer; for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 ) { int tile_height = tile_height0; if( y + tile_height > m_height ) tile_height = m_height - y; for( x = 0; x < m_width; x += tile_width0 ) { int tile_width = tile_width0, ok; if( x + tile_width > m_width ) tile_width = m_width - x; if( !is_tiled ) ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer ); else ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer ); if( !ok ) { close(); return false; } for( i = 0; i < tile_height; i++ ) if( color ) icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, data + x*3 + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); else icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, data + x + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); } } result = true; } } close(); return result; }