LCOV - code coverage report
Current view: top level - libavcodec - exif.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 57 68.4 %
Date: 2017-12-15 18:13:28 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :  * EXIF metadata parser
       3             :  * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * EXIF metadata parser
      25             :  * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
      26             :  */
      27             : 
      28             : #include "exif.h"
      29             : 
      30             : 
      31         300 : static const char *exif_get_tag_name(uint16_t id)
      32             : {
      33             :     int i;
      34             : 
      35       22600 :     for (i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
      36       22576 :         if (tag_list[i].id == id)
      37         276 :             return tag_list[i].name;
      38             :     }
      39             : 
      40          24 :     return NULL;
      41             : }
      42             : 
      43             : 
      44         300 : static int exif_add_metadata(void *logctx, int count, int type,
      45             :                              const char *name, const char *sep,
      46             :                              GetByteContext *gb, int le,
      47             :                              AVDictionary **metadata)
      48             : {
      49         300 :     switch(type) {
      50           0 :     case 0:
      51           0 :         av_log(logctx, AV_LOG_WARNING,
      52             :                "Invalid TIFF tag type 0 found for %s with size %d\n",
      53             :                name, count);
      54           0 :         return 0;
      55           0 :     case TIFF_DOUBLE   : return ff_tadd_doubles_metadata(count, name, sep, gb, le, metadata);
      56           0 :     case TIFF_SSHORT   : return ff_tadd_shorts_metadata(count, name, sep, gb, le, 1, metadata);
      57         108 :     case TIFF_SHORT    : return ff_tadd_shorts_metadata(count, name, sep, gb, le, 0, metadata);
      58           0 :     case TIFF_SBYTE    : return ff_tadd_bytes_metadata(count, name, sep, gb, le, 1, metadata);
      59          46 :     case TIFF_BYTE     :
      60          46 :     case TIFF_UNDEFINED: return ff_tadd_bytes_metadata(count, name, sep, gb, le, 0, metadata);
      61          52 :     case TIFF_STRING   : return ff_tadd_string_metadata(count, name, gb, le, metadata);
      62          82 :     case TIFF_SRATIONAL:
      63          82 :     case TIFF_RATIONAL : return ff_tadd_rational_metadata(count, name, sep, gb, le, metadata);
      64          12 :     case TIFF_SLONG    :
      65          12 :     case TIFF_LONG     : return ff_tadd_long_metadata(count, name, sep, gb, le, metadata);
      66           0 :     default:
      67           0 :         avpriv_request_sample(logctx, "TIFF tag type (%u)", type);
      68           0 :         return 0;
      69             :     };
      70             : }
      71             : 
      72             : 
      73         316 : static int exif_decode_tag(void *logctx, GetByteContext *gbytes, int le,
      74             :                            int depth, AVDictionary **metadata)
      75             : {
      76             :     int ret, cur_pos;
      77             :     unsigned id, count;
      78             :     enum TiffTypes type;
      79             : 
      80         316 :     if (depth > 2) {
      81           0 :         return 0;
      82             :     }
      83             : 
      84         316 :     ff_tread_tag(gbytes, le, &id, &type, &count, &cur_pos);
      85             : 
      86         316 :     if (!bytestream2_tell(gbytes)) {
      87           0 :         bytestream2_seek(gbytes, cur_pos, SEEK_SET);
      88           0 :         return 0;
      89             :     }
      90             : 
      91             :     // read count values and add it metadata
      92             :     // store metadata or proceed with next IFD
      93         316 :     ret = ff_tis_ifd(id);
      94         316 :     if (ret) {
      95          16 :         ret = ff_exif_decode_ifd(logctx, gbytes, le, depth + 1, metadata);
      96             :     } else {
      97         300 :         const char *name = exif_get_tag_name(id);
      98         300 :         char *use_name   = (char*) name;
      99             : 
     100         300 :         if (!use_name) {
     101          24 :             use_name = av_malloc(7);
     102          24 :             if (!use_name) {
     103           0 :                 return AVERROR(ENOMEM);
     104             :             }
     105          24 :             snprintf(use_name, 7, "0x%04X", id);
     106             :         }
     107             : 
     108         300 :         ret = exif_add_metadata(logctx, count, type, use_name, NULL,
     109             :                                 gbytes, le, metadata);
     110             : 
     111         300 :         if (!name) {
     112          24 :             av_freep(&use_name);
     113             :         }
     114             :     }
     115             : 
     116         316 :     bytestream2_seek(gbytes, cur_pos, SEEK_SET);
     117             : 
     118         316 :     return ret;
     119             : }
     120             : 
     121             : 
     122          30 : int ff_exif_decode_ifd(void *logctx, GetByteContext *gbytes,
     123             :                        int le, int depth, AVDictionary **metadata)
     124             : {
     125             :     int i, ret;
     126             :     int entries;
     127             : 
     128          30 :     entries = ff_tget_short(gbytes, le);
     129             : 
     130          30 :     if (bytestream2_get_bytes_left(gbytes) < entries * 12) {
     131           0 :         return AVERROR_INVALIDDATA;
     132             :     }
     133             : 
     134         346 :     for (i = 0; i < entries; i++) {
     135         316 :         if ((ret = exif_decode_tag(logctx, gbytes, le, depth, metadata)) < 0) {
     136           0 :             return ret;
     137             :         }
     138             :     }
     139             : 
     140             :     // return next IDF offset or 0x000000000 or a value < 0 for failure
     141          30 :     return ff_tget_long(gbytes, le);
     142             : }
     143             : 
     144           0 : int avpriv_exif_decode_ifd(void *logctx, const uint8_t *buf, int size,
     145             :                            int le, int depth, AVDictionary **metadata)
     146             : {
     147             :     GetByteContext gb;
     148             : 
     149           0 :     bytestream2_init(&gb, buf, size);
     150             : 
     151           0 :     return ff_exif_decode_ifd(logctx, &gb, le, depth, metadata);
     152             : }

Generated by: LCOV version 1.13