diff --git a/src/pipeline.cc b/src/pipeline.cc index 17bbe955..8c43fe02 100755 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -250,11 +250,16 @@ class PipelineWorker : public AsyncWorker { // Calculate angle of rotation Angle rotation; bool flip; - std::tie(rotation, flip) = CalculateRotationAndFlip(baton->angle, image); + bool flop; + std::tie(rotation, flip, flop) = CalculateRotationAndFlip(baton->angle, image); if (flip && !baton->flip) { // Add flip operation due to EXIF mirroring baton->flip = TRUE; } + if (flop && !baton->flop) { + // Add flip operation due to EXIF mirroring + baton->flop = TRUE; + } // Rotate pre-extract if (baton->rotateBeforePreExtract && rotation != Angle::D0) { @@ -1041,18 +1046,19 @@ class PipelineWorker : public AsyncWorker { 2. Use input image EXIF Orientation header - supports mirroring 3. Otherwise default to zero, i.e. no rotation */ - std::tuple + std::tuple CalculateRotationAndFlip(int const angle, VipsImage const *input) { Angle rotate = Angle::D0; bool flip = FALSE; + bool flop = FALSE; if (angle == -1) { switch(ExifOrientation(input)) { case 6: rotate = Angle::D90; break; case 3: rotate = Angle::D180; break; case 8: rotate = Angle::D270; break; - case 2: flip = TRUE; break; // flip 1 + case 2: flop = TRUE; break; // flop 1 case 7: flip = TRUE; rotate = Angle::D90; break; // flip 6 - case 4: flip = TRUE; rotate = Angle::D180; break; // flip 3 + case 4: flop = TRUE; rotate = Angle::D180; break; // flop 3 case 5: flip = TRUE; rotate = Angle::D270; break; // flip 8 } } else { @@ -1064,7 +1070,7 @@ class PipelineWorker : public AsyncWorker { rotate = Angle::D270; } } - return std::make_tuple(rotate, flip); + return std::make_tuple(rotate, flip, flop); } /* @@ -1240,3 +1246,4 @@ NAN_METHOD(pipeline) { Local queueLength[1] = { New(counterQueue) }; queueListener->Call(1, queueLength); } + diff --git a/test/fixtures/Landscape_1.jpg b/test/fixtures/Landscape_1.jpg new file mode 100755 index 00000000..015c5f17 Binary files /dev/null and b/test/fixtures/Landscape_1.jpg differ diff --git a/test/fixtures/Landscape_2.jpg b/test/fixtures/Landscape_2.jpg new file mode 100755 index 00000000..2e7fb579 Binary files /dev/null and b/test/fixtures/Landscape_2.jpg differ diff --git a/test/fixtures/Landscape_3.jpg b/test/fixtures/Landscape_3.jpg new file mode 100755 index 00000000..74505cfc Binary files /dev/null and b/test/fixtures/Landscape_3.jpg differ diff --git a/test/fixtures/Landscape_4.jpg b/test/fixtures/Landscape_4.jpg new file mode 100755 index 00000000..ea133fbb Binary files /dev/null and b/test/fixtures/Landscape_4.jpg differ diff --git a/test/fixtures/Landscape_5.jpg b/test/fixtures/Landscape_5.jpg old mode 100644 new mode 100755 diff --git a/test/fixtures/Landscape_6.jpg b/test/fixtures/Landscape_6.jpg new file mode 100755 index 00000000..7426aba0 Binary files /dev/null and b/test/fixtures/Landscape_6.jpg differ diff --git a/test/fixtures/Landscape_7.jpg b/test/fixtures/Landscape_7.jpg new file mode 100755 index 00000000..a541d95e Binary files /dev/null and b/test/fixtures/Landscape_7.jpg differ diff --git a/test/fixtures/Landscape_8.jpg b/test/fixtures/Landscape_8.jpg old mode 100644 new mode 100755 diff --git a/test/fixtures/Portrait_1.jpg b/test/fixtures/Portrait_1.jpg new file mode 100755 index 00000000..f5797797 Binary files /dev/null and b/test/fixtures/Portrait_1.jpg differ diff --git a/test/fixtures/Portrait_2.jpg b/test/fixtures/Portrait_2.jpg new file mode 100755 index 00000000..4d9212c2 Binary files /dev/null and b/test/fixtures/Portrait_2.jpg differ diff --git a/test/fixtures/Portrait_3.jpg b/test/fixtures/Portrait_3.jpg new file mode 100755 index 00000000..2f88b6d2 Binary files /dev/null and b/test/fixtures/Portrait_3.jpg differ diff --git a/test/fixtures/Portrait_4.jpg b/test/fixtures/Portrait_4.jpg new file mode 100755 index 00000000..cc947dad Binary files /dev/null and b/test/fixtures/Portrait_4.jpg differ diff --git a/test/fixtures/Portrait_5.jpg b/test/fixtures/Portrait_5.jpg new file mode 100755 index 00000000..b14114bc Binary files /dev/null and b/test/fixtures/Portrait_5.jpg differ diff --git a/test/fixtures/Portrait_6.jpg b/test/fixtures/Portrait_6.jpg new file mode 100755 index 00000000..79617a97 Binary files /dev/null and b/test/fixtures/Portrait_6.jpg differ diff --git a/test/fixtures/Portrait_7.jpg b/test/fixtures/Portrait_7.jpg new file mode 100755 index 00000000..fbcde86d Binary files /dev/null and b/test/fixtures/Portrait_7.jpg differ diff --git a/test/fixtures/Portrait_8.jpg b/test/fixtures/Portrait_8.jpg new file mode 100755 index 00000000..07beac8d Binary files /dev/null and b/test/fixtures/Portrait_8.jpg differ diff --git a/test/fixtures/expected/Landscape_1-out.jpg b/test/fixtures/expected/Landscape_1-out.jpg new file mode 100644 index 00000000..5db6bad1 Binary files /dev/null and b/test/fixtures/expected/Landscape_1-out.jpg differ diff --git a/test/fixtures/expected/Landscape_2-out.jpg b/test/fixtures/expected/Landscape_2-out.jpg new file mode 100644 index 00000000..360029e9 Binary files /dev/null and b/test/fixtures/expected/Landscape_2-out.jpg differ diff --git a/test/fixtures/expected/Landscape_3-out.jpg b/test/fixtures/expected/Landscape_3-out.jpg new file mode 100644 index 00000000..9d11f4e0 Binary files /dev/null and b/test/fixtures/expected/Landscape_3-out.jpg differ diff --git a/test/fixtures/expected/Landscape_4-out.jpg b/test/fixtures/expected/Landscape_4-out.jpg new file mode 100644 index 00000000..b1af4a51 Binary files /dev/null and b/test/fixtures/expected/Landscape_4-out.jpg differ diff --git a/test/fixtures/expected/Landscape_5-out.jpg b/test/fixtures/expected/Landscape_5-out.jpg new file mode 100644 index 00000000..59b56a71 Binary files /dev/null and b/test/fixtures/expected/Landscape_5-out.jpg differ diff --git a/test/fixtures/expected/Landscape_6-out.jpg b/test/fixtures/expected/Landscape_6-out.jpg new file mode 100644 index 00000000..9895a5da Binary files /dev/null and b/test/fixtures/expected/Landscape_6-out.jpg differ diff --git a/test/fixtures/expected/Landscape_7-out.jpg b/test/fixtures/expected/Landscape_7-out.jpg new file mode 100644 index 00000000..b0356811 Binary files /dev/null and b/test/fixtures/expected/Landscape_7-out.jpg differ diff --git a/test/fixtures/expected/Landscape_8-out.jpg b/test/fixtures/expected/Landscape_8-out.jpg new file mode 100644 index 00000000..fb1aee1c Binary files /dev/null and b/test/fixtures/expected/Landscape_8-out.jpg differ diff --git a/test/fixtures/expected/Portrait_1-out.jpg b/test/fixtures/expected/Portrait_1-out.jpg new file mode 100644 index 00000000..6e597836 Binary files /dev/null and b/test/fixtures/expected/Portrait_1-out.jpg differ diff --git a/test/fixtures/expected/Portrait_2-out.jpg b/test/fixtures/expected/Portrait_2-out.jpg new file mode 100644 index 00000000..3ead7a59 Binary files /dev/null and b/test/fixtures/expected/Portrait_2-out.jpg differ diff --git a/test/fixtures/expected/Portrait_3-out.jpg b/test/fixtures/expected/Portrait_3-out.jpg new file mode 100644 index 00000000..438b4370 Binary files /dev/null and b/test/fixtures/expected/Portrait_3-out.jpg differ diff --git a/test/fixtures/expected/Portrait_4-out.jpg b/test/fixtures/expected/Portrait_4-out.jpg new file mode 100644 index 00000000..e6716715 Binary files /dev/null and b/test/fixtures/expected/Portrait_4-out.jpg differ diff --git a/test/fixtures/expected/Portrait_5-out.jpg b/test/fixtures/expected/Portrait_5-out.jpg new file mode 100644 index 00000000..8aaca7d3 Binary files /dev/null and b/test/fixtures/expected/Portrait_5-out.jpg differ diff --git a/test/fixtures/expected/Portrait_6-out.jpg b/test/fixtures/expected/Portrait_6-out.jpg new file mode 100644 index 00000000..f454e0f1 Binary files /dev/null and b/test/fixtures/expected/Portrait_6-out.jpg differ diff --git a/test/fixtures/expected/Portrait_7-out.jpg b/test/fixtures/expected/Portrait_7-out.jpg new file mode 100644 index 00000000..5a5c9095 Binary files /dev/null and b/test/fixtures/expected/Portrait_7-out.jpg differ diff --git a/test/fixtures/expected/Portrait_8-out.jpg b/test/fixtures/expected/Portrait_8-out.jpg new file mode 100644 index 00000000..e980f3cc Binary files /dev/null and b/test/fixtures/expected/Portrait_8-out.jpg differ diff --git a/test/fixtures/index.js b/test/fixtures/index.js index 5d2cb4e0..a17a8600 100755 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -40,6 +40,24 @@ var fingerprint = function(image, callback) { module.exports = { + inputJpgWithLandscapeExif1: getPath('Landscape_1.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif2: getPath('Landscape_2.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif3: getPath('Landscape_3.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif4: getPath('Landscape_4.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif5: getPath('Landscape_5.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif6: getPath('Landscape_6.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif7: getPath('Landscape_7.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithLandscapeExif8: getPath('Landscape_8.jpg'), // https://github.com/recurser/exif-orientation-examples + + inputJpgWithPortraitExif1: getPath('Portrait_1.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif2: getPath('Portrait_2.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif3: getPath('Portrait_3.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif4: getPath('Portrait_4.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif5: getPath('Portrait_5.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif6: getPath('Portrait_6.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif7: getPath('Portrait_7.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpgWithPortraitExif8: getPath('Portrait_8.jpg'), // https://github.com/recurser/exif-orientation-examples + inputJpg: getPath('2569067123_aca715a2ee_o.jpg'), // http://www.flickr.com/photos/grizdave/2569067123/ inputJpgWithExif: getPath('Landscape_8.jpg'), // https://github.com/recurser/exif-orientation-examples/blob/master/Landscape_8.jpg inputJpgWithExifMirroring: getPath('Landscape_5.jpg'), // https://github.com/recurser/exif-orientation-examples/blob/master/Landscape_5.jpg diff --git a/test/unit/rotate.js b/test/unit/rotate.js index 17fcdf96..83cce49b 100755 --- a/test/unit/rotate.js +++ b/test/unit/rotate.js @@ -9,6 +9,23 @@ sharp.cache(0); describe('Rotation', function() { + ['Landscape', 'Portrait'].forEach(function(orientation) { + [1,2,3,4,5,6,7,8].forEach(function(exifTag) { + it('Input image has Orientation EXIF tag value of (' + exifTag + '), auto-rotate', function(done) { + sharp(fixtures['inputJpgWith'+orientation+'Exif'+exifTag]) + .rotate() + .resize(320) + .toBuffer(function(err, data, info) { + if (err) throw err; + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(orientation === 'Landscape' ? 240 : 427, info.height); + fixtures.assertSimilar(fixtures.expected(orientation + '_' + exifTag + '-out.jpg'), data, done); + }); + }); + }); + }); + it('Rotate by 90 degrees, respecting output input size', function(done) { sharp(fixtures.inputJpg).rotate(90).resize(320, 240).toBuffer(function(err, data, info) { if (err) throw err;