Merge commit '46ce9ded96ffcb798b03da894cdb5fdac376a6ee'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 3 Jun 2013 09:44:11 +0000 (11:44 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 3 Jun 2013 09:44:11 +0000 (11:44 +0200)
* commit '46ce9ded96ffcb798b03da894cdb5fdac376a6ee':
  tiff: K&R formatting cosmetics

Conflicts:
libavcodec/tiff.c
libavcodec/tiff.h
libavcodec/tiffenc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/tiff.c
libavcodec/tiff.h
libavcodec/tiffenc.c

  #if CONFIG_ZLIB
  #include <zlib.h>
  #endif
- #include "lzw.h"
- #include "tiff.h"
- #include "tiff_data.h"
- #include "faxcompr.h"
- #include "internal.h"
- #include "mathops.h"
  #include "libavutil/attributes.h"
++#include "libavutil/avstring.h"
  #include "libavutil/intreadwrite.h"
  #include "libavutil/imgutils.h"
- #include "libavutil/avstring.h"
+ #include "avcodec.h"
++#include "bytestream.h"
+ #include "faxcompr.h"
+ #include "internal.h"
+ #include "lzw.h"
+ #include "mathops.h"
+ #include "tiff.h"
++#include "tiff_data.h"
  
  typedef struct TiffContext {
      AVCodecContext *avctx;
@@@ -81,19 -76,17 +82,23 @@@ static unsigned tget_long(GetByteContex
      return v;
  }
  
 -static unsigned tget(const uint8_t **p, int type, int le)
 +static double tget_double(GetByteContext *gb, int le)
 +{
 +    av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
 +    return i.f64;
 +}
 +
 +static unsigned tget(GetByteContext *gb, int type, int le)
  {
      switch (type) {
-     case TIFF_BYTE : return bytestream2_get_byte(gb);
-     case TIFF_SHORT: return tget_short(gb, le);
-     case TIFF_LONG : return tget_long(gb, le);
-     default        : return UINT_MAX;
+     case TIFF_BYTE:
 -        return *(*p)++;
++        return bytestream2_get_byte(gb);
+     case TIFF_SHORT:
 -        return tget_short(p, le);
++        return tget_short(gb, le);
+     case TIFF_LONG:
 -        return tget_long(p, le);
++        return tget_long(gb, le);
+     default:
+         return UINT_MAX;
      }
  }
  
@@@ -356,11 -97,11 +361,11 @@@ static int tiff_uncompress(uint8_t *dst
      z_stream zstream = { 0 };
      int zret;
  
-     zstream.next_in = (uint8_t *)src;
-     zstream.avail_in = size;
-     zstream.next_out = dst;
 -    zstream.next_in   = src;
++    zstream.next_in   = (uint8_t *)src;
+     zstream.avail_in  = size;
+     zstream.next_out  = dst;
      zstream.avail_out = *len;
-     zret = inflateInit(&zstream);
+     zret              = inflateInit(&zstream);
      if (zret != Z_OK) {
          av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
          return zret;
@@@ -430,11 -118,8 +435,11 @@@ static int tiff_unpack_strip(TiffContex
  {
      int c, line, pixels, code, ret;
      const uint8_t *ssrc = src;
-     int width = ((s->width * s->bpp) + 7) >> 3;
+     int width           = ((s->width * s->bpp) + 7) >> 3;
  
 +    if (s->planar)
 +        width /= s->bppcount;
 +
      if (size <= 0)
          return AVERROR_INVALIDDATA;
  
          unsigned long outlen;
          int ret;
          outlen = width * lines;
-         zbuf = av_malloc(outlen);
+         zbuf   = av_malloc(outlen);
          if (!zbuf)
              return AVERROR(ENOMEM);
 +        if (s->fill_order) {
 +            if ((ret = deinvert_buffer(s, src, size)) < 0)
 +                return ret;
 +            ssrc = src = s->deinvert_buf;
 +        }
          ret = tiff_uncompress(zbuf, &outlen, src, size);
          if (ret != Z_OK) {
              av_log(s->avctx, AV_LOG_ERROR,
          }
          src = zbuf;
          for (line = 0; line < lines; line++) {
-             if(s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8){
 -            memcpy(dst, src, width);
++            if(s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
 +                horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
 +            }else{
 +                memcpy(dst, src, width);
 +            }
              dst += stride;
              src += width;
          }
                                 "Copy went out of bounds\n");
                          return AVERROR_INVALIDDATA;
                      }
 -                    memcpy(dst + pixels, src, code);
 +                    if (ssrc + size - src < code) {
 +                        av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
 +                        return AVERROR_INVALIDDATA;
 +                    }
 +                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
 +                                    dst, 1, src, 0, code, pixels);
-                     src += code;
+                     src    += code;
                      pixels += code;
                  } else if (code != -128) { // -127..-1
                      code = (-code) + 1;
@@@ -703,14 -342,19 +709,13 @@@ static int tiff_decode_tag(TiffContext 
              }
          default:
              value = UINT_MAX;
 -            buf   = start + off;
 +            bytestream2_seek(&s->gb, off, SEEK_SET);
          }
      } else {
-         if (count <= 4 && type_sizes[type] * count <= 4) {
+         if (count <= 4 && type_sizes[type] * count <= 4)
 -            buf -= 4;
 +            bytestream2_seek(&s->gb, -4, SEEK_CUR);
-         } else {
+         else
 -            buf = start + off;
 -    }
 -
 -    if (buf && (buf < start || buf > end_buf)) {
 -        av_log(s->avctx, AV_LOG_ERROR,
 -               "Tag referencing position outside the image\n");
 -        return AVERROR_INVALIDDATA;
 +            bytestream2_seek(&s->gb, off, SEEK_SET);
-         }
      }
  
      switch (tag) {
          break;
      case TIFF_STRIP_OFFS:
          if (count == 1) {
-             s->strippos = 0;
-             s->stripoff = value;
 -            s->stripdata = NULL;
++            s->strippos  = 0;
+             s->stripoff  = value;
          } else
 -            s->stripdata = start + off;
 +            s->strippos = off;
          s->strips = count;
          if (s->strips == 1)
              s->rps = s->height;
          break;
      case TIFF_STRIP_SIZE:
          if (count == 1) {
 -            s->stripsizes = NULL;
 +            s->stripsizesoff = 0;
-             s->stripsize = value;
-             s->strips = 1;
+             s->stripsize  = value;
+             s->strips     = 1;
          } else {
 -            s->stripsizes = start + off;
 +            s->stripsizesoff = off;
          }
          s->strips = count;
          s->sstype = type;
  static int decode_frame(AVCodecContext *avctx,
                          void *data, int *got_frame, AVPacket *avpkt)
  {
 -    const uint8_t *buf = avpkt->data;
 -    int buf_size       = avpkt->size;
      TiffContext *const s = avctx->priv_data;
      AVFrame *const p = data;
 -    const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
      unsigned off;
 -    int id, le, ret;
 +    int id, le, ret, plane, planes;
-     int i, j, entries;
-     int stride;
+     int i, j, entries, stride;
      unsigned soff, ssize;
      uint8_t *dst;
 +    GetByteContext stripsizes;
 +    GetByteContext stripdata;
 +
 +    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
  
-     //parse image header
+     // parse image header
 -    if (end_buf - buf < 8)
 +    if (avpkt->size < 8)
          return AVERROR_INVALIDDATA;
-     id = bytestream2_get_le16u(&s->gb);
 -    id   = AV_RL16(buf);
 -    buf += 2;
++    id   = bytestream2_get_le16u(&s->gb);
      if (id == 0x4949)
          le = 1;
      else if (id == 0x4D4D)
          av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
          return AVERROR_INVALIDDATA;
      }
-     s->le = le;
+     s->le         = le;
 +    // TIFF_BPP is not a required tag and defaults to 1
-     s->bppcount = s->bpp = 1;
-     s->invert = 0;
-     s->compr = TIFF_RAW;
++    s->bppcount   = s->bpp = 1;
+     s->invert     = 0;
+     s->compr      = TIFF_RAW;
      s->fill_order = 0;
 +    free_geotags(s);
 +
      // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
      // that further identifies the file as a TIFF file"
 -    if (tget_short(&buf, le) != 42) {
 +    if (tget_short(&s->gb, le) != 42) {
          av_log(avctx, AV_LOG_ERROR,
                 "The answer to life, universe and everything is not correct!\n");
          return AVERROR_INVALIDDATA;
  
      if (s->strips == 1 && !s->stripsize) {
          av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
 -        s->stripsize = buf_size - s->stripoff;
 +        s->stripsize = avpkt->size - s->stripoff;
      }
 -    stride = p->linesize[0];
 -    dst    = p->data[0];
 +
 +    if (s->stripsizesoff) {
 +        if (s->stripsizesoff >= (unsigned)avpkt->size)
 +            return AVERROR_INVALIDDATA;
 +        bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, avpkt->size - s->stripsizesoff);
 +    }
 +    if (s->strippos) {
 +        if (s->strippos >= (unsigned)avpkt->size)
 +            return AVERROR_INVALIDDATA;
 +        bytestream2_init(&stripdata, avpkt->data + s->strippos, avpkt->size - s->strippos);
 +    }
 +
 +    if (s->rps <= 0) {
 +        av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    planes = s->planar ? s->bppcount : 1;
 +    for (plane = 0; plane < planes; plane++) {
 +        stride = p->linesize[plane];
-         dst = p->data[plane];
++        dst    = p->data[plane];
      for (i = 0; i < s->height; i += s->rps) {
 -        if (s->stripsizes) {
 -            if (s->stripsizes >= end_buf)
 -                return AVERROR_INVALIDDATA;
 -            ssize = tget(&s->stripsizes, s->sstype, s->le);
 -        } else
 +        if (s->stripsizesoff)
 +            ssize = tget(&stripsizes, s->sstype, s->le);
 +        else
              ssize = s->stripsize;
  
 -        if (s->stripdata) {
 -            if (s->stripdata >= end_buf)
 -                return AVERROR_INVALIDDATA;
 -            soff = tget(&s->stripdata, s->sot, s->le);
 -        } else
 +        if (s->strippos)
 +            soff = tget(&stripdata, s->sot, s->le);
 +        else
              soff = s->stripoff;
  
 -        if (soff > buf_size || ssize > buf_size - soff) {
 +        if (soff > avpkt->size || ssize > avpkt->size - soff) {
              av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
              return AVERROR_INVALIDDATA;
          }
          dst += s->rps * stride;
      }
      if (s->predictor == 2) {
-         dst = p->data[plane];
-         soff = s->bpp >> 3;
 -        dst   = p->data[0];
++        dst   = p->data[plane];
+         soff  = s->bpp >> 3;
          ssize = s->width * soff;
 -        for (i = 0; i < s->height; i++) {
 -            for (j = soff; j < ssize; j++)
 -                dst[j] += dst[j - soff];
 -            dst += stride;
 +        if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE ||
 +            s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE) {
 +            for (i = 0; i < s->height; i++) {
 +                for (j = soff; j < ssize; j += 2)
 +                    AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
 +                dst += stride;
 +            }
 +        } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
 +                   s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE) {
 +            for (i = 0; i < s->height; i++) {
 +                for (j = soff; j < ssize; j += 2)
 +                    AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
 +                dst += stride;
 +            }
 +        } else {
 +            for (i = 0; i < s->height; i++) {
 +                for (j = soff; j < ssize; j++)
 +                    dst[j] += dst[j - soff];
 +                dst += stride;
 +            }
          }
      }
  
@@@ -39,48 -37,27 +39,48 @@@ enum TiffTags 
      TIFF_HEIGHT,
      TIFF_BPP,
      TIFF_COMPR,
-     TIFF_INVERT = 0x106,
-     TIFF_FILL_ORDER = 0x10A,
-     TIFF_DOCUMENT_NAME = 0x10D,
-     TIFF_IMAGE_DESCRIPTION = 0x10E,
-     TIFF_MAKE = 0x10F,
-     TIFF_MODEL = 0x110,
-     TIFF_STRIP_OFFS = 0x111,
-     TIFF_SAMPLES_PER_PIXEL = 0x115,
-     TIFF_ROWSPERSTRIP = 0x116,
+     TIFF_INVERT             = 0x106,
+     TIFF_FILL_ORDER         = 0x10A,
++    TIFF_DOCUMENT_NAME      = 0x10D,
++    TIFF_IMAGE_DESCRIPTION  = 0x10E,
++    TIFF_MAKE               = 0x10F,
++    TIFF_MODEL              = 0x110,
+     TIFF_STRIP_OFFS         = 0x111,
+     TIFF_SAMPLES_PER_PIXEL  = 0x115,
+     TIFF_ROWSPERSTRIP       = 0x116,
      TIFF_STRIP_SIZE,
-     TIFF_XRES = 0x11A,
-     TIFF_YRES = 0x11B,
-     TIFF_PLANAR = 0x11C,
-     TIFF_PAGE_NAME = 0x11D,
-     TIFF_XPOS = 0x11E,
-     TIFF_YPOS = 0x11F,
-     TIFF_T4OPTIONS = 0x124,
+     TIFF_XRES               = 0x11A,
+     TIFF_YRES               = 0x11B,
+     TIFF_PLANAR             = 0x11C,
++    TIFF_PAGE_NAME          = 0x11D,
+     TIFF_XPOS               = 0x11E,
+     TIFF_YPOS               = 0x11F,
+     TIFF_T4OPTIONS          = 0x124,
      TIFF_T6OPTIONS,
-     TIFF_RES_UNIT = 0x128,
-     TIFF_PAGE_NUMBER = 0x129,
-     TIFF_SOFTWARE_NAME = 0x131,
-     TIFF_DATE = 0x132,
-     TIFF_ARTIST = 0x13B,
-     TIFF_HOST_COMPUTER = 0x13C,
-     TIFF_PREDICTOR = 0x13D,
-     TIFF_PAL = 0x140,
-     TIFF_TILE_WIDTH = 0x142,
-     TIFF_TILE_LENGTH = 0x143,
-     TIFF_TILE_OFFSETS = 0x144,
-     TIFF_TILE_BYTE_COUNTS = 0x145,
-     TIFF_EXTRASAMPLES = 0x152,
+     TIFF_RES_UNIT           = 0x128,
++    TIFF_PAGE_NUMBER        = 0x129,
+     TIFF_SOFTWARE_NAME      = 0x131,
++    TIFF_DATE               = 0x132,
++    TIFF_ARTIST             = 0x13B,
++    TIFF_HOST_COMPUTER      = 0x13C,
+     TIFF_PREDICTOR          = 0x13D,
+     TIFF_PAL                = 0x140,
++    TIFF_TILE_WIDTH         = 0x142,
++    TIFF_TILE_LENGTH        = 0x143,
++    TIFF_TILE_OFFSETS       = 0x144,
++    TIFF_TILE_BYTE_COUNTS   = 0x145,
++    TIFF_EXTRASAMPLES       = 0x152,
      TIFF_YCBCR_COEFFICIENTS = 0x211,
-     TIFF_YCBCR_SUBSAMPLING = 0x212,
-     TIFF_YCBCR_POSITIONING = 0x213,
-     TIFF_REFERENCE_BW = 0x214,
-     TIFF_COPYRIGHT = 0x8298,
-     TIFF_MODEL_TIEPOINT = 0x8482,
-     TIFF_MODEL_PIXEL_SCALE = 0x830E,
-     TIFF_MODEL_TRANSFORMATION = 0x8480,
-     TIFF_GEO_KEY_DIRECTORY = 0x87AF,
-     TIFF_GEO_DOUBLE_PARAMS = 0x87B0,
-     TIFF_GEO_ASCII_PARAMS = 0x87B1
+     TIFF_YCBCR_SUBSAMPLING  = 0x212,
+     TIFF_YCBCR_POSITIONING  = 0x213,
+     TIFF_REFERENCE_BW       = 0x214,
++    TIFF_COPYRIGHT          = 0x8298,
++    TIFF_MODEL_TIEPOINT     = 0x8482,
++    TIFF_MODEL_PIXEL_SCALE  = 0x830E,
++    TIFF_MODEL_TRANSFORMATION= 0x8480,
++    TIFF_GEO_KEY_DIRECTORY  = 0x87AF,
++    TIFF_GEO_DOUBLE_PARAMS  = 0x87B0,
++    TIFF_GEO_ASCII_PARAMS   = 0x87B1
  };
  
  /** list of TIFF compression types */
   * @author Bartlomiej Wolowiec
   */
  
+ #include "config.h"
+ #if CONFIG_ZLIB
+ #include <zlib.h>
+ #endif
 +#include "libavutil/imgutils.h"
  #include "libavutil/log.h"
  #include "libavutil/opt.h"
  #include "libavutil/pixdesc.h"
  #include "avcodec.h"
- #include "config.h"
- #if CONFIG_ZLIB
- #include <zlib.h>
- #endif
  #include "bytestream.h"
- #include "tiff.h"
- #include "rle.h"
 +#include "internal.h"
  #include "lzw.h"
  #include "put_bits.h"
+ #include "rle.h"
+ #include "tiff.h"
  
  #define TIFF_MAX_ENTRY 32
  
@@@ -54,34 -52,25 +54,33 @@@ typedef struct TiffEncoderContext 
      AVCodecContext *avctx;
      AVFrame picture;
  
-     int width;                          ///< picture width
-     int height;                         ///< picture height
-     unsigned int bpp;                   ///< bits per pixel
-     int compr;                          ///< compression level
-     int bpp_tab_size;                   ///< bpp_tab size
-     int photometric_interpretation;     ///< photometric interpretation
-     int strips;                         ///< number of strips
+     int width;                              ///< picture width
+     int height;                             ///< picture height
+     unsigned int bpp;                       ///< bits per pixel
+     int compr;                              ///< compression level
+     int bpp_tab_size;                       ///< bpp_tab size
+     int photometric_interpretation;         ///< photometric interpretation
+     int strips;                             ///< number of strips
 +    uint32_t *strip_sizes;
 +    unsigned int strip_sizes_size;
 +    uint32_t *strip_offsets;
 +    unsigned int strip_offsets_size;
 +    uint8_t *yuv_line;
 +    unsigned int yuv_line_size;
-     int rps;                            ///< row per strip
-     uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
-     int num_entries;                    ///< number of entires
-     uint8_t **buf;                      ///< actual position in buffer
-     uint8_t *buf_start;                 ///< pointer to first byte in buffer
-     int buf_size;                       ///< buffer size
-     uint16_t subsampling[2];            ///< YUV subsampling factors
-     struct LZWEncodeState *lzws;        ///< LZW Encode state
-     uint32_t dpi;                       ///< image resolution in DPI
+     int rps;                                ///< row per strip
+     uint8_t entries[TIFF_MAX_ENTRY * 12];   ///< entries in header
+     int num_entries;                        ///< number of entries
+     uint8_t **buf;                          ///< actual position in buffer
+     uint8_t *buf_start;                     ///< pointer to first byte in buffer
+     int buf_size;                           ///< buffer size
+     uint16_t subsampling[2];                ///< YUV subsampling factors
+     struct LZWEncodeState *lzws;            ///< LZW encode state
++    uint32_t dpi;                           ///< image resolution in DPI
  } TiffEncoderContext;
  
  /**
 - * Check free space in buffer
 + * Check free space in buffer.
 + *
   * @param s Tiff context
   * @param need Needed bytes
   * @return 0 - ok, 1 - no free space
@@@ -97,15 -86,15 +96,15 @@@ static inline int check_size(TiffEncode
  }
  
  /**
 - * Put n values to buffer
 + * Put n values to buffer.
   *
 - * @param p Pointer to pointer to output buffer
 - * @param n Number of values
 - * @param val Pointer to values
 - * @param type Type of values
 - * @param flip =0 - normal copy, >0 - flip
 + * @param p pointer to pointer to output buffer
 + * @param n number of values
 + * @param val pointer to values
 + * @param type type of values
 + * @param flip = 0 - normal copy, >0 - flip
   */
- static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
+ static void tnput(uint8_t **p, int n, const uint8_t *val, enum TiffTypes type,
                    int flip)
  {
      int i;
  
  /**
   * Add entry to directory in tiff header.
 + *
   * @param s Tiff context
 - * @param tag Tag that identifies the entry
 - * @param type Entry type
 - * @param count The number of values
 - * @param ptr_val Pointer to values
 + * @param tag tag that identifies the entry
 + * @param type entry type
 + * @param count the number of values
 + * @param ptr_val pointer to values
   */
- static void add_entry(TiffEncoderContext * s,
-                       enum TiffTags tag, enum TiffTypes type, int count,
-                       const void *ptr_val)
+ static void add_entry(TiffEncoderContext *s, enum TiffTags tag,
+                       enum TiffTypes type, int count, const void *ptr_val)
  {
      uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
  
@@@ -156,19 -144,18 +155,18 @@@ static void add_entry1(TiffEncoderConte
  }
  
  /**
 - * Encode one strip in tiff file
 + * Encode one strip in tiff file.
   *
   * @param s Tiff context
 - * @param src Input buffer
 - * @param dst Output buffer
 - * @param n Size of input buffer
 - * @param compr Compression method
 - * @return Number of output bytes. If an output error is encountered, -1 returned
 + * @param src input buffer
 + * @param dst output buffer
 + * @param n size of input buffer
 + * @param compr compression method
 + * @return number of output bytes. If an output error is encountered, -1 is returned
   */
- static int encode_strip(TiffEncoderContext * s, const int8_t * src,
-                         uint8_t * dst, int n, int compr)
+ static int encode_strip(TiffEncoderContext *s, const int8_t *src,
+                         uint8_t *dst, int n, int compr)
  {
      switch (compr) {
  #if CONFIG_ZLIB
      case TIFF_DEFLATE:
@@@ -200,91 -188,78 +199,91 @@@ static void pack_yuv(TiffEncoderContex
  {
      AVFrame *p = &s->picture;
      int i, j, k;
-     int w = (s->width - 1) / s->subsampling[0] + 1;
+     int w       = (s->width - 1) / s->subsampling[0] + 1;
      uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
      uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
-     if(s->width % s->subsampling[0] || s->height % s->subsampling[1]){
-         for (i = 0; i < w; i++){
 -    for (i = 0; i < w; i++) {
 -        for (j = 0; j < s->subsampling[1]; j++)
 -            for (k = 0; k < s->subsampling[0]; k++)
 -                *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
 -                                    i * s->subsampling[0] + k];
 -        *dst++ = *pu++;
 -        *dst++ = *pv++;
++    if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) {
++        for (i = 0; i < w; i++) {
 +            for (j = 0; j < s->subsampling[1]; j++)
 +                for (k = 0; k < s->subsampling[0]; k++)
 +                    *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
 +                                        FFMIN(i * s->subsampling[0] + k, s->width-1)];
 +            *dst++ = *pu++;
 +            *dst++ = *pv++;
 +        }
 +    }else{
-         for (i = 0; i < w; i++){
++        for (i = 0; i < w; i++) {
 +            for (j = 0; j < s->subsampling[1]; j++)
 +                for (k = 0; k < s->subsampling[0]; k++)
 +                    *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
 +                                        i * s->subsampling[0] + k];
 +            *dst++ = *pu++;
 +            *dst++ = *pv++;
 +        }
      }
  }
  
-     avctx->coded_frame= &s->picture;
 +static av_cold int encode_init(AVCodecContext *avctx)
 +{
 +    TiffEncoderContext *s = avctx->priv_data;
 +
- static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
++    avctx->coded_frame            = &s->picture;
 +    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 +    avctx->coded_frame->key_frame = 1;
 +    s->avctx = avctx;
 +
 +    return 0;
 +}
 +
+ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                          const AVFrame *pict, int *got_packet)
  {
 +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
      TiffEncoderContext *s = avctx->priv_data;
      AVFrame *const p = &s->picture;
      int i;
      uint8_t *ptr;
      uint8_t *offset;
      uint32_t strips;
 -    uint32_t *strip_sizes   = NULL;
 -    uint32_t *strip_offsets = NULL;
      int bytes_per_row;
-     uint32_t res[2] = { s->dpi, 1 };        // image resolution (72/1)
 -    uint32_t res[2]    = { 72, 1 };     // image resolution (72/1)
 -    uint16_t bpp_tab[] = { 8, 8, 8, 8 };
 -    int ret;
 -    int is_yuv = 0;
 -    uint8_t *yuv_line = NULL;
++    uint32_t res[2] = { s->dpi, 1 };    // image resolution (72/1)
 +    uint16_t bpp_tab[4];
 +    int ret = -1;
 +    int is_yuv = 0, alpha = 0;
      int shift_h, shift_v;
 -    const AVPixFmtDescriptor *pfd;
 -
 -    s->avctx = avctx;
  
 -    *p                 = *pict;
 -    p->pict_type       = AV_PICTURE_TYPE_I;
 -    p->key_frame       = 1;
 -    avctx->coded_frame = &s->picture;
 +    *p = *pict;
  
-     s->width = avctx->width;
-     s->height = avctx->height;
+     s->width          = avctx->width;
+     s->height         = avctx->height;
      s->subsampling[0] = 1;
      s->subsampling[1] = 1;
  
-     s->bpp = av_get_bits_per_pixel(desc);
 +    avctx->bits_per_coded_sample =
++    s->bpp          = av_get_bits_per_pixel(desc);
 +    s->bpp_tab_size = desc->nb_components;
 +
      switch (avctx->pix_fmt) {
 +    case AV_PIX_FMT_RGBA64LE:
 +    case AV_PIX_FMT_RGBA:
 +        alpha = 1;
      case AV_PIX_FMT_RGB48LE:
 -    case AV_PIX_FMT_GRAY16LE:
      case AV_PIX_FMT_RGB24:
 -    case AV_PIX_FMT_GRAY8:
 -    case AV_PIX_FMT_PAL8:
 -        pfd    = av_pix_fmt_desc_get(avctx->pix_fmt);
 -        s->bpp = av_get_bits_per_pixel(pfd);
 -        if (pfd->flags & AV_PIX_FMT_FLAG_PAL)
 -            s->photometric_interpretation = 3;
 -        else if (pfd->flags & AV_PIX_FMT_FLAG_RGB)
 -            s->photometric_interpretation = 2;
 -        else
 -            s->photometric_interpretation = 1;
 -        s->bpp_tab_size = pfd->nb_components;
 -        for (i = 0; i < s->bpp_tab_size; i++)
 -            bpp_tab[i] = s->bpp / s->bpp_tab_size;
 +        s->photometric_interpretation = 2;
          break;
 +    case AV_PIX_FMT_GRAY8:
 +        avctx->bits_per_coded_sample = 0x28;
 +    case AV_PIX_FMT_GRAY8A:
 +        alpha = avctx->pix_fmt == AV_PIX_FMT_GRAY8A;
 +    case AV_PIX_FMT_GRAY16LE:
      case AV_PIX_FMT_MONOBLACK:
 -        s->bpp                        = 1;
          s->photometric_interpretation = 1;
 -        s->bpp_tab_size               = 0;
 +        break;
 +    case AV_PIX_FMT_PAL8:
 +        s->photometric_interpretation = 3;
          break;
      case AV_PIX_FMT_MONOWHITE:
 -        s->bpp                        = 1;
          s->photometric_interpretation = 0;
 -        s->bpp_tab_size               = 0;
          break;
      case AV_PIX_FMT_YUV420P:
      case AV_PIX_FMT_YUV422P:
      case AV_PIX_FMT_YUV444P:
      case AV_PIX_FMT_YUV410P:
      case AV_PIX_FMT_YUV411P:
+         av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
          s->photometric_interpretation = 6;
-         avcodec_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
-         s->subsampling[0] = 1 << shift_h;
-         s->subsampling[1] = 1 << shift_v;
-         is_yuv = 1;
 -        s->bpp                        = 8 + (16 >> (shift_h + shift_v));
+         s->subsampling[0]             = 1 << shift_h;
+         s->subsampling[1]             = 1 << shift_v;
 -        s->bpp_tab_size               = 3;
+         is_yuv                        = 1;
          break;
      default:
          av_log(s->avctx, AV_LOG_ERROR,
          return -1;
      }
  
-     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
-         //best choose for DEFLATE
 +    for (i = 0; i < s->bpp_tab_size; i++)
 +        bpp_tab[i] = desc->comp[i].depth_minus1 + 1;
 +
+     if (s->compr == TIFF_DEFLATE       ||
+         s->compr == TIFF_ADOBE_DEFLATE ||
+         s->compr == TIFF_LZW)
+         // best choice for DEFLATE
          s->rps = s->height;
      else
-         s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
-     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
+         // suggest size of strip
+         s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);
+     // round rps up
+     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1];
  
      strips = (s->height - 1) / s->rps + 1;
  
-     if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * s->bpp * 2 +
-                                   avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
 -    if (!pkt->data &&
 -        (ret = av_new_packet(pkt,
++    if ((ret = ff_alloc_packet2(avctx, pkt,
+                              avctx->width * avctx->height * s->bpp * 2 +
 -                             avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
++                             avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
          return ret;
 -    }
      ptr          = pkt->data;
      s->buf_start = pkt->data;
      s->buf       = &ptr;
      offset = ptr;
      bytestream_put_le32(&ptr, 0);
  
-     av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips);
 -    strip_sizes   = av_mallocz(sizeof(*strip_sizes)   * strips);
 -    strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
 -    if (!strip_sizes || !strip_offsets) {
++    av_fast_padded_mallocz(&s->strip_sizes  , &s->strip_sizes_size  , sizeof(s->strip_sizes  [0]) * strips);
 +    av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
 +
 +    if (!s->strip_sizes || !s->strip_offsets) {
          ret = AVERROR(ENOMEM);
          goto fail;
      }
  
-     bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
-                     * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
-     if (is_yuv){
+     bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
+                      s->subsampling[0] * s->subsampling[1] + 7) >> 3;
+     if (is_yuv) {
 -        yuv_line = av_malloc(bytes_per_row);
 -        if (yuv_line == NULL) {
 +        av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
-         if (s->yuv_line == NULL){
++        if (s->yuv_line == NULL) {
              av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
              ret = AVERROR(ENOMEM);
              goto fail;
              ret = AVERROR(ENOMEM);
              goto fail;
          }
 -        strip_offsets[0] = ptr - pkt->data;
 +        s->strip_offsets[0] = ptr - pkt->data;
-         zn = 0;
+         zn               = 0;
          for (j = 0; j < s->rps; j++) {
-             if (is_yuv){
+             if (is_yuv) {
 -                pack_yuv(s, yuv_line, j);
 -                memcpy(zbuf + zn, yuv_line, bytes_per_row);
 +                pack_yuv(s, s->yuv_line, j);
 +                memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
                  j += s->subsampling[1] - 1;
-             }
-             else
+             } else
                  memcpy(zbuf + j * bytes_per_row,
                         p->data[0] + j * p->linesize[0], bytes_per_row);
              zn += bytes_per_row;
              av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
              goto fail;
          }
-         ptr += ret;
+         ptr           += ret;
 -        strip_sizes[0] = ptr - pkt->data - strip_offsets[0];
 +        s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
      } else
  #endif
-         if (s->compr == TIFF_LZW) {
-             s->lzws = av_malloc(ff_lzw_encode_state_size);
-             if (!s->lzws) {
-                 ret = AVERROR(ENOMEM);
-                 goto fail;
-             }
 +    {
+     if (s->compr == TIFF_LZW) {
+         s->lzws = av_malloc(ff_lzw_encode_state_size);
+         if (!s->lzws) {
+             ret = AVERROR(ENOMEM);
+             goto fail;
          }
-         for (i = 0; i < s->height; i++) {
-             if (s->strip_sizes[i / s->rps] == 0) {
-                 if(s->compr == TIFF_LZW){
-                     ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
-                                        12, FF_LZW_TIFF, put_bits);
-                 }
-                 s->strip_offsets[i / s->rps] = ptr - pkt->data;
-             }
-             if (is_yuv){
-                  pack_yuv(s, s->yuv_line, i);
-                  ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
-                  i += s->subsampling[1] - 1;
-             }
-             else
-                 ret = encode_strip(s, p->data[0] + i * p->linesize[0],
-                         ptr, bytes_per_row, s->compr);
-             if (ret < 0) {
-                 av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
-                 goto fail;
-             }
-             s->strip_sizes[i / s->rps] += ret;
-             ptr += ret;
-             if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
-                 ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
-                 s->strip_sizes[(i / s->rps )] += ret ;
-                 ptr += ret;
+     }
+     for (i = 0; i < s->height; i++) {
 -        if (strip_sizes[i / s->rps] == 0) {
++        if (s->strip_sizes[i / s->rps] == 0) {
+             if (s->compr == TIFF_LZW) {
+                 ff_lzw_encode_init(s->lzws, ptr,
+                                    s->buf_size - (*s->buf - s->buf_start),
+                                    12, FF_LZW_TIFF, put_bits);
              }
 -            strip_offsets[i / s->rps] = ptr - pkt->data;
++            s->strip_offsets[i / s->rps] = ptr - pkt->data;
+         }
+         if (is_yuv) {
 -            pack_yuv(s, yuv_line, i);
 -            ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
++            pack_yuv(s, s->yuv_line, i);
++            ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
+             i  += s->subsampling[1] - 1;
+         } else
+             ret = encode_strip(s, p->data[0] + i * p->linesize[0],
+                                ptr, bytes_per_row, s->compr);
+         if (ret < 0) {
+             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
+             goto fail;
          }
-         if(s->compr == TIFF_LZW)
-             av_free(s->lzws);
 -        strip_sizes[i / s->rps] += ret;
++        s->strip_sizes[i / s->rps] += ret;
+         ptr                     += ret;
+         if (s->compr == TIFF_LZW &&
+             (i == s->height - 1 || i % s->rps == s->rps - 1)) {
+             ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
 -            strip_sizes[(i / s->rps)] += ret;
 -            ptr                       += ret;
++            s->strip_sizes[(i / s->rps)] += ret;
++            ptr                          += ret;
+         }
+     }
+     if (s->compr == TIFF_LZW)
+         av_free(s->lzws);
 +    }
  
      s->num_entries = 0;
  
-     add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);
-     add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);
-     add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);
+     add_entry1(s, TIFF_SUBFILE, TIFF_LONG, 0);
+     add_entry1(s, TIFF_WIDTH,   TIFF_LONG, s->width);
+     add_entry1(s, TIFF_HEIGHT,  TIFF_LONG, s->height);
  
      if (s->bpp_tab_size)
-     add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
+         add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab);
  
-     add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
-     add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
-     add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, s->strip_offsets);
+     add_entry1(s, TIFF_COMPR,      TIFF_SHORT, s->compr);
+     add_entry1(s, TIFF_INVERT,     TIFF_SHORT, s->photometric_interpretation);
 -    add_entry(s,  TIFF_STRIP_OFFS, TIFF_LONG,  strips, strip_offsets);
++    add_entry(s,  TIFF_STRIP_OFFS, TIFF_LONG,  strips, s->strip_offsets);
  
      if (s->bpp_tab_size)
-     add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
+         add_entry1(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
  
-     add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
-     add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, s->strip_sizes);
-     add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
-     add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
-     add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
+     add_entry1(s, TIFF_ROWSPERSTRIP, TIFF_LONG,     s->rps);
 -    add_entry(s,  TIFF_STRIP_SIZE,   TIFF_LONG,     strips, strip_sizes);
++    add_entry(s,  TIFF_STRIP_SIZE,   TIFF_LONG,     strips, s->strip_sizes);
+     add_entry(s,  TIFF_XRES,         TIFF_RATIONAL, 1,      res);
+     add_entry(s,  TIFF_YRES,         TIFF_RATIONAL, 1,      res);
+     add_entry1(s, TIFF_RES_UNIT,     TIFF_SHORT,    2);
  
-     if(!(avctx->flags & CODEC_FLAG_BITEXACT))
-     add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
-               strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
+     if (!(avctx->flags & CODEC_FLAG_BITEXACT))
+         add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING,
+                   strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
  
      if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
          uint16_t pal[256 * 3];
          }
          add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
      }
-     if (is_yuv){
 +    if (alpha)
 +        add_entry1(s,TIFF_EXTRASAMPLES,      TIFF_SHORT,            2);
+     if (is_yuv) {
          /** according to CCIR Recommendation 601.1 */
-         uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
+         uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
          add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
 +        if (avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)
 +            add_entry1(s, TIFF_YCBCR_POSITIONING, TIFF_SHORT, 2);
          add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
      }
-     bytestream_put_le32(&offset, ptr - pkt->data);    // write offset to dir
+     // write offset to dir
+     bytestream_put_le32(&offset, ptr - pkt->data);
  
      if (check_size(s, 6 + s->num_entries * 12)) {
          ret = AVERROR(EINVAL);
@@@ -506,13 -473,12 +511,13 @@@ static av_cold int encode_close(AVCodec
  #define OFFSET(x) offsetof(TiffEncoderContext, x)
  #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  static const AVOption options[] = {
-     { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
-     { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
-     { "raw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW},      0, 0, VE, "compression_algo" },
-     { "lzw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_LZW},      0, 0, VE, "compression_algo" },
 +    {"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},
+     { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT,   { .i64 = TIFF_PACKBITS }, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
+     { "packbits",         NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_PACKBITS }, 0,        0,            VE, "compression_algo" },
+     { "raw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_RAW      }, 0,        0,            VE, "compression_algo" },
+     { "lzw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_LZW      }, 0,        0,            VE, "compression_algo" },
  #if CONFIG_ZLIB
-     { "deflate",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_DEFLATE},  0, 0, VE, "compression_algo" },
+     { "deflate",          NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_DEFLATE  }, 0,        0,            VE, "compression_algo" },
  #endif
      { NULL },
  };
@@@ -529,18 -496,14 +535,17 @@@ AVCodec ff_tiff_encoder = 
      .type           = AVMEDIA_TYPE_VIDEO,
      .id             = AV_CODEC_ID_TIFF,
      .priv_data_size = sizeof(TiffEncoderContext),
 +    .init           = encode_init,
      .encode2        = encode_frame,
 +    .close          = encode_close,
      .pix_fmts       = (const enum AVPixelFormat[]) {
 -        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_PAL8,
 -        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16LE,
 +        AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
 +        AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE,
          AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_MONOWHITE,
 -        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
 -        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
 +        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
 +        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_RGB48LE,
 +        AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
          AV_PIX_FMT_NONE
      },
-     .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
      .priv_class     = &tiffenc_class,
  };