Пример #1
0
/* Get ICC Profile handle from buffer */
gcmmhprofile_t
gscms_get_profile_handle_mem(gs_memory_t *mem, unsigned char *buffer,
                             unsigned int input_size)
{
    cmsSetLogErrorHandler(gscms_error);
    return(cmsOpenProfileFromMemTHR((cmsContext)mem,buffer,input_size));
}
Пример #2
0
/**
 * cd_util_create_colprof:
 **/
static gboolean
cd_util_create_colprof (CdUtilPrivate *priv,
			CdDom *dom,
			const GNode *root,
			GError **error)
{
	const gchar *basename = "profile";
	const gchar *data_ti3;
	const gchar *viewcond;
	const GNode *node_enle;
	const GNode *node_enpo;
	const GNode *node_shape;
	const GNode *node_stle;
	const GNode *node_stpo;
	const GNode *tmp;
	gboolean ret = FALSE;
	gdouble enle;
	gdouble enpo;
	gdouble klimit;
	gdouble shape;
	gdouble stle;
	gdouble stpo;
	gdouble tlimit;
	gint exit_status = 0;
	gsize len = 0;
	g_autofree gchar *cmdline = NULL;
	g_autofree gchar *data = NULL;
	g_autofree gchar *debug_stderr = NULL;
	g_autofree gchar *debug_stdout = NULL;
	g_autofree gchar *output_fn = NULL;
	g_autofree gchar *ti3_fn = NULL;
	g_autoptr(GFile) output_file = NULL;
	g_autoptr(GFile) ti3_file = NULL;
	g_autoptr(GPtrArray) argv = NULL;

#ifndef TOOL_COLPROF
	/* no support */
	g_set_error_literal (error, 1, 0,
			     "not compiled with --enable-print-profiles");
	return FALSE;
#endif

	/* create common options */
	argv = g_ptr_array_new_with_free_func (g_free);
#ifdef TOOL_COLPROF
	g_ptr_array_add (argv, g_strdup (TOOL_COLPROF));
#endif
	g_ptr_array_add (argv, g_strdup ("-nc"));	/* no embedded ti3 */
	g_ptr_array_add (argv, g_strdup ("-qm"));	/* medium quality */
	g_ptr_array_add (argv, g_strdup ("-bm"));	/* medium quality B2A */

	/* get values */
	node_stle = cd_dom_get_node (dom, root, "stle");
	node_stpo = cd_dom_get_node (dom, root, "stpo");
	node_enpo = cd_dom_get_node (dom, root, "enpo");
	node_enle = cd_dom_get_node (dom, root, "enle");
	node_shape = cd_dom_get_node (dom, root, "shape");
	if (node_stle != NULL && node_stpo != NULL && node_enpo != NULL &&
	    node_enle != NULL && node_shape != NULL) {
		stle = cd_dom_get_node_data_as_double (node_stle);
		stpo = cd_dom_get_node_data_as_double (node_stpo);
		enpo = cd_dom_get_node_data_as_double (node_enpo);
		enle = cd_dom_get_node_data_as_double (node_enle);
		shape = cd_dom_get_node_data_as_double (node_shape);
		if (stle == G_MAXDOUBLE || stpo == G_MAXDOUBLE || enpo == G_MAXDOUBLE ||
		    enle == G_MAXDOUBLE || shape == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid stle, stpo, enpo, enle, shape");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup ("-kp"));
		g_ptr_array_add (argv, g_strdup_printf ("%f", stle));
		g_ptr_array_add (argv, g_strdup_printf ("%f", stpo));
		g_ptr_array_add (argv, g_strdup_printf ("%f", enpo));
		g_ptr_array_add (argv, g_strdup_printf ("%f", enle));
		g_ptr_array_add (argv, g_strdup_printf ("%f", shape));
	}

	/* total ink limit */
	tmp = cd_dom_get_node (dom, root, "tlimit");
	if (tmp != NULL) {
		tlimit = cd_dom_get_node_data_as_double (tmp);
		if (tlimit == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid tlimit");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup_printf ("-l%.0f", tlimit));
	}

	/* black ink limit */
	tmp = cd_dom_get_node (dom, root, "klimit");
	if (tmp != NULL) {
		klimit = cd_dom_get_node_data_as_double (tmp);
		if (klimit == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid klimit");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup_printf ("-L%.0f", klimit));
	}

	/* input viewing conditions */
	tmp = cd_dom_get_node (dom, root, "input_viewing_conditions");
	if (tmp != NULL) {
		viewcond = cd_dom_get_node_data (tmp);
		g_ptr_array_add (argv, g_strdup_printf ("-c%s", viewcond));
	}

	/* output viewing conditions */
	tmp = cd_dom_get_node (dom, root, "output_viewing_conditions");
	if (tmp != NULL) {
		viewcond = cd_dom_get_node_data (tmp);
		g_ptr_array_add (argv, g_strdup_printf ("-d%s", viewcond));
	}

	/* get source filename and copy into working directory */
	tmp = cd_dom_get_node (dom, root, "data_ti3");
	if (tmp == NULL) {
		g_set_error_literal (error, 1, 0,
				     "XML error: no data_ti3");
		return FALSE;
	}
	data_ti3 = cd_dom_get_node_data (tmp);
	ti3_fn = g_strdup_printf ("/tmp/%s.ti3", basename);
	ti3_file = g_file_new_for_path (ti3_fn);
	ret = g_file_replace_contents (ti3_file,
				       data_ti3,
				       strlen (data_ti3),
				       NULL,
				       FALSE,
				       G_FILE_CREATE_NONE,
				       NULL,
				       NULL,
				       error);
	if (!ret)
		return FALSE;

	/* ensure temporary icc profile does not already exist */
	output_fn = g_strdup_printf ("/tmp/%s.icc", basename);
	output_file = g_file_new_for_path (output_fn);
	if (g_file_query_exists (output_file, NULL)) {
		if (!g_file_delete (output_file, NULL, error))
			return FALSE;
	}

	/* run colprof in working directory */
	g_ptr_array_add (argv, g_strdup_printf ("-O%s.icc", basename));
	g_ptr_array_add (argv, g_strdup (basename));
	g_ptr_array_add (argv, NULL);
	ret = g_spawn_sync ("/tmp",
			    (gchar **) argv->pdata,
			    NULL,
			    0,
			    NULL, NULL,
			    &debug_stdout,
			    &debug_stderr,
			    &exit_status,
			    error);
	if (!ret)
		return FALSE;

	/* failed */
	if (exit_status != 0) {
		cmdline = g_strjoinv (" ", (gchar **) argv->pdata);
		g_set_error (error, 1, 0,
			     "Failed to generate %s using '%s'\nOutput: %s\nError:\t%s",
			     output_fn, cmdline, debug_stdout, debug_stderr);
		return FALSE;
	}

	/* load resulting .icc file */
	if (!g_file_load_contents (output_file, NULL, &data, &len, NULL, error))
		return FALSE;

	/* open /tmp/$basename.icc as hProfile */
	priv->lcms_profile = cmsOpenProfileFromMemTHR (cd_icc_get_context (priv->icc),
						       data, len);
	if (priv->lcms_profile == NULL) {
		g_set_error (error, 1, 0,
			     "Failed to open generated %s",
			     output_fn);
		return FALSE;
	}

	/* delete temp files */
	if (!g_file_delete (output_file, NULL, error))
		return FALSE;
	if (!g_file_delete (ti3_file, NULL, error))
		return FALSE;
	return TRUE;
}