/*
 * GStreamer gstreamer-lcms
 * Copyright (C) 2016 Andreas Frisch <fraxinas@dreambox.guru>
 *
 * gstlcms.c
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-lcms
 * @short_description: Uses LittleCMS 2 to perform ICC profile correction
 *
 * This is a color management plugin that uses LittleCMS 2 to correct
 * frames using the given ICC (International Color Consortium) profiles.
 * Falls back to internal sRGB profile if no ICC file is specified in property.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * <para>(write everything in one line, without the backslash characters)</para>
 * |[
 * gst-launch-1.0 filesrc location=photo_camera.png ! pngdec ! \
 * videoconvert ! lcms input-profile=sRGB.icc dest-profile=printer.icc \
 * pngenc ! filesink location=photo_print.png
 * ]|
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstlcms.h"

#include <gst/gst.h>
#include <gst/video/video.h>
#include <stdlib.h>
#include <string.h>

GST_DEBUG_CATEGORY_STATIC (lcms_debug);
#define GST_CAT_DEFAULT lcms_debug

/* GstLcms properties */
enum
{
  PROP_0,
  PROP_INTENT,
  PROP_LOOKUP_METHOD,
  PROP_SRC_FILE,
  PROP_DST_FILE,
  PROP_PRESERVE_BLACK,
  PROP_EMBEDDED_PROFILE
};

GType
gst_lcms_intent_get_type (void)
{
  static volatile gsize intent_type = 0;
  static const GEnumValue intent[] = {
    {GST_LCMS_INTENT_PERCEPTUAL, "Perceptual",
        "perceptual"},
    {GST_LCMS_INTENT_RELATIVE_COLORIMETRIC, "Relative Colorimetric",
        "relative"},
    {GST_LCMS_INTENT_SATURATION, "Saturation",
        "saturation"},
    {GST_LCMS_INTENT_ABSOLUTE_COLORIMETRIC, "Absolute Colorimetric",
        "absolute"},
    {0, NULL, NULL},
  };

  if (g_once_init_enter (&intent_type)) {
    GType tmp = g_enum_register_static ("GstLcmsIntent", intent);
    g_once_init_leave (&intent_type, tmp);
  }
  return (GType) intent_type;
}

static GType
gst_lcms_lookup_method_get_type (void)
{
  static volatile gsize lookup_method_type = 0;
  static const GEnumValue lookup_method[] = {
    {GST_LCMS_LOOKUP_METHOD_UNCACHED,
          "Uncached, calculate every pixel on the fly (very slow playback)",
        "uncached"},
    {GST_LCMS_LOOKUP_METHOD_PRECALCULATED,
          "Precalculate lookup table (takes a long time getting READY)",
        "precalculated"},
    {GST_LCMS_LOOKUP_METHOD_CACHED,
          "Calculate and cache color replacement values on first occurence",
        "cached"},
    {0, NULL, NULL},
  };

  if (g_once_init_enter (&lookup_method_type)) {
    GType tmp = g_enum_register_static ("GstLcmsLookupMethod", lookup_method);
    g_once_init_leave (&lookup_method_type, tmp);
  }
  return (GType) lookup_method_type;
}

#define DEFAULT_INTENT  GST_LCMS_INTENT_PERCEPTUAL
#define DEFAULT_LOOKUP_METHOD     GST_LCMS_LOOKUP_METHOD_CACHED
#define DEFAULT_PRESERVE_BLACK    FALSE
#define DEFAULT_EMBEDDED_PROFILE  TRUE

static GstStaticPadTemplate gst_lcms_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ "
            "ARGB, BGRA, ABGR, RGBA, xRGB," "RGBx, xBGR, BGRx, RGB, BGR }"))
    );

static GstStaticPadTemplate gst_lcms_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ "
            "ARGB, BGRA, ABGR, RGBA, xRGB," "RGBx, xBGR, BGRx, RGB, BGR }"))
    );

static void gst_lcms_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_lcms_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_lcms_finalize (GObject * object);
static GstStateChangeReturn gst_lcms_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_lcms_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info);
static gboolean gst_lcms_sink_event (GstBaseTransform * trans,
    GstEvent * event);
static void gst_lcms_handle_tags (GstLcms * lcms, GstTagList * taglist);
static void gst_lcms_handle_tag_sample (GstLcms * lcms, GstSample * sample);
static GstFlowReturn gst_lcms_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * inframe, GstVideoFrame * outframe);
static GstFlowReturn gst_lcms_transform_frame_ip (GstVideoFilter * vfilter,
    GstVideoFrame * frame);

static void gst_lcms_get_ready (GstLcms * lcms);
static void gst_lcms_create_transform (GstLcms * lcms);
static void gst_lcms_cleanup_cms (GstLcms * lcms);
static void gst_lcms_init_lookup_table (GstLcms * lcms);
static void gst_lcms_process_rgb (GstLcms * lcms, GstVideoFrame * inframe,
    GstVideoFrame * outframe);

G_DEFINE_TYPE (GstLcms, gst_lcms, GST_TYPE_VIDEO_FILTER);

static void
gst_lcms_class_init (GstLcmsClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = (GstElementClass *) klass;
  GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;

  GST_DEBUG_CATEGORY_INIT (lcms_debug, "lcms", 0, "lcms");

  gobject_class->set_property = gst_lcms_set_property;
  gobject_class->get_property = gst_lcms_get_property;
  gobject_class->finalize = gst_lcms_finalize;

  g_object_class_install_property (gobject_class, PROP_INTENT,
      g_param_spec_enum ("intent", "Rendering intent",
          "Select the rendering intent of the color correction",
          GST_TYPE_LCMS_INTENT, DEFAULT_INTENT,
          (G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SRC_FILE,
      g_param_spec_string ("input-profile", "Input ICC profile file",
          "Specify the input ICC profile file to apply", NULL,
          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DST_FILE,
      g_param_spec_string ("dest-profile", "Destination ICC profile file",
          "Specify the destination ICC profile file to apply", NULL,
          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_LOOKUP_METHOD,
      g_param_spec_enum ("lookup", "Lookup method",
          "Select the caching method for the color compensation calculations",
          GST_TYPE_LCMS_LOOKUP_METHOD, DEFAULT_LOOKUP_METHOD,
          (G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_PRESERVE_BLACK,
      g_param_spec_boolean ("preserve-black", "Preserve black",
          "Select whether purely black pixels should be preserved",
          DEFAULT_PRESERVE_BLACK,
          (G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_EMBEDDED_PROFILE,
      g_param_spec_boolean ("embedded-profile", "Embedded Profile",
          "Extract and use source profiles embedded in images",
          DEFAULT_EMBEDDED_PROFILE,
          (G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  gst_element_class_set_static_metadata (element_class,
      "LCMS2 ICC correction", "Filter/Effect/Video",
      "Uses LittleCMS 2 to perform ICC profile correction",
      "Andreas Frisch <fraxinas@opendreambox.org>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_lcms_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_lcms_src_template));

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_lcms_change_state);

  trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_lcms_sink_event);

  vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_lcms_set_info);
  vfilter_class->transform_frame_ip =
      GST_DEBUG_FUNCPTR (gst_lcms_transform_frame_ip);
  vfilter_class->transform_frame = GST_DEBUG_FUNCPTR (gst_lcms_transform_frame);
}

static void
gst_lcms_init (GstLcms * lcms)
{
  lcms->color_lut = NULL;
  lcms->cms_inp_profile = NULL;
  lcms->cms_dst_profile = NULL;
  lcms->cms_transform = NULL;
}

static void
gst_lcms_finalize (GObject * object)
{
  GstLcms *lcms = GST_LCMS (object);
  if (lcms->color_lut)
    g_free (lcms->color_lut);
  g_free (lcms->inp_profile_filename);
  g_free (lcms->dst_profile_filename);
  G_OBJECT_CLASS (gst_lcms_parent_class)->finalize (object);
}

static void
gst_lcms_set_intent (GstLcms * lcms, GstLcmsIntent intent)
{
  GEnumValue *val =
      g_enum_get_value (G_ENUM_CLASS (g_type_class_ref
          (GST_TYPE_LCMS_INTENT)), intent);
  const gchar *value_nick;

  g_return_if_fail (GST_IS_LCMS (lcms));
  if (!val) {
    GST_ERROR_OBJECT (lcms, "no such rendering intent %i!", intent);
    return;
  }
  value_nick = val->value_nick;

  GST_OBJECT_LOCK (lcms);
  lcms->intent = intent;
  GST_OBJECT_UNLOCK (lcms);

  GST_DEBUG_OBJECT (lcms, "successfully set rendering intent to %s (%i)",
      value_nick, intent);
  return;
}

static GstLcmsIntent
gst_lcms_get_intent (GstLcms * lcms)
{
  g_return_val_if_fail (GST_IS_LCMS (lcms), (GstLcmsIntent) - 1);
  return lcms->intent;
}

static void
gst_lcms_set_lookup_method (GstLcms * lcms, GstLcmsLookupMethod method)
{
  GEnumValue *val =
      g_enum_get_value (G_ENUM_CLASS (g_type_class_ref
          (GST_TYPE_LCMS_LOOKUP_METHOD)), method);
  const gchar *value_nick;

  g_return_if_fail (GST_IS_LCMS (lcms));
  if (!val) {
    GST_ERROR_OBJECT (lcms, "no such lookup method %i!", method);
    return;
  }
  value_nick = val->value_nick;

  GST_OBJECT_LOCK (lcms);
  lcms->lookup_method = method;
  GST_OBJECT_UNLOCK (lcms);

  GST_DEBUG_OBJECT (lcms, "successfully set lookup method to %s (%i)",
      value_nick, method);
  return;
}

static GstLcmsLookupMethod
gst_lcms_get_lookup_method (GstLcms * lcms)
{
  g_return_val_if_fail (GST_IS_LCMS (lcms), (GstLcmsLookupMethod) - 1);
  return lcms->lookup_method;
}

static void
gst_lcms_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  const gchar *filename;
  GstLcms *lcms = GST_LCMS (object);

  switch (prop_id) {
    case PROP_SRC_FILE:
    {
      GST_OBJECT_LOCK (lcms);
      filename = g_value_get_string (value);
      if (filename
          && g_file_test (filename,
              (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
        if (lcms->inp_profile_filename)
          g_free (lcms->inp_profile_filename);
        lcms->inp_profile_filename = g_strdup (filename);
      } else {
        GST_WARNING_OBJECT (lcms, "Input profile file '%s' not found!",
            filename);
      }
      GST_OBJECT_UNLOCK (lcms);
      break;
    }
    case PROP_DST_FILE:
    {
      GST_OBJECT_LOCK (lcms);
      filename = g_value_get_string (value);
      if (g_file_test (filename,
              (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
        if (lcms->dst_profile_filename)
          g_free (lcms->dst_profile_filename);
        lcms->dst_profile_filename = g_strdup (filename);
      } else {
        GST_WARNING_OBJECT (lcms, "Destination profile file '%s' not found!",
            filename);
      }
      GST_OBJECT_UNLOCK (lcms);
      break;
    }
    case PROP_INTENT:
      gst_lcms_set_intent (lcms, (GstLcmsIntent) g_value_get_enum (value));
      break;
    case PROP_LOOKUP_METHOD:
      gst_lcms_set_lookup_method (lcms,
          (GstLcmsLookupMethod) g_value_get_enum (value));
      break;
    case PROP_PRESERVE_BLACK:
      lcms->preserve_black = g_value_get_boolean (value);
      break;
    case PROP_EMBEDDED_PROFILE:
      lcms->embeddedprofiles = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_lcms_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstLcms *lcms = GST_LCMS (object);

  switch (prop_id) {
    case PROP_SRC_FILE:
      g_value_set_string (value, lcms->inp_profile_filename);
      break;
    case PROP_DST_FILE:
      g_value_set_string (value, lcms->dst_profile_filename);
      break;
    case PROP_INTENT:
      g_value_set_enum (value, gst_lcms_get_intent (lcms));
      break;
    case PROP_LOOKUP_METHOD:
      g_value_set_enum (value, gst_lcms_get_lookup_method (lcms));
      break;
    case PROP_PRESERVE_BLACK:
      g_value_set_boolean (value, lcms->preserve_black);
      break;
    case PROP_EMBEDDED_PROFILE:
      g_value_set_boolean (value, lcms->embeddedprofiles);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_lcms_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstLcms *lcms = GST_LCMS (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_DEBUG_OBJECT (lcms, "GST_STATE_CHANGE_NULL_TO_READY");
      gst_lcms_get_ready (lcms);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    {
      if (!lcms->cms_inp_profile) {
        if (!lcms->cms_dst_profile) {
          GST_WARNING_OBJECT (lcms,
              "No input or output ICC profile specified, falling back to passthrough!");
          gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (lcms), TRUE);
          GST_BASE_TRANSFORM_CLASS (GST_LCMS_GET_CLASS
              (lcms))->transform_ip_on_passthrough = lcms->embeddedprofiles;
          return GST_STATE_CHANGE_SUCCESS;
        }
        lcms->cms_inp_profile = cmsCreate_sRGBProfile ();
        GST_INFO_OBJECT (lcms,
            "No input profile specified, falling back to sRGB");
      }
    }

    default:
      break;
  }

  if (ret == GST_STATE_CHANGE_SUCCESS)
    ret =
        GST_ELEMENT_CLASS (gst_lcms_parent_class)->change_state (element,
        transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_lcms_cleanup_cms (lcms);
    default:
      break;
  }
  return ret;
}

static void
gst_lcms_get_ready (GstLcms * lcms)
{
  if (lcms->inp_profile_filename) {
    lcms->cms_inp_profile =
        cmsOpenProfileFromFile (lcms->inp_profile_filename, "r");
    if (!lcms->cms_inp_profile)
      GST_ERROR_OBJECT (lcms, "Couldn't parse input ICC profile '%s'",
          lcms->inp_profile_filename);
    else
      GST_DEBUG_OBJECT (lcms, "Successfully opened input ICC profile '%s'",
          lcms->inp_profile_filename);
  }

  if (lcms->dst_profile_filename) {
    lcms->cms_dst_profile =
        cmsOpenProfileFromFile (lcms->dst_profile_filename, "r");
    if (!lcms->cms_dst_profile)
      GST_ERROR_OBJECT (lcms,
          "Couldn't parse destination ICC profile '%s'",
          lcms->dst_profile_filename);
    else
      GST_DEBUG_OBJECT (lcms, "Successfully opened output ICC profile '%s'",
          lcms->dst_profile_filename);
  }

  if (lcms->lookup_method != GST_LCMS_LOOKUP_METHOD_UNCACHED) {
    gst_lcms_init_lookup_table (lcms);
  }
}

static void
gst_lcms_cleanup_cms (GstLcms * lcms)
{
  if (lcms->cms_inp_profile) {
    cmsCloseProfile (lcms->cms_inp_profile);
    lcms->cms_inp_profile = NULL;
  }
  if (lcms->cms_dst_profile) {
    cmsCloseProfile (lcms->cms_dst_profile);
    lcms->cms_dst_profile = NULL;
  }
  if (lcms->cms_transform) {
    cmsDeleteTransform (lcms->cms_transform);
    lcms->cms_transform = NULL;
  }
}

static void
gst_lcms_init_lookup_table (GstLcms * lcms)
{
  guint32 p;
  const guint32 color_max = 0x01000000;

  if (lcms->color_lut)
    g_free (lcms->color_lut);

  lcms->color_lut = g_new (guint32, color_max);

  if (lcms->color_lut == NULL) {
    GST_ELEMENT_ERROR (lcms, RESOURCE, FAILED, ("LUT alloc failed"),
        ("Unable to open allocate memory for lookup table!"));
    return;
  }

  if (lcms->lookup_method == GST_LCMS_LOOKUP_METHOD_PRECALCULATED) {
    cmsHTRANSFORM hTransform;
    hTransform =
        cmsCreateTransform (lcms->cms_inp_profile, TYPE_RGB_8,
        lcms->cms_dst_profile, TYPE_RGB_8, lcms->intent, 0);
    /*FIXME use cmsFLAGS_COPY_ALPHA when new lcms2 2.8 release is available */
    for (p = 0; p < color_max; p++)
      cmsDoTransform (hTransform, (const cmsUInt32Number *) &p,
          &lcms->color_lut[p], 1);
    cmsDeleteTransform (hTransform);
    GST_DEBUG_OBJECT (lcms, "writing lookup table finished");
  } else if (lcms->lookup_method == GST_LCMS_LOOKUP_METHOD_CACHED) {
    memset (lcms->color_lut, 0xAA, color_max * sizeof (guint32));
    GST_DEBUG_OBJECT (lcms, "initialized empty lookup table for caching");
  }
  if (lcms->preserve_black)
    lcms->color_lut[0] = 0x000000;
}

static cmsUInt32Number
gst_lcms_cms_format_from_gst (GstVideoFormat gst_format)
{
  cmsUInt32Number cms_format = 0;
  switch (gst_format) {
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_xRGB:
      cms_format = TYPE_ARGB_8;
      break;
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_ABGR:
      cms_format = TYPE_ABGR_8;
      break;
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_BGRx:
      cms_format = TYPE_BGRA_8;
      break;
    case GST_VIDEO_FORMAT_BGR:
      cms_format = TYPE_BGR_8;
      break;
    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_RGBx:
      cms_format = TYPE_RGBA_8;
      break;
    case GST_VIDEO_FORMAT_RGB:
      cms_format = TYPE_RGB_8;
      break;
    default:
      break;
  }
  return cms_format;
}

static gboolean
gst_lcms_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
{
  GstLcms *lcms = GST_LCMS (vfilter);

  GST_DEBUG_OBJECT (lcms,
      "setting caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps,
      outcaps);

  lcms->cms_inp_format =
      gst_lcms_cms_format_from_gst (GST_VIDEO_INFO_FORMAT (in_info));
  lcms->cms_dst_format =
      gst_lcms_cms_format_from_gst (GST_VIDEO_INFO_FORMAT (out_info));

  if (gst_base_transform_is_passthrough (GST_BASE_TRANSFORM (lcms)))
    return TRUE;

  if (!lcms->cms_inp_format || !lcms->cms_dst_format)
    goto invalid_caps;

  if (lcms->cms_inp_format == lcms->cms_dst_format
      && lcms->lookup_method != GST_LCMS_LOOKUP_METHOD_UNCACHED) {
    gst_base_transform_set_in_place (GST_BASE_TRANSFORM (lcms), TRUE);
  } else
    gst_base_transform_set_in_place (GST_BASE_TRANSFORM (lcms), FALSE);

  gst_lcms_create_transform (lcms);
  lcms->process = gst_lcms_process_rgb;

  return TRUE;

invalid_caps:
  {
    GST_ERROR_OBJECT (lcms, "Invalid caps: %" GST_PTR_FORMAT, incaps);
    return FALSE;
  }
}

static void
gst_lcms_create_transform (GstLcms * lcms)
{
  if (!lcms->cms_dst_profile) {
    lcms->cms_dst_profile = cmsCreate_sRGBProfile ();
    GST_INFO_OBJECT (lcms, "No output profile specified, falling back to sRGB");
  }
  lcms->cms_transform =
      cmsCreateTransform (lcms->cms_inp_profile, lcms->cms_inp_format,
      lcms->cms_dst_profile, lcms->cms_dst_format, lcms->intent, 0);
  if (lcms->cms_transform) {
    GST_DEBUG_OBJECT (lcms, "created transformation format=%i->%i",
        lcms->cms_inp_format, lcms->cms_dst_format);
  } else {
    GST_WARNING_OBJECT (lcms,
        "couldn't create transformation format=%i->%i, fallback to passthrough!",
        lcms->cms_inp_format, lcms->cms_dst_format);
    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (lcms), TRUE);
  }
}

static gboolean
gst_lcms_sink_event (GstBaseTransform * trans, GstEvent * event)
{
  gboolean ret = FALSE;
  GstLcms *lcms = GST_LCMS (trans);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      if (lcms->embeddedprofiles) {
        GstTagList *taglist = NULL;
        /* icc profiles might be embedded in attachments */
        gst_event_parse_tag (event, &taglist);
        gst_lcms_handle_tags (lcms, taglist);
      }
      break;
    }
    default:
      break;
  }
  ret =
      GST_BASE_TRANSFORM_CLASS (gst_lcms_parent_class)->sink_event (trans,
      event);
  return ret;
}

static void
gst_lcms_handle_tag_sample (GstLcms * lcms, GstSample * sample)
{
  GstBuffer *buf;
  const GstStructure *structure;

  buf = gst_sample_get_buffer (sample);
  structure = gst_sample_get_info (sample);

  if (!buf || !structure)
    return;

  if (gst_structure_has_name (structure, "application/vnd.iccprofile")) {
    if (!lcms->inp_profile_filename
        && lcms->lookup_method != GST_LCMS_LOOKUP_METHOD_UNCACHED) {
      GstMapInfo map;
      const gchar *icc_name;
      icc_name = gst_structure_get_string (structure, "icc-name");
      gst_buffer_map (buf, &map, GST_MAP_READ);
      lcms->cms_inp_profile = cmsOpenProfileFromMem (map.data, map.size);
      gst_buffer_unmap (buf, &map);
      if (!lcms->cms_inp_profile)
        GST_WARNING_OBJECT (lcms,
            "Couldn't parse embedded input ICC profile '%s'", icc_name);
      else {
        GST_DEBUG_OBJECT (lcms,
            "Successfully opened embedded input ICC profile '%s'", icc_name);
        if (lcms->cms_inp_format) {
          gst_lcms_create_transform (lcms);
          gst_lcms_init_lookup_table (lcms);
        }
      }
    } else {
      GST_DEBUG_OBJECT (lcms,
          "disregarding embedded ICC profile because input profile file was explicitly specified");
    }
  } else
    GST_DEBUG_OBJECT (lcms, "attachment is not an ICC profile");
}

static void
gst_lcms_handle_tags (GstLcms * lcms, GstTagList * taglist)
{
  guint tag_size;

  if (!taglist)
    return;

  tag_size = gst_tag_list_get_tag_size (taglist, GST_TAG_ATTACHMENT);
  if (tag_size > 0) {
    guint index;
    GstSample *sample;
    for (index = 0; index < tag_size; index++) {
      if (gst_tag_list_get_sample_index (taglist, GST_TAG_ATTACHMENT, index,
              &sample)) {
        gst_lcms_handle_tag_sample (lcms, sample);
        gst_sample_unref (sample);
      }
    }
  }
}

static GstFlowReturn
gst_lcms_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * inframe)
{
  GstLcms *lcms = GST_LCMS (vfilter);
  if (!gst_base_transform_is_passthrough (GST_BASE_TRANSFORM (lcms)))
    lcms->process (lcms, inframe, NULL);
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_lcms_transform_frame (GstVideoFilter * vfilter, GstVideoFrame * inframe,
    GstVideoFrame * outframe)
{
  GstLcms *lcms = GST_LCMS (vfilter);
  if (!gst_base_transform_is_passthrough (GST_BASE_TRANSFORM (lcms)))
    lcms->process (lcms, inframe, outframe);
  return GST_FLOW_OK;
}

static void
gst_lcms_process_rgb (GstLcms * lcms, GstVideoFrame * inframe,
    GstVideoFrame * outframe)
{
  gint height;
  gint width, in_stride, out_stride;
  gint in_pixel_stride, out_pixel_stride;
  gint in_offsets[4], out_offsets[4];
  guint8 *in_data, *out_data;
  gint i, j;
  gint in_row_wrap, out_row_wrap;
  guint8 alpha = 0;

  in_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (inframe, 0);
  in_stride = GST_VIDEO_FRAME_PLANE_STRIDE (inframe, 0);
  width = GST_VIDEO_FRAME_COMP_WIDTH (inframe, 0);
  height = GST_VIDEO_FRAME_COMP_HEIGHT (inframe, 0);
  in_pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (inframe, 0);

  in_offsets[0] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 0);
  in_offsets[1] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 1);
  in_offsets[2] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 2);
  in_offsets[3] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 3);

  if (outframe) {
    if (width != GST_VIDEO_FRAME_COMP_WIDTH (outframe, 0)
        || height != GST_VIDEO_FRAME_COMP_HEIGHT (outframe, 0)) {
      GST_WARNING_OBJECT (lcms,
          "can't transform, input dimensions != output dimensions!");
      return;
    }
    out_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (outframe, 0);
    out_stride = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, 0);
    out_pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (outframe, 0);
    out_offsets[0] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 0);
    out_offsets[1] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 1);
    out_offsets[2] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 2);
    out_offsets[3] = GST_VIDEO_FRAME_COMP_OFFSET (inframe, 3);
    GST_LOG_OBJECT (lcms,
        "transforming frame (%ix%i) stride=%i->%i pixel_stride=%i->%i format=%s->%s",
        width, height, in_stride, out_stride, in_pixel_stride, out_pixel_stride,
        gst_video_format_to_string (inframe->info.finfo->format),
        gst_video_format_to_string (outframe->info.finfo->format));
  } else {                      /* in-place transformation */
    GST_LOG_OBJECT (lcms,
        "transforming frame IN-PLACE (%ix%i) pixel_stride=%i format=%s", width,
        height, in_pixel_stride,
        gst_video_format_to_string (inframe->info.finfo->format));
    out_data = in_data;
    out_stride = in_stride;
    out_pixel_stride = in_pixel_stride;
    out_offsets[0] = in_offsets[0];
    out_offsets[1] = in_offsets[1];
    out_offsets[2] = in_offsets[2];
    out_offsets[3] = in_offsets[3];
  }

  in_row_wrap = in_stride - in_pixel_stride * width;
  out_row_wrap = out_stride - out_pixel_stride * width;

  if (lcms->lookup_method == GST_LCMS_LOOKUP_METHOD_UNCACHED) {
    if (!GST_VIDEO_FORMAT_INFO_HAS_ALPHA (inframe->info.finfo)
        && !lcms->preserve_black) {
      GST_DEBUG_OBJECT (lcms,
          "GST_LCMS_LOOKUP_METHOD_UNCACHED WITHOUT alpha AND WITHOUT preserve-black -> picture-at-once transformation!");
      cmsDoTransformStride (lcms->cms_transform, in_data, out_data,
          height * width, out_pixel_stride);
    } else {
      GST_DEBUG_OBJECT (lcms,
          "GST_LCMS_LOOKUP_METHOD_UNCACHED WITH alpha or preserve-black -> pixel-by-pixel transformation!");
      for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {
          if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (inframe->info.finfo))
            alpha = in_data[in_offsets[3]];
          if (lcms->preserve_black && (in_data[in_offsets[0]] == 0x00)
              && (in_data[in_offsets[1]] == 0x00)
              && (in_data[in_offsets[2]] == 0x0))
            out_data[out_offsets[0]] = out_data[out_offsets[1]] =
                out_data[out_offsets[2]] = 0x00;
          else
            cmsDoTransformStride (lcms->cms_transform, in_data, out_data, 1,
                in_pixel_stride);
          if (alpha)
            out_data[in_offsets[3]] = alpha;
          in_data += in_pixel_stride;
          out_data += out_pixel_stride;
        }
        in_data += in_row_wrap;
        out_data += out_row_wrap;
      }
    }
  } else if (lcms->lookup_method == GST_LCMS_LOOKUP_METHOD_PRECALCULATED) {
    guint32 color, new_color;
    GST_LOG_OBJECT (lcms, "GST_LCMS_LOOKUP_METHOD_PRECALCULATED");
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        color =
            in_data[in_offsets[0]] |
            in_data[in_offsets[1]] << 0x08 | in_data[in_offsets[2]] << 0x10;
        new_color = lcms->color_lut[color];
        out_data[out_offsets[0]] = (new_color & 0x0000FF) >> 0x00;
        out_data[out_offsets[1]] = (new_color & 0x00FF00) >> 0x08;
        out_data[out_offsets[2]] = (new_color & 0xFF0000) >> 0x10;
        GST_TRACE_OBJECT (lcms,
            "(%i:%i)@%p original color 0x%08X (dest was 0x%08X)", i, j, in_data,
            color, new_color);
        if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (inframe->info.finfo)) {
          out_data[in_offsets[3]] = in_data[out_offsets[3]];
        }
        in_data += in_pixel_stride;
        out_data += out_pixel_stride;
      }
      in_data += in_row_wrap;
      out_data += out_row_wrap;
    }
  } else if (lcms->lookup_method == GST_LCMS_LOOKUP_METHOD_CACHED) {
    guint32 color, new_color;
    GST_LOG_OBJECT (lcms, "GST_LCMS_LOOKUP_METHOD_CACHED");
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (inframe->info.finfo))
          alpha = in_data[in_offsets[3]];
        color =
            in_data[in_offsets[0]] |
            in_data[in_offsets[1]] << 0x08 | in_data[in_offsets[2]] << 0x10;
        new_color = lcms->color_lut[color];
        if (new_color == 0xAAAAAAAA) {
          cmsDoTransform (lcms->cms_transform, in_data, out_data, 1);
          new_color =
              out_data[out_offsets[0]] |
              out_data[out_offsets[1]] << 0x08 |
              out_data[out_offsets[2]] << 0x10;
          GST_OBJECT_LOCK (lcms);
          lcms->color_lut[color] = new_color;
          GST_OBJECT_UNLOCK (lcms);
          GST_TRACE_OBJECT (lcms, "cached color 0x%08X -> 0x%08X", color,
              new_color);
        } else {
          out_data[out_offsets[0]] = (new_color & 0x0000FF) >> 0x00;
          out_data[out_offsets[1]] = (new_color & 0x00FF00) >> 0x08;
          out_data[out_offsets[2]] = (new_color & 0xFF0000) >> 0x10;
        }
        if (alpha) {
          out_data[in_offsets[3]] = alpha;
        }
        in_data += in_pixel_stride;
        out_data += out_pixel_stride;
      }
      in_data += in_row_wrap;
      out_data += out_row_wrap;
    }
  }
}
