@@ -92,45 +92,43 @@ class PipelineWorker : public Napi::AsyncWorker {
92
92
// Calculate angle of rotation
93
93
VipsAngle rotation = VIPS_ANGLE_D0;
94
94
VipsAngle autoRotation = VIPS_ANGLE_D0;
95
- bool autoFlip = false ;
96
95
bool autoFlop = false ;
97
96
98
97
if (baton->input ->autoOrient ) {
99
98
// Rotate and flip image according to Exif orientation
100
- std::tie (autoRotation, autoFlip, autoFlop) = CalculateExifRotationAndFlip (sharp::ExifOrientation (image));
99
+ std::tie (autoRotation, autoFlop) = CalculateExifRotationAndFlop (sharp::ExifOrientation (image));
101
100
}
102
101
103
102
rotation = CalculateAngleRotation (baton->angle );
104
103
105
- // Rotate pre-extract
106
- bool const shouldRotateBefore = baton->rotateBeforePreExtract &&
107
- (rotation != VIPS_ANGLE_D0 || autoRotation != VIPS_ANGLE_D0 ||
108
- autoFlip || baton->flip || autoFlop || baton->flop ||
109
- baton->rotationAngle != 0.0 );
110
-
111
- if (shouldRotateBefore) {
112
- image = sharp::StaySequential (image,
113
- rotation != VIPS_ANGLE_D0 ||
114
- autoRotation != VIPS_ANGLE_D0 ||
115
- autoFlip ||
116
- baton->flip ||
117
- baton->rotationAngle != 0.0 );
104
+ bool const shouldRotateBefore = baton->rotateBefore &&
105
+ (rotation != VIPS_ANGLE_D0 || baton->flip || baton->flop || baton->rotationAngle != 0.0 );
106
+ bool const shouldOrientBefore = (shouldRotateBefore || baton->orientBefore ) &&
107
+ (autoRotation != VIPS_ANGLE_D0 || autoFlop);
118
108
109
+ if (shouldOrientBefore) {
110
+ image = sharp::StaySequential (image, autoRotation != VIPS_ANGLE_D0);
119
111
if (autoRotation != VIPS_ANGLE_D0) {
120
112
if (autoRotation != VIPS_ANGLE_D180) {
121
113
MultiPageUnsupported (nPages, " Rotate" );
122
114
}
123
115
image = image.rot (autoRotation);
124
116
autoRotation = VIPS_ANGLE_D0;
125
117
}
126
- if (autoFlip != baton->flip ) {
118
+ if (autoFlop) {
119
+ image = image.flip (VIPS_DIRECTION_HORIZONTAL);
120
+ autoFlop = false ;
121
+ }
122
+ }
123
+
124
+ if (shouldRotateBefore) {
125
+ image = sharp::StaySequential (image, rotation != VIPS_ANGLE_D0 || baton->flip || baton->rotationAngle != 0.0 );
126
+ if (baton->flip ) {
127
127
image = image.flip (VIPS_DIRECTION_VERTICAL);
128
- autoFlip = false ;
129
128
baton->flip = false ;
130
129
}
131
- if (autoFlop != baton->flop ) {
130
+ if (baton->flop ) {
132
131
image = image.flip (VIPS_DIRECTION_HORIZONTAL);
133
- autoFlop = false ;
134
132
baton->flop = false ;
135
133
}
136
134
if (rotation != VIPS_ANGLE_D0) {
@@ -145,6 +143,7 @@ class PipelineWorker : public Napi::AsyncWorker {
145
143
std::vector<double > background;
146
144
std::tie (image, background) = sharp::ApplyAlpha (image, baton->rotationBackground , false );
147
145
image = image.rotate (baton->rotationAngle , VImage::option ()->set (" background" , background)).copy_memory ();
146
+ baton->rotationAngle = 0.0 ;
148
147
}
149
148
}
150
149
@@ -183,8 +182,7 @@ class PipelineWorker : public Napi::AsyncWorker {
183
182
// When auto-rotating by 90 or 270 degrees, swap the target width and
184
183
// height to ensure the behavior aligns with how it would have been if
185
184
// the rotation had taken place *before* resizing.
186
- if (!baton->rotateBeforePreExtract &&
187
- (autoRotation == VIPS_ANGLE_D90 || autoRotation == VIPS_ANGLE_D270)) {
185
+ if (autoRotation == VIPS_ANGLE_D90 || autoRotation == VIPS_ANGLE_D270) {
188
186
std::swap (targetResizeWidth, targetResizeHeight);
189
187
}
190
188
@@ -206,7 +204,7 @@ class PipelineWorker : public Napi::AsyncWorker {
206
204
// - input colourspace is not specified;
207
205
bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0 ) &&
208
206
baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold < 0.0 &&
209
- baton->colourspacePipeline == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
207
+ baton->colourspacePipeline == VIPS_INTERPRETATION_LAST && !(shouldOrientBefore || shouldRotateBefore) ;
210
208
211
209
if (shouldPreShrink) {
212
210
// The common part of the shrink: the bit by which both axes must be shrunk
@@ -398,7 +396,6 @@ class PipelineWorker : public Napi::AsyncWorker {
398
396
image = sharp::StaySequential (image,
399
397
autoRotation != VIPS_ANGLE_D0 ||
400
398
baton->flip ||
401
- autoFlip ||
402
399
rotation != VIPS_ANGLE_D0);
403
400
// Auto-rotate post-extract
404
401
if (autoRotation != VIPS_ANGLE_D0) {
@@ -408,7 +405,7 @@ class PipelineWorker : public Napi::AsyncWorker {
408
405
image = image.rot (autoRotation);
409
406
}
410
407
// Mirror vertically (up-down) about the x-axis
411
- if (baton->flip != autoFlip ) {
408
+ if (baton->flip ) {
412
409
image = image.flip (VIPS_DIRECTION_VERTICAL);
413
410
}
414
411
// Mirror horizontally (left-right) about the y-axis
@@ -515,7 +512,7 @@ class PipelineWorker : public Napi::AsyncWorker {
515
512
}
516
513
517
514
// Rotate post-extract non-90 angle
518
- if (!baton->rotateBeforePreExtract && baton->rotationAngle != 0.0 ) {
515
+ if (!baton->rotateBefore && baton->rotationAngle != 0.0 ) {
519
516
MultiPageUnsupported (nPages, " Rotate" );
520
517
image = sharp::StaySequential (image);
521
518
std::vector<double > background;
@@ -656,21 +653,16 @@ class PipelineWorker : public Napi::AsyncWorker {
656
653
if (composite->input ->autoOrient ) {
657
654
// Respect EXIF Orientation
658
655
VipsAngle compositeAutoRotation = VIPS_ANGLE_D0;
659
- bool compositeAutoFlip = false ;
660
656
bool compositeAutoFlop = false ;
661
- std::tie (compositeAutoRotation, compositeAutoFlip, compositeAutoFlop) =
662
- CalculateExifRotationAndFlip (sharp::ExifOrientation (compositeImage));
657
+ std::tie (compositeAutoRotation, compositeAutoFlop) =
658
+ CalculateExifRotationAndFlop (sharp::ExifOrientation (compositeImage));
663
659
664
660
compositeImage = sharp::RemoveExifOrientation (compositeImage);
665
- compositeImage = sharp::StaySequential (compositeImage,
666
- compositeAutoRotation != VIPS_ANGLE_D0 || compositeAutoFlip);
661
+ compositeImage = sharp::StaySequential (compositeImage, compositeAutoRotation != VIPS_ANGLE_D0);
667
662
668
663
if (compositeAutoRotation != VIPS_ANGLE_D0) {
669
664
compositeImage = compositeImage.rot (compositeAutoRotation);
670
665
}
671
- if (compositeAutoFlip) {
672
- compositeImage = compositeImage.flip (VIPS_DIRECTION_VERTICAL);
673
- }
674
666
if (compositeAutoFlop) {
675
667
compositeImage = compositeImage.flip (VIPS_DIRECTION_HORIZONTAL);
676
668
}
@@ -1402,21 +1394,20 @@ class PipelineWorker : public Napi::AsyncWorker {
1402
1394
Calculate the angle of rotation and need-to-flip for the given Exif orientation
1403
1395
By default, returns zero, i.e. no rotation.
1404
1396
*/
1405
- std::tuple<VipsAngle, bool , bool >
1406
- CalculateExifRotationAndFlip (int const exifOrientation) {
1397
+ std::tuple<VipsAngle, bool >
1398
+ CalculateExifRotationAndFlop (int const exifOrientation) {
1407
1399
VipsAngle rotate = VIPS_ANGLE_D0;
1408
- bool flip = false ;
1409
1400
bool flop = false ;
1410
1401
switch (exifOrientation) {
1411
1402
case 6 : rotate = VIPS_ANGLE_D90; break ;
1412
1403
case 3 : rotate = VIPS_ANGLE_D180; break ;
1413
1404
case 8 : rotate = VIPS_ANGLE_D270; break ;
1414
- case 2 : flop = true ; break ; // flop 1
1415
- case 7 : flip = true ; rotate = VIPS_ANGLE_D90 ; break ; // flip 6
1416
- case 4 : flop = true ; rotate = VIPS_ANGLE_D180; break ; // flop 3
1417
- case 5 : flip = true ; rotate = VIPS_ANGLE_D270 ; break ; // flip 8
1405
+ case 2 : flop = true ; break ;
1406
+ case 7 : flop = true ; rotate = VIPS_ANGLE_D270 ; break ;
1407
+ case 4 : flop = true ; rotate = VIPS_ANGLE_D180; break ;
1408
+ case 5 : flop = true ; rotate = VIPS_ANGLE_D90 ; break ;
1418
1409
}
1419
- return std::make_tuple (rotate, flip, flop);
1410
+ return std::make_tuple (rotate, flop);
1420
1411
}
1421
1412
1422
1413
/*
@@ -1641,7 +1632,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1641
1632
baton->angle = sharp::AttrAsInt32 (options, " angle" );
1642
1633
baton->rotationAngle = sharp::AttrAsDouble (options, " rotationAngle" );
1643
1634
baton->rotationBackground = sharp::AttrAsVectorOfDouble (options, " rotationBackground" );
1644
- baton->rotateBeforePreExtract = sharp::AttrAsBool (options, " rotateBeforePreExtract" );
1635
+ baton->rotateBefore = sharp::AttrAsBool (options, " rotateBefore" );
1636
+ baton->orientBefore = sharp::AttrAsBool (options, " orientBefore" );
1645
1637
baton->flip = sharp::AttrAsBool (options, " flip" );
1646
1638
baton->flop = sharp::AttrAsBool (options, " flop" );
1647
1639
baton->extendTop = sharp::AttrAsInt32 (options, " extendTop" );
0 commit comments