func: static int decode_frame(AVCodecContext void *data, int *got_frame, AVPacket *avpkt) TiffContext * const s = avctx -> AVFrame * const p = ThreadFrame frame = . f = data unsigned off ; int le , ret , plane , planes ; int i , j , entries , stride ; if ( ret = ff_tdecode_header ( & s -> gb , & le , & off ) )  if ( off >= UINT_MAX - 14 || avpkt -> size < off + 14 )  s -> le = le; s -> bppcount = s -> bpp = 1; s -> photometric = TIFF_PHOTOMETRIC_NONE; s -> compr = TIFF_RAW; s -> fill_order = 0; s -> stripsizesoff = s -> strippos = 0; entries = ff_tget_short ( & s -> gb , le ); if ( bytestream2_get_bytes_left ( & s -> gb ) < entries * 12 )  for (i = 0; i < entries; i++) if ( ( ret = tiff_decode_tag ( s , p ) ) < 0 )  static int tiff_decode_tag(TiffContext *s, AVFrame *frame) unsigned tag , type , count , off , value = 0 , value2 = 0 ; int i , start ; int ret ; double * dp ; ret = ff_tread_tag ( & s -> gb , s -> le , & tag , & type , & count , & start ); if ( ret < 0 )  off = bytestream2_tell ( & s -> gb ); if ( count == 1 )  switch ( type )  value = ff_tget ( & s -> gb , type , s -> le ); value = ff_tget ( & s -> gb , TIFF_LONG , s -> le ); if ( count <= 4 )  value = UINT_MAX; switch ( tag )  s -> width = value; s -> height = value; if ( count > 4U )  return AVERROR_INVALIDDATA ; s -> bppcount = count; if ( count == 1 )  s -> bpp = value; switch ( type )  s -> bpp = 0; if ( bytestream2_get_bytes_left ( & s -> gb ) < type_sizes [ type ] * count )  return AVERROR_INVALIDDATA ; for (i = 0; i < count; i++) s -> bpp += ff_tget ( & s -> gb , type , s -> le ); s -> bpp = - 1; if ( count != 1 )  return AVERROR_INVALIDDATA ; if ( value > 4U )  return AVERROR_INVALIDDATA ; if ( s -> bppcount == 1 )  s -> bpp *= value; s -> bppcount = value; s -> compr = value; s -> predictor = 0; switch ( s -> compr )  s -> fax_opts = 0; return AVERROR_PATCHWELCOME ; return AVERROR_INVALIDDATA ; if ( ! value || ( type == TIFF_LONG && value == UINT_MAX ) )  value = s -> height; s -> rps = FFMIN ( value , s -> height ); if ( count == 1 )  s -> strippos = off; s -> strips = count; if ( s -> strips == 1 )  s -> rps = s -> height; s -> sot = type; if ( count == 1 )  s -> stripsizesoff = off; s -> strips = count; s -> sstype = type; return AVERROR_PATCHWELCOME ; s -> predictor = value; switch ( value )  s -> photometric = value; return AVERROR_PATCHWELCOME ; return AVERROR_INVALIDDATA ; if ( value < 1 || value > 2 )  value = 1; s -> fill_order = value - 1; GetByteContext pal_gb [ 3 ] ; off = type_sizes [ type ]; if ( count / 3 > 256 || bytestream2_get_bytes_left ( & s -> gb ) < count / 3 * off * 3 )  return AVERROR_INVALIDDATA ; pal_gb [ 0 ] = pal_gb [ 1 ] = pal_gb [ 2 ] = s -> gb; off = ( type_sizes [ type ] - 1 ) << 3; for (i = 0; i < count / 3; i++) uint32_t p = 0xFF000000 ; p |= ( ff_tget ( & pal_gb [ 0 ] , type , s -> le ) >> off ) << 16; p |= ( ff_tget ( & pal_gb [ 1 ] , type , s -> le ) >> off ) << 8; p |= ff_tget ( & pal_gb [ 2 ] , type , s -> le ) >> off; s -> palette [ i ] = p; s -> palette_is_set = 1; s -> planar = value == 2; if ( count != 2 )  return AVERROR_INVALIDDATA ; for (i = 0; i < count; i++) s -> subsampling [ i ] = ff_tget ( & s -> gb , type , s -> le ); if ( s -> compr == TIFF_G3 )  s -> fax_opts = value; if ( s -> compr == TIFF_G4 )  s -> fax_opts = value; s -> geotag_count = ff_tget_short ( & s -> gb , s -> le ); if ( s -> geotag_count > count / 4 - 1 )  s -> geotag_count = count / 4 - 1; if ( bytestream2_get_bytes_left ( & s -> gb ) < s -> geotag_count * sizeof ( int16_t ) * 4 )  s -> geotag_count = 0; return - 1 ; s -> geotags = av_mallocz_array ( s -> geotag_count , sizeof ( TiffGeoTag ) ); if ( ! s -> geotags )  s -> geotag_count = 0; for (i = 0; i < s->geotag_count; i++) s -> geotags [ i ] . key = ff_tget_short ( & s -> gb , s -> le ); s -> geotags [ i ] . type = ff_tget_short ( & s -> gb , s -> le ); s -> geotags [ i ] . count = ff_tget_short ( & s -> gb , s -> le ); if ( ! s -> geotags [ i ] . type )  s -> geotags [ i ] . val = get_geokey_val ( s -> geotags [ i ] . key , ff_tget_short ( & s -> gb , s -> le ) ); static char *get_geokey_val(int key, int val) char * ap ; if ( val == TIFF_GEO_KEY_UNDEFINED )  return av_strdup ( "undefined" ) ; if ( val == TIFF_GEO_KEY_USER_DEFINED )  return av_strdup ( "User-Defined" ) ; switch ( key )  ap = av_strdup ( search_keyval ( ff_tiff_proj_cs_type_codes , FF_ARRAY_ELEMS ( ff_tiff_proj_cs_type_codes ) , val ) ); static const char *search_keyval(const TiffGeoTagKeyName *keys, int n, int id) TiffGeoTagKeyName * r = bsearch ( & id , keys , n , sizeof ( keys [ 0 ] ) , cmp_id_key ) ; if ( r )  return r -> name ; return NULL ; if ( ap )  return ap ; ap = av_strdup ( search_keyval ( ff_tiff_projection_codes , FF_ARRAY_ELEMS ( ff_tiff_projection_codes ) , val ) ); static const char *search_keyval(const TiffGeoTagKeyName *keys, int n, int id) TiffGeoTagKeyName * r = bsearch ( & id , keys , n , sizeof ( keys [ 0 ] ) , cmp_id_key ) ; if ( r )  return r -> name ; return NULL ; if ( ap )  return ap ; ap = av_malloc ( 14 ); if ( ap )  snprintf ( ap , 14 , "Unknown-%d" , val ); return ap ; s -> geotags [ i ] . offset = ff_tget_short ( & s -> gb , s -> le ); if ( count >= INT_MAX / sizeof ( int64_t ) )  return AVERROR_INVALIDDATA ; if ( bytestream2_get_bytes_left ( & s -> gb ) < count * sizeof ( int64_t ) )  return AVERROR_INVALIDDATA ; dp = av_malloc_array ( count , sizeof ( double ) ); if ( ! dp )  for (i = 0; i < count; i++) dp [ i ] = ff_tget_double ( & s -> gb , s -> le ); for (i = 0; i < s->geotag_count; i++) if ( s -> geotags [ i ] . type == TIFF_GEO_DOUBLE_PARAMS )  if ( s -> geotags [ i ] . count == 0 || s -> geotags [ i ] . offset + s -> geotags [ i ] . count > count )  char * ap = doubles2str ( & dp [ s -> geotags [ i ] . offset ] , s -> geotags [ i ] . count , ", " ) ; static char *doubles2str(double *dp, int count, const char *sep) int i ; char * ap , * ap0 ; uint64_t component_len ; if ( ! sep )  sep = ", "; component_len = 24L L + strlen ( sep ) if ( count >= ( INT_MAX - 1 ) / component_len )  return NULL ; ap = av_malloc ( component_len * count + 1 ); if ( ! ap )  return NULL ; ap0 = ap; ap [ 0 ] = '\0'; for (i = 0; i < count; i++) unsigned l = snprintf ( ap , component_len , "%.15g%s" , dp [ i ] , sep ) ; if ( l >= component_len )  return NULL ; ap += l; ap0 [ strlen ( ap0 ) - strlen ( sep ) ] = '\0'; return ap0 ; if ( ! ap )  return AVERROR ( ENOMEM ) ; s -> geotags [ i ] . val = ap; for (i = 0; i < s->geotag_count; i++) if ( s -> geotags [ i ] . type == TIFF_GEO_ASCII_PARAMS )  if ( s -> geotags [ i ] . count == 0 || s -> geotags [ i ] . offset + s -> geotags [ i ] . count > count )  char * ap ; if ( bytestream2_get_bytes_left ( & s -> gb ) < s -> geotags [ i ] . count )  return AVERROR_INVALIDDATA ; ap = av_malloc ( s -> geotags [ i ] . count ); if ( ! ap )  return AVERROR ( ENOMEM ) ; ap [ s -> geotags [ i ] . count - 1 ] = '\0'; s -> geotags [ i ] . val = ap; if ( s -> avctx -> err_recognition & AV_EF_EXPLODE )  return AVERROR_INVALIDDATA ; if ( s -> bpp > 64U )  return AVERROR_INVALIDDATA ; return 0 ; for (i = 0; i<s->geotag_count; i++) const char * keyname = get_geokey_name ( s -> geotags [ i ] . key ) ; static const char *get_geokey_name(int key) return NULL ; if ( ! keyname )  if ( get_geokey_type ( s -> geotags [ i ] . key ) != s -> geotags [ i ] . type )  static int get_geokey_type(int key) return AVERROR_INVALIDDATA ; ret = av_dict_set ( avpriv_frame_get_metadatap ( p ) , keyname , s -> geotags [ i ] . val , 0 ); if ( ret < 0 )  if ( ! s -> strippos && ! s -> stripoff )  if ( ( ret = init_image ( s , & frame ) ) < 0 )  static int init_image(TiffContext *s, ThreadFrame *frame) int ret ; int create_gray_palette = 0 ; if ( s -> bpp >= 100 || s -> bppcount >= 10 )  switch ( s -> planar * 1000 + s -> bpp * 10 + s -> bppcount )  if ( ! s -> palette_is_set )  s -> avctx -> pix_fmt = AV_PIX_FMT_MONOBLACK; s -> avctx -> pix_fmt = AV_PIX_FMT_PAL8; if ( ! s -> palette_is_set )  create_gray_palette = 1; s -> avctx -> pix_fmt = s -> palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8; if ( s -> photometric == TIFF_PHOTOMETRIC_YCBCR )  if ( s -> subsampling [ 0 ] == 1 && s -> subsampling [ 1 ] == 1 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV444P; if ( s -> subsampling [ 0 ] == 2 && s -> subsampling [ 1 ] == 1 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV422P; if ( s -> subsampling [ 0 ] == 4 && s -> subsampling [ 1 ] == 1 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV411P; if ( s -> subsampling [ 0 ] == 1 && s -> subsampling [ 1 ] == 2 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV440P; if ( s -> subsampling [ 0 ] == 2 && s -> subsampling [ 1 ] == 2 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV420P; if ( s -> subsampling [ 0 ] == 4 && s -> subsampling [ 1 ] == 4 )  s -> avctx -> pix_fmt = AV_PIX_FMT_YUV410P; s -> avctx -> pix_fmt = AV_PIX_FMT_RGB24; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE; s -> avctx -> pix_fmt = AV_PIX_FMT_YA8; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE; s -> avctx -> pix_fmt = AV_PIX_FMT_RGBA; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE; s -> avctx -> pix_fmt = AV_PIX_FMT_GBRP; s -> avctx -> pix_fmt = AV_PIX_FMT_GBRAP; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE; s -> avctx -> pix_fmt = s -> le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE; if ( s -> photometric == TIFF_PHOTOMETRIC_YCBCR )  const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get ( s -> avctx -> pix_fmt ) ; if ( ( desc -> flags & AV_PIX_FMT_FLAG_RGB ) || ! ( desc -> flags & AV_PIX_FMT_FLAG_PLANAR ) || desc -> nb_components < 3 )  if ( s -> width != s -> avctx -> width || s -> height != s -> avctx -> height )  ret = ff_set_dimensions ( s -> avctx , s -> width , s -> height ); if ( ret < 0 )  if ( ( ret = ff_thread_get_buffer ( s -> avctx , frame , 0 ) ) < 0 )  if ( s -> avctx -> pix_fmt == AV_PIX_FMT_PAL8 )  if ( ! create_gray_palette )  memcpy ( frame -> f -> data [ 1 ] , s -> palette , sizeof ( s -> palette ) ); 