예제 #1
0
static cmsHPROFILE _create_profile(gchar *iccprofile)
{
  cmsHPROFILE profile = NULL;
  if(!strcmp(iccprofile, "sRGB"))
  {
    // default: sRGB
    profile = dt_colorspaces_create_srgb_profile();
  }
  else if(!strcmp(iccprofile, "linear_rec709_rgb") || !strcmp(iccprofile, "linear_rgb"))
  {
    profile = dt_colorspaces_create_linear_rec709_rgb_profile();
  }
  else if(!strcmp(iccprofile, "linear_rec2020_rgb"))
  {
    profile = dt_colorspaces_create_linear_rec2020_rgb_profile();
  }
  else if(!strcmp(iccprofile, "adobergb"))
  {
    profile = dt_colorspaces_create_adobergb_profile();
  }
  else if(!strcmp(iccprofile, "X profile"))
  {
    // x default
    pthread_rwlock_rdlock(&darktable.control->xprofile_lock);
    if(darktable.control->xprofile_data)
      profile = cmsOpenProfileFromMem(darktable.control->xprofile_data, darktable.control->xprofile_size);
    pthread_rwlock_unlock(&darktable.control->xprofile_lock);
  }
  else
  {
    // else: load file name
    char filename[PATH_MAX];
    dt_colorspaces_find_profile(filename, sizeof(filename), iccprofile, "out");
    profile = cmsOpenProfileFromFile(filename, "r");
  }

  /* if no match lets fallback to srgb profile */
  if (!profile)
    profile = dt_colorspaces_create_srgb_profile();

  return profile;
}
예제 #2
0
파일: LCMS.c 프로젝트: frohoff/jdk6
/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    loadProfile
 * Signature: ([B)J
 */
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile
  (JNIEnv *env, jobject obj, jbyteArray data)
{
    jbyte* dataArray;
    jint dataSize;
    storeID_t sProf;

    dataArray = (*env)->GetByteArrayElements (env, data, 0);
    dataSize = (*env)->GetArrayLength (env, data);

    sProf.pf = cmsOpenProfileFromMem((LPVOID)dataArray, (DWORD) dataSize);

    (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);

    if (sProf.pf == NULL) {
        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
    }

    return sProf.j;
}
예제 #3
0
static PyObject*
cms_profile_fromstring(PyObject* self, PyObject* args)
{
    cmsHPROFILE hProfile;

    char* pProfile;
    int nProfile;
    if (!PyArg_ParseTuple(args, "s#:profile_fromstring", &pProfile, &nProfile))
        return NULL;

    cmsErrorAction(LCMS_ERROR_IGNORE);

    hProfile = cmsOpenProfileFromMem(pProfile, nProfile);
    if (!hProfile) {
        PyErr_SetString(PyExc_IOError, "cannot open profile from string");
        return NULL;
    }

    return cms_profile_new(hProfile);
}
예제 #4
0
ScColorProfile ScLcms2ColorMgmtEngineImpl::openProfileFromMem(ScColorMgmtEngine& engine, const QByteArray& data)
{
	ScColorProfile profile;
	cmsHPROFILE	lcmsProf = cmsOpenProfileFromMem((const void *) data.data(), data.size());
	if (lcmsProf)
	{
		ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
		QString desc = profData->productDescription();
		if (!desc.isEmpty())
			profData->m_profilePath = QString("memprofile://%1").arg(desc);
		profData->m_profileData = data;
		profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
	}
	if (profile.isNull() && lcmsProf)
	{
		cmsCloseProfile(lcmsProf);
		lcmsProf = NULL;
	}
	return profile;
}
예제 #5
0
파일: lcms.c 프로젝트: DevMaggio/gimp
static cmsHPROFILE
lcms_load_profile (const gchar *filename,
                   guchar      *checksum)
{
  cmsHPROFILE  profile;
  GMappedFile *file;
  gchar       *data;
  gsize        len;
  GError      *error = NULL;

  g_return_val_if_fail (filename != NULL, NULL);

  file = g_mapped_file_new (filename, FALSE, &error);

  if (! file)
    {
      g_message ("%s", error->message);
      g_error_free (error);

      return NULL;
    }

  data = g_mapped_file_get_contents (file);
  len = g_mapped_file_get_length (file);

  profile = cmsOpenProfileFromMem (data, len);

  if (profile)
    {
      lcms_calculate_checksum (data, len, checksum);
    }
  else
    {
      g_message (_("Could not load ICC profile from '%s'"),
                 gimp_filename_to_utf8 (filename));
    }

  g_mapped_file_unref (file);

  return profile;
}
예제 #6
0
/**
 * gimp_color_profile_new_from_lcms_profile:
 * @lcms_profile: an LCMS cmsHPROFILE pointer
 * @error:        return location for #GError
 *
 * This function creates a GimpColorProfile from a cmsHPROFILE. On
 * error, %NULL is returned and @error is set. The passed
 * @lcms_profile pointer is not retained by the created
 * #GimpColorProfile.
 *
 * Return value: the #GimpColorProfile, or %NULL.
 *
 * Since: 2.10
 **/
GimpColorProfile *
gimp_color_profile_new_from_lcms_profile (gpointer   lcms_profile,
                                          GError   **error)
{
  cmsUInt32Number size;

  g_return_val_if_fail (lcms_profile != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (cmsSaveProfileToMem (lcms_profile, NULL, &size))
    {
      guint8 *data = g_malloc (size);

      if (cmsSaveProfileToMem (lcms_profile, data, &size))
        {
          gsize length = size;

          lcms_profile = cmsOpenProfileFromMem (data, length);

          if (lcms_profile)
            {
              GimpColorProfile *profile;

              profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL);

              profile->priv->lcms_profile = lcms_profile;
              profile->priv->data         = data;
              profile->priv->length       = length;

              return profile;
            }
        }

      g_free (data);
    }

  g_set_error_literal (error, gimp_color_profile_error_quark (), 0,
                       _("Could not save color profile to memory"));

  return NULL;
}
예제 #7
0
파일: cmsprofile.cpp 프로젝트: KDE/gwenview
Profile::Ptr Profile::getMonitorProfile()
{
    cmsHPROFILE hProfile = 0;
    // Get the profile from you config file if the user has set it.
    // if the user allows override through the atom, do this:
#ifdef HAVE_X11
    if (QX11Info::isPlatformX11()) {
        // get the current screen...
        int screen = -1;

        Atom type;
        int format;
        unsigned long nitems;
        unsigned long bytes_after;
        quint8 *str;

        static Atom icc_atom = XInternAtom(QX11Info::display(), "_ICC_PROFILE", True);

        if (XGetWindowProperty(QX11Info::display(),
                               QX11Info::appRootWindow(screen),
                               icc_atom,
                               0,
                               INT_MAX,
                               False,
                               XA_CARDINAL,
                               &type,
                               &format,
                               &nitems,
                               &bytes_after,
                               (unsigned char **) &str) == Success
                ) {
            hProfile = cmsOpenProfileFromMem((void*)str, nitems);
        }
    }
#endif
    if (!hProfile) {
        return getSRgbProfile();
    }
    return Profile::Ptr(new Profile(hProfile));
}
예제 #8
0
static cmsHPROFILE
cdisplay_lcms_get_rgb_profile (CdisplayLcms *lcms)
{
  GimpColorConfig  *config;
  GimpColorManaged *managed;
  cmsHPROFILE       profile = NULL;

  managed = gimp_color_display_get_managed (GIMP_COLOR_DISPLAY (lcms));

  if (managed)
    {
      gsize         len;
      const guint8 *data = gimp_color_managed_get_icc_profile (managed, &len);

      if (data)
        profile = cmsOpenProfileFromMem ((gpointer) data, len);

      if (profile && ! gimp_lcms_profile_is_rgb (profile))
        {
          cmsCloseProfile (profile);
          profile = NULL;
        }
    }

  if (! profile)
    {
      config = gimp_color_display_get_config (GIMP_COLOR_DISPLAY (lcms));

      if (config->rgb_profile)
        profile = cmsOpenProfileFromFile (config->rgb_profile, "r");

      if (profile && ! gimp_lcms_profile_is_rgb (profile))
        {
          cmsCloseProfile (profile);
          profile = NULL;
        }
    }

  return profile;
}
예제 #9
0
파일: colorout.c 프로젝트: bgK/darktable
static cmsHPROFILE _create_profile(gchar *iccprofile)
{
  cmsHPROFILE profile = NULL;
  if(!strcmp(iccprofile, "sRGB"))
  {
    // default: sRGB
    profile = dt_colorspaces_create_srgb_profile();
  }
  else if(!strcmp(iccprofile, "linear_rgb"))
  {
    profile = dt_colorspaces_create_linear_rgb_profile();
  }
  else if(!strcmp(iccprofile, "adobergb"))
  {
    profile = dt_colorspaces_create_adobergb_profile();
  }
  else if(!strcmp(iccprofile, "X profile"))
  {
    // x default
    if(darktable.control->xprofile_data)
      profile = cmsOpenProfileFromMem(darktable.control->xprofile_data, darktable.control->xprofile_size);
    else
      profile = NULL;
  }
  else
  {
    // else: load file name
    char filename[1024];
    dt_colorspaces_find_profile(filename, 1024, iccprofile, "out");
    profile = cmsOpenProfileFromFile(filename, "r");
  }

  /* if no match lets fallback to srgb profile */
  if (!profile)
    profile = dt_colorspaces_create_srgb_profile();

  return profile;
}
예제 #10
0
파일: lcms.c 프로젝트: DevMaggio/gimp
static cmsHPROFILE
lcms_image_get_profile (GimpColorConfig *config,
                        gint32           image,
                        guchar          *checksum)
{
  GimpParasite *parasite;
  cmsHPROFILE   profile = NULL;

  g_return_val_if_fail (image != -1, NULL);

  parasite = gimp_image_get_parasite (image, "icc-profile");

  if (parasite)
    {
      profile = cmsOpenProfileFromMem ((gpointer) gimp_parasite_data (parasite),
                                       gimp_parasite_data_size (parasite));

      if (profile)
        {
          lcms_calculate_checksum (gimp_parasite_data (parasite),
                                   gimp_parasite_data_size (parasite),
                                   checksum);
        }
      else
        {
          g_message (_("Data attached as 'icc-profile' does not appear to "
                       "be an ICC color profile"));
        }

      gimp_parasite_free (parasite);
    }
  else if (config->rgb_profile)
    {
      profile = lcms_load_profile (config->rgb_profile, checksum);
    }

  return profile;
}
예제 #11
0
파일: _imagingcms.c 프로젝트: kmike/Pillow
static PyObject*
cms_profile_fromstring(PyObject* self, PyObject* args)
{
    cmsHPROFILE hProfile;

    char* pProfile;
    int nProfile;
#if PY_VERSION_HEX >= 0x03000000
    if (!PyArg_ParseTuple(args, "y#:profile_frombytes", &pProfile, &nProfile))
        return NULL;
#else
    if (!PyArg_ParseTuple(args, "s#:profile_fromstring", &pProfile, &nProfile))
        return NULL;
#endif

    hProfile = cmsOpenProfileFromMem(pProfile, nProfile);
    if (!hProfile) {
        PyErr_SetString(PyExc_IOError, "cannot open profile from string");
        return NULL;
    }

    return cms_profile_new(hProfile);
}
예제 #12
0
void TestKoLcmsColorProfile::testConversion()
{
    const KoColorSpace *sRgb = KoColorSpaceRegistry::instance()->rgb16("sRGB built-in");
    Q_ASSERT(sRgb);
    const KoColorSpace *linearRgb = KoColorSpaceRegistry::instance()->rgb16("scRGB (linear)");
    Q_ASSERT(linearRgb);

    quint16 src[4];
    src[0] = 257;
    src[1] = 257;
    src[2] = 257;
    src[3] = 65535;

    quint16 dst[4];
    memset(&dst, 0, 8);

    linearRgb->convertPixelsTo((quint8 *)&src, (quint8 *)&dst, sRgb, 1, KoColorConversionTransformation::IntentRelativeColorimetric, KoColorConversionTransformation::BlackpointCompensation);

    quint16 dst2[4];
    memset(&dst2, 0, 8);

    cmsHPROFILE sRgbProfile = cmsCreate_sRGBProfile();
    QByteArray rawData = linearRgb->profile()->rawData();
    cmsHPROFILE linearRgbProfile = cmsOpenProfileFromMem((void *)rawData.constData(), rawData.size());

    cmsHTRANSFORM tf = cmsCreateTransform(linearRgbProfile,
                                          TYPE_BGRA_16,
                                          sRgbProfile,
                                          TYPE_BGRA_16,
                                          INTENT_RELATIVE_COLORIMETRIC,
                                          cmsFLAGS_NOOPTIMIZE);

    cmsDoTransform(tf, (quint8 *)&src, (quint8 *)&dst2, 1);

    Q_ASSERT(dst[0] == dst2[0]);

}
예제 #13
0
파일: wxcms.cpp 프로젝트: ndevenish/Hugin
        void CorrectImage(wxImage& image, const vigra::ImageImportInfo::ICCProfile& iccProfile, const cmsHPROFILE& monitorProfile)
        {
            cmsHPROFILE inputICC = NULL;
            if (!iccProfile.empty())
            {
                inputICC = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size());
            };
            // check type of input profile
            if (inputICC != NULL)
            {
                if (cmsGetColorSpace(inputICC) != cmsSigRgbData)
                {
                    cmsCloseProfile(inputICC);
                    inputICC = NULL;
                };
            };
            // if there is no icc profile in file fall back to sRGB
            if (inputICC == NULL)
            {
                inputICC = cmsCreate_sRGBProfile();
            };
            // now build transform
            cmsHTRANSFORM transform = cmsCreateTransform(inputICC, TYPE_RGB_8,
                monitorProfile, TYPE_RGB_8,
                INTENT_PERCEPTUAL, cmsFLAGS_BLACKPOINTCOMPENSATION);
            unsigned char* imgData = image.GetData();
            const int imgWidth = image.GetWidth();
            const int imgHeight = image.GetHeight();
#pragma omp parallel for
            for (int y = 0; y < imgHeight; ++y)
            {
                cmsDoTransform(transform, imgData + 3 * y * imgWidth, imgData + 3 * y * imgWidth, imgWidth);
            };
            cmsDeleteTransform(transform);
            cmsCloseProfile(inputICC);
        };
예제 #14
0
파일: color-man.c 프로젝트: metux/geeqie
static cmsHPROFILE color_man_cache_load_profile(ColorManProfileType type, const gchar *file,
						guchar *data, guint data_len)
{
	cmsHPROFILE profile = NULL;

	switch (type)
		{
		case COLOR_PROFILE_FILE:
			if (file)
				{
				gchar *pathl;

				pathl = path_from_utf8(file);
				profile = cmsOpenProfileFromFile(pathl, "r");
				g_free(pathl);
				}
			break;
		case COLOR_PROFILE_SRGB:
			profile = cmsCreate_sRGBProfile();
			break;
		case COLOR_PROFILE_ADOBERGB:
			profile = color_man_create_adobe_comp();
			break;
		case COLOR_PROFILE_MEM:
			if (data)
				{
				profile = cmsOpenProfileFromMem(data, data_len);
				}
			break;
		case COLOR_PROFILE_NONE:
		default:
			break;
		}

	return profile;
}
예제 #15
0
파일: lcms.c 프로젝트: DevMaggio/gimp
static gboolean
lcms_image_set_profile (gint32       image,
                        cmsHPROFILE  profile,
                        const gchar *filename,
                        gboolean     undo_group)
{
  g_return_val_if_fail (image != -1, FALSE);

  if (filename)
    {
      GimpParasite *parasite;
      GMappedFile  *file;
      GError       *error = NULL;

      file = g_mapped_file_new (filename, FALSE, &error);

      if (! file)
        {
          g_message ("%s", error->message);
          g_error_free (error);

          return FALSE;
        }

      /* check that this file is actually an ICC profile */
      if (! profile)
        {
          profile = cmsOpenProfileFromMem (g_mapped_file_get_contents (file),
                                           g_mapped_file_get_length (file));

          if (profile)
            {
              cmsCloseProfile (profile);
            }
          else
            {
              g_message (_("'%s' does not appear to be an ICC color profile"),
                         gimp_filename_to_utf8 (filename));
              return FALSE;
            }
        }

      if (undo_group)
        gimp_image_undo_group_start (image);

      parasite = gimp_parasite_new ("icc-profile",
                                    GIMP_PARASITE_PERSISTENT |
                                    GIMP_PARASITE_UNDOABLE,
                                    g_mapped_file_get_length (file),
                                    g_mapped_file_get_contents (file));

      g_mapped_file_unref (file);

      gimp_image_attach_parasite (image, parasite);
      gimp_parasite_free (parasite);
    }
  else
    {
      if (undo_group)
        gimp_image_undo_group_start (image);

      gimp_image_detach_parasite (image, "icc-profile");
    }

  gimp_image_detach_parasite (image, "icc-profile-name");

  if (undo_group)
    gimp_image_undo_group_end (image);

  return TRUE;
}
예제 #16
0
// Get the display ICC profile of the monitor associated with the widget.
// For X display, uses the ICC profile specifications version 0.2 from
// http://burtonini.com/blog/computers/xicc
// Based on code from Gimp's modules/cdisplay_lcms.c
void dt_ctl_set_display_profile()
{
  if(!dt_control_running()) return;
  // make sure that no one gets a broken profile
  // FIXME: benchmark if the try is really needed when moving/resizing the window. Maybe we can just lock it and block
  if(pthread_rwlock_trywrlock(&darktable.control->xprofile_lock))
    return; // we are already updating the profile. Or someone is reading right now. Too bad we can't distinguish that. Whatever ...

  GtkWidget *widget = dt_ui_center(darktable.gui->ui);
  guint8 *buffer = NULL;
  gint buffer_size = 0;
  gchar *profile_source = NULL;

#if defined GDK_WINDOWING_X11

  // we will use the xatom no matter what configured when compiled without colord
  gboolean use_xatom = TRUE;
#if defined USE_COLORDGTK
  gboolean use_colord = TRUE;
  gchar *display_profile_source = dt_conf_get_string("ui_last/display_profile_source");
  if(display_profile_source)
  {
    if(!strcmp(display_profile_source, "xatom"))
      use_colord = FALSE;
    else if(!strcmp(display_profile_source, "colord"))
      use_xatom = FALSE;
    g_free(display_profile_source);
  }
#endif

  /* let's have a look at the xatom, just in case ... */
  if(use_xatom)
  {
    GdkScreen *screen = gtk_widget_get_screen(widget);
    if ( screen==NULL )
      screen = gdk_screen_get_default();
    int monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window(widget));
    char *atom_name;
    if (monitor > 0)
      atom_name = g_strdup_printf("_ICC_PROFILE_%d", monitor);
    else
      atom_name = g_strdup("_ICC_PROFILE");

    profile_source = g_strdup_printf("xatom %s", atom_name);

    GdkAtom type = GDK_NONE;
    gint format = 0;
    gdk_property_get(gdk_screen_get_root_window(screen),
                    gdk_atom_intern(atom_name, FALSE), GDK_NONE,
                    0, 64 * 1024 * 1024, FALSE,
                    &type, &format, &buffer_size, &buffer);
    g_free(atom_name);
  }

#ifdef USE_COLORDGTK
  /* also try to get the profile from colord. this will set the value asynchronously! */
  if(use_colord)
  {
    CdWindow *window = cd_window_new();
    GtkWidget *center_widget = dt_ui_center(darktable.gui->ui);
    cd_window_get_profile(window, center_widget, NULL, dt_ctl_get_display_profile_colord_callback, NULL);
  }
#endif

#elif defined GDK_WINDOWING_QUARTZ
  GdkScreen *screen = gtk_widget_get_screen(widget);
  if ( screen==NULL )
    screen = gdk_screen_get_default();
  int monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget));

  CGDirectDisplayID ids[monitor + 1];
  uint32_t total_ids;
  CMProfileRef prof = NULL;
  if(CGGetOnlineDisplayList(monitor + 1, &ids[0], &total_ids) == kCGErrorSuccess && total_ids == monitor + 1)
    CMGetProfileByAVID(ids[monitor], &prof);
  if ( prof!=NULL )
  {
    CFDataRef data;
    data = CMProfileCopyICCData(NULL, prof);
    CMCloseProfile(prof);

    UInt8 *tmp_buffer = (UInt8 *) g_malloc(CFDataGetLength(data));
    CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), tmp_buffer);

    buffer = (guint8 *) tmp_buffer;
    buffer_size = CFDataGetLength(data);

    CFRelease(data);
  }
  profile_source = g_strdup("osx color profile api");
#elif defined G_OS_WIN32
  (void)widget;
  HDC hdc = GetDC (NULL);
  if ( hdc!=NULL )
  {
    DWORD len = 0;
    GetICMProfile (hdc, &len, NULL);
    gchar *path = g_new (gchar, len);

    if (GetICMProfile (hdc, &len, path))
    {
      gsize size;
      g_file_get_contents(path, (gchar**)&buffer, &size, NULL);
      buffer_size = size;
    }
    g_free (path);
    ReleaseDC (NULL, hdc);
  }
  profile_source = g_strdup("windows color profile api");
#endif

  int profile_changed = buffer_size > 0 &&
                        (darktable.control->xprofile_size != buffer_size || memcmp(darktable.control->xprofile_data, buffer, buffer_size) != 0);
  if(profile_changed)
  {
    cmsHPROFILE profile = NULL;
    char name[512];
    // thanks to ufraw for this!
    g_free(darktable.control->xprofile_data);
    darktable.control->xprofile_data = buffer;
    darktable.control->xprofile_size = buffer_size;
    profile = cmsOpenProfileFromMem(buffer, buffer_size);
    if(profile)
    {
      dt_colorspaces_get_profile_name(profile, "en", "US", name, sizeof(name));
      cmsCloseProfile(profile);
    }
    dt_print(DT_DEBUG_CONTROL, "[color profile] we got a new screen profile `%s' from the %s (size: %d)\n", *name?name:"(unknown)", profile_source, buffer_size);
  }
  pthread_rwlock_unlock(&darktable.control->xprofile_lock);
  if(profile_changed)
    dt_control_signal_raise(darktable.signals, DT_SIGNAL_CONTROL_PROFILE_CHANGED);
  g_free(profile_source);
}
예제 #17
0
/**
 * gimp_color_profile_new_from_file:
 * @file:  a #GFile
 * @error: return location for #GError
 *
 * This function opens an ICC color profile from @file.
 *
 * Return value: the #GimpColorProfile, or %NULL. On error, %NULL is
 *               returned and @error is set.
 *
 * Since: 2.10
 **/
GimpColorProfile *
gimp_color_profile_new_from_file (GFile   *file,
                                  GError **error)
{
  GimpColorProfile *profile      = NULL;
  cmsHPROFILE       lcms_profile = NULL;
  guint8           *data         = NULL;
  gsize             length       = 0;
  gchar            *path;

  g_return_val_if_fail (G_IS_FILE (file), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  path = g_file_get_path (file);

  if (path)
    {
      GMappedFile  *mapped;

      mapped = g_mapped_file_new (path, FALSE, error);

      if (! mapped)
        return NULL;

      length = g_mapped_file_get_length (mapped);
      data   = g_memdup (g_mapped_file_get_contents (mapped), length);

      lcms_profile = cmsOpenProfileFromMem (data, length);

      g_mapped_file_unref (mapped);
    }
  else
    {
      GFileInfo *info;

      info = g_file_query_info (file,
                                G_FILE_ATTRIBUTE_STANDARD_SIZE,
                                G_FILE_QUERY_INFO_NONE,
                                NULL, error);
      if (info)
        {
          GInputStream *input;

          length = g_file_info_get_size (info);
          data   = g_malloc (length);

          g_object_unref (info);

          input = G_INPUT_STREAM (g_file_read (file, NULL, error));

          if (input)
            {
              gsize bytes_read;

              if (g_input_stream_read_all (input, data, length,
                                           &bytes_read, NULL, error) &&
                  bytes_read == length)
                {
                  lcms_profile = cmsOpenProfileFromMem (data, length);
                }

              g_object_unref (input);
            }
        }
    }

  if (lcms_profile)
    {
      profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL);

      profile->priv->lcms_profile = lcms_profile;
      profile->priv->data         = data;
      profile->priv->length       = length;
    }
  else
    {
      if (data)
        g_free (data);

      if (error && *error == NULL)
        {
          g_set_error (error, gimp_color_profile_error_quark (), 0,
                       _("'%s' does not appear to be an ICC color profile"),
                       gimp_file_get_utf8_name (file));
        }
    }

  return profile;
}
예제 #18
0
파일: jpgicc.c 프로젝트: etlegacy/EasyGen
static
int TransformImage(char *cDefInpProf, char *cOutProf)
{
       cmsHPROFILE hIn, hOut, hProof;
       cmsHTRANSFORM xform;
       cmsUInt32Number wInput, wOutput;
       int OutputColorSpace;
       cmsUInt32Number dwFlags = 0;
       cmsUInt32Number EmbedLen;
       cmsUInt8Number* EmbedBuffer;


       cmsSetAdaptationState(ObserverAdaptationState);

       if (BlackPointCompensation) {

            dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
       }


       switch (PrecalcMode) {

       case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break;
       case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break;
       case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break;
       default:;
       }


       if (GamutCheck) {
            dwFlags |= cmsFLAGS_GAMUTCHECK;
            cmsSetAlarmCodes(Alarm);
       }

       // Take input color space
       wInput = GetInputPixelType();

        if (lIsDeviceLink) {

            hIn = cmsOpenProfileFromFile(cDefInpProf, "r");
            hOut = NULL;
            hProof = NULL;
       }
        else {

        if (!IgnoreEmbedded && read_icc_profile(&Decompressor, &EmbedBuffer, &EmbedLen))
        {
              hIn = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);

               if (Verbose) {

                  fprintf(stdout, " (Embedded profile found)\n");
				  PrintProfileInformation(hIn);
                  fflush(stdout);
              }

               if (hIn != NULL && SaveEmbedded != NULL)
                          SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded);

              free(EmbedBuffer);
        }
        else
        {
            // Default for ITU/Fax
            if (cDefInpProf == NULL && T_COLORSPACE(wInput) == PT_Lab)
                cDefInpProf = "*Lab";

            if (cDefInpProf != NULL && cmsstrcasecmp(cDefInpProf, "*lab") == 0)
                hIn = CreateITU2PCS_ICC();
            else
                hIn = OpenStockProfile(0, cDefInpProf);
       }

        if (cOutProf != NULL && cmsstrcasecmp(cOutProf, "*lab") == 0)
            hOut = CreatePCS2ITU_ICC();
        else
        hOut = OpenStockProfile(0, cOutProf);

       hProof = NULL;
       if (cProofing != NULL) {

           hProof = OpenStockProfile(0, cProofing);
           if (hProof == NULL) {
            FatalError("Proofing profile couldn't be read.");
           }
           dwFlags |= cmsFLAGS_SOFTPROOFING;
          }
       }

        if (!hIn)
            FatalError("Input profile couldn't be read.");
        if (!hOut)
            FatalError("Output profile couldn't be read.");

       // Assure both, input profile and input JPEG are on same colorspace
       if (cmsGetColorSpace(hIn) != _cmsICCcolorSpace(T_COLORSPACE(wInput)))
              FatalError("Input profile is not operating in proper color space");


       // Output colorspace is given by output profile

        if (lIsDeviceLink) {
            OutputColorSpace = GetDevicelinkColorSpace(hIn);
        }
        else {
            OutputColorSpace = GetProfileColorSpace(hOut);
        }

       jpeg_copy_critical_parameters(&Decompressor, &Compressor);

       WriteOutputFields(OutputColorSpace);

       wOutput      = ComputeOutputFormatDescriptor(wInput, OutputColorSpace);


       xform = cmsCreateProofingTransform(hIn, wInput,
                                          hOut, wOutput,
                                          hProof, Intent,
                                          ProofingIntent, dwFlags);
	   if (xform == NULL)
                 FatalError("Cannot transform by using the profiles");

       DoTransform(xform, OutputColorSpace);


       jcopy_markers_execute(&Decompressor, &Compressor);

       cmsDeleteTransform(xform);
       cmsCloseProfile(hIn);
       cmsCloseProfile(hOut);
       if (hProof) cmsCloseProfile(hProof);

       return 1;
}
예제 #19
0
mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
                                      mng_ptr    pProfile)
{
  return cmsOpenProfileFromMem (pProfile, iProfilesize);
}
예제 #20
0
static cmsHPROFILE
cdisplay_lcms_get_display_profile (CdisplayLcms *lcms)
{
  GimpColorConfig *config;
  cmsHPROFILE      profile = NULL;

  config = gimp_color_display_get_config (GIMP_COLOR_DISPLAY (lcms));

#if defined GDK_WINDOWING_X11
  if (config->display_profile_from_gdk)
    {
      GdkScreen *screen;
      GdkAtom    type    = GDK_NONE;
      gint       format  = 0;
      gint       nitems  = 0;
      gint       monitor = 0;
      gchar     *atom_name;
      guchar    *data    = NULL;

      screen = cdisplay_lcms_get_screen (lcms, &monitor);

      if (monitor > 0)
        atom_name = g_strdup_printf ("_ICC_PROFILE_%d", monitor);
      else
        atom_name = g_strdup ("_ICC_PROFILE");

      if (gdk_property_get (gdk_screen_get_root_window (screen),
                            gdk_atom_intern (atom_name, FALSE),
                            GDK_NONE,
                            0, 64 * 1024 * 1024, FALSE,
                            &type, &format, &nitems, &data) && nitems > 0)
        {
          profile = cmsOpenProfileFromMem (data, nitems);
          g_free (data);
        }

      g_free (atom_name);
    }

#elif defined GDK_WINDOWING_QUARTZ
  if (config->display_profile_from_gdk)
    {
      CMProfileRef  prof    = NULL;
      gint          monitor = 0;

      cdisplay_lcms_get_screen (lcms, &monitor);

      CMGetProfileByAVID (monitor, &prof);

      if (prof)
        {
          CFDataRef data;

          data = CMProfileCopyICCData (NULL, prof);
          CMCloseProfile (prof);

          if (data)
            {
              UInt8 *buffer = g_malloc (CFDataGetLength (data));

              /* We cannot use CFDataGetBytesPtr(), because that returns
               * a const pointer where cmsOpenProfileFromMem wants a
               * non-const pointer.
               */
              CFDataGetBytes (data, CFRangeMake (0, CFDataGetLength (data)),
                              buffer);

              profile = cmsOpenProfileFromMem (buffer, CFDataGetLength (data));

              g_free (buffer);
              CFRelease (data);
            }
        }
    }

#elif defined G_OS_WIN32
  if (config->display_profile_from_gdk)
    {
      HDC hdc = GetDC (NULL);

      if (hdc)
        {
          gchar *path;
          gint32 len = 0;

          GetICMProfile (hdc, &len, NULL);
          path = g_new (gchar, len);

          if (GetICMProfile (hdc, &len, path))
            profile = cmsOpenProfileFromFile (path, "r");

          g_free (path);
          ReleaseDC (NULL, hdc);
        }
    }
#endif

  if (! profile && config->display_profile)
    profile = cmsOpenProfileFromFile (config->display_profile, "r");

  return profile;
}
예제 #21
0
static
cmsHPROFILE GetTIFFProfile(TIFF* in)
{    
    cmsCIExyYTRIPLE Primaries;
	float* chr;
    cmsCIExyY WhitePoint;
    float* wp;
    int i;       
    LPGAMMATABLE Gamma[3]; 
    LPWORD gmr, gmg, gmb;
    cmsHPROFILE hProfile;
    DWORD EmbedLen;
    LPBYTE EmbedBuffer;
      
              
       if (IgnoreEmbedded) return NULL;

       if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) {

              hProfile = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
   
              if (Verbose) {

                  fprintf(stdout, " (Embedded profile found)\n");
                  fprintf(stdout, "Product name: %s\n", cmsTakeProductName(hProfile));
                  fprintf(stdout, "Description : %s\n", cmsTakeProductDesc(hProfile));                          
                  fflush(stdout);
              }

              if (hProfile != NULL && SaveEmbedded != NULL)
                  SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded);

              if (hProfile) return hProfile;
       }

        // Try to see if "colorimetric" tiff

       if (TIFFGetField(in, TIFFTAG_PRIMARYCHROMATICITIES, &chr)) {
                      
           Primaries.Red.x   =  chr[0];
           Primaries.Red.y   =  chr[1];
           Primaries.Green.x =  chr[2];
           Primaries.Green.y =  chr[3];
           Primaries.Blue.x  =  chr[4];
           Primaries.Blue.y  =  chr[5];
           
           Primaries.Red.Y = Primaries.Green.Y = Primaries.Blue.Y = 1.0;
                      
           if (TIFFGetField(in, TIFFTAG_WHITEPOINT, &wp)) {
               
               WhitePoint.x = wp[0];
               WhitePoint.y = wp[1];
               WhitePoint.Y = 1.0;
                                             
               // Transferfunction is a bit harder....
               
               for (i=0; i < 3; i++)
                   Gamma[i] = cmsAllocGamma(256);
                                            
               TIFFGetFieldDefaulted(in, TIFFTAG_TRANSFERFUNCTION,
                   &gmr, 
                   &gmg,
                   &gmb);
               
               CopyMemory(Gamma[0]->GammaTable, gmr, 256*sizeof(WORD));
               CopyMemory(Gamma[1]->GammaTable, gmg, 256*sizeof(WORD));
               CopyMemory(Gamma[2]->GammaTable, gmb, 256*sizeof(WORD));
               
               hProfile = cmsCreateRGBProfile(&WhitePoint, &Primaries, Gamma);
               
               for (i=0; i < 3; i++)
                   cmsFreeGamma(Gamma[i]);

                if (Verbose) {
                  fprintf(stdout, " (Colorimetric TIFF)\n");
                }
             
               
               return hProfile;
           }
       }

       return NULL;
}
예제 #22
0
PyObject *
load_png_fast_progressive (char *filename,
                           PyObject *get_buffer_callback)
{
  // Note: we are not using the method that libpng calls "Reading PNG
  // files progressively". That method would involve feeding the data
  // into libpng piece by piece, which is not necessary if we can give
  // libpng a simple FILE pointer.

  png_structp png_ptr = NULL;
  png_infop info_ptr = NULL;
  PyObject * result = NULL;
  FILE *fp = NULL;
  uint32_t width, height;
  uint32_t rows_left;
  png_byte color_type;
  png_byte bit_depth;
  bool have_alpha;
  char *cm_processing = NULL;

  // ICC profile-based colour conversion data.
  png_charp icc_profile_name = NULL;
  int icc_compression_type = 0;
#if PNG_LIBPNG_VER < 10500    // 1.5.0beta36, according to libpng CHANGES
  png_charp icc_profile = NULL;
#else
  png_bytep icc_profile = NULL;
#endif
  png_uint_32 icc_proflen = 0;

  // The sRGB flag has an intent field, which we ignore - 
  // the target gamut is sRGB already.
  int srgb_intent = 0;

  // Generic RGB space conversion params.
  // The assumptions we're making are those of sRGB,
  // but they'll be overridden by gammas or primaries in the file if used.
  bool generic_rgb_have_gAMA = false;
  bool generic_rgb_have_cHRM = false;
  double generic_rgb_file_gamma = 45455 / PNG_gAMA_scale;
  double generic_rgb_white_x = 31270 / PNG_cHRM_scale;
  double generic_rgb_white_y = 32900 / PNG_cHRM_scale;
  double generic_rgb_red_x   = 64000 / PNG_cHRM_scale;
  double generic_rgb_red_y   = 33000 / PNG_cHRM_scale;
  double generic_rgb_green_x = 30000 / PNG_cHRM_scale;
  double generic_rgb_green_y = 60000 / PNG_cHRM_scale;
  double generic_rgb_blue_x  = 15000 / PNG_cHRM_scale;
  double generic_rgb_blue_y  =  6000 / PNG_cHRM_scale;

  // Indicates the case where no CM information was present in the file and we
  // treated it as sRGB.
  bool possible_legacy_png = false;

  // LCMS stuff
  cmsHPROFILE input_buffer_profile = NULL;
  cmsHPROFILE nparray_data_profile = cmsCreate_sRGBProfile();
  cmsHTRANSFORM input_buffer_to_nparray = NULL;
  cmsToneCurve *gamma_transfer_func = NULL;
  cmsUInt32Number input_buffer_format = 0;

  cmsSetLogErrorHandler(log_lcms2_error);

  fp = fopen(filename, "rb");
  if (!fp) {
    PyErr_SetFromErrno(PyExc_IOError);
    //PyErr_Format(PyExc_IOError, "Could not open PNG file for writing: %s",
    //             filename);
    goto cleanup;
  }

  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
                                    png_read_error_callback, NULL);
  if (!png_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_write_struct() failed");
    goto cleanup;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_info_struct() failed");
    goto cleanup;
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    goto cleanup;
  }

  png_init_io(png_ptr, fp);

  png_read_info(png_ptr, info_ptr);

  // If there's an embedded ICC profile, use it in preference to any other
  // colour management information present.
  if (png_get_iCCP (png_ptr, info_ptr, &icc_profile_name,
                    &icc_compression_type, &icc_profile,
                    &icc_proflen))
  {
    input_buffer_profile = cmsOpenProfileFromMem(icc_profile, icc_proflen);
    if (! input_buffer_profile) {
      PyErr_SetString(PyExc_MemoryError, "cmsOpenProfileFromMem() failed");
      goto cleanup;
    }
    cm_processing = "iCCP (use embedded colour profile)";
  }

  // Shorthand for sRGB.
  else if (png_get_sRGB (png_ptr, info_ptr, &srgb_intent)) {
    input_buffer_profile = cmsCreate_sRGBProfile();
    cm_processing = "sRGB (explicit sRGB chunk)";
  }

  else {
    // We might have generic RGB transformation information in the form of
    // the chromaticities for R, G and B and a generic gamma curve.

    if (png_get_cHRM (png_ptr, info_ptr,
                      &generic_rgb_white_x, &generic_rgb_white_y,
                      &generic_rgb_red_x, &generic_rgb_red_y,
                      &generic_rgb_green_x, &generic_rgb_green_y,
                      &generic_rgb_blue_x, &generic_rgb_blue_y))
    {
      generic_rgb_have_cHRM = true;
    }
    if (png_get_gAMA(png_ptr, info_ptr, &generic_rgb_file_gamma)) {
      generic_rgb_have_gAMA = true;
    }
    if (generic_rgb_have_gAMA || generic_rgb_have_cHRM) {
      cmsCIExyYTRIPLE primaries = {{generic_rgb_red_x, generic_rgb_red_y},
                                   {generic_rgb_green_x, generic_rgb_green_y},
                                   {generic_rgb_blue_x, generic_rgb_blue_y}};
      cmsCIExyY white_point = {generic_rgb_white_x, generic_rgb_white_y};
      gamma_transfer_func = cmsBuildGamma(NULL, 1.0/generic_rgb_file_gamma);
      cmsToneCurve *transfer_funcs[3] = {gamma_transfer_func,
                                         gamma_transfer_func,
                                         gamma_transfer_func };
      input_buffer_profile = cmsCreateRGBProfile(&white_point, &primaries,
                                                transfer_funcs);
      cm_processing = "cHRM and/or gAMA (generic RGB space)";
    }

    // Possible legacy PNG, or rather one which might have been written with an
    // old version of MyPaint. Treat as sRGB, but flag the strangeness because
    // it might be important for PNGs in old OpenRaster files.
    else {
      possible_legacy_png = true;
      input_buffer_profile = cmsCreate_sRGBProfile();
      cm_processing = "sRGB (no CM chunks present)";
    }
  }

  if (png_get_interlace_type (png_ptr, info_ptr) != PNG_INTERLACE_NONE) {
    PyErr_SetString(PyExc_RuntimeError,
                    "Interlaced PNG files are not supported!");
    goto cleanup;
  }

  color_type = png_get_color_type(png_ptr, info_ptr);
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  have_alpha = color_type & PNG_COLOR_MASK_ALPHA;

  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(png_ptr);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(png_ptr);
  }

  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png_ptr);
    have_alpha = true;
  }

  if (bit_depth < 8) {
    png_set_packing(png_ptr);
  }

  if (!have_alpha) {
    png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(png_ptr);
  }

  png_read_update_info(png_ptr, info_ptr);

  // Verify what we have done
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  if (! (bit_depth == 8 || bit_depth == 16)) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to 8 or 16 bits per channel");
    goto cleanup;
  }
  if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB_ALPHA) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong color_type)");
    goto cleanup;
  }
  if (png_get_channels(png_ptr, info_ptr) != 4) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong number of channels)");
    goto cleanup;
  }

  // PNGs use network byte order, i.e. big-endian in descending order
  // of bit significance. LittleCMS uses whatever's detected for the compiler.
  // ref: http://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order
  if (bit_depth == 16) {
#ifdef CMS_USE_BIG_ENDIAN
    input_buffer_format = TYPE_RGBA_16;
#else
    input_buffer_format = TYPE_RGBA_16_SE;
#endif
  }
  else {
    input_buffer_format = TYPE_RGBA_8;
  }

  input_buffer_to_nparray = cmsCreateTransform
        (input_buffer_profile, input_buffer_format,
         nparray_data_profile, TYPE_RGBA_8,
         INTENT_PERCEPTUAL, 0);

  width = png_get_image_width(png_ptr, info_ptr);
  height = png_get_image_height(png_ptr, info_ptr);
  rows_left = height;

  while (rows_left) {
    PyObject *pyarr = NULL;
    uint32_t rows = 0;
    uint32_t row = 0;
    const uint8_t input_buf_bytes_per_pixel = (bit_depth==8) ? 4 : 8;
    const uint32_t input_buf_row_stride = sizeof(png_byte) * width
                                          * input_buf_bytes_per_pixel;
    png_byte *input_buffer = NULL;
    png_bytep *input_buf_row_pointers = NULL;

    pyarr = PyObject_CallFunction(get_buffer_callback, "ii", width, height);
    if (! pyarr) {
      PyErr_Format(PyExc_RuntimeError, "Get-buffer callback failed");
      goto cleanup;
    }
#ifdef HEAVY_DEBUG
    //assert(PyArray_ISCARRAY(arr));
    assert(PyArray_NDIM(pyarr) == 3);
    assert(PyArray_DIM(pyarr, 1) == width);
    assert(PyArray_DIM(pyarr, 2) == 4);
    assert(PyArray_TYPE(pyarr) == NPY_UINT8);
    assert(PyArray_ISBEHAVED(pyarr));
    assert(PyArray_STRIDE(pyarr, 1) == 4*sizeof(uint8_t));
    assert(PyArray_STRIDE(pyarr, 2) ==   sizeof(uint8_t));
#endif
    rows = PyArray_DIM(pyarr, 0);

    if (rows > rows_left) {
      PyErr_Format(PyExc_RuntimeError,
                   "Attempt to read %d rows from the PNG, "
                   "but only %d are left",
                   rows, rows_left);
      goto cleanup;
    }

    input_buffer = (png_byte *) malloc(rows * input_buf_row_stride);
    input_buf_row_pointers = (png_bytep *)malloc(rows * sizeof(png_bytep));
    for (row=0; row<rows; row++) {
      input_buf_row_pointers[row] = input_buffer + (row * input_buf_row_stride);
    }

    png_read_rows(png_ptr, input_buf_row_pointers, NULL, rows);
    rows_left -= rows;

    for (row=0; row<rows; row++) {
      uint8_t *pyarr_row = (uint8_t *)PyArray_DATA(pyarr)
                         + row*PyArray_STRIDE(pyarr, 0);
      uint8_t *input_row = input_buf_row_pointers[row];
      // Really minimal fake colour management. Just remaps to sRGB.
      cmsDoTransform(input_buffer_to_nparray, input_row, pyarr_row, width);
      // lcms2 ignores alpha, so copy that verbatim
      // If it's 8bpc RGBA, use A.
      // If it's 16bpc RrGgBbAa, use A.
      for (uint32_t i=0; i<width; ++i) {
        const uint32_t pyarr_alpha_byte = (i*4) + 3;
        const uint32_t buf_alpha_byte = (i*input_buf_bytes_per_pixel)
                                       + ((bit_depth==8) ? 3 : 6);
        pyarr_row[pyarr_alpha_byte] = input_row[buf_alpha_byte];
      }
    }

    free(input_buf_row_pointers);
    free(input_buffer);

    Py_DECREF(pyarr);
  }

  png_read_end(png_ptr, NULL);

  result = Py_BuildValue("{s:b,s:i,s:i,s:s}",
                         "possible_legacy_png", possible_legacy_png,
                         "width", width,
                         "height", height,
                         "cm_conversions_applied", cm_processing);

 cleanup:
  if (info_ptr) png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  // libpng's style is to free internally allocated stuff like the icc
  // tables in png_destroy_*(). I think.
  if (fp) fclose(fp);
  if (input_buffer_profile) cmsCloseProfile(input_buffer_profile);
  if (nparray_data_profile) cmsCloseProfile(nparray_data_profile);
  if (input_buffer_to_nparray) cmsDeleteTransform(input_buffer_to_nparray);
  if (gamma_transfer_func) cmsFreeToneCurve(gamma_transfer_func);

  return result;
}
예제 #23
0
cmsHPROFILE
dt_colorspaces_create_output_profile(const int imgid)
{
  char profile[1024];
  profile[0] = '\0';
  // db lookup colorout params, and dt_conf_() for override
  gchar *overprofile = dt_conf_get_string("plugins/lighttable/export/iccprofile");
  if(!overprofile || !strcmp(overprofile, "image"))
  {
    const dt_iop_colorout_params_t *params;
    // sqlite:
    sqlite3_stmt *stmt;
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select op_params from history where imgid=?1 and operation='colorout'", -1, &stmt, NULL);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
    if(sqlite3_step(stmt) == SQLITE_ROW)
    {
      params = sqlite3_column_blob(stmt, 0);
      g_strlcpy(profile, params->iccprofile, 1024);
    }
    sqlite3_finalize(stmt);
  }
  if(!overprofile && profile[0] == '\0')
  {
    g_strlcpy(profile, "sRGB", 1024);
  }
  else if(profile[0] == '\0')
  {
    g_strlcpy(profile, overprofile, 1024);
  }

  if(overprofile)
  {
    g_free(overprofile);
  }

  cmsHPROFILE output = NULL;

  if(!strcmp(profile, "sRGB"))
    output = dt_colorspaces_create_srgb_profile();
  else if(!strcmp(profile, "linear_rgb"))
    output = dt_colorspaces_create_linear_rgb_profile();
  else if(!strcmp(profile, "XYZ"))
    output = dt_colorspaces_create_xyz_profile();
  else if(!strcmp(profile, "adobergb"))
    output = dt_colorspaces_create_adobergb_profile();
  else if(!strcmp(profile, "X profile"))
  {
    pthread_rwlock_rdlock(&darktable.control->xprofile_lock);
    if(darktable.control->xprofile_data)
      output = cmsOpenProfileFromMem(darktable.control->xprofile_data, darktable.control->xprofile_size);
    pthread_rwlock_unlock(&darktable.control->xprofile_lock);
  }
  else
  {
    // else: load file name
    char filename[DT_MAX_PATH_LEN];
    dt_colorspaces_find_profile(filename, DT_MAX_PATH_LEN, profile, "out");
    output = cmsOpenProfileFromFile(filename, "r");
  }
  if(!output) output = dt_colorspaces_create_srgb_profile();
  return output;
}
예제 #24
0
void CLASS apply_profile (const char *input, const char *output)
{
  char *prof;
  cmsHPROFILE hInProfile=0, hOutProfile=0;
  cmsHTRANSFORM hTransform;
  FILE *fp;
  unsigned size;

#ifndef USE_LCMS2
  cmsErrorAction (LCMS_ERROR_SHOW);
#endif
  if (strcmp (input, "embed"))
    hInProfile = cmsOpenProfileFromFile (input, "r");
  else if (profile_length) {
#ifndef LIBRAW_LIBRARY_BUILD
    prof = (char *) malloc (profile_length);
    merror (prof, "apply_profile()");
    fseek (ifp, profile_offset, SEEK_SET);
    fread (prof, 1, profile_length, ifp);
    hInProfile = cmsOpenProfileFromMem (prof, profile_length);
    free (prof);
#else
    hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
#endif
  } else
    {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
#endif
#ifdef DCRAW_VERBOSE
          fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
#endif
    }
  if (!hInProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
#endif
          return;
      }
  if (!output)
    hOutProfile = cmsCreate_sRGBProfile();
  else if ((fp = fopen (output, "rb"))) {
    fread (&size, 4, 1, fp);
    fseek (fp, 0, SEEK_SET);
    oprof = (unsigned *) malloc (size = ntohl(size));
    merror (oprof, "apply_profile()");
    fread (oprof, 1, size, fp);
    fclose (fp);
    if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
      free (oprof);
      oprof = 0;
    }
  }
#ifdef DCRAW_VERBOSE
 else
    fprintf (stderr,_("Cannot open file %s!\n"), output);
#endif
  if (!hOutProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
#endif
          goto quit;
      }
#ifdef DCRAW_VERBOSE
  if (verbose)
    fprintf (stderr,_("Applying color profile...\n"));
#endif
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2);
#endif
  hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
	hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
  cmsDoTransform (hTransform, image, image, width*height);
  raw_color = 1;		/* Don't use rgb_cam with a profile */
  cmsDeleteTransform (hTransform);
  cmsCloseProfile (hOutProfile);
quit:
  cmsCloseProfile (hInProfile);
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2);
#endif
}
예제 #25
0
static
int TransformImage(char *cDefInpProf, char *cOutProf)
{
       cmsHPROFILE hIn, hOut, hProof;
       cmsHTRANSFORM xform;
       DWORD wInput, wOutput;
       int OutputColorSpace;
       DWORD dwFlags = 0; 
       DWORD EmbedLen;
       LPBYTE EmbedBuffer;


       if (BlackPointCompensation) {

            dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;            
       }

       switch (PrecalcMode) {
           
       case 0: dwFlags |= cmsFLAGS_NOTPRECALC; break;
       case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break;
       case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break;
       default:;
       }
        

       if (GamutCheck)
            dwFlags |= cmsFLAGS_GAMUTCHECK;
        

        if (lIsDeviceLink) {

            hIn = cmsOpenProfileFromFile(cDefInpProf, "r");
            hOut = NULL;
            hProof = NULL;
       }
        else {

        if (!IgnoreEmbedded && read_icc_profile(&Decompressor, &EmbedBuffer, &EmbedLen))
        {
              hIn = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);

               if (Verbose) {

                  fprintf(stdout, " (Embedded profile found)\n");
                  fprintf(stdout, "Product name: %s\n", cmsTakeProductName(hIn));
                  fprintf(stdout, "Description : %s\n", cmsTakeProductDesc(hIn));                          
                  fflush(stdout);
              }

               if (hIn != NULL && SaveEmbedded != NULL)
                          SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded);

              free(EmbedBuffer);
        }
        else
        {
                hIn = OpenStockProfile(cDefInpProf);
       }

        hOut = OpenStockProfile(cOutProf);


       hProof = NULL;
       if (cProofing != NULL) {

           hProof = OpenStockProfile(cProofing);
       }
        }

       // Take input color space

       wInput = GetInputPixelType();

       // Assure both, input profile and input JPEG are on same colorspace

       
       if (cmsGetColorSpace(hIn) != _cmsICCcolorSpace(T_COLORSPACE(wInput)))
              FatalError("Input profile is not operating in proper color space");
       

       // Output colorspace is given by output profile

        if (lIsDeviceLink) {
            OutputColorSpace = T_COLORSPACE(wInput);
        }
        else {
            OutputColorSpace = GetProfileColorSpace(hOut);
        }

       jpeg_copy_critical_parameters(&Decompressor, &Compressor);
       
       WriteOutputFields(OutputColorSpace);               
       
       wOutput      = ComputeOutputFormatDescriptor(wInput, OutputColorSpace);
       
       xform = cmsCreateProofingTransform(hIn, wInput, 
                                          hOut, wOutput, 
                                          hProof, Intent, 
                                          ProofingIntent, dwFlags);

       // Handle tile by tile or strip by strip strtok

       DoTransform(xform);

       
       jcopy_markers_execute(&Decompressor, &Compressor);
       
       cmsDeleteTransform(xform);
       cmsCloseProfile(hIn);
       cmsCloseProfile(hOut);
       if (hProof) cmsCloseProfile(hProof);
       
       return 1;
}
예제 #26
0
static gpointer
jpeg_load_cmyk_transform (guint8 *profile_data,
                          gsize   profile_len)
{
  GimpColorConfig *config       = gimp_get_color_configuration ();
  cmsHPROFILE      cmyk_profile = NULL;
  cmsHPROFILE      rgb_profile  = NULL;
  cmsUInt32Number  flags        = 0;
  cmsHTRANSFORM    transform;

  /*  try to load the embedded CMYK profile  */
  if (profile_data)
    {
      cmyk_profile = cmsOpenProfileFromMem (profile_data, profile_len);

      if (cmyk_profile)
        {
          if (! gimp_lcms_profile_is_cmyk (cmyk_profile))
            {
              cmsCloseProfile (cmyk_profile);
              cmyk_profile = NULL;
            }
        }
    }

  /*  if that fails, try to load the CMYK profile configured in the prefs  */
  if (! cmyk_profile && config->cmyk_profile)
    {
      cmyk_profile = cmsOpenProfileFromFile (config->cmyk_profile, "r");

      if (cmyk_profile && ! gimp_lcms_profile_is_cmyk (cmyk_profile))
        {
          cmsCloseProfile (cmyk_profile);
          cmyk_profile = NULL;
        }
    }

  /*  bail out if we can't load any CMYK profile  */
  if (! cmyk_profile)
    {
      g_object_unref (config);
      return NULL;
    }

  /*  try to load the RGB profile configured in the prefs  */
  if (config->rgb_profile)
    {
      rgb_profile = cmsOpenProfileFromFile (config->rgb_profile, "r");

      if (rgb_profile && ! gimp_lcms_profile_is_rgb (rgb_profile))
        {
          cmsCloseProfile (rgb_profile);
          rgb_profile = NULL;
        }
    }

  /*  make the real sRGB profile as a fallback  */
  if (! rgb_profile)
    {
      rgb_profile = gimp_lcms_create_srgb_profile ();
    }

  if (config->display_intent ==
      GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC)
    {
      flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
    }

  transform = cmsCreateTransform (cmyk_profile, TYPE_CMYK_8_REV,
                                  rgb_profile,  TYPE_RGB_8,
                                  config->display_intent,
                                  flags);

  cmsCloseProfile (cmyk_profile);
  cmsCloseProfile (rgb_profile);

  g_object_unref (config);

  return transform;
}
예제 #27
0
cmsHPROFILE dkCmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize)
{
    return cmsOpenProfileFromMem(MemPtr, static_cast<cmsUInt32Number>( dwSize ));
}
예제 #28
0
bool LcmsColorProfileContainer::init()
{
    if (d->profile) {
        cmsCloseProfile(d->profile);
    }

    d->profile = cmsOpenProfileFromMem((void *)d->data->rawData().constData(), d->data->rawData().size());

#ifndef NDEBUG
    if (d->data->rawData().size() == 4096) {
        qWarning() << "Profile has a size of 4096, which is suspicious and indicates a possible misuse of QIODevice::read(int), check your code.";
    }
#endif

    if (d->profile) {
        wchar_t buffer[_BUFFER_SIZE_];
        d->colorSpaceSignature = cmsGetColorSpace(d->profile);
        d->deviceClass = cmsGetDeviceClass(d->profile);
        cmsGetProfileInfo(d->profile, cmsInfoDescription, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_);
        d->name = QString::fromWCharArray(buffer);

        //apparantly this should give us a localised string??? Not sure about this.
        cmsGetProfileInfo(d->profile, cmsInfoModel, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_);
        d->productDescription = QString::fromWCharArray(buffer);

        cmsGetProfileInfo(d->profile, cmsInfoManufacturer, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_);
        d->manufacturer = QString::fromWCharArray(buffer);

        cmsGetProfileInfo(d->profile, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_);
        d->copyright = QString::fromWCharArray(buffer);

        cmsProfileClassSignature profile_class;
        profile_class = cmsGetDeviceClass(d->profile);
        d->valid = (profile_class != cmsSigNamedColorClass);

        //This is where obtain the whitepoint, and convert it to the actual white point of the profile in the case a Chromatic adaption tag is
        //present. This is necessary for profiles following the v4 spec.
        cmsCIEXYZ baseMediaWhitePoint;//dummy to hold copy of mediawhitepoint if this is modified by chromatic adaption.
        if (cmsIsTag(d->profile, cmsSigMediaWhitePointTag)) {
            d->mediaWhitePoint = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigMediaWhitePointTag));
            baseMediaWhitePoint = d->mediaWhitePoint;
            cmsXYZ2xyY(&d->whitePoint, &d->mediaWhitePoint);

            if (cmsIsTag(d->profile, cmsSigChromaticAdaptationTag)) {
                //the chromatic adaption tag represent a matrix from the actual white point of the profile to D50.
                cmsCIEXYZ *CAM1 = (cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigChromaticAdaptationTag);
                //We first put all our data into structures we can manipulate.
                double d3dummy [3] = {d->mediaWhitePoint.X, d->mediaWhitePoint.Y, d->mediaWhitePoint.Z};
                QGenericMatrix<1, 3, double> whitePointMatrix(d3dummy);
                QTransform invertDummy(CAM1[0].X, CAM1[0].Y, CAM1[0].Z, CAM1[1].X, CAM1[1].Y, CAM1[1].Z, CAM1[2].X, CAM1[2].Y, CAM1[2].Z);
                //we then abuse QTransform's invert function because it probably does matrix invertion 20 times better than I can program.
                //if the matrix is uninvertable, invertedDummy will be an identity matrix, which for us means that it won't give any noticeble
                //effect when we start multiplying.
                QTransform invertedDummy = invertDummy.inverted();
                //we then put the QTransform into a generic 3x3 matrix.
                double d9dummy [9] = {invertedDummy.m11(), invertedDummy.m12(), invertedDummy.m13(),
                                      invertedDummy.m21(), invertedDummy.m22(), invertedDummy.m23(),
                                      invertedDummy.m31(), invertedDummy.m32(), invertedDummy.m33()
                                     };
                QGenericMatrix<3, 3, double> chromaticAdaptionMatrix(d9dummy);
                //multiplying our inverted adaption matrix with the whitepoint gives us the right whitepoint.
                QGenericMatrix<1, 3, double> result = chromaticAdaptionMatrix * whitePointMatrix;
                //and then we pour the matrix into the whitepoint variable. Generic matrix does row/column for indices even though it
                //uses column/row for initialising.
                d->mediaWhitePoint.X = result(0, 0);
                d->mediaWhitePoint.Y = result(1, 0);
                d->mediaWhitePoint.Z = result(2, 0);
                cmsXYZ2xyY(&d->whitePoint, &d->mediaWhitePoint);
            }
        }
        //This is for RGB profiles, but it only works for matrix profiles. Need to design it to work with non-matrix profiles.
        if (cmsIsTag(d->profile, cmsSigRedColorantTag)) {
            cmsCIEXYZTRIPLE tempColorants;
            tempColorants.Red = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigRedColorantTag));
            tempColorants.Green = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigGreenColorantTag));
            tempColorants.Blue = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigBlueColorantTag));
            //convert to d65, this is useless.
            cmsAdaptToIlluminant(&d->colorants.Red, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Red);
            cmsAdaptToIlluminant(&d->colorants.Green, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Green);
            cmsAdaptToIlluminant(&d->colorants.Blue, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Blue);
            //d->colorants = tempColorants;
            d->hasColorants = true;
        } else {
            //qDebug()<<d->name<<": has no colorants";
            d->hasColorants = false;
        }
        //retrieve TRC.
        if (cmsIsTag(d->profile, cmsSigRedTRCTag) && cmsIsTag(d->profile, cmsSigBlueTRCTag) && cmsIsTag(d->profile, cmsSigGreenTRCTag)) {

            d->redTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigRedTRCTag));
            d->greenTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigGreenTRCTag));
            d->blueTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigBlueTRCTag));
            d->redTRCReverse = cmsReverseToneCurve(d->redTRC);
            d->greenTRCReverse = cmsReverseToneCurve(d->greenTRC);
            d->blueTRCReverse = cmsReverseToneCurve(d->blueTRC);
            d->hasTRC = true;

        } else if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) {
            d->grayTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigGrayTRCTag));
            d->grayTRCReverse = cmsReverseToneCurve(d->grayTRC);
            d->hasTRC = true;
        } else {
            d->hasTRC = false;
        }

        // Check if the profile can convert (something->this)
        d->suitableForOutput = cmsIsMatrixShaper(d->profile)
                               || (cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT) &&
                                   cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT));

        d->version = cmsGetProfileVersion(d->profile);
        d->defaultIntent = cmsGetHeaderRenderingIntent(d->profile);
        d->isMatrixShaper = cmsIsMatrixShaper(d->profile);
        d->isPerceptualCLUT = cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT);
        d->isSaturationCLUT = cmsIsCLUT(d->profile, INTENT_SATURATION, LCMS_USED_AS_INPUT);
        d->isAbsoluteCLUT = cmsIsCLUT(d->profile, INTENT_SATURATION, LCMS_USED_AS_INPUT);
        d->isRelativeCLUT = cmsIsCLUT(d->profile, INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT);

        return true;
    }

    return false;
}
예제 #29
0
/* Get ICC Profile handle from buffer */
gcmmhprofile_t
gscms_get_profile_handle_mem(unsigned char *buffer, unsigned int input_size)
{
    cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error);
    return(cmsOpenProfileFromMem(buffer,input_size));
}
예제 #30
0
파일: color-man.c 프로젝트: metux/geeqie
static cmsHPROFILE color_man_create_adobe_comp(void)
{
	/* ClayRGB1998 is AdobeRGB compatible */
#include "ClayRGB1998_icc.h"
	return cmsOpenProfileFromMem(ClayRGB1998_icc, ClayRGB1998_icc_len);
}