コード例 #1
0
ファイル: exif.cpp プロジェクト: GilseoneMoraes/opencv
/**
 * @brief Get exif directory structure contained in file (if any)
 *          This is internal function and is not exposed to client
 *
 *  @return Map where key is tag number and value is ExifEntry_t structure
 */
std::map<int, ExifEntry_t > ExifReader::getExif()
{
    const std::streamsize markerSize = 2;
    const std::streamsize offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
    unsigned char appMarker[markerSize];
    m_exif.erase( m_exif.begin(), m_exif.end() );

    std::streamsize count;

    bool exifFound = false, stopSearch = false;
    while( ( !m_stream.eof() ) && !exifFound && !stopSearch )
    {
        m_stream.read( reinterpret_cast<char*>(appMarker), markerSize );
        count = m_stream.gcount();
        if( count < markerSize )
        {
            break;
        }
        unsigned char marker = appMarker[1];
        size_t bytesToSkip;
        size_t exifSize;
        switch( marker )
        {
            //For all the markers just skip bytes in file pointed by followed two bytes (field size)
            case SOF0: case SOF2: case DHT: case DQT: case DRI: case SOS:
            case RST0: case RST1: case RST2: case RST3: case RST4: case RST5: case RST6: case RST7:
            case APP0: case APP2: case APP3: case APP4: case APP5: case APP6: case APP7: case APP8:
            case APP9: case APP10: case APP11: case APP12: case APP13: case APP14: case APP15:
            case COM:
                bytesToSkip = getFieldSize();
                if (bytesToSkip < markerSize) {
                    throw ExifParsingError();
                }
                m_stream.seekg( static_cast<long>( bytesToSkip - markerSize ), m_stream.cur );
                if ( m_stream.fail() ) {
                    throw ExifParsingError();
                }
                break;

            //SOI and EOI don't have the size field after the marker
            case SOI: case EOI:
                break;

            case APP1: //actual Exif Marker
                exifSize = getFieldSize();
                if (exifSize <= offsetToTiffHeader) {
                    throw ExifParsingError();
                }
                m_data.resize( exifSize - offsetToTiffHeader );
                m_stream.seekg( static_cast<long>( offsetToTiffHeader ), m_stream.cur );
                if ( m_stream.fail() ) {
                    throw ExifParsingError();
                }
                m_stream.read( reinterpret_cast<char*>(&m_data[0]), exifSize - offsetToTiffHeader );
                count = m_stream.gcount();
                exifFound = true;
                break;

            default: //No other markers are expected according to standard. May be a signal of error
                stopSearch = true;
                break;
        }
    }

    if( !exifFound )
    {
        return m_exif;
    }

    parseExif();

    return m_exif;
}
コード例 #2
0
ファイル: jpeg_exif.cpp プロジェクト: renatoGarcia/opencv
/**
 * @brief Get exif directory structure contained in jpeg file (if any)
 *          This is internal function and is not exposed to client
 *
 *  @return Map where key is tag number and value is ExifEntry_t structure
 */
std::map<int, ExifEntry_t > ExifReader::getExif()
{
    const size_t markerSize = 2;
    const size_t offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
    unsigned char appMarker[markerSize];
    m_exif.erase( m_exif.begin(), m_exif.end() );

    size_t count;

    FILE* f = fopen( m_filename.c_str(), "rb" );

    if( !f )
    {
        return m_exif; //Until this moment the map is empty
    }

    bool exifFound = false;
    while( ( !feof( f ) ) && !exifFound )
    {
        count = fread( appMarker, sizeof(unsigned char), markerSize, f );
        if( count < markerSize )
        {
            break;
        }
        unsigned char marker = appMarker[1];
        size_t bytesToSkip;
        size_t exifSize;
        switch( marker )
        {
            //For all the markers just skip bytes in file pointed by followed two bytes (field size)
            case SOF0: case SOF2: case DHT: case DQT: case DRI: case SOS:
            case RST0: case RST1: case RST2: case RST3: case RST4: case RST5: case RST6: case RST7:
            case APP0: case APP2: case APP3: case APP4: case APP5: case APP6: case APP7: case APP8:
            case APP9: case APP10: case APP11: case APP12: case APP13: case APP14: case APP15:
            case COM:
                bytesToSkip = getFieldSize( f );
                fseek( f, static_cast<long>( bytesToSkip - markerSize ), SEEK_CUR );
                break;

            //SOI and EOI don't have the size field after the marker
            case SOI: case EOI:
                break;

            case APP1: //actual Exif Marker
                exifSize = getFieldSize(f);
                m_data.resize( exifSize - offsetToTiffHeader );
                fseek(f, static_cast<long>( offsetToTiffHeader ), SEEK_CUR);
                count = fread( &m_data[0], sizeof( unsigned char ), exifSize - offsetToTiffHeader, f );
                exifFound = true;
                break;

            default: //No other markers are expected according to standard. May be a signal of error
                break;
        }
    }

    fclose(f);

    if( !exifFound )
    {
        return m_exif;
    }

    parseExif();

    return m_exif;
}