Kaynağa Gözat

Set whitelevel in DNG output

Martijn Braam 1 yıl önce
ebeveyn
işleme
bc55cd7310
5 değiştirilmiş dosya ile 63 ekleme ve 3 silme
  1. 25 2
      doc/makedng.1.scd
  2. 14 0
      include/libdng.h
  3. 15 0
      src/libdng.c
  4. 1 0
      tests/test_dng_validate.sh
  5. 8 1
      util/makedng.c

+ 25 - 2
doc/makedng.1.scd

@@ -8,7 +8,7 @@ makedng - pack raw sensor data into a dng file with metadata
 
 makedng [OPTIONS] input-file output-file
 
-OPTIONS := { -w width | -h height | -p pixfmt | -m make,model | -s software | -o orientation }
+OPTIONS := { -w width | -h height | -p pixfmt | -m make,model | -s software | -o orientation | -n r,g,b | -b r,g,b | -e program }
 
 # DESCRIPTION
 
@@ -37,6 +37,15 @@ metadata to correctly render the file.
 *-c dcp-file*
 	Load a DCP calibration file and append the color profile to the final DNG.
 
+*-n red,green,blue*
+	Set the neutral whitepoint for the picture as the 3 floating point gain values.
+
+*-b red,green,blue*
+	Set the analog sensor gain for the three color channels as three comma seperated floats.
+
+*-e program*
+	Set the exposure program in the EXIF data using one of the program numbers from the DNG spec.
+
 # PIXEL FORMATS
 
 The pixel format argument accepts the following values:
@@ -75,4 +84,18 @@ pBCC, SBGGR12P: BG,GR bayer pixel data
 	RG16, SRGGB16: RG,GB bayer pixel data++
 GR16, SGRBG16: GR,BG bayer pixel data++
 GB16, SGBRG16: GB,RG bayer pixel data++
-BYR2, SBGGR16: BG,GR bayer pixel data
+BYR2, SBGGR16: BG,GR bayer pixel data
+
+# EXPOSURE PROGRAMS
+
+The defined exposure programs in the DNG specification are:
+
+- 0: Undefined exposure program (default)
+- 1: Full manual program
+- 2: Full auto program
+- 3: Aperture priority
+- 4: Shutter priority
+- 5: Creative program
+- 6: Action program (fast shutter)
+- 7: Portrait program (Large aperture)
+- 8: Landscape program (Small aperture)

+ 14 - 0
include/libdng.h

@@ -15,6 +15,7 @@ typedef struct {
 		char *software;
 		uint16_t orientation;
 		struct tm datetime;
+		uint16_t exposure_program;
 
 		// Raw image data
 		uint16_t bayer_pattern_dimensions[2];
@@ -49,6 +50,16 @@ typedef struct {
 #define LIBDNG_ORIENTATION_RIGHTBOT 7
 #define LIBDNG_ORIENTATION_LEFTBOT 8
 
+#define LIBDNG_EXPOSUREPROGRAM_UNDEFINED 0
+#define LIBDNG_EXPOSUREPROGRAM_MANUAL 1
+#define LIBDNG_EXPOSUREPROGRAM_NORMAL 2
+#define LIBDNG_EXPOSUREPROGRAM_APERTURE_PRIORITY 3
+#define LIBDNG_EXPOSUREPROGRAM_SHUTTER_PRIORITY 4
+#define LIBDNG_EXPOSUREPROGRAM_CREATIVE 5
+#define LIBDNG_EXPOSUREPROGRAM_ACTION 6
+#define LIBDNG_EXPOSUREPROGRAM_PORTRAIT 7
+#define LIBDNG_EXPOSUREPROGRAM_LANDSCAPE 8
+
 EXPORT int
 libdng_init();
 
@@ -88,6 +99,9 @@ libdng_set_analog_balance(libdng_info *dng, float red, float green, float blue);
 EXPORT int
 libdng_load_calibration_file(libdng_info *dng, const char *path);
 
+EXPORT int
+libdng_set_exposure_program(libdng_info *dng, uint16_t mode);
+
 EXPORT int
 libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned int height, const uint8_t *data,
 	size_t length);

+ 15 - 0
src/libdng.c

@@ -183,6 +183,19 @@ libdng_set_analog_balance(libdng_info *dng, float red, float green, float blue)
 	return 1;
 }
 
+int
+libdng_set_exposure_program(libdng_info *dng, uint16_t mode)
+{
+	if (dng == NULL)
+		return 0;
+
+	if (mode > 8)
+		return 0;
+
+	dng->exposure_program = mode;
+	return 1;
+}
+
 int
 libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned int height, const uint8_t *data,
 	size_t length)
@@ -293,6 +306,8 @@ libdng_write(libdng_info *dng, const char *path, unsigned int width, unsigned in
 		TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, datetime);
 	}
 
+	TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, dng->exposure_program);
+
 	uint64_t exif_offset = 0;
 	if (!TIFFWriteCustomDirectory(tif, &exif_offset)) {
 		fprintf(stderr, "Can't write EXIF\n");

+ 1 - 0
tests/test_dng_validate.sh

@@ -31,6 +31,7 @@ $makedng -w 1280 -h 720 -p RGGB \
   -o 2 \
   -n 0.1,0.2,0.3 \
   -b 0.4,0.5,0.6 \
+  -e 2 \
   scratch/data.rgb scratch/fields.dng
 
 # Validate DNG

+ 8 - 1
util/makedng.c

@@ -21,6 +21,7 @@ usage(char *name)
 	fprintf(stderr, "  -c dcp         Append calibration data from .dcp file\n");
 	fprintf(stderr, "  -n r,g,b       Set the whitepoint as 3 comma seperated floats\n");
 	fprintf(stderr, "  -b r,g,b       Set sensor analog gain as 3 comma seperated floats\n");
+	fprintf(stderr, "  -e program     Set the exposure program in EXIF, 0-8\n");
 }
 
 int
@@ -43,8 +44,9 @@ main(int argc, char *argv[])
 	uint16_t orientation = 0;
 	float neutral[] = {1.0f, 1.0f, 1.0f};
 	float balance[] = {1.0f, 1.0f, 1.0f};
+	uint16_t exposure_program = 0;
 
-	while ((c = getopt(argc, argv, "w:h:p:o:m:s:c:n:b:")) != -1) {
+	while ((c = getopt(argc, argv, "w:h:p:o:m:s:c:n:b:e:")) != -1) {
 		switch (c) {
 			case 'w':
 				val = strtol(optarg, &end, 10);
@@ -88,6 +90,10 @@ main(int argc, char *argv[])
 					return 1;
 				}
 				break;
+			case 'e':
+				val = strtol(optarg, &end, 10);
+				exposure_program = (uint16_t) val;
+				break;
 			case '?':
 				if (optopt == 'd' || optopt == 'l') {
 					fprintf(stderr, "Option -%c requires an argument.\n", optopt);
@@ -152,6 +158,7 @@ main(int argc, char *argv[])
 
 	libdng_set_neutral(&info, neutral[0], neutral[1], neutral[2]);
 	libdng_set_analog_balance(&info, balance[0], balance[1], balance[2]);
+	libdng_set_exposure_program(&info, exposure_program);
 
 	printf("Reading %s...\n", argv[optind]);
 	FILE *src = fopen(argv[optind], "r");