Use libdng to write the output images

This commit is contained in:
Martijn Braam
2023-11-20 15:05:52 +01:00
parent aba8eace21
commit 90321888c8

View File

@@ -9,18 +9,15 @@
#include <assert.h>
#include <gtk/gtk.h>
#include <math.h>
#include <tiffio.h>
#ifndef SYSCONFDIR
#include "config.h"
#endif
#include "dcp.h"
#include "gl_util.h"
#include "libdng.h"
#include <sys/mman.h>
#define TIFFTAG_FORWARDMATRIX1 50964
#define TIFFTAG_FORWARDMATRIX2 50965
static const float colormatrix_srgb[] = { 3.2409f, -1.5373f, -0.4986f,
-0.9692f, 1.8759f, 0.0415f,
0.0556f, -0.2039f, 1.0569f };
@@ -45,66 +42,6 @@ static char capture_fname[255];
static GSettings *settings;
static void
register_custom_tiff_tags(TIFF *tif)
{
static const TIFFFieldInfo custom_fields[] = {
{ TIFFTAG_FORWARDMATRIX1,
-1,
-1,
TIFF_SRATIONAL,
FIELD_CUSTOM,
1,
1,
"ForwardMatrix1" },
{ TIFFTAG_FORWARDMATRIX2,
-1,
-1,
TIFF_SRATIONAL,
FIELD_CUSTOM,
1,
1,
"ForwardMatrix2" },
{ DCPTAG_PROFILE_TONE_CURVE,
-1,
-1,
TIFF_FLOAT,
FIELD_CUSTOM,
1,
1,
"ProfileToneCurve" },
{ DCPTAG_PROFILE_HUE_SAT_MAP_DIMS,
-1,
-1,
TIFF_FLOAT,
FIELD_CUSTOM,
1,
1,
"ProfileHueSatMapDims" },
{ DCPTAG_PROFILE_HUE_SAT_MAP_DATA_1,
-1,
-1,
TIFF_FLOAT,
FIELD_CUSTOM,
1,
1,
"ProfileHueSatMapData1" },
{ DCPTAG_PROFILE_HUE_SAT_MAP_DATA_2,
-1,
-1,
TIFF_FLOAT,
FIELD_CUSTOM,
1,
1,
"ProfileHueSatMapData2" },
};
// Add missing dng fields
TIFFMergeFieldInfo(tif,
custom_fields,
sizeof(custom_fields) / sizeof(custom_fields[0]));
}
void
mp_process_find_all_processors(GtkListStore *store)
{
@@ -212,7 +149,7 @@ mp_process_find_processor(char *script)
static void
setup(MPPipeline *pipeline, const void *data)
{
TIFFSetTagExtender(register_custom_tiff_tags);
libdng_init();
settings = g_settings_new("org.postmarketos.Megapixels");
}
@@ -554,20 +491,21 @@ process_image_for_capture(const uint8_t *image, int count)
char fname[255];
sprintf(fname, "%s/%d.dng", burst_dir, count);
TIFF *tif = TIFFOpen(fname, "w");
if (!tif) {
printf("Could not open tiff\n");
}
libdng_info dng = { 0 };
libdng_new(&dng);
// Define TIFF thumbnail
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width >> 4);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height >> 4);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_MAKE, state_proc.configuration->make);
TIFFSetField(tif, TIFFTAG_MODEL, state_proc.configuration->model);
libdng_set_mode_from_pixfmt(&dng, state_proc.mode->v4l_pixfmt);
libdng_set_make_model(&dng,
state_proc.configuration->make,
state_proc.configuration->model);
libdng_write(&dng,
fname,
state_proc.mode->width,
state_proc.mode->height,
image,
count);
libdng_free(&dng);
uint16_t orientation;
if (state_proc.device_rotation == 0) {
@@ -585,19 +523,7 @@ process_image_for_capture(const uint8_t *image, int count)
}
TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation);
TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_SOFTWARE, "Megapixels");
long sub_offset = 0;
TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &sub_offset);
TIFFSetField(tif, TIFFTAG_DNGVERSION, "\001\001\0\0");
TIFFSetField(tif, TIFFTAG_DNGBACKWARDVERSION, "\001\0\0\0");
char uniquecameramodel[255];
sprintf(uniquecameramodel,
"%s %s",
state_proc.configuration->make,
state_proc.configuration->model);
TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, uniquecameramodel);
static float neutral[] = { 1.0f, 1.0f, 1.0f };
neutral[0] = state_proc.red;
@@ -616,28 +542,6 @@ process_image_for_capture(const uint8_t *image, int count)
}
TIFFWriteDirectory(tif);
// Define main photo
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height);
TIFFSetField(tif,
TIFFTAG_BITSPERSAMPLE,
libmegapixels_format_bits_per_pixel(state_proc.mode->format));
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
static const short cfapatterndim[] = { 2, 2 };
TIFFSetField(tif, TIFFTAG_CFAREPEATPATTERNDIM, cfapatterndim);
#if (TIFFLIB_VERSION < 20201219) && !LIBTIFF_CFA_PATTERN
TIFFSetField(tif,
TIFFTAG_CFAPATTERN,
mp_pixel_format_cfa_pattern(mode.pixel_format));
#else
TIFFSetField(tif,
TIFFTAG_CFAPATTERN,
4,
libmegapixels_format_cfa_pattern(state_proc.mode->format));
#endif
printf("TIFF version %d\n", TIFFLIB_VERSION);
int whitelevel =
(1 << libmegapixels_format_bits_per_pixel(state_proc.mode->format)) -