我正在尝试从任意像素数组生成TIFF/EP Profile 2 raw (.dng)图像。该像素阵列表示拜耳模式(CFA)。
我研究了TIFF/EP文件规范,通过使用libtiff,我包含了生成完整. ng文件所必需的所有标记。但是,我不能用draww转换创建的文件(draww显示它不能解码文件)。
一个问题可能是由两个标签给出的,这两个标签在TIFF/EP规范中被声明为强制性的,但似乎没有在libtiff中实现:SensingMethod和TIFF/EPStandardID标签。我真的必须包含它们吗(我看到的示例代码忽略了这些标记,但仍然可以正常工作),如果是这样,我如何手动将它们添加到libtiff中?此外,设置SubIFD标记会产生错误消息"断言失败:*pa<=0xFFFFFFFFUL,文件tif_dirwrite.c,行1869"
总而言之,我不认为我的问题仅仅是由于这三个标签,我认为有一些根本性的错误。也许你们中有人可以看一下我的代码并给出一些提示?我不得不说libtiff的文档相当糟糕,所以我的代码灵感来自于极少的示例代码之一:elphel_dng.c.非常感谢!费边
p。我把生成的文件上传到Dropbox
c++#include "tiffio.h"
#include <iostream>
using namespace std;
int main(void)
{
TIFF *tif = TIFFOpen("8bitRaw.dng", "w");
const int sampleperpixel = 1;
const int width = 4;
const int height = 4;
static const short bayerPatternDimensions[] = { 2,2 };
static const double cam_xyz[] = { 2.0413690, -0.5649464, -0.3446944, -0.9692660, 1.8760108, 0.0415560,0.0134474, -0.1183897, 1.0154096 }; //AdobeRGB
static const double neutral[] = { 1.0, 1.0, 1.0 };
long max_white = 255;
long sub_offset = 0;
int row, i;
float gamma = 80;
//Arbitrary Bayer pixel values:
unsigned char image[height][width*sampleperpixel] = {};
image[0][0] = 5; image[0][1] = 165; image[0][2] = 0; image[0][3] = 255;
image[1][0] = 0; image[1][1] = 21; image[1][2] = 0; image[1][3] = 10;
image[2][0] = 0; image[2][1] = 0; image[2][2] = 30; image[2][3] = 5;
image[3][0] = 21; image[3][1] = 120; image[3][2] = 1; image[3][3] = 254;
//Black Thumbnail pixel values:
unsigned char Thumbnail_RGB_Array[] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
//Linearization Table:
unsigned short curve[256];
for (i = 0; i < 256; i++)
curve[i] = 255 * pow(i / 255.0, 100.0 / gamma) + 0.5;
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 4);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, 4);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_XRESOLUTION, 75.0);
TIFFSetField(tif, TIFFTAG_YRESOLUTION, 75.0);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
TIFFSetField(tif, TIFFTAG_MAKE, "DummyMake");
TIFFSetField(tif, TIFFTAG_MODEL, "DummyModel");
TIFFSetField(tif, TIFFTAG_SOFTWARE, "DummySoftware");
TIFFSetField(tif, TIFFTAG_ORIGINALRAWFILENAME, 1, "DummyName.dng");
TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, "DummyUniqueModel");
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "DummyImageDescription");
TIFFSetField(tif, TIFFTAG_COPYRIGHT, "DummyCopyright");
TIFFSetField(tif, TIFFTAG_DATETIME, "2016:06:30 11:11:15");
TIFFSetField(tif, TIFFTAG_DNGVERSION, " 1 1 0 0");
TIFFSetField(tif, TIFFTAG_DNGBACKWARDVERSION, " 1 0 0 0");
TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, cam_xyz);
TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral);
TIFFSetField(tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21);
//SensingMethodTag and TIFF/EPStandardID tag: Libtiff doesn't seem to know these:
//TIFFSetField(tif, 37399, 2);
//TIFFSetField(tif, 37398, " 1 1 0 0");
//Yields an error:
//TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &sub_offset);
//Write a black 4x4 pixel dummy thumbnail:
for (row = 0; row < 4 ; row++)
TIFFWriteScanline(tif, Thumbnail_RGB_Array, row, 0);
TIFFWriteDirectory(tif);
//Now write main raw image:
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_CFAREPEATPATTERNDIM, bayerPatternDimensions);
TIFFSetField(tif, TIFFTAG_CFAPATTERN, " 1 0 2 1");
TIFFSetField(tif, TIFFTAG_CFAPLANECOLOR, 3, " 0 1 2");
TIFFSetField(tif, TIFFTAG_LINEARIZATIONTABLE, 256, curve);
TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &max_white);
TIFFWriteScanline(tif, image[0], 0, 0);
TIFFWriteScanline(tif, image[1], 1, 0);
TIFFWriteScanline(tif, image[2], 2, 0);
TIFFWriteScanline(tif, image[3], 3, 0);
TIFFClose(tif);
return 0;
}
我有几乎相同的需求,并从您离开的地方继续。下面是一段代码,它生成一个128 × 128的原始拜耳10位DNG图像,该图像与dng_validate, draw, lightroom和resolve兼容。
我已经去掉了几乎所有的东西,只保留了最小值,以使dng_validate满意。
#include <tiffio.h>
#include <math.h>
int main (void)
{
const int width = 128;
const int height = 128;
static const short bayerPatternDimensions[] = { 2, 2 };
static const float ColorMatrix1[] =
{
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
};
static const float AsShotNeutral[] =
{
1.0, 1.0, 1.0,
};
int row, i;
float gamma = 80;
#define GR 0x80, 0x20, 0x08, 0x02, 0x00,
#define WH 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
#define BL 0x00, 0x00, 0x00, 0x00, 0x00,
#define BLK(N) N N N N N N N N
// Arbitrary Bayer pixel values:
unsigned char image[] =
{
BLK(WH)
BLK(GR)
BLK(BL)
BLK(WH)
BLK(GR)
BLK(BL)
BLK(WH)
BLK(GR)
BLK(BL)
};
TIFF* tif = TIFFOpen ("out.dng", "w");
TIFFSetField (tif, TIFFTAG_DNGVERSION, " 1 1 0 0");
TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 0);
TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 10);
TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
TIFFSetField (tif, TIFFTAG_CFAREPEATPATTERNDIM, bayerPatternDimensions);
TIFFSetField (tif, TIFFTAG_CFAPATTERN, " 0 1 1 2");
TIFFSetField (tif, TIFFTAG_MAKE, "DNG");
TIFFSetField (tif, TIFFTAG_UNIQUECAMERAMODEL, "DNG");
TIFFSetField (tif, TIFFTAG_COLORMATRIX1, 9, ColorMatrix1);
TIFFSetField (tif, TIFFTAG_ASSHOTNEUTRAL, 3, AsShotNeutral);
TIFFSetField (tif, TIFFTAG_CFALAYOUT, 1);
TIFFSetField (tif, TIFFTAG_CFAPLANECOLOR, 3, " 0 1 2");
unsigned char* cur = image;
for (row = 0; row < height;)
{
for (i = 0; i < 32; ++i, ++row)
TIFFWriteScanline (tif, cur, row, 0);
cur += 40;
}
TIFFClose (tif);
return 0;
}
draw是非常顽固的工作,我不得不得到它的源代码和跟踪在gdb中找到错误的条件:
if (!load_raw || height < 22 || width < 22 ||
tiff_bps > 16 || tiff_samples > 6 || colors > 4)
is_raw = 0;
所以你第一次尝试创建一个4x4的图像会自动失败,因为这个