/** * 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 ) ); }
/** * 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 ) ); }
/** * 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 ) ); }
/** * 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 ) ); }