LCOV - code coverage report
Current view: top level - libavcodec - tiff_common.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 92 133 69.2 %
Date: 2017-12-17 04:34:43 Functions: 12 14 85.7 %

          Line data    Source code
       1             : /*
       2             :  * TIFF Common Routines
       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             :  * TIFF Common Routines
      25             :  * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
      26             :  */
      27             : 
      28             : #include "tiff_common.h"
      29             : 
      30             : 
      31         931 : int ff_tis_ifd(unsigned tag)
      32             : {
      33             :     int i;
      34        3652 :     for (i = 0; i < FF_ARRAY_ELEMS(ifd_tags); i++) {
      35        2753 :         if (ifd_tags[i] == tag) {
      36          32 :             return i + 1;
      37             :         }
      38             :     }
      39         899 :     return 0;
      40             : }
      41             : 
      42             : 
      43        1599 : unsigned ff_tget_short(GetByteContext *gb, int le)
      44             : {
      45        1599 :     return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
      46             : }
      47             : 
      48             : 
      49        2637 : unsigned ff_tget_long(GetByteContext *gb, int le)
      50             : {
      51        2637 :     return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
      52             : }
      53             : 
      54             : 
      55           0 : double ff_tget_double(GetByteContext *gb, int le)
      56             : {
      57           0 :     av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
      58           0 :     return i.f64;
      59             : }
      60             : 
      61             : 
      62        1687 : unsigned ff_tget(GetByteContext *gb, int type, int le)
      63             : {
      64        1687 :     switch (type) {
      65           0 :     case TIFF_BYTE:  return bytestream2_get_byte(gb);
      66         171 :     case TIFF_SHORT: return ff_tget_short(gb, le);
      67        1516 :     case TIFF_LONG:  return ff_tget_long(gb, le);
      68           0 :     default:         return UINT_MAX;
      69             :     }
      70             : }
      71             : 
      72       15420 : static const char *auto_sep(int count, const char *sep, int i, int columns)
      73             : {
      74       15420 :     if (sep)
      75           4 :         return i ? sep : "";
      76       15416 :     if (i && i%columns) {
      77       14232 :         return ", ";
      78             :     } else
      79        1184 :         return columns < count ? "\n" : "";
      80             : }
      81             : 
      82          82 : int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
      83             :                               GetByteContext *gb, int le, AVDictionary **metadata)
      84             : {
      85             :     AVBPrint bp;
      86             :     char *ap;
      87             :     int32_t nom, denom;
      88             :     int i;
      89             : 
      90          82 :     if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
      91           0 :         return AVERROR_INVALIDDATA;
      92          82 :     if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
      93           0 :         return AVERROR_INVALIDDATA;
      94             : 
      95          82 :     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
      96             : 
      97         164 :     for (i = 0; i < count; i++) {
      98          82 :         nom   = ff_tget_long(gb, le);
      99          82 :         denom = ff_tget_long(gb, le);
     100          82 :         av_bprintf(&bp, "%s%7"PRId32":%-7"PRId32, auto_sep(count, sep, i, 4), nom, denom);
     101             :     }
     102             : 
     103          82 :     if ((i = av_bprint_finalize(&bp, &ap))) {
     104           0 :         return i;
     105             :     }
     106          82 :     if (!ap) {
     107           0 :         return AVERROR(ENOMEM);
     108             :     }
     109             : 
     110          82 :     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
     111             : 
     112          82 :     return 0;
     113             : }
     114             : 
     115             : 
     116          12 : int ff_tadd_long_metadata(int count, const char *name, const char *sep,
     117             :                           GetByteContext *gb, int le, AVDictionary **metadata)
     118             : {
     119             :     AVBPrint bp;
     120             :     char *ap;
     121             :     int i;
     122             : 
     123          12 :     if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
     124           0 :         return AVERROR_INVALIDDATA;
     125          12 :     if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
     126           0 :         return AVERROR_INVALIDDATA;
     127             : 
     128          12 :     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
     129             : 
     130          24 :     for (i = 0; i < count; i++) {
     131          12 :         av_bprintf(&bp, "%s%7i", auto_sep(count, sep, i, 8), ff_tget_long(gb, le));
     132             :     }
     133             : 
     134          12 :     if ((i = av_bprint_finalize(&bp, &ap))) {
     135           0 :         return i;
     136             :     }
     137          12 :     if (!ap) {
     138           0 :         return AVERROR(ENOMEM);
     139             :     }
     140             : 
     141          12 :     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
     142             : 
     143          12 :     return 0;
     144             : }
     145             : 
     146             : 
     147           0 : int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
     148             :                              GetByteContext *gb, int le, AVDictionary **metadata)
     149             : {
     150             :     AVBPrint bp;
     151             :     char *ap;
     152             :     int i;
     153             : 
     154           0 :     if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
     155           0 :         return AVERROR_INVALIDDATA;
     156           0 :     if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
     157           0 :         return AVERROR_INVALIDDATA;
     158             : 
     159           0 :     av_bprint_init(&bp, 10 * count, 100 * count);
     160             : 
     161           0 :     for (i = 0; i < count; i++) {
     162           0 :         av_bprintf(&bp, "%s%.15g", auto_sep(count, sep, i, 4), ff_tget_double(gb, le));
     163             :     }
     164             : 
     165           0 :     if ((i = av_bprint_finalize(&bp, &ap))) {
     166           0 :         return i;
     167             :     }
     168           0 :     if (!ap) {
     169           0 :         return AVERROR(ENOMEM);
     170             :     }
     171             : 
     172           0 :     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
     173             : 
     174           0 :     return 0;
     175             : }
     176             : 
     177             : 
     178         110 : int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
     179             :                             GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
     180             : {
     181             :     AVBPrint bp;
     182             :     char *ap;
     183             :     int i;
     184             : 
     185         110 :     if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
     186           0 :         return AVERROR_INVALIDDATA;
     187         110 :     if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
     188           0 :         return AVERROR_INVALIDDATA;
     189             : 
     190         110 :     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
     191             : 
     192         222 :     for (i = 0; i < count; i++) {
     193         112 :         int v = is_signed ? (int16_t)ff_tget_short(gb, le) :  ff_tget_short(gb, le);
     194         112 :         av_bprintf(&bp, "%s%5i", auto_sep(count, sep, i, 8), v);
     195             :     }
     196             : 
     197         110 :     if ((i = av_bprint_finalize(&bp, &ap))) {
     198           0 :         return i;
     199             :     }
     200         110 :     if (!ap) {
     201           0 :         return AVERROR(ENOMEM);
     202             :     }
     203             : 
     204         110 :     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
     205             : 
     206         110 :     return 0;
     207             : }
     208             : 
     209             : 
     210          46 : int ff_tadd_bytes_metadata(int count, const char *name, const char *sep,
     211             :                            GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
     212             : {
     213             :     AVBPrint bp;
     214             :     char *ap;
     215             :     int i;
     216             : 
     217          46 :     if (count >= INT_MAX / sizeof(int8_t) || count < 0)
     218           0 :         return AVERROR_INVALIDDATA;
     219          46 :     if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t))
     220           0 :         return AVERROR_INVALIDDATA;
     221             : 
     222          46 :     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
     223             : 
     224       15260 :     for (i = 0; i < count; i++) {
     225       15214 :         int v = is_signed ? (int8_t)bytestream2_get_byte(gb) :  bytestream2_get_byte(gb);
     226       15214 :         av_bprintf(&bp, "%s%3i", auto_sep(count, sep, i, 16), v);
     227             :     }
     228             : 
     229          46 :     if ((i = av_bprint_finalize(&bp, &ap))) {
     230           0 :         return i;
     231             :     }
     232          46 :     if (!ap) {
     233           0 :         return AVERROR(ENOMEM);
     234             :     }
     235             : 
     236          46 :     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
     237             : 
     238          46 :     return 0;
     239             : }
     240             : 
     241          64 : int ff_tadd_string_metadata(int count, const char *name,
     242             :                             GetByteContext *gb, int le, AVDictionary **metadata)
     243             : {
     244             :     char *value;
     245             : 
     246          64 :     if (bytestream2_get_bytes_left(gb) < count || count < 0)
     247           0 :         return AVERROR_INVALIDDATA;
     248             : 
     249          64 :     value = av_malloc(count + 1);
     250          64 :     if (!value)
     251           0 :         return AVERROR(ENOMEM);
     252             : 
     253          64 :     bytestream2_get_bufferu(gb, value, count);
     254          64 :     value[count] = 0;
     255             : 
     256          64 :     av_dict_set(metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
     257          64 :     return 0;
     258             : }
     259             : 
     260             : 
     261          35 : int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
     262             : {
     263          35 :     if (bytestream2_get_bytes_left(gb) < 8) {
     264           0 :         return AVERROR_INVALIDDATA;
     265             :     }
     266             : 
     267          35 :     *le = bytestream2_get_le16u(gb);
     268          35 :     if (*le == AV_RB16("II")) {
     269          25 :         *le = 1;
     270          10 :     } else if (*le == AV_RB16("MM")) {
     271          10 :         *le = 0;
     272             :     } else {
     273           0 :         return AVERROR_INVALIDDATA;
     274             :     }
     275             : 
     276          35 :     if (ff_tget_short(gb, *le) != 42) {
     277           0 :         return AVERROR_INVALIDDATA;
     278             :     }
     279             : 
     280          35 :     *ifd_offset = ff_tget_long(gb, *le);
     281             : 
     282          35 :     return 0;
     283             : }
     284             : 
     285             : 
     286         615 : int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
     287             :                  unsigned *count, int *next)
     288             : {
     289             :     int ifd_tag;
     290             :     int valid_type;
     291             : 
     292         615 :     *tag    = ff_tget_short(gb, le);
     293         615 :     *type   = ff_tget_short(gb, le);
     294         615 :     *count  = ff_tget_long (gb, le);
     295             : 
     296         615 :     ifd_tag    = ff_tis_ifd(*tag);
     297         615 :     valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
     298             : 
     299         615 :     *next = bytestream2_tell(gb) + 4;
     300             : 
     301             :     // check for valid type
     302         615 :     if (!valid_type) {
     303           0 :         return AVERROR_INVALIDDATA;
     304             :     }
     305             : 
     306             :     // seek to offset if this is an IFD-tag or
     307             :     // if count values do not fit into the offset value
     308         615 :     if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
     309         265 :         bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
     310             :     }
     311             : 
     312         615 :     return 0;
     313             : }

Generated by: LCOV version 1.13