Skip to content

Commit 5a37d3e

Browse files
committed
add an intent option to thumbnail
"intent" lets you set the rendering intent for any ICC conversions -- the default is the (more correct) relative, but "perceptual" can look better see https://github.com/jcupitt/libvips/issues/714
1 parent 820c279 commit 5a37d3e

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- remove lcms1 support, it had bitrotted
1515
- `join` tagged as seq
1616
- support tiffsave_buffer for pyramids, thanks bubba
17+
- thumbnail and vipsthumbnail have an option for rendering intent, thanks kleisauke
1718

1819
29/8/17 started 8.5.9
1920
- make --fail stop jpeg read on any libjpeg warning, thanks @mceachen

libvips/resample/thumbnail.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* - add FORCE
1010
* 29/5/17
1111
* - don't cache (thanks tomasc)
12+
* 30/8/17
13+
* - add intent option, thanks kleisauke
1214
*/
1315

1416
/*
@@ -81,6 +83,7 @@ typedef struct _VipsThumbnail {
8183
gboolean linear;
8284
char *export_profile;
8385
char *import_profile;
86+
VipsIntent intent;
8487

8588
/* Set by subclasses to the input image.
8689
*/
@@ -375,6 +378,7 @@ vips_thumbnail_build( VipsObject *object )
375378
if( vips_icc_import( in, &t[1],
376379
"input_profile", thumbnail->import_profile,
377380
"embedded", TRUE,
381+
"intent", thumbnail->intent,
378382
"pcs", VIPS_PCS_XYZ,
379383
NULL ) )
380384
return( -1 );
@@ -442,6 +446,7 @@ vips_thumbnail_build( VipsObject *object )
442446
g_info( "exporting to device space with a profile" );
443447
if( vips_icc_export( in, &t[7],
444448
"output_profile", thumbnail->export_profile,
449+
"intent", thumbnail->intent,
445450
NULL ) )
446451
return( -1 );
447452
in = t[7];
@@ -470,6 +475,7 @@ vips_thumbnail_build( VipsObject *object )
470475

471476
if( vips_icc_transform( in, &t[7],
472477
thumbnail->export_profile,
478+
"intent", thumbnail->intent,
473479
"embedded", TRUE,
474480
NULL ) ) {
475481
g_warning( _( "unable to import with "
@@ -489,6 +495,7 @@ vips_thumbnail_build( VipsObject *object )
489495
if( vips_icc_transform( in, &t[7],
490496
thumbnail->export_profile,
491497
"input_profile", thumbnail->import_profile,
498+
"intent", thumbnail->intent,
492499
"embedded", FALSE,
493500
NULL ) )
494501
return( -1 );
@@ -630,6 +637,13 @@ vips_thumbnail_class_init( VipsThumbnailClass *class )
630637
G_STRUCT_OFFSET( VipsThumbnail, export_profile ),
631638
NULL );
632639

640+
VIPS_ARG_ENUM( class, "intent", 120,
641+
_( "Intent" ),
642+
_( "Rendering intent" ),
643+
VIPS_ARGUMENT_OPTIONAL_INPUT,
644+
G_STRUCT_OFFSET( VipsThumbnail, intent ),
645+
VIPS_TYPE_INTENT, VIPS_INTENT_RELATIVE );
646+
633647
}
634648

635649
static void
@@ -638,6 +652,7 @@ vips_thumbnail_init( VipsThumbnail *thumbnail )
638652
thumbnail->width = 1;
639653
thumbnail->height = 1;
640654
thumbnail->auto_rotate = TRUE;
655+
thumbnail->intent = VIPS_INTENT_RELATIVE;
641656
}
642657

643658
typedef struct _VipsThumbnailFile {
@@ -745,6 +760,7 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
745760
* * @linear: %gboolean, perform shrink in linear light
746761
* * @import_profile: %gchararray, fallback import ICC profile
747762
* * @export_profile: %gchararray, export ICC profile
763+
* * @intent: #VipsIntent, rendering intent
748764
*
749765
* Make a thumbnail from a file. Shrinking is done in three stages: using any
750766
* shrink-on-load features available in the file import library, using a block
@@ -786,6 +802,9 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
786802
* input image has no ICC profile, or if the profile embedded in the
787803
* input image is broken.
788804
*
805+
* Use @intent to set the rendering intent for any ICC transform. The default
806+
* is #VIPS_INTENT_RELATIVE.
807+
*
789808
* See also: vips_thumbnail_buffer().
790809
*
791810
* Returns: 0 on success, -1 on error.
@@ -917,6 +936,7 @@ vips_thumbnail_buffer_init( VipsThumbnailBuffer *buffer )
917936
* * @linear: %gboolean, perform shrink in linear light
918937
* * @import_profile: %gchararray, fallback import ICC profile
919938
* * @export_profile: %gchararray, export ICC profile
939+
* * @intent: #VipsIntent, rendering intent
920940
*
921941
* Exacty as vips_thumbnail(), but read from a memory buffer.
922942
*
@@ -1031,6 +1051,7 @@ vips_thumbnail_image_init( VipsThumbnailImage *image )
10311051
* * @linear: %gboolean, perform shrink in linear light
10321052
* * @import_profile: %gchararray, fallback import ICC profile
10331053
* * @export_profile: %gchararray, export ICC profile
1054+
* * @intent: #VipsIntent, rendering intent
10341055
*
10351056
* Exacty as vips_thumbnail(), but read from an existing image.
10361057
*

tools/vipsthumbnail.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
* - support VipSize restrictions
9393
* 4/5/17
9494
* - add ! geo modifier
95+
* 30/8/17
96+
* - add --intent
9597
*/
9698

9799
#ifdef HAVE_CONFIG_H
@@ -125,6 +127,7 @@ static gboolean linear_processing = FALSE;
125127
static gboolean crop_image = FALSE;
126128
static char *smartcrop_image = NULL;
127129
static gboolean rotate_image = FALSE;
130+
static char *thumbnail_intent = NULL;
128131

129132
/* Deprecated and unused.
130133
*/
@@ -162,6 +165,10 @@ static GOptionEntry options[] = {
162165
G_OPTION_ARG_STRING, &smartcrop_image,
163166
N_( "shrink and crop to fill SIZE using STRATEGY" ),
164167
N_( "STRATEGY" ) },
168+
{ "intent", 'n', 0,
169+
G_OPTION_ARG_STRING, &thumbnail_intent,
170+
N_( "ICC transform with INTENT" ),
171+
N_( "INTENT" ) },
165172
{ "rotate", 't', 0,
166173
G_OPTION_ARG_NONE, &rotate_image,
167174
N_( "auto-rotate" ), NULL },
@@ -245,18 +252,28 @@ thumbnail_process( VipsObject *process, const char *filename )
245252
{
246253
VipsInteresting interesting;
247254
VipsImage *image;
255+
VipsIntent intent;
248256

249257
interesting = VIPS_INTERESTING_NONE;
250258
if( crop_image )
251259
interesting = VIPS_INTERESTING_CENTRE;
252260
if( smartcrop_image ) {
253261
int n;
254-
262+
255263
if( (n = vips_enum_from_nick( "vipsthumbnail",
256264
VIPS_TYPE_INTERESTING, smartcrop_image )) < 0 )
257265
return( -1 );
258266
interesting = n;
259267
}
268+
intent = VIPS_INTENT_RELATIVE;
269+
if( thumbnail_intent ) {
270+
int n;
271+
272+
if( (n = vips_enum_from_nick( "vipsthumbnail",
273+
VIPS_TYPE_INTENT, thumbnail_intent )) < 0 )
274+
return( -1 );
275+
intent = n;
276+
}
260277

261278
if( vips_thumbnail( filename, &image, thumbnail_width,
262279
"height", thumbnail_height,
@@ -266,6 +283,7 @@ thumbnail_process( VipsObject *process, const char *filename )
266283
"linear", linear_processing,
267284
"import_profile", import_profile,
268285
"export_profile", export_profile,
286+
"intent", intent,
269287
NULL ) )
270288
return( -1 );
271289

0 commit comments

Comments
 (0)