Browse Source

Test DNG writing against custom libtiff code

Martijn Braam 1 year ago
parent
commit
ceb2c6d8aa
5 changed files with 113 additions and 9 deletions
  1. 6 6
      src/libdng.c
  2. 6 1
      tests/CMakeLists.txt
  3. 92 0
      tests/check_dng.c
  4. 8 1
      tests/meson.build
  5. 1 1
      util/makedng.c

+ 6 - 6
src/libdng.c

@@ -163,7 +163,7 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 
 	TIFF *tif = TIFFOpen(path, "w");
 	if (!tif) {
-		return -1;
+		return 0;
 	}
 	libdng_set_datetime_now(dng);
 
@@ -223,7 +223,7 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 	}
 
 	if (!TIFFWriteDirectory(tif)) {
-		return -1;
+		return 0;
 	}
 
 	// Define the raw data IFD
@@ -243,12 +243,12 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 		TIFFWriteScanline(tif, (void *) raw_frame + (row * stride), row, 0);
 	}
 	if (!TIFFWriteDirectory(tif)) {
-		return -1;
+		return 0;
 	}
 
 	if (TIFFCreateEXIFDirectory(tif) != 0) {
 		fprintf(stderr, "Could not create EXIF\n");
-		return -1;
+		return 0;
 	}
 
 	if (dng->datetime.tm_year) {
@@ -261,7 +261,7 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 	uint64_t exif_offset = 0;
 	if (!TIFFWriteCustomDirectory(tif, &exif_offset)) {
 		fprintf(stderr, "Can't write EXIF\n");
-		return -1;
+		return 0;
 	}
 	TIFFFreeDirectory(tif);
 
@@ -277,5 +277,5 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 		free(raw_frame);
 	}
 	
-	return 0;
+	return 1;
 }

+ 6 - 1
tests/CMakeLists.txt

@@ -6,4 +6,9 @@ add_executable(check_mode check_mode.c greatest.h)
 target_include_directories(check_mode PUBLIC include)
 target_link_libraries(check_mode PUBLIC libdng check)
 
-add_test(NAME check_mode COMMAND check_mode)
+add_executable(check_dng check_dng.c greatest.h)
+target_include_directories(check_dng PUBLIC include)
+target_link_libraries(check_dng PUBLIC libdng check)
+
+add_test(NAME check_mode COMMAND check_mode)
+add_test(NAME check_dng COMMAND check_dng)

+ 92 - 0
tests/check_dng.c

@@ -0,0 +1,92 @@
+#include <stdbool.h>
+#include <tiffio.h>
+#include "greatest.h"
+#include "libdng.h"
+
+static enum greatest_test_res
+check_str_tag(TIFF *im, uint32_t tag, const char *name, const char *expected)
+{
+	char *temp;
+	if (TIFFGetField(im, tag, &temp) != 1) {
+			FAILm(name);
+	}
+		ASSERT_STR_EQm(name, expected, temp);
+		PASS();
+}
+
+static enum greatest_test_res
+check_int_tag(TIFF *im, uint32_t tag, const char *name, int expected)
+{
+	uint32_t temp;
+	if (TIFFGetField(im, tag, &temp) != 1) {
+			FAILm(name);
+	}
+		ASSERT_EQ_FMTm(name, expected, temp, "%d");
+		PASS();
+}
+
+
+TEST generate_simple_dng(void)
+{
+	libdng_info info = {0};
+	libdng_new(&info);
+		ASSERT_EQm("Set mode", 1, libdng_set_mode_from_name(&info, "RGGB"));
+		ASSERT_EQm("Set make", 1, libdng_set_make_model(&info, "Make", "Model"));
+		ASSERT_EQm("Set software", 1, libdng_set_software(&info, "Software"));
+		ASSERT_EQm("Set orientation", 1, libdng_set_orientation(&info, 4));
+	uint8_t *data = malloc(1280 * 720);
+		ASSERT_EQm("Write DNG", 1, libdng_write(&info, "test.dng", 1280, 720, data, 1280 * 720));
+	free(data);
+	libdng_free(&info);
+
+	// Use LibTIFF directly to verify results
+	TIFF *im = TIFFOpen("test.dng", "r");
+	if (im == NULL) {
+			FAILm("Could not open result");
+	}
+
+	// Check IFD0 with most metadata and the thumbnail image
+		CHECK_CALL(check_int_tag(im, TIFFTAG_ORIENTATION, "ORIENTATION", 4));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_BITSPERSAMPLE, "THUMB_BPS", 8));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_SAMPLESPERPIXEL, "THUMB_CHANNELS", 3));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_PHOTOMETRIC, "THUMB_PHOTOMETRIC", PHOTOMETRIC_RGB));
+
+		CHECK_CALL(check_str_tag(im, TIFFTAG_MAKE, "MAKE", "Make"));
+		CHECK_CALL(check_str_tag(im, TIFFTAG_MODEL, "MODEL", "Model"));
+		CHECK_CALL(check_str_tag(im, TIFFTAG_UNIQUECAMERAMODEL, "UCM", "Make Model"));
+		CHECK_CALL(check_str_tag(im, TIFFTAG_SOFTWARE, "SOFTWARE", "Software"));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_ORIENTATION, "ORIENTATION", 4));
+
+	// Switch to IFD1 which has the raw data
+	int subifd_count = 0;
+	void *ptr;
+	toff_t subifd_offsets[2];
+	TIFFGetField(im, TIFFTAG_SUBIFD, &subifd_count, &ptr);
+	memcpy(subifd_offsets, ptr, subifd_count * sizeof(subifd_offsets[0]));
+	TIFFSetSubDirectory(im, subifd_offsets[0]);
+
+	// Check IFD1 metadata
+		CHECK_CALL(check_int_tag(im, TIFFTAG_IMAGEWIDTH, "RAW_WIDTH", 1280));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_IMAGELENGTH, "RAW_HEIGHT", 720));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_BITSPERSAMPLE, "RAW_BPS", 8));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_SAMPLESPERPIXEL, "RAW_CHANNELS", 1));
+		CHECK_CALL(check_int_tag(im, TIFFTAG_PHOTOMETRIC, "RAW_PHOTOMETRIC", PHOTOMETRIC_CFA));
+
+		PASS();
+}
+
+SUITE (test_suite)
+{
+		RUN_TEST(generate_simple_dng);
+}
+
+GREATEST_MAIN_DEFS();
+
+int
+main(int argc, char **argv)
+{
+	GREATEST_MAIN_BEGIN();
+	libdng_init();
+	RUN_SUITE(test_suite);
+	GREATEST_MAIN_END();
+}

+ 8 - 1
tests/meson.build

@@ -3,4 +3,11 @@ check_mode = executable('check_mode', 'check_mode.c', 'greatest.h',
     link_with: libdng,
     install: false,
 )
-test('check_mode', check_mode)
+check_mode = executable('check_dng', 'check_dng.c', 'greatest.h',
+    include_directories: inc,
+    link_with: libdng,
+    install: false,
+)
+
+test('check_mode', check_mode)
+test('check_dng', check_dng)

+ 1 - 1
util/makedng.c

@@ -146,7 +146,7 @@ main(int argc, char *argv[])
 	fclose(src);
 
 	printf("Writing %s...\n", argv[optind + 1]);
-	if (libdng_write(&info, argv[optind + 1], width, height, data, src_size) < 0) {
+	if (!libdng_write(&info, argv[optind + 1], width, height, data, src_size)) {
 		fprintf(stderr, "Could not write DNG\n");
 		return 1;
 	}