Skip to content

Commit

Permalink
💾 Add TIFF support
Browse files Browse the repository at this point in the history
See this issue: #117
  • Loading branch information
dbouron committed Apr 5, 2022
1 parent c46e83a commit 99d6fb7
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 19 deletions.
27 changes: 25 additions & 2 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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 "")
Expand Down Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions lib/VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 3 additions & 2 deletions src/main/java/com/criteo/vips/enums/VipsImageFormat.java
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -21,7 +21,8 @@ public enum VipsImageFormat {
PNG(".png"),
WEBP(".webp"),
GIF(".gif"),
AVIF(".avif");
AVIF(".avif"),
TIFF(".tiff");

private final String extension;

Expand Down
45 changes: 31 additions & 14 deletions src/test/java/com/criteo/vips/VipsImageTest.java
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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<String, byte[]> SignatureByExtension = new HashMap<>();
private static Map<String, ArrayList<Byte[]>> 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")
Expand All @@ -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 {
Expand Down Expand Up @@ -105,7 +116,6 @@ public String toString() {
};

@BeforeClass

public static void onceExecutedBeforeAll() {
VipsContext.setLeak(true);
VipsContext.setMaxCache(0);
Expand Down Expand Up @@ -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<Byte[]> 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);
}
}

Expand Down
13 changes: 12 additions & 1 deletion src/test/java/com/criteo/vips/VipsTestUtils.java
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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;

}
}
Binary file added src/test/resources/deflate_compression.tiff
Binary file not shown.
Binary file added src/test/resources/lzw_compression.tiff
Binary file not shown.
Binary file added src/test/resources/none_compression.tiff
Binary file not shown.
Binary file added src/test/resources/pack_bits_compression.tiff
Binary file not shown.

0 comments on commit 99d6fb7

Please sign in to comment.