Exemplo n.º 1
0
/**
 * cd_util_get_profile_coverage:
 **/
static gdouble
cd_util_get_profile_coverage (CdUtilPrivate *priv,
			      CdStandardSpace standard_space,
			      GError **error)
{
	gchar *filename = NULL;
	gdouble coverage = -1.0f;
	cmsHPROFILE profile;

	/* get the correct standard space */
	filename = cd_util_get_standard_space_filename (priv,
							standard_space,
							error);
	if (filename == NULL)
		goto out;

	/* work out the coverage */
	profile = cd_icc_get_handle (priv->icc);
	coverage = cd_util_get_coverage (profile, filename, error);
	if (coverage < 0.0f)
		goto out;
out:
	g_free (filename);
	return coverage;
}
Exemplo n.º 2
0
/**
 * cd_util_extract_vcgt:
 **/
static gboolean
cd_util_extract_vcgt (CdUtilPrivate *priv, gchar **values, GError **error)
{
	cmsFloat32Number in;
	cmsHPROFILE lcms_profile;
	const cmsToneCurve **vcgt;
	guint i;
	guint size;

	/* check arguments */
	if (g_strv_length (values) != 2) {
		g_set_error_literal (error, 1, 0,
				     "invalid input, expect 'filename' size'");
		return FALSE;
	}

	/* invalid size */
	size = atoi (values[1]);
	if (size <= 1 || size > 1024) {
		g_set_error_literal (error, 1, 0,
				     "invalid size,expected 2-1024");
		return FALSE;
	}

	/* does profile have VCGT */
	lcms_profile = cd_icc_get_handle (priv->icc);
	vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag);
	if (vcgt == NULL || vcgt[0] == NULL) {
		g_set_error_literal (error, 1, 0,
				     "profile does not have any VCGT data");
		return FALSE;
	}

	/* output data */
	g_print ("idx,red,green,blue\n");
	for (i = 0; i < size; i++) {
		in = (gdouble) i / (gdouble) (size - 1);
		g_print ("%u,", i);
		g_print ("%f,", cmsEvalToneCurveFloat(vcgt[0], in));
		g_print ("%f,", cmsEvalToneCurveFloat(vcgt[1], in));
		g_print ("%f\n", cmsEvalToneCurveFloat(vcgt[2], in));
	}

	/* success */
	priv->rewrite_file = FALSE;
	return TRUE;
}
Exemplo n.º 3
0
/**
 * cd_icc_utils_get_coverage_calc:
 **/
static gboolean
cd_icc_utils_get_coverage_calc (CdIcc *icc,
				CdIcc *icc_reference,
				gdouble *coverage,
				GError **error)
{
	const guint cube_size = 33;
	cmsHPROFILE profile_null = NULL;
	cmsHTRANSFORM transform = NULL;
	cmsUInt32Number dimensions[] = { cube_size, cube_size, cube_size };
	CdIccUtilsGamutCheckHelper helper;
	gboolean ret = TRUE;
	guint cnt = 0;
	guint data_len = cube_size * cube_size * cube_size;
	guint i;
	g_autofree cmsFloat32Number *data = NULL;
	g_autofree cmsUInt16Number *alarm_codes = NULL;

	/* create a proofing transform with gamut check */
	profile_null = cmsCreateNULLProfileTHR (cd_icc_get_context (icc));
	transform = cmsCreateProofingTransformTHR (cd_icc_get_context (icc),
						   cd_icc_get_handle (icc),
						   TYPE_RGB_FLT,
						   profile_null,
						   TYPE_GRAY_FLT,
						   cd_icc_get_handle (icc_reference),
						   INTENT_ABSOLUTE_COLORIMETRIC,
						   INTENT_ABSOLUTE_COLORIMETRIC,
						   cmsFLAGS_GAMUTCHECK |
						   cmsFLAGS_SOFTPROOFING);
	if (transform == NULL) {
		ret = FALSE;
		g_set_error (error,
			     CD_ICC_ERROR,
			     CD_ICC_ERROR_INVALID_COLORSPACE,
			     "Failed to setup transform for %s->%s",
			     cd_icc_get_filename (icc),
			     cd_icc_get_filename (icc_reference));
		goto out;
	}

	/* set gamut alarm to 0xffff */
	alarm_codes = g_new0 (cmsUInt16Number, cmsMAXCHANNELS);
	alarm_codes[0] = 0xffff;
	cmsSetAlarmCodes (alarm_codes);

	/* slice profile in regular intevals */
	data = g_new0 (cmsFloat32Number, data_len * 3);
	helper.data = data;
	helper.idx = 0;
	ret = cmsSliceSpaceFloat (3, dimensions,
				  cd_icc_utils_get_coverage_sample_cb,
				  &helper);
	if (!ret) {
		g_set_error_literal (error,
				     CD_ICC_ERROR,
				     CD_ICC_ERROR_INTERNAL,
				     "Failed to slice data");
		goto out;
	}

	/* transform each one of those nodes across the proofing transform */
	cmsDoTransform (transform, helper.data, helper.data, data_len);

	/* count the nodes that gives you zero and divide by total number */
	for (i = 0; i < data_len; i++) {
		if (helper.data[i] == 0.0)
			cnt++;
	}

	/* success */
	if (coverage != NULL)
		*coverage = (gdouble) cnt / (gdouble) data_len;
out:
	cmsCloseProfile (profile_null);
	if (transform != NULL)
		cmsDeleteTransform (transform);
	return ret;
}