defmodule Exexif.Data.Thumbnail do @moduledoc """ Internal representation of Thumbnail tag in the EXIF. """ @type t :: %Exexif.Data.Thumbnail{ thumbnail_offset: non_neg_integer(), thumbnail_size: non_neg_integer() } @fields [ :thumbnail_offset, :thumbnail_size ] @spec fields :: [:thumbnail_offset | :thumbnail_size] @doc false def fields, do: @fields defstruct @fields @spec to_image(binary(), t()) :: :ok | {:error, :bad_thumbnail_data | :file.posix()} @doc "Converts the thumbnail to image and writes it to the file" def to_image(_, %Exexif.Data.Thumbnail{thumbnail_offset: offset, thumbnail_size: size}) when is_nil(offset) or is_nil(size), do: {:error, :bad_thumbnail_data} def to_image(file, %Exexif.Data.Thumbnail{thumbnail_offset: offset, thumbnail_size: size}) when is_binary(file) do [name, dot, ext] = String.split(file, ~r/(?=.{3,4}\z)/) with {:ok, src} <- File.open(file, [:read], fn f -> IO.binread(f, offset) IO.binread(f, size) end), {:ok, _dst} <- File.open("#{name}-thumb#{dot}#{ext}", [:write], &IO.binwrite(&1, src)), do: :ok end defimpl String.Chars, for: Exexif.Data.Thumbnail do @spec to_string(data :: Exexif.Data.Thumbnail.t()) :: <<_::64, _::_*8>> def to_string(data), do: "Image Thumbnail of size #{data.thumbnail_size}" end end