Subversion Repositories Kolibri OS

Rev

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.     return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
  46. }
  47.  
  48.  
  49. unsigned ff_tget_long(GetByteContext *gb, int le)
  50. {
  51.     return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
  52. }
  53.  
  54.  
  55. double ff_tget_double(GetByteContext *gb, int le)
  56. {
  57.     av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
  58.     return i.f64;
  59. }
  60.  
  61.  
  62. unsigned ff_tget(GetByteContext *gb, int type, int le)
  63. {
  64.     switch (type) {
  65.     case TIFF_BYTE:  return bytestream2_get_byte(gb);
  66.     case TIFF_SHORT: return ff_tget_short(gb, le);
  67.     case TIFF_LONG:  return ff_tget_long(gb, le);
  68.     default:         return UINT_MAX;
  69.     }
  70. }
  71.  
  72. static const char *auto_sep(int count, const char *sep, int i, int columns)
  73. {
  74.     if (sep)
  75.         return i ? sep : "";
  76.     if (i && i%columns) {
  77.         return ", ";
  78.     } else
  79.         return columns < count ? "\n" : "";
  80. }
  81.  
  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.     if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
  91.         return AVERROR_INVALIDDATA;
  92.     if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
  93.         return AVERROR_INVALIDDATA;
  94.  
  95.     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
  96.  
  97.     for (i = 0; i < count; i++) {
  98.         nom   = ff_tget_long(gb, le);
  99.         denom = ff_tget_long(gb, le);
  100.         av_bprintf(&bp, "%s%7i:%-7i", auto_sep(count, sep, i, 4), nom, denom);
  101.     }
  102.  
  103.     if ((i = av_bprint_finalize(&bp, &ap))) {
  104.         return i;
  105.     }
  106.     if (!ap) {
  107.         return AVERROR(ENOMEM);
  108.     }
  109.  
  110.     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
  111.  
  112.     return 0;
  113. }
  114.  
  115.  
  116. 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.     if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
  124.         return AVERROR_INVALIDDATA;
  125.     if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
  126.         return AVERROR_INVALIDDATA;
  127.  
  128.     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
  129.  
  130.     for (i = 0; i < count; i++) {
  131.         av_bprintf(&bp, "%s%7i", auto_sep(count, sep, i, 8), ff_tget_long(gb, le));
  132.     }
  133.  
  134.     if ((i = av_bprint_finalize(&bp, &ap))) {
  135.         return i;
  136.     }
  137.     if (!ap) {
  138.         return AVERROR(ENOMEM);
  139.     }
  140.  
  141.     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
  142.  
  143.     return 0;
  144. }
  145.  
  146.  
  147. 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.     if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
  155.         return AVERROR_INVALIDDATA;
  156.     if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
  157.         return AVERROR_INVALIDDATA;
  158.  
  159.     av_bprint_init(&bp, 10 * count, 100 * count);
  160.  
  161.     for (i = 0; i < count; i++) {
  162.         av_bprintf(&bp, "%s%.15g", auto_sep(count, sep, i, 4), ff_tget_double(gb, le));
  163.     }
  164.  
  165.     if ((i = av_bprint_finalize(&bp, &ap))) {
  166.         return i;
  167.     }
  168.     if (!ap) {
  169.         return AVERROR(ENOMEM);
  170.     }
  171.  
  172.     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
  173.  
  174.     return 0;
  175. }
  176.  
  177.  
  178. 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.     if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
  186.         return AVERROR_INVALIDDATA;
  187.     if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
  188.         return AVERROR_INVALIDDATA;
  189.  
  190.     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
  191.  
  192.     for (i = 0; i < count; i++) {
  193.         int v = is_signed ? (int16_t)ff_tget_short(gb, le) :  ff_tget_short(gb, le);
  194.         av_bprintf(&bp, "%s%5i", auto_sep(count, sep, i, 8), v);
  195.     }
  196.  
  197.     if ((i = av_bprint_finalize(&bp, &ap))) {
  198.         return i;
  199.     }
  200.     if (!ap) {
  201.         return AVERROR(ENOMEM);
  202.     }
  203.  
  204.     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
  205.  
  206.     return 0;
  207. }
  208.  
  209.  
  210. 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.     if (count >= INT_MAX / sizeof(int8_t) || count < 0)
  218.         return AVERROR_INVALIDDATA;
  219.     if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t))
  220.         return AVERROR_INVALIDDATA;
  221.  
  222.     av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
  223.  
  224.     for (i = 0; i < count; i++) {
  225.         int v = is_signed ? (int8_t)bytestream2_get_byte(gb) :  bytestream2_get_byte(gb);
  226.         av_bprintf(&bp, "%s%3i", auto_sep(count, sep, i, 16), v);
  227.     }
  228.  
  229.     if ((i = av_bprint_finalize(&bp, &ap))) {
  230.         return i;
  231.     }
  232.     if (!ap) {
  233.         return AVERROR(ENOMEM);
  234.     }
  235.  
  236.     av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
  237.  
  238.     return 0;
  239. }
  240.  
  241. int ff_tadd_string_metadata(int count, const char *name,
  242.                             GetByteContext *gb, int le, AVDictionary **metadata)
  243. {
  244.     char *value;
  245.  
  246.     if (bytestream2_get_bytes_left(gb) < count || count < 0)
  247.         return AVERROR_INVALIDDATA;
  248.  
  249.     value = av_malloc(count + 1);
  250.     if (!value)
  251.         return AVERROR(ENOMEM);
  252.  
  253.     bytestream2_get_bufferu(gb, value, count);
  254.     value[count] = 0;
  255.  
  256.     av_dict_set(metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
  257.     return 0;
  258. }
  259.  
  260.  
  261. int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
  262. {
  263.     if (bytestream2_get_bytes_left(gb) < 8) {
  264.         return AVERROR_INVALIDDATA;
  265.     }
  266.  
  267.     *le = bytestream2_get_le16u(gb);
  268.     if (*le == AV_RB16("II")) {
  269.         *le = 1;
  270.     } else if (*le == AV_RB16("MM")) {
  271.         *le = 0;
  272.     } else {
  273.         return AVERROR_INVALIDDATA;
  274.     }
  275.  
  276.     if (ff_tget_short(gb, *le) != 42) {
  277.         return AVERROR_INVALIDDATA;
  278.     }
  279.  
  280.     *ifd_offset = ff_tget_long(gb, *le);
  281.  
  282.     return 0;
  283. }
  284.  
  285.  
  286. 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.     *tag    = ff_tget_short(gb, le);
  293.     *type   = ff_tget_short(gb, le);
  294.     *count  = ff_tget_long (gb, le);
  295.  
  296.     ifd_tag    = ff_tis_ifd(*tag);
  297.     valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
  298.  
  299.     *next = bytestream2_tell(gb) + 4;
  300.  
  301.     // check for valid type
  302.     if (!valid_type) {
  303.         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.     if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
  309.         bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
  310.     }
  311.  
  312.     return 0;
  313. }
  314.