Exemple #1
0
/**
 * im_lab_morph:
 * @in: input image
 * @out: output image
 * @mask: cast correction table
 * @L_offset: L adjustment
 * @L_scale: L adjustment
 * @a_scale: a scale
 * @b_scale: b scale
 *
 * Morph an image in CIELAB colour space. Useful for certain types of gamut
 * mapping, or correction of greyscales on some printers.
 *
 * We perform three adjustments:
 * 	
 * <itemizedlist>
 *   <listitem>
 *     <para>
 *       <emphasis>cast</emphasis>
 *
 * Pass in @mask containing CIELAB readings for a neutral greyscale. For
 * example:
 *
 * <tgroup cols='3' align='left' colsep='1' rowsep='1'>
 *   <tbody>
 *     <row>
 *       <entry>3</entry>
 *       <entry>4</entry>
 *     </row>
 *     <row>
 *       <entry>14.23</entry>
 *       <entry>4.8</entry>
 *       <entry>-3.95</entry>
 *     </row>
 *     <row>
 *       <entry>18.74</entry>
 *       <entry>2.76</entry>
 *       <entry>-2.62</entry>
 *     </row>
 *     <row>
 *       <entry>23.46</entry>
 *       <entry>1.4</entry>
 *       <entry>-1.95</entry>
 *     </row>
 *     <row>
 *       <entry>27.53</entry>
 *       <entry>1.76</entry>
 *       <entry>-2.01</entry>
 *     </row>
 *   </tbody>
 * </tgroup>
 *
 * Interpolation from this makes cast corrector. The top and tail are
 * interpolated towards [0, 0, 0] and [100, 0, 0], intermediate values are 
 * interpolated along straight lines fitted between the specified points. 
 * Rows may be in any order (ie. they need not be sorted on L*).
 *
 * Each pixel is displaced in a/b by the amount specified for that L in the
 * table.
 *     </para>
 *   </listitem>
 *   <listitem>
 *     <para>
 *       <emphasis>L*</emphasis>
 *	
 * Pass in scale and offset for L. L' = (L + offset) * scale.
 *     </para>
 *   </listitem>
 *   <listitem>
 *     <para>
 *       <emphasis>saturation</emphasis>
 *
 * scale a and b by these amounts, eg. 1.5 increases saturation. 
 *     </para>
 *   </listitem>
 * </itemizedlist>
 *
 * Find the top two by generating and printing a greyscale. Find the bottom
 * by printing a Macbeth and looking at a/b spread
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_lab_morph( IMAGE *in, IMAGE *out,
	DOUBLEMASK *mask, 
	double L_offset, double L_scale, 
	double a_scale, double b_scale )
{
	Params *parm;

        /* Recurse for coded images.
         */
	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t[2];

		if( im_open_local_array( out, t, 2, "im_lab_morph", "p" ) ||
			im_LabQ2Lab( in, t[0] ) ||
			im_lab_morph( t[0], t[1], 
				mask, L_offset, L_scale, a_scale, b_scale ) ||
			im_Lab2LabQ( t[1], out ) )
			return( -1 );

		return( 0 );
	}

	if( !(parm = IM_NEW( out, Params )) ||
		morph_init( parm,
			in, out, L_scale, L_offset, mask, a_scale, b_scale ) ) 
		return( -1 );

	return( im__colour_unary( "im_lab_morph", in, out, IM_TYPE_LAB,
		(im_wrapone_fn) morph_buffer, parm, NULL ) );
}
Exemple #2
0
/**
 * im_UCS2LCh:
 * @in: input image
 * @out: output image
 *
 * Turn UCS to LCh.
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_UCS2LCh( IMAGE *in, IMAGE *out )
{
	im_col_make_tables_UCS();

	return( im__colour_unary( "im_UCS2LCh", in, out, IM_TYPE_LCH,
		(im_wrapone_fn) imb_UCS2LCh, NULL, NULL ) );
}
Exemple #3
0
/**
 * im_Yxy2XYZ:
 * @in: input image
 * @out: output image
 *
 * Turn Yxy to XYZ.
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_Yxy2XYZ( IMAGE *in, IMAGE *out )
{
	return( im__colour_unary( "im_Yxy2XYZ", in, out, IM_TYPE_XYZ,
		(im_wrapone_fn) imb_Yxy2XYZ, NULL, NULL ) );
}
Exemple #4
0
/**
 * im_LCh2UCS:
 * @in: input image
 * @out: output image
 *
 * Turn LCh to UCS.
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_LCh2UCS( IMAGE *in, IMAGE *out )
{	
	return( im__colour_unary( "im_LCh2UCS", in, out, IM_TYPE_UCS,
		(im_wrapone_fn) imb_LCh2UCS, NULL, NULL ) );
}