Saucexages v0.2.0 Saucexages.MediaInfo View Source

This module is used to provide facilities for working with type information described in the SAUCE spec. Typically, this consists at a minimum of a data type, possibly combined with a file type. The combination of the two together comprise the actual information type the SAUCE data is representing.

This module uses the concept of a media_type_id atom to abstract and simplify the underlying media types. This allows a simple, compact, and human-readable representation when working with SAUCE information. media_type_id can be further used to decode and understand any type dependent fields within a SAUCE record.

The type dependent fields include the following as describe by the SAUCE spec that may vary in meaning across media types:

  • t_info_1
  • t_info_2
  • t_info_3
  • t_info_4
  • t_flags
  • t_info_s

Additionally, this module provides a number of convenience wrappers and tools for interrogating SAUCE information, fields, and related info. If you are building any sort of UI, behavior, or module that relies on type-specific field information (ex: aspect ratio, number of lines, etc.) then you should carefully scan the functions available in this module as most typical use-cases are considered.

Use-Cases

This module provides many functions to support the type dependent fields in SAUCE records.

Some basic use-cases include:

  • Getting domain-specific names of SAUCE record values such as character_width, pixel_height, and ansi_flags among many others.
  • Reading and writing fields based on type-specific information, for example fields that are required or specific to that type
  • Extracting font, flags, colors, and other specific information, particularly in the case of character types such as ANSi art.
  • Selecting the appropriate types based on actual file type/mime type/metadata
  • Validating type information to avoid reading or writing invalid data for encoding/decoding SAUCE data

Notes

There is a very nasty edge-case in which file_type may be used to store data. According to the spec, this is only the case for the data type - binary text. As such, this module wraps this edge-case while handling all other data types cleanly as possible. Note that due to this edge-case, it is not possible to assume the media_type_id is redundant with file_type. As such, the file_type data is fully represented as a separate field to avoid data truncation or corruption.

Link to this section Summary

Functions

Returns a map consisting of only basic info about the given media_type_id

Extracts the integer data type from a given media_type_id

Extracts the data_type_id associated for a known media_type_id

Returns a detailed map of any media info that can be converted per-file type, along with basic file type information

Returns the field name associated with a given file type and file type field

Returns the file_type associated with the given media_type_id

Lists all known file type ids per the given data_type_id or data_type

Returns a detailed map of any media info that can be converted per-file type. Only the detailed information is returned

Lists all meta information about file types

Lists all the meta information about the given media_type_id

Returns the media_type_id associated with the given file_type integer value and data_type_id or data_type

Returns the media_type_id associated with the given file_type integer value and data_type_id or data_type

Checks if the combination of ‘file_type’ and ‘data_type’ corresponds to a valid, known file type

Checks if the combination of ‘file_type’ and ‘data_type’ corresponds to a valid, known file type

Lists all known file types

Lists all known file type ids per the given data_type_id or data_type

Creates a new MediaInfo based on the given file_type and data_type

Reads data dynamically for a given file type based on its meta information and converts the data if possible

Reads the fields given in the field_ids list dynamically and returns data based on file type information, converting data when possible. The field ids may be any field that is part of a MediaInfo. A new map will be returned with any valid fields converted accordingly

Reads data dynamically for a given file info map based on its meta information and converts the data if possible

Returns a mapped version of the t_flags field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_flags field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_1 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_1 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_2 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_2 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_3 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_3 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_4 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_4 field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_s field as a tuple containing the field type as the first element and the field value as the second element

Returns a mapped version of the t_info_s field as a tuple containing the field type as the first element and the field value as the second element

Returns a keyword list of all the type dependent fields for a given file type

Returns a list of all field names used by a given file type

Lists all dynamic file type fields that can be found in a SAUCE record

Lists all dynamic file type fields that can be found in a SAUCE record for the given media_type_id

Lists all dynamic file type fields that can be found in a SAUCE record for the given file_type and data_type

Returns a tuple of file_type and data_type associated with the given media_type_id to be used with SAUCE data directly, for example writing a SAUCE

Link to this section Types

Link to this type media_type_id() View Source
media_type_id() ::
  :none
  | :ascii
  | :ansi
  | :ansimation
  | :rip
  | :pcboard
  | :avatar
  | :html
  | :source
  | :tundra_draw
  | :gif
  | :pcx
  | :lmb_iff
  | :tga
  | :fli
  | :flc
  | :bmp
  | :gl
  | :dl
  | :wpg_bitmap
  | :png
  | :jpg
  | :mpg
  | :avi
  | :dxf
  | :dwg
  | :wpg_vector
  | :"3ds"
  | :mod
  | :"669"
  | :stm
  | :s3m
  | :mtm
  | :far
  | :ult
  | :amf
  | :dmf
  | :okt
  | :rol
  | :cmf
  | :mid
  | :sadt
  | :voc
  | :wav
  | :smp8
  | :smp8s
  | :smp16
  | :smp16s
  | :patch8
  | :patch16
  | :xm
  | :hsc
  | :it
  | :binary_text
  | :xbin
  | :zip
  | :arj
  | :lzh
  | :arc
  | :tar
  | :zoo
  | :rar
  | :uc2
  | :pak
  | :sqz
  | :executable
Link to this type t() View Source
t() :: %Saucexages.MediaInfo{
  data_type: non_neg_integer(),
  file_size: non_neg_integer(),
  file_type: file_type(),
  t_flags: non_neg_integer(),
  t_info_1: non_neg_integer(),
  t_info_2: non_neg_integer(),
  t_info_3: non_neg_integer(),
  t_info_4: non_neg_integer(),
  t_info_s: String.t()
}

Link to this section Functions

Link to this function basic_info(file_type) View Source
basic_info(t()) :: map()
basic_info(media_type_id()) :: map()

Returns a map consisting of only basic info about the given media_type_id.

The following keys are always returned:

  • media_type_id - The unique identifier for a file type.
  • data_type_id - The unique identifier for a data type.
  • name - The friendly name for a file type.

Examples

iex> Saucexages.MediaInfo.basic_info(:ansi)
%{data_type_id: :character, media_type_id: :ansi, name: "ANSi"}

iex> Saucexages.MediaInfo.basic_info(:png)
%{data_type_id: :bitmap, media_type_id: :png, name: "PNG"}

iex> Saucexages.MediaInfo.basic_info(:binary_text)
%{data_type_id: :binary_text, media_type_id: :binary_text, name: "Binary Text"}

Extracts the integer data type from a given media_type_id.

Examples

iex> Saucexages.MediaInfo.data_type(:ansi)
1

iex> Saucexages.MediaInfo.data_type(:gif)
2

iex> Saucexages.MediaInfo.data_type(:chicken_salad)
0

Extracts the data_type_id associated for a known media_type_id.

If the file type or data type is unknown, :none is returned.

Examples

iex> Saucexages.MediaInfo.data_type_id(:ansi)
:character

iex> Saucexages.MediaInfo.data_type_id(:mod)
:audio

iex> Saucexages.MediaInfo.data_type_id(:fried_chicken)
:none
Link to this function details(media_info) View Source
details(t()) :: map()

Returns a detailed map of any media info that can be converted per-file type, along with basic file type information.

Useful for editors or specialized processing.

Any type-specific fields that have special meaning will be converted accordingly. Type-specific fields without meaning will be left as is to account for cases when developers, apps, users, etc. have added this data contrary to the SAUCE spec.

Examples

iex> Saucexages.MediaInfo.details(%Saucexages.MediaInfo{file_type: 1, data_type: 1, t_flags: 17, t_info_1: 80, t_info_2: 250, t_info_s: "IBM VGA"})
%{
  ansi_flags: %Saucexages.AnsiFlags{
    aspect_ratio: :modern,
    letter_spacing: :none,
    non_blink_mode?: true
  },
  character_width: 80,
  data_type: 1,
  data_type_id: :character,
  file_size: 0,
  file_type: 1,
  media_type_id: :ansi,
  font_id: :ibm_vga,
  name: "ANSi",
  number_of_lines: 250,
  t_info_3: 0,
  t_info_4: 0
}
Link to this function field_type(media_type_id, field_type_id) View Source
field_type(media_type_id(), atom()) :: atom()

Returns the field name associated with a given file type and file type field.

Examples

iex> Saucexages.MediaInfo.field_type(:ansi, :t_info_s)
:font_id

iex> Saucexages.MediaInfo.field_type(:ansi, :t_flags)
:ansi_flags
Link to this function file_type(media_type_id) View Source
file_type(media_type_id()) :: file_type()

Returns the file_type associated with the given media_type_id.

Examples

iex> Saucexages.MediaInfo.file_type(:ansi)
1

iex> Saucexages.MediaInfo.file_type(:png)
10
Link to this macro file_types_for(data_type) View Source (macro)

Lists all known file type ids per the given data_type_id or data_type.

For file types that don’t exist for a given data type, ex: binary_text, an empty list will be returned.

Examples

iex> Saucexages.MediaInfo.file_types_for(:character)
[0, 1, 2, 3, 4, 5, 6, 7, 8]

iex> Saucexages.MediaInfo.file_types_for(1)
[0, 1, 2, 3, 4, 5, 6, 7, 8]


iex> Saucexages.MediaInfo.file_types_for(:binary_text)
[]
Link to this function media_details(media_info) View Source
media_details(t()) :: map()

Returns a detailed map of any media info that can be converted per-file type. Only the detailed information is returned.

Useful for editors or specialized processing.

Examples

iex> Saucexages.MediaInfo.media_details(%Saucexages.MediaInfo{file_type: 1, data_type: 1, t_flags: 17, t_info_1: 80, t_info_2: 250, t_info_s: "IBM VGA"})
%{
  ansi_flags: %Saucexages.AnsiFlags{
    aspect_ratio: :modern,
    letter_spacing: :none,
    non_blink_mode?: true
  },
  character_width: 80,
  data_type: 1,
  file_size: 0,
  file_type: 1,
  font_id: :ibm_vga,
  number_of_lines: 250,
  t_info_3: 0,
  t_info_4: 0
}
Link to this macro media_meta() View Source (macro)
media_meta() :: [Saucexages.MediaInfoMeta.t()]

Lists all meta information about file types.

Useful for building interfaces, specialized parsing, and dynamic access.

Link to this function media_meta_by(media_type_id) View Source
media_meta_by(media_type_id()) :: Saucexages.MediaInfoMeta.t() | nil

Lists all the meta information about the given media_type_id.

Examples

iex> Saucexages.MediaInfo.media_meta_by(:ansi)
%Saucexages.MediaInfoMeta{
  data_type_id: :character,
  file_type: 1,
  media_type_id: :ansi,
  name: "ANSi",
  t_flags: :ansi_flags,
  t_info_1: :character_width,
  t_info_2: :number_of_lines,
  t_info_3: nil,
  t_info_4: nil,
  t_info_s: :font_id
}
Link to this function media_type_id(map) View Source
media_type_id(t()) :: media_type_id()

Returns the media_type_id associated with the given file_type integer value and data_type_id or data_type.

Examples

iex> Saucexages.MediaInfo.new(1, 1) |> Saucexages.MediaInfo.media_type_id()
:ansi

iex> Saucexages.MediaInfo.new(10, 2) |> Saucexages.MediaInfo.media_type_id()
:png

iex> Saucexages.MediaInfo.new(27, :binary_text) |> Saucexages.MediaInfo.media_type_id()
:binary_text

Returns the media_type_id associated with the given file_type integer value and data_type_id or data_type.

Examples

iex> Saucexages.MediaInfo.media_type_id(1, :character)
:ansi

iex> Saucexages.MediaInfo.media_type_id(10, :bitmap)
:png

iex> Saucexages.MediaInfo.media_type_id(10, 2)
:png
Link to this function media_type_id?(media_info) View Source
media_type_id?(t()) :: boolean()

Checks if the combination of ‘file_type’ and ‘data_type’ corresponds to a valid, known file type.

Examples

iex> Saucexages.MediaInfo.new(1, 1) |> Saucexages.MediaInfo.media_type_id?()
true

iex> Saucexages.MediaInfo.new(999, 5) |> Saucexages.MediaInfo.media_type_id?()
true

iex> Saucexages.MediaInfo.new(999, 1) |> Saucexages.MediaInfo.media_type_id?()
false
Link to this function media_type_id?(file_type, data_type) View Source
media_type_id?(file_type(), Saucexages.DataType.data_type()) :: boolean()

Checks if the combination of ‘file_type’ and ‘data_type’ corresponds to a valid, known file type.

Examples

iex> Saucexages.MediaInfo.media_type_id?(1, 1)
true
iex> Saucexages.MediaInfo.media_type_id?(999, 999)
false
iex> Saucexages.MediaInfo.media_type_id?(999, 5)
true
iex> Saucexages.MediaInfo.media_type_id?(-1, 5)
false
Link to this macro media_type_ids() View Source (macro)
media_type_ids() :: [media_type_id()]

Lists all known file types.

Link to this macro media_type_ids_for(data_type) View Source (macro)

Lists all known file type ids per the given data_type_id or data_type.

Examples

iex> Saucexages.MediaInfo.media_type_ids_for(:character)
[:ascii, :ansi, :ansimation, :rip, :pcboard, :avatar, :html, :source, :tundra_draw]

iex> Saucexages.MediaInfo.media_type_ids_for(1)
[:ascii, :ansi, :ansimation, :rip, :pcboard, :avatar, :html, :source, :tundra_draw]
Link to this function new(file_type, data_type, opts \\ []) View Source

Creates a new MediaInfo based on the given file_type and data_type.

Link to this function read_field(media_type_id, field_type_id, value, conversion_fn \\ &read_field_value/3) View Source
read_field(media_type_id(), atom(), term(), function()) :: {atom(), term()}

Reads data dynamically for a given file type based on its meta information and converts the data if possible.

Returns a 2-tuple containing the new field id (if any) as the first element, and the field data (if any) as the second element.

Optionally, a 3-arity conversion function that takes the same parameters, media_type_id, field_type_id, and value may be passed for custom conversions.

Examples

iex> Saucexages.MediaInfo.read_field(:ansi, :t_flags, 17)
{:ansi_flags, %Saucexages.AnsiFlags{aspect_ratio: :modern, letter_spacing: :none, non_blink_mode?: true}}

iex> Saucexages.MediaInfo.read_field(:png, :t_info_1, 640)
{:pixel_width, 640}
Link to this function read_fields(media_info, field_ids, conversion_fn \\ &read_field_value/3) View Source

Reads the fields given in the field_ids list dynamically and returns data based on file type information, converting data when possible. The field ids may be any field that is part of a MediaInfo. A new map will be returned with any valid fields converted accordingly.

Unknown field ids will be ignored.

Optionally, a 3-arity conversion function that takes the same parameters, media_type_id, field_type_id, and value may be passed for custom conversions.

Examples

iex> Saucexages.MediaInfo.read_fields(%Saucexages.MediaInfo{file_type: 1, data_type: 1, t_flags: 17, t_info_1: 80, t_info_2: 250, t_info_s: "IBM VGA"}, [:t_info_s, :t_info_1,  :t_info_2])
%{character_width: 80, font_id: :ibm_vga, number_of_lines: 250}

iex> Saucexages.MediaInfo.read_fields(%Saucexages.MediaInfo{file_type: 1, data_type: 1, t_flags: 17, t_info_1: 80, t_info_2: 250, t_info_s: "IBM VGA"}, [:t_info_s, :cheese, :data_type])
%{font_id: :ibm_vga, data_type: 1}
Link to this function read_media_field(media_info, field_type_id, default_value \\ nil, conversion_fn \\ &read_field_value/3) View Source
read_media_field(t(), atom(), term(), function()) :: {atom(), term()}

Reads data dynamically for a given file info map based on its meta information and converts the data if possible.

Returns a 2-tuple containing the new field id (if any) as the first element, and the field data (if any) as the second element.

If the value does not exist in the map, you may pass a default_value to be used in these cases.

Optionally, a 3-arity conversion function that takes the same parameters, media_type_id, field_type_id, and value may be passed for custom conversions.

Examples

iex> Saucexages.MediaInfo.read_media_field(%{file_type: 1, data_type: 1, t_flags: 17}, :t_flags)
{:ansi_flags,
   %Saucexages.AnsiFlags{
     aspect_ratio: :modern,
     letter_spacing: :none,
     non_blink_mode?: true
}}

iex> Saucexages.MediaInfo.read_media_field(%{file_type: 1, data_type: 1, t_flags: 17, t_info_1: 80}, :t_info_2, 22)
{:number_of_lines, 22}
Link to this function t_flags(media_info) View Source
t_flags(t()) :: {atom(), term()}

Returns a mapped version of the t_flags field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_flags(media_type_id, value) View Source
t_flags(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_flags field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_1(media_info) View Source
t_info_1(t()) :: {atom(), term()}

Returns a mapped version of the t_info_1 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_1(media_type_id, value) View Source
t_info_1(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_info_1 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_2(media_info) View Source
t_info_2(t()) :: {atom(), term()}

Returns a mapped version of the t_info_2 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_2(media_type_id, value) View Source
t_info_2(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_info_2 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_3(media_info) View Source
t_info_3(t()) :: {atom(), term()}

Returns a mapped version of the t_info_3 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_3(media_type_id, value) View Source
t_info_3(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_info_3 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_4(media_info) View Source
t_info_4(t()) :: {atom(), term()}

Returns a mapped version of the t_info_4 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_4(media_type_id, value) View Source
t_info_4(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_info_4 field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_s(media_info) View Source
t_info_s(t()) :: {atom(), term()}

Returns a mapped version of the t_info_s field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function t_info_s(media_type_id, value) View Source
t_info_s(media_type_id(), term()) :: {atom(), term()}

Returns a mapped version of the t_info_s field as a tuple containing the field type as the first element and the field value as the second element.

Link to this function type_field_mapping(media_type_id) View Source
type_field_mapping(media_type_id()) :: Enum.t()

Returns a keyword list of all the type dependent fields for a given file type.

Useful for building interfaces, specialized parsing, and dynamic access.

Examples

iex> Saucexages.MediaInfo.type_field_mapping(:ansi)
[
  t_flags: :ansi_flags,
  t_info_1: :character_width,
  t_info_2: :number_of_lines,
  t_info_s: :font_id
]
Link to this function type_field_names(media_type_id) View Source
type_field_names(media_type_id()) :: [atom()]

Returns a list of all field names used by a given file type.

Useful for building interfaces, specialized parsing, and dynamic access.

Examples

iex> Saucexages.MediaInfo.type_field_names(:ansi)
[:ansi_flags, :character_width, :number_of_lines, :font_id]

iex> Saucexages.MediaInfo.type_field_names(:gif)
[:pixel_width, :pixel_height, :pixel_depth]
Link to this macro type_fields() View Source (macro)
type_fields() :: [atom()]

Lists all dynamic file type fields that can be found in a SAUCE record.

The meaning of each of these fields varies by media_type_id, and therefore by the combination of data_type and usually file_type.

Useful for building interfaces, specialized parsing, and dynamic access.

Examples

iex> Saucexages.MediaInfo.type_fields()
[:t_info_1, :t_info_2, :t_info_3, :t_info_4, :t_flags, :t_info_s]
Link to this macro type_fields(media_type_id) View Source (macro)
type_fields(media_type_id()) :: [atom()]

Lists all dynamic file type fields that can be found in a SAUCE record for the given media_type_id.

Useful for building interfaces, specialized parsing, and dynamic access.

If you need the mapping between SAUCE fields and what they mean for a file type, see type_field_mapping/1. If you need the names of each field specific to the given file type, see type_field_names/1.

Examples

iex> Saucexages.MediaInfo.type_fields(:ansi)
[:t_flags, :t_info_1, :t_info_2, :t_info_s]

iex> Saucexages.MediaInfo.type_fields(:gif)
[:t_info_1, :t_info_2, :t_info_3]
Link to this macro type_fields(file_type, data_type) View Source (macro)
type_fields(file_type(), Saucexages.DataType.data_type()) :: [atom()]

Lists all dynamic file type fields that can be found in a SAUCE record for the given file_type and data_type.

Useful for building interfaces, specialized parsing, and dynamic access.

If you need the mapping between SAUCE fields and what they mean for a file type, see type_field_map/1. If you need the names of each field specific to the given file type, see type_field_names/1.

Examples

iex> Saucexages.MediaInfo.type_fields(1, 1)
[:t_flags, :t_info_1, :t_info_2, :t_info_s]

iex> Saucexages.MediaInfo.type_fields(0, 2)
[:t_info_1, :t_info_2, :t_info_3]
Link to this function type_handle(media_type_id) View Source
type_handle(media_type_id()) :: type_handle()

Returns a tuple of file_type and data_type associated with the given media_type_id to be used with SAUCE data directly, for example writing a SAUCE.

Examples

iex> Saucexages.MediaInfo.type_handle(:ansi)
{1, 1}
iex> Saucexages.MediaInfo.type_handle(:png)
{10, 2}