Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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