diff options
author | Hubert Figuiere <hub@quagmire.(none)> | 2007-10-08 17:20:53 -0400 |
---|---|---|
committer | Hubert Figuiere <hub@quagmire.(none)> | 2007-10-08 17:20:53 -0400 |
commit | b59600f97c57c0f577f5dd8aa3238c00db76c293 (patch) | |
tree | 3e627a83bf48f7d212b092a75fd6ce2bb4b1b9fe /dcraw | |
parent | 5ef9b89a0e3d1989413d578b9d004e6c58a02efa (diff) |
more stuff from dcraw... for archiving purpose
Diffstat (limited to 'dcraw')
-rw-r--r-- | dcraw/elphel_dng.c | 141 | ||||
-rw-r--r-- | dcraw/libtiff.patch | 47 |
2 files changed, 188 insertions, 0 deletions
diff --git a/dcraw/elphel_dng.c b/dcraw/elphel_dng.c new file mode 100644 index 0000000..6b5405b --- /dev/null +++ b/dcraw/elphel_dng.c @@ -0,0 +1,141 @@ +/* + Converts Elphel camera output from Elphel-JPEG to Adobe DNG. + gcc -o elphel_dng elphel_dng.c -O4 -Wall -lm -ljpeg -ltiff + Requires LibTIFF 3.8.0 plus a patch. + + Written by Dave Coffin for Berkeley Engineering and Research. + + Free for all uses. + + $Revision: 1.4 $ + $Date: 2006/02/18 22:50:53 $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <math.h> +#include <jpeglib.h> +#include <tiffio.h> + +#ifdef MODE1 +#define ROT(x) (x) +#else +#define ROT(x) ((x) >> 1 | ((x) & 1) << 3) +#endif + +int main (int argc, char **argv) +{ + static const short CFARepeatPatternDim[] = { 2,2 }; + static const float cam_xyz[] = + { 2.005,-0.771,-0.269, -0.752,1.688,0.064, -0.149,0.283,0.745 }; + static const float neutral[] = { 0.807133, 1.0, 0.913289 }; + long sub_offset=0, white=0x3fff; + struct jpeg_error_mgr jerr; + struct jpeg_decompress_struct cinfo; + JSAMPARRAY buf; + float gam; + int status=1, i, r, c, row, col; + unsigned short curve[256], *out; + struct stat st; + struct tm tm; + char datetime[64]; + FILE *ifp; + TIFF *tif; + + if (argc != 4) { + fprintf (stderr, "Usage: %s gamma infile outfile\n" + "Example: %s 100 cgi.jpg output.dng\n", argv[0],argv[0]); + return 1; + } + if ((gam = atof(argv[1])) <= 0) { + fprintf (stderr, "Gamma must be positive!\n"); + return 1; + } + for (i=0; i < 256; i++) + curve[i] = 0x3fff * pow (i/255.0, 100/gam) + 0.5; + + if (!(ifp = fopen (argv[2], "rb"))) { + perror (argv[2]); + return 1; + } + stat (argv[2], &st); + gmtime_r (&st.st_mtime, &tm); + sprintf (datetime, "%04d:%02d:%02d %02d:%02d:%02d", + tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec); + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + jpeg_read_header (&cinfo, TRUE); + if ((cinfo.image_width | cinfo.image_height) & 15) { + fprintf (stderr, "Dimensions must be multiples of 16!\n"); + goto fail; + } + cinfo.dct_method = JDCT_FLOAT; + cinfo.out_color_space = JCS_GRAYSCALE; + jpeg_start_decompress (&cinfo); + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.image_width, 16); + if (!(tif = TIFFOpen (argv[3], "w"))) goto fail; + out = calloc (cinfo.image_width, sizeof *out); + + TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 1); + TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cinfo.image_width >> 4); + TIFFSetField (tif, TIFFTAG_IMAGELENGTH, cinfo.image_height >> 4); + TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField (tif, TIFFTAG_MAKE, "Elphel"); + TIFFSetField (tif, TIFFTAG_MODEL, "Model 323"); + TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField (tif, TIFFTAG_SOFTWARE, "elphel_dng"); + TIFFSetField (tif, TIFFTAG_DATETIME, datetime); + TIFFSetField (tif, TIFFTAG_SUBIFD, 1, &sub_offset); + TIFFSetField (tif, TIFFTAG_DNGVERSION, "\001\001\0\0"); + TIFFSetField (tif, TIFFTAG_DNGBACKWARDVERSION, "\001\0\0\0"); + TIFFSetField (tif, TIFFTAG_UNIQUECAMERAMODEL, "Elphel Model 323"); + TIFFSetField (tif, TIFFTAG_COLORMATRIX1, 9, cam_xyz); + TIFFSetField (tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral); + TIFFSetField (tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21); + TIFFSetField (tif, TIFFTAG_ORIGINALRAWFILENAME, argv[2]); + memset (buf[0], 0, cinfo.image_width); // all-black thumbnail + for (row=0; row < cinfo.image_height >> 4; row++) + TIFFWriteScanline (tif, buf[0], row, 0); + TIFFWriteDirectory (tif); + + TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 0); + TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cinfo.image_width); + TIFFSetField (tif, TIFFTAG_IMAGELENGTH, cinfo.image_height); + TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA); + TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField (tif, TIFFTAG_CFAREPEATPATTERNDIM, CFARepeatPatternDim); + TIFFSetField (tif, TIFFTAG_CFAPATTERN, 4, "\001\0\002\001"); + TIFFSetField (tif, TIFFTAG_LINEARIZATIONTABLE, 256, curve); + TIFFSetField (tif, TIFFTAG_WHITELEVEL, 1, &white); + + for (row=0; row < cinfo.image_height; row += 16) { + for (r=0; r < 16; ) + r += jpeg_read_scanlines (&cinfo, buf+r, 16-r); + for (r=0; r < 16; r++) { + for (col=0; col < cinfo.image_width; col += 16) + for (c=0; c < 16; c++) + out[col+c] = buf[ROT(r)][col+ROT(c)]; + TIFFWriteScanline (tif, out, row+r, 0); + } + } + free (out); + TIFFClose (tif); + jpeg_finish_decompress (&cinfo); + status = 0; +fail: + jpeg_destroy_decompress (&cinfo); + fclose (ifp); + return status; +} diff --git a/dcraw/libtiff.patch b/dcraw/libtiff.patch new file mode 100644 index 0000000..32a2d13 --- /dev/null +++ b/dcraw/libtiff.patch @@ -0,0 +1,47 @@ +--- tiff-3.8.2/libtiff/tif_dirinfo.c 2006-02-07 08:51:03.000000000 -0500 ++++ tiff-3.8.2/libtiff/tif_dirinfo.c 2006-10-26 11:09:51.000000000 -0400 +@@ -252,6 +252,10 @@ + FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen" }, + { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16,16, TIFF_FLOAT, + FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera" }, ++ { TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, FIELD_CUSTOM, ++ 0, 0, "CFARepeatPatternDim" }, ++ { TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, FIELD_CUSTOM, ++ 0, 1, "CFAPattern" }, + { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, FIELD_CUSTOM, + 1, 0, "Copyright" }, + /* end Pixar tags */ +@@ -298,10 +302,10 @@ + 0, 1, "BlackLevelDeltaH" }, + { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, + 0, 1, "BlackLevelDeltaV" }, +- { TIFFTAG_WHITELEVEL, -2, -2, TIFF_LONG, FIELD_CUSTOM, +- 0, 0, "WhiteLevel" }, +- { TIFFTAG_WHITELEVEL, -2, -2, TIFF_SHORT, FIELD_CUSTOM, +- 0, 0, "WhiteLevel" }, ++ { TIFFTAG_WHITELEVEL, -2, -1, TIFF_LONG, FIELD_CUSTOM, ++ 0, 1, "WhiteLevel" }, ++ { TIFFTAG_WHITELEVEL, -2, -1, TIFF_SHORT, FIELD_CUSTOM, ++ 0, 1, "WhiteLevel" }, + { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, + 0, 0, "DefaultScale" }, + { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, +--- tiff-3.8.2/libtiff/tiff.h 2005-12-27 06:28:23.000000000 -0500 ++++ tiff-3.8.2/libtiff/tiff.h 2006-10-26 11:09:51.000000000 -0400 +@@ -207,6 +207,7 @@ + #define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ + #define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ + #define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ ++#define PHOTOMETRIC_CFA 32803 /* color filter array */ + #define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ + #define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ + #define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +@@ -383,6 +384,8 @@ + #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 + /* tag 33405 is a private tag registered to Eastman Kodak */ + #define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ ++#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ ++#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */ + /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ + #define TIFFTAG_COPYRIGHT 33432 /* copyright string */ + /* IPTC TAG from RichTIFF specifications */ |