LCOV - code coverage report
Current view: top level - libavcodec - tiffenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 130 266 48.9 %
Date: 2017-12-11 04:34:20 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :  * TIFF image encoder
       3             :  * Copyright (c) 2007 Bartlomiej Wolowiec
       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 image encoder
      25             :  * @author Bartlomiej Wolowiec
      26             :  */
      27             : 
      28             : #include "config.h"
      29             : #if CONFIG_ZLIB
      30             : #include <zlib.h>
      31             : #endif
      32             : 
      33             : #include "libavutil/imgutils.h"
      34             : #include "libavutil/log.h"
      35             : #include "libavutil/opt.h"
      36             : #include "libavutil/pixdesc.h"
      37             : #include "avcodec.h"
      38             : #include "bytestream.h"
      39             : #include "internal.h"
      40             : #include "lzw.h"
      41             : #include "put_bits.h"
      42             : #include "rle.h"
      43             : #include "tiff.h"
      44             : 
      45             : #define TIFF_MAX_ENTRY 32
      46             : 
      47             : /** sizes of various TIFF field types (string size = 1)*/
      48             : static const uint8_t type_sizes2[14] = {
      49             :     0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
      50             : };
      51             : 
      52             : typedef struct TiffEncoderContext {
      53             :     AVClass *class;                         ///< for private options
      54             :     AVCodecContext *avctx;
      55             : 
      56             :     int width;                              ///< picture width
      57             :     int height;                             ///< picture height
      58             :     unsigned int bpp;                       ///< bits per pixel
      59             :     int compr;                              ///< compression level
      60             :     int bpp_tab_size;                       ///< bpp_tab size
      61             :     enum TiffPhotometric photometric_interpretation;  ///< photometric interpretation
      62             :     int strips;                             ///< number of strips
      63             :     uint32_t *strip_sizes;
      64             :     unsigned int strip_sizes_size;
      65             :     uint32_t *strip_offsets;
      66             :     unsigned int strip_offsets_size;
      67             :     uint8_t *yuv_line;
      68             :     unsigned int yuv_line_size;
      69             :     int rps;                                ///< row per strip
      70             :     uint8_t entries[TIFF_MAX_ENTRY * 12];   ///< entries in header
      71             :     int num_entries;                        ///< number of entries
      72             :     uint8_t **buf;                          ///< actual position in buffer
      73             :     uint8_t *buf_start;                     ///< pointer to first byte in buffer
      74             :     int buf_size;                           ///< buffer size
      75             :     uint16_t subsampling[2];                ///< YUV subsampling factors
      76             :     struct LZWEncodeState *lzws;            ///< LZW encode state
      77             :     uint32_t dpi;                           ///< image resolution in DPI
      78             : } TiffEncoderContext;
      79             : 
      80             : /**
      81             :  * Check free space in buffer.
      82             :  *
      83             :  * @param s Tiff context
      84             :  * @param need Needed bytes
      85             :  * @return 0 - ok, 1 - no free space
      86             :  */
      87          91 : static inline int check_size(TiffEncoderContext *s, uint64_t need)
      88             : {
      89          91 :     if (s->buf_size < *s->buf - s->buf_start + need) {
      90           0 :         *s->buf = s->buf_start + s->buf_size + 1;
      91           0 :         av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n");
      92           0 :         return 1;
      93             :     }
      94          91 :     return 0;
      95             : }
      96             : 
      97             : /**
      98             :  * Put n values to buffer.
      99             :  *
     100             :  * @param p pointer to pointer to output buffer
     101             :  * @param n number of values
     102             :  * @param val pointer to values
     103             :  * @param type type of values
     104             :  * @param flip = 0 - normal copy, >0 - flip
     105             :  */
     106         169 : static void tnput(uint8_t **p, int n, const uint8_t *val, enum TiffTypes type,
     107             :                   int flip)
     108             : {
     109             :     int i;
     110             : #if HAVE_BIGENDIAN
     111             :     flip ^= ((int[]) { 0, 0, 0, 1, 3, 3 })[type];
     112             : #endif
     113        5135 :     for (i = 0; i < n * type_sizes2[type]; i++)
     114        4966 :         *(*p)++ = val[i ^ flip];
     115         169 : }
     116             : 
     117             : /**
     118             :  * Add entry to directory in tiff header.
     119             :  *
     120             :  * @param s Tiff context
     121             :  * @param tag tag that identifies the entry
     122             :  * @param type entry type
     123             :  * @param count the number of values
     124             :  * @param ptr_val pointer to values
     125             :  */
     126         169 : static int add_entry(TiffEncoderContext *s, enum TiffTags tag,
     127             :                      enum TiffTypes type, int count, const void *ptr_val)
     128             : {
     129         169 :     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
     130             : 
     131         169 :     av_assert0(s->num_entries < TIFF_MAX_ENTRY);
     132             : 
     133         169 :     bytestream_put_le16(&entries_ptr, tag);
     134         169 :     bytestream_put_le16(&entries_ptr, type);
     135         169 :     bytestream_put_le32(&entries_ptr, count);
     136             : 
     137         169 :     if (type_sizes[type] * (int64_t)count <= 4) {
     138         104 :         tnput(&entries_ptr, count, ptr_val, type, 0);
     139             :     } else {
     140          65 :         bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
     141          65 :         if (check_size(s, count * (int64_t)type_sizes2[type]))
     142           0 :             return AVERROR_INVALIDDATA;
     143          65 :         tnput(s->buf, count, ptr_val, type, 0);
     144             :     }
     145             : 
     146         169 :     s->num_entries++;
     147         169 :     return 0;
     148             : }
     149             : 
     150         104 : static int add_entry1(TiffEncoderContext *s,
     151             :                       enum TiffTags tag, enum TiffTypes type, int val)
     152             : {
     153         104 :     uint16_t w  = val;
     154         104 :     uint32_t dw = val;
     155         104 :     return add_entry(s, tag, type, 1,
     156             :                      type == TIFF_SHORT ? (void *)&w : (void *)&dw);
     157             : }
     158             : 
     159             : /**
     160             :  * Encode one strip in tiff file.
     161             :  *
     162             :  * @param s Tiff context
     163             :  * @param src input buffer
     164             :  * @param dst output buffer
     165             :  * @param n size of input buffer
     166             :  * @param compr compression method
     167             :  * @return number of output bytes. If an output error is encountered, a negative
     168             :  * value corresponding to an AVERROR error code is returned.
     169             :  */
     170        3744 : static int encode_strip(TiffEncoderContext *s, const int8_t *src,
     171             :                         uint8_t *dst, int n, int compr)
     172             : {
     173        3744 :     switch (compr) {
     174             : #if CONFIG_ZLIB
     175           0 :     case TIFF_DEFLATE:
     176             :     case TIFF_ADOBE_DEFLATE:
     177             :     {
     178           0 :         unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
     179           0 :         if (compress(dst, &zlen, src, n) != Z_OK) {
     180           0 :             av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
     181           0 :             return AVERROR_EXTERNAL;
     182             :         }
     183           0 :         return zlen;
     184             :     }
     185             : #endif
     186           0 :     case TIFF_RAW:
     187           0 :         if (check_size(s, n))
     188           0 :             return AVERROR(EINVAL);
     189           0 :         memcpy(dst, src, n);
     190           0 :         return n;
     191        3744 :     case TIFF_PACKBITS:
     192        3744 :         return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start),
     193             :                              src, 1, n, 2, 0xff, -1, 0);
     194           0 :     case TIFF_LZW:
     195           0 :         return ff_lzw_encode(s->lzws, src, n);
     196           0 :     default:
     197           0 :         av_log(s->avctx, AV_LOG_ERROR, "Unsupported compression method: %d\n",
     198             :                compr);
     199           0 :         return AVERROR(EINVAL);
     200             :     }
     201             : }
     202             : 
     203           0 : static void pack_yuv(TiffEncoderContext *s, const AVFrame *p,
     204             :                      uint8_t *dst, int lnum)
     205             : {
     206             :     int i, j, k;
     207           0 :     int w       = (s->width - 1) / s->subsampling[0] + 1;
     208           0 :     uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
     209           0 :     uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
     210           0 :     if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) {
     211           0 :         for (i = 0; i < w; i++) {
     212           0 :             for (j = 0; j < s->subsampling[1]; j++)
     213           0 :                 for (k = 0; k < s->subsampling[0]; k++)
     214           0 :                     *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
     215           0 :                                         FFMIN(i * s->subsampling[0] + k, s->width-1)];
     216           0 :             *dst++ = *pu++;
     217           0 :             *dst++ = *pv++;
     218             :         }
     219             :     }else{
     220           0 :         for (i = 0; i < w; i++) {
     221           0 :             for (j = 0; j < s->subsampling[1]; j++)
     222           0 :                 for (k = 0; k < s->subsampling[0]; k++)
     223           0 :                     *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
     224           0 :                                         i * s->subsampling[0] + k];
     225           0 :             *dst++ = *pu++;
     226           0 :             *dst++ = *pv++;
     227             :         }
     228             :     }
     229           0 : }
     230             : 
     231             : #define ADD_ENTRY(s, tag, type, count, ptr_val)         \
     232             :     do {                                                \
     233             :         ret = add_entry(s, tag, type, count, ptr_val);  \
     234             :         if (ret < 0)                                    \
     235             :             goto fail;                                  \
     236             :     } while (0)
     237             : 
     238             : #define ADD_ENTRY1(s, tag, type, val)           \
     239             :     do {                                        \
     240             :         ret = add_entry1(s, tag, type, val);    \
     241             :         if (ret < 0)                            \
     242             :             goto fail;                          \
     243             :     } while (0)
     244             : 
     245          13 : static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     246             :                         const AVFrame *pict, int *got_packet)
     247             : {
     248          13 :     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     249          13 :     TiffEncoderContext *s = avctx->priv_data;
     250          13 :     const AVFrame *const p = pict;
     251             :     int i;
     252             :     uint8_t *ptr;
     253             :     uint8_t *offset;
     254             :     uint32_t strips;
     255             :     int bytes_per_row;
     256          13 :     uint32_t res[2] = { s->dpi, 1 };    // image resolution (72/1)
     257             :     uint16_t bpp_tab[4];
     258          13 :     int ret = 0;
     259          13 :     int is_yuv = 0, alpha = 0;
     260             :     int shift_h, shift_v;
     261             :     int packet_size;
     262             : 
     263          13 :     s->width          = avctx->width;
     264          13 :     s->height         = avctx->height;
     265          13 :     s->subsampling[0] = 1;
     266          13 :     s->subsampling[1] = 1;
     267             : 
     268          13 :     if (!desc)
     269           0 :         return AVERROR(EINVAL);
     270             : 
     271          13 :     avctx->bits_per_coded_sample =
     272          13 :     s->bpp          = av_get_bits_per_pixel(desc);
     273          13 :     s->bpp_tab_size = desc->nb_components;
     274             : 
     275          13 :     switch (avctx->pix_fmt) {
     276           0 :     case AV_PIX_FMT_RGBA64LE:
     277             :     case AV_PIX_FMT_RGBA:
     278           0 :         alpha = 1;
     279          13 :     case AV_PIX_FMT_RGB48LE:
     280             :     case AV_PIX_FMT_RGB24:
     281          13 :         s->photometric_interpretation = TIFF_PHOTOMETRIC_RGB;
     282          13 :         break;
     283           0 :     case AV_PIX_FMT_GRAY8:
     284           0 :         avctx->bits_per_coded_sample = 0x28;
     285           0 :     case AV_PIX_FMT_GRAY8A:
     286             :     case AV_PIX_FMT_YA16LE:
     287           0 :         alpha = avctx->pix_fmt == AV_PIX_FMT_GRAY8A || avctx->pix_fmt == AV_PIX_FMT_YA16LE;
     288           0 :     case AV_PIX_FMT_GRAY16LE:
     289             :     case AV_PIX_FMT_MONOBLACK:
     290           0 :         s->photometric_interpretation = TIFF_PHOTOMETRIC_BLACK_IS_ZERO;
     291           0 :         break;
     292           0 :     case AV_PIX_FMT_PAL8:
     293           0 :         s->photometric_interpretation = TIFF_PHOTOMETRIC_PALETTE;
     294           0 :         break;
     295           0 :     case AV_PIX_FMT_MONOWHITE:
     296           0 :         s->photometric_interpretation = TIFF_PHOTOMETRIC_WHITE_IS_ZERO;
     297           0 :         break;
     298           0 :     case AV_PIX_FMT_YUV420P:
     299             :     case AV_PIX_FMT_YUV422P:
     300             :     case AV_PIX_FMT_YUV440P:
     301             :     case AV_PIX_FMT_YUV444P:
     302             :     case AV_PIX_FMT_YUV410P:
     303             :     case AV_PIX_FMT_YUV411P:
     304           0 :         av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
     305           0 :         s->photometric_interpretation = TIFF_PHOTOMETRIC_YCBCR;
     306           0 :         s->subsampling[0]             = 1 << shift_h;
     307           0 :         s->subsampling[1]             = 1 << shift_v;
     308           0 :         is_yuv                        = 1;
     309           0 :         break;
     310           0 :     default:
     311           0 :         av_log(s->avctx, AV_LOG_ERROR,
     312             :                "This colors format is not supported\n");
     313           0 :         return AVERROR(EINVAL);
     314             :     }
     315             : 
     316          52 :     for (i = 0; i < s->bpp_tab_size; i++)
     317          39 :         bpp_tab[i] = desc->comp[i].depth;
     318             : 
     319          26 :     if (s->compr == TIFF_DEFLATE       ||
     320          26 :         s->compr == TIFF_ADOBE_DEFLATE ||
     321          13 :         s->compr == TIFF_LZW)
     322             :         // best choice for DEFLATE
     323           0 :         s->rps = s->height;
     324             :     else
     325             :         // suggest size of strip
     326          13 :         s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);
     327             :     // round rps up
     328          13 :     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1];
     329             : 
     330          13 :     strips = (s->height - 1) / s->rps + 1;
     331             : 
     332          39 :     bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
     333          26 :                      s->subsampling[0] * s->subsampling[1] + 7) >> 3;
     334          26 :     packet_size = avctx->height * bytes_per_row * 2 +
     335          13 :                   avctx->height * 4 + AV_INPUT_BUFFER_MIN_SIZE;
     336             : 
     337          13 :     if ((ret = ff_alloc_packet2(avctx, pkt, packet_size, 0)) < 0)
     338           0 :         return ret;
     339          13 :     ptr          = pkt->data;
     340          13 :     s->buf_start = pkt->data;
     341          13 :     s->buf       = &ptr;
     342          13 :     s->buf_size  = pkt->size;
     343             : 
     344          13 :     if (check_size(s, 8)) {
     345           0 :         ret = AVERROR(EINVAL);
     346           0 :         goto fail;
     347             :     }
     348             : 
     349             :     // write header
     350          13 :     bytestream_put_le16(&ptr, 0x4949);
     351          13 :     bytestream_put_le16(&ptr, 42);
     352             : 
     353          13 :     offset = ptr;
     354          13 :     bytestream_put_le32(&ptr, 0);
     355             : 
     356          13 :     if (strips > INT_MAX / FFMAX(sizeof(s->strip_sizes[0]), sizeof(s->strip_offsets[0]))) {
     357           0 :         ret = AVERROR(ENOMEM);
     358           0 :         goto fail;
     359             :     }
     360          13 :     av_fast_padded_mallocz(&s->strip_sizes  , &s->strip_sizes_size  , sizeof(s->strip_sizes  [0]) * strips);
     361          13 :     av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
     362             : 
     363          13 :     if (!s->strip_sizes || !s->strip_offsets) {
     364           0 :         ret = AVERROR(ENOMEM);
     365           0 :         goto fail;
     366             :     }
     367             : 
     368          13 :     if (is_yuv) {
     369           0 :         av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
     370           0 :         if (s->yuv_line == NULL) {
     371           0 :             av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
     372           0 :             ret = AVERROR(ENOMEM);
     373           0 :             goto fail;
     374             :         }
     375             :     }
     376             : 
     377             : #if CONFIG_ZLIB
     378          13 :     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
     379             :         uint8_t *zbuf;
     380             :         int zlen, zn;
     381             :         int j;
     382             : 
     383           0 :         zlen = bytes_per_row * s->rps;
     384           0 :         zbuf = av_malloc(zlen);
     385           0 :         if (!zbuf) {
     386           0 :             ret = AVERROR(ENOMEM);
     387           0 :             goto fail;
     388             :         }
     389           0 :         s->strip_offsets[0] = ptr - pkt->data;
     390           0 :         zn               = 0;
     391           0 :         for (j = 0; j < s->rps; j++) {
     392           0 :             if (is_yuv) {
     393           0 :                 pack_yuv(s, p, s->yuv_line, j);
     394           0 :                 memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
     395           0 :                 j += s->subsampling[1] - 1;
     396             :             } else
     397           0 :                 memcpy(zbuf + j * bytes_per_row,
     398           0 :                        p->data[0] + j * p->linesize[0], bytes_per_row);
     399           0 :             zn += bytes_per_row;
     400             :         }
     401           0 :         ret = encode_strip(s, zbuf, ptr, zn, s->compr);
     402           0 :         av_free(zbuf);
     403           0 :         if (ret < 0) {
     404           0 :             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
     405           0 :             goto fail;
     406             :         }
     407           0 :         ptr           += ret;
     408           0 :         s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
     409             :     } else
     410             : #endif
     411             :     {
     412          13 :     if (s->compr == TIFF_LZW) {
     413           0 :         s->lzws = av_malloc(ff_lzw_encode_state_size);
     414           0 :         if (!s->lzws) {
     415           0 :             ret = AVERROR(ENOMEM);
     416           0 :             goto fail;
     417             :         }
     418             :     }
     419        3757 :     for (i = 0; i < s->height; i++) {
     420        3744 :         if (s->strip_sizes[i / s->rps] == 0) {
     421         546 :             if (s->compr == TIFF_LZW) {
     422           0 :                 ff_lzw_encode_init(s->lzws, ptr,
     423           0 :                                    s->buf_size - (*s->buf - s->buf_start),
     424             :                                    12, FF_LZW_TIFF, put_bits);
     425             :             }
     426         546 :             s->strip_offsets[i / s->rps] = ptr - pkt->data;
     427             :         }
     428        3744 :         if (is_yuv) {
     429           0 :             pack_yuv(s, p, s->yuv_line, i);
     430           0 :             ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
     431           0 :             i  += s->subsampling[1] - 1;
     432             :         } else
     433        3744 :             ret = encode_strip(s, p->data[0] + i * p->linesize[0],
     434             :                                ptr, bytes_per_row, s->compr);
     435        3744 :         if (ret < 0) {
     436           0 :             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
     437           0 :             goto fail;
     438             :         }
     439        3744 :         s->strip_sizes[i / s->rps] += ret;
     440        3744 :         ptr                     += ret;
     441        3744 :         if (s->compr == TIFF_LZW &&
     442           0 :             (i == s->height - 1 || i % s->rps == s->rps - 1)) {
     443           0 :             ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
     444           0 :             s->strip_sizes[(i / s->rps)] += ret;
     445           0 :             ptr                          += ret;
     446             :         }
     447             :     }
     448          13 :     if (s->compr == TIFF_LZW)
     449           0 :         av_freep(&s->lzws);
     450             :     }
     451             : 
     452          13 :     s->num_entries = 0;
     453             : 
     454          13 :     ADD_ENTRY1(s, TIFF_SUBFILE, TIFF_LONG, 0);
     455          13 :     ADD_ENTRY1(s, TIFF_WIDTH,   TIFF_LONG, s->width);
     456          13 :     ADD_ENTRY1(s, TIFF_HEIGHT,  TIFF_LONG, s->height);
     457             : 
     458          13 :     if (s->bpp_tab_size)
     459          13 :         ADD_ENTRY(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab);
     460             : 
     461          13 :     ADD_ENTRY1(s, TIFF_COMPR,       TIFF_SHORT, s->compr);
     462          13 :     ADD_ENTRY1(s, TIFF_PHOTOMETRIC, TIFF_SHORT, s->photometric_interpretation);
     463          13 :     ADD_ENTRY(s,  TIFF_STRIP_OFFS,  TIFF_LONG,  strips, s->strip_offsets);
     464             : 
     465          13 :     if (s->bpp_tab_size)
     466          13 :         ADD_ENTRY1(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
     467             : 
     468          13 :     ADD_ENTRY1(s, TIFF_ROWSPERSTRIP, TIFF_LONG,     s->rps);
     469          13 :     ADD_ENTRY(s,  TIFF_STRIP_SIZE,   TIFF_LONG,     strips, s->strip_sizes);
     470          13 :     ADD_ENTRY(s,  TIFF_XRES,         TIFF_RATIONAL, 1,      res);
     471          13 :     if (avctx->sample_aspect_ratio.num > 0 &&
     472           0 :         avctx->sample_aspect_ratio.den > 0) {
     473           0 :         AVRational y = av_mul_q(av_make_q(s->dpi, 1),
     474             :                                 avctx->sample_aspect_ratio);
     475           0 :         res[0] = y.num;
     476           0 :         res[1] = y.den;
     477             :     }
     478          13 :     ADD_ENTRY(s,  TIFF_YRES,         TIFF_RATIONAL, 1,      res);
     479          13 :     ADD_ENTRY1(s, TIFF_RES_UNIT,     TIFF_SHORT,    2);
     480             : 
     481          13 :     if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT))
     482           0 :         ADD_ENTRY(s, TIFF_SOFTWARE_NAME, TIFF_STRING,
     483             :                   strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
     484             : 
     485          13 :     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
     486             :         uint16_t pal[256 * 3];
     487           0 :         for (i = 0; i < 256; i++) {
     488           0 :             uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
     489           0 :             pal[i]       = ((rgb >> 16) & 0xff) * 257;
     490           0 :             pal[i + 256] = ((rgb >>  8) & 0xff) * 257;
     491           0 :             pal[i + 512] =  (rgb        & 0xff) * 257;
     492             :         }
     493           0 :         ADD_ENTRY(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
     494             :     }
     495          13 :     if (alpha)
     496           0 :         ADD_ENTRY1(s,TIFF_EXTRASAMPLES,      TIFF_SHORT,            2);
     497          13 :     if (is_yuv) {
     498             :         /** according to CCIR Recommendation 601.1 */
     499           0 :         uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
     500           0 :         ADD_ENTRY(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
     501           0 :         if (avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)
     502           0 :             ADD_ENTRY1(s, TIFF_YCBCR_POSITIONING, TIFF_SHORT, 2);
     503           0 :         ADD_ENTRY(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
     504             :     }
     505             :     // write offset to dir
     506          13 :     bytestream_put_le32(&offset, ptr - pkt->data);
     507             : 
     508          13 :     if (check_size(s, 6 + s->num_entries * 12)) {
     509           0 :         ret = AVERROR(EINVAL);
     510           0 :         goto fail;
     511             :     }
     512          13 :     bytestream_put_le16(&ptr, s->num_entries);  // write tag count
     513          13 :     bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);
     514          13 :     bytestream_put_le32(&ptr, 0);
     515             : 
     516          13 :     pkt->size   = ptr - pkt->data;
     517          13 :     pkt->flags |= AV_PKT_FLAG_KEY;
     518          13 :     *got_packet = 1;
     519             : 
     520          13 : fail:
     521          13 :     return ret < 0 ? ret : 0;
     522             : }
     523             : 
     524           1 : static av_cold int encode_init(AVCodecContext *avctx)
     525             : {
     526           1 :     TiffEncoderContext *s = avctx->priv_data;
     527             : 
     528             : #if !CONFIG_ZLIB
     529             :     if (s->compr == TIFF_DEFLATE) {
     530             :         av_log(avctx, AV_LOG_ERROR,
     531             :                "Deflate compression needs zlib compiled in\n");
     532             :         return AVERROR(ENOSYS);
     533             :     }
     534             : #endif
     535             : 
     536             : #if FF_API_CODED_FRAME
     537             : FF_DISABLE_DEPRECATION_WARNINGS
     538           1 :     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     539           1 :     avctx->coded_frame->key_frame = 1;
     540             : FF_ENABLE_DEPRECATION_WARNINGS
     541             : #endif
     542           1 :     s->avctx = avctx;
     543             : 
     544           1 :     return 0;
     545             : }
     546             : 
     547           1 : static av_cold int encode_close(AVCodecContext *avctx)
     548             : {
     549           1 :     TiffEncoderContext *s = avctx->priv_data;
     550             : 
     551           1 :     av_freep(&s->strip_sizes);
     552           1 :     av_freep(&s->strip_offsets);
     553           1 :     av_freep(&s->yuv_line);
     554             : 
     555           1 :     return 0;
     556             : }
     557             : 
     558             : #define OFFSET(x) offsetof(TiffEncoderContext, x)
     559             : #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
     560             : static const AVOption options[] = {
     561             :     {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
     562             :     { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT,   { .i64 = TIFF_PACKBITS }, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
     563             :     { "packbits",         NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_PACKBITS }, 0,        0,            VE, "compression_algo" },
     564             :     { "raw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_RAW      }, 0,        0,            VE, "compression_algo" },
     565             :     { "lzw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_LZW      }, 0,        0,            VE, "compression_algo" },
     566             :     { "deflate",          NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_DEFLATE  }, 0,        0,            VE, "compression_algo" },
     567             :     { NULL },
     568             : };
     569             : 
     570             : static const AVClass tiffenc_class = {
     571             :     .class_name = "TIFF encoder",
     572             :     .item_name  = av_default_item_name,
     573             :     .option     = options,
     574             :     .version    = LIBAVUTIL_VERSION_INT,
     575             : };
     576             : 
     577             : AVCodec ff_tiff_encoder = {
     578             :     .name           = "tiff",
     579             :     .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     580             :     .type           = AVMEDIA_TYPE_VIDEO,
     581             :     .id             = AV_CODEC_ID_TIFF,
     582             :     .priv_data_size = sizeof(TiffEncoderContext),
     583             :     .init           = encode_init,
     584             :     .close          = encode_close,
     585             :     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
     586             :     .encode2        = encode_frame,
     587             :     .pix_fmts       = (const enum AVPixelFormat[]) {
     588             :         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_PAL8,
     589             :         AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
     590             :         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_YA16LE,
     591             :         AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_MONOWHITE,
     592             :         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
     593             :         AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
     594             :         AV_PIX_FMT_NONE
     595             :     },
     596             :     .priv_class     = &tiffenc_class,
     597             : };

Generated by: LCOV version 1.13