diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1296a9ea..17661e13 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -108,6 +108,24 @@ else() add_custom_target(libjpeg "") endif() +find_library(TIFF tiff EXACT PATHS "${EXT_INSTALL_DIR}/lib" NO_DEFAULT_PATH) +if(NOT TIFF) + ExternalProject_Add(tiff + URL "http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/tiff" + CONFIGURE_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tiff/src/tiff/configure + ${CONFIGURE_VARS} + --enable-shared + --disable-static + --without-x + --disable-cxx + --disable-lzma + DEPENDS libjpeg + ) +else() + add_custom_target(tiff "") +endif() + if (WITH_LIBSPNG) list(APPEND LIBSPNG_FLAGS --with-libspng @@ -181,6 +199,8 @@ if(NOT LIBWEBP) --with-jpeglibdir=${EXT_INSTALL_DIR}/lib --with-pngincludedir=${EXT_INSTALL_DIR}/include --with-pnglibdir=${EXT_INSTALL_DIR}/lib + --with-tiffincludedir=${EXT_INSTALL_DIR}/include + --with-tifflibdir=${EXT_INSTALL_DIR}/lib --enable-shared --disable-static --disable-dependency-tracking @@ -191,7 +211,7 @@ if(NOT LIBWEBP) --enable-sse4.1 --enable-sse2 --enable-threading - DEPENDS libjpeg libpng giflib + DEPENDS libjpeg libpng giflib tiff ) else() add_custom_target(libwebp "") @@ -272,13 +292,16 @@ if(NOT VIPS) --with-jpeg --with-jpeg-includes=${EXT_INSTALL_DIR}/include --with-jpeg-libraries=${EXT_INSTALL_DIR}/lib + --with-tiff + --with-tiff-includes=${EXT_INSTALL_DIR}/include + --with-tiff-libraries=${EXT_INSTALL_DIR}/lib --without-magick --without-orc --without-gsf --without-rsvg ${LIBSPNG_FLAGS} ${LIBHEIF_FLAGS} - DEPENDS libjpeg libpng libspng giflib libwebp libimagequant lcms2 libheif + DEPENDS libjpeg libpng libspng giflib libwebp libimagequant lcms2 libheif tiff BUILD_IN_SOURCE 1 ) else() diff --git a/lib/VERSIONS b/lib/VERSIONS index f281687f..af26efb0 100644 --- a/lib/VERSIONS +++ b/lib/VERSIONS @@ -8,4 +8,5 @@ WEBP_VERSION=1.1.0 AOM_VERSION=2.0.0 HEIF_VERSION=1.9.1 LCMS2_VERSION=2.11 +TIFF_VERSION=4.1.0 VIPS_VERSION=8.12.1 diff --git a/src/main/java/com/criteo/vips/enums/VipsImageFormat.java b/src/main/java/com/criteo/vips/enums/VipsImageFormat.java index f3fbb857..8a272fa6 100644 --- a/src/main/java/com/criteo/vips/enums/VipsImageFormat.java +++ b/src/main/java/com/criteo/vips/enums/VipsImageFormat.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2019 Criteo + Copyright (c) 2022 Criteo Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,8 @@ public enum VipsImageFormat { PNG(".png"), WEBP(".webp"), GIF(".gif"), - AVIF(".avif"); + AVIF(".avif"), + TIFF(".tiff"); private final String extension; diff --git a/src/test/java/com/criteo/vips/VipsImageTest.java b/src/test/java/com/criteo/vips/VipsImageTest.java index b3a81925..2aa4a896 100644 --- a/src/test/java/com/criteo/vips/VipsImageTest.java +++ b/src/test/java/com/criteo/vips/VipsImageTest.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2019 Criteo + Copyright (c) 2022 Criteo Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -36,6 +36,8 @@ import java.nio.ByteBuffer; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.stream.IntStream; @@ -56,17 +58,22 @@ public class VipsImageTest { private static PixelPacket WhitePixel = new PixelPacket(255.0, 255.0, 255.0); private static PixelPacket TransparentPixel = new PixelPacket(255.0, 255.0, 255.0, 0.0); - private static Map SignatureByExtension = new HashMap<>(); + private static Map> SignaturesByExtension = new HashMap<>(); static { - SignatureByExtension.put(".jpg", new byte[]{(byte) 0xFF, (byte) 0xD8, (byte) 0xFF}); - SignatureByExtension.put(".png", new byte[]{(byte) 137, 80, 78, 71, 13, 10, 26, 10}); - SignatureByExtension.put(".webp", new byte[]{'R', 'I', 'F', 'F'}); - SignatureByExtension.put(".gif", new byte[]{'G', 'I', 'F'}); - SignatureByExtension.put(".avif", new byte[]{(byte) + SignaturesByExtension.put(".jpg", new ArrayList() {{ add(new Byte[]{(byte) 0xFF, (byte) 0xD8, (byte) 0xFF}); }}); + SignaturesByExtension.put(".png", new ArrayList() {{ add(new Byte[]{(byte) 137, 80, 78, 71, 13, 10, 26, 10}); }}); + SignaturesByExtension.put(".webp", new ArrayList() {{ add(new Byte[]{'R', 'I', 'F', 'F'}); }}); + SignaturesByExtension.put(".gif", new ArrayList() {{ add(new Byte[]{'G', 'I', 'F'}); }}); + SignaturesByExtension.put(".avif", new ArrayList() {{ add(new Byte[]{(byte) 0x00, 0x00, 0x00, 0x18, 'f', 't', 'y', 'p', 'a', 'v', 'i', 'f' - }); + }); }}); + // TIFF file begins with "II" for little-endian or "MM" for big-endian + SignaturesByExtension.put(".tiff", new ArrayList() {{ + add(new Byte[]{'I', 'I'}); + add(new Byte[]{'M', 'M'}); + }}); } @DataPoints("filenames") @@ -75,7 +82,11 @@ public class VipsImageTest { "transparent.png", "logo.webp", "cat.gif", - "02.gif" + "02.gif", + "deflate_compression.tiff", + "lzw_compression.tiff", + "none_compression.tiff", + "pack_bits_compression.tiff" }; static class DominantColour { @@ -105,7 +116,6 @@ public String toString() { }; @BeforeClass - public static void onceExecutedBeforeAll() { VipsContext.setLeak(true); VipsContext.setMaxCache(0); @@ -510,13 +520,20 @@ public void TestShouldWriteToArrayHasCorrectHeaderSignature(String filename, Vip // libvips can't save into gif format Assume.assumeTrue(vipsImageFormat != VipsImageFormat.GIF); Assume.assumeTrue(vipsImageFormat != VipsImageFormat.AVIF); - byte[] expected = SignatureByExtension.get(vipsImageFormat.getFileExtension()); - byte[] signature = new byte[expected.length]; + ArrayList expectedSignatures = SignaturesByExtension.get(vipsImageFormat.getFileExtension()); ByteBuffer buffer = VipsTestUtils.getDirectByteBuffer(filename); try (VipsImage img = new VipsImage(buffer, buffer.capacity())) { byte[] out = img.writeToArray(vipsImageFormat, JPGQuality, true); - System.arraycopy(out, 0, signature, 0, signature.length); - assertArrayEquals(expected, signature); + boolean success = false; + for (Byte[] signature : expectedSignatures) { + if (success) + break; + byte[] expectedSignature = VipsTestUtils.toPrimitives(signature); + byte[] fileSignature = new byte[signature.length]; + System.arraycopy(out, 0, fileSignature, 0, fileSignature.length); + success |= Arrays.equals(fileSignature, expectedSignature); + } + assertTrue("The file image format signature is not equal to the expected one", success); } } diff --git a/src/test/java/com/criteo/vips/VipsTestUtils.java b/src/test/java/com/criteo/vips/VipsTestUtils.java index 1f320e20..993e9127 100644 --- a/src/test/java/com/criteo/vips/VipsTestUtils.java +++ b/src/test/java/com/criteo/vips/VipsTestUtils.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2019 Criteo + Copyright (c) 2022 Criteo Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -37,4 +37,15 @@ public static ByteBuffer getDirectByteBuffer(String filename) throws IOException buffer.put(bytes, 0, bytes.length); return buffer; } + + public static byte[] toPrimitives(Byte[] oBytes) + { + + byte[] bytes = new byte[oBytes.length]; + for(int i = 0; i < oBytes.length; i++){ + bytes[i] = oBytes[i]; + } + return bytes; + + } } diff --git a/src/test/resources/deflate_compression.tiff b/src/test/resources/deflate_compression.tiff new file mode 100644 index 00000000..5acb65bb Binary files /dev/null and b/src/test/resources/deflate_compression.tiff differ diff --git a/src/test/resources/lzw_compression.tiff b/src/test/resources/lzw_compression.tiff new file mode 100644 index 00000000..5be33d75 Binary files /dev/null and b/src/test/resources/lzw_compression.tiff differ diff --git a/src/test/resources/none_compression.tiff b/src/test/resources/none_compression.tiff new file mode 100644 index 00000000..8c41941e Binary files /dev/null and b/src/test/resources/none_compression.tiff differ diff --git a/src/test/resources/pack_bits_compression.tiff b/src/test/resources/pack_bits_compression.tiff new file mode 100644 index 00000000..effaa5da Binary files /dev/null and b/src/test/resources/pack_bits_compression.tiff differ