Browse Source

Support specifying a thumbnail image

Martijn Braam 1 year ago
parent
commit
d284dece45
2 changed files with 31 additions and 6 deletions
  1. 5 0
      include/libdng.h
  2. 26 6
      src/libdng.c

+ 5 - 0
include/libdng.h

@@ -106,4 +106,9 @@ EXPORT int
 libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned int height, const uint8_t *data,
 	size_t length);
 
+EXPORT int
+libdng_write_with_thumbnail(libdng_info *dng, const char *path, unsigned int width, unsigned int height,
+	const uint8_t *data,
+	size_t length, unsigned int thumb_width, unsigned int thumb_height, const uint8_t *thumb, size_t thumb_length);
+
 #endif //LIBDNG_LIBRARY_H

+ 26 - 6
src/libdng.c

@@ -201,6 +201,14 @@ int
 libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned int height, const uint8_t *data,
 	size_t length)
 {
+	return libdng_write_with_thumbnail(dng, path, width, height, data, length, 0, 0, NULL, 0);
+}
+
+int
+libdng_write_with_thumbnail(libdng_info *dng, const char *path, unsigned int width, unsigned int height,
+	const uint8_t *data, size_t length, unsigned int thumb_width, unsigned int thumb_height, const uint8_t *thumb,
+	size_t thumb_length)
+{
 
 	uint8_t *raw_frame = (uint8_t *) data;
 	if (dng->needs_repack) {
@@ -221,12 +229,18 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 
 	uint64_t ifd0_offsets[] = {0L};
 
+	// When not supplying a thumbnail generate a black thumb with 1/16th of the
+	// resolution of the full picture
+	if (thumb_length == 0) {
+		thumb_width = width >> 4;
+		thumb_height = height >> 4;
+	}
 
 	// First IFD describes the thumbnail and contains most of the metadata
 	// Tags are in numerical order
 	TIFFSetField(tif, TIFFTAG_SUBFILETYPE, DNG_SUBFILETYPE_THUMBNAIL);
-	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width >> 4);
-	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height >> 4);
+	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, thumb_width);
+	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, thumb_height);
 	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
 	TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
 	TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
@@ -261,13 +275,19 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 	TIFFSetField(tif, DNGTAG_UNIQUECAMERAMODEL, ucm);
 	TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &ifd0_offsets);
 
-	// Write black thumbnail, only windows uses this
-	{
-		unsigned char *buf = (unsigned char *) calloc(1, (width >> 4) * 3);
-		for (int row = 0; row < (height >> 4); row++) {
+	if (thumb_length == 0) {
+		// Generate a single black scanline and write it
+		unsigned char *buf = (unsigned char *) calloc(1, thumb_width * 3);
+		for (int row = 0; row < thumb_height; row++) {
 			TIFFWriteScanline(tif, buf, row, 0);
 		}
 		free(buf);
+	} else {
+		// Write the supplied thumbnail
+		unsigned int t_stride = thumb_width;
+		for (int row = 0; row < thumb_height; row++) {
+			TIFFWriteScanline(tif, (void *) thumb + (row * t_stride), row, 0);
+		}
 	}
 
 	if (!TIFFWriteDirectory(tif)) {