27 #include <libopenraw++/thumbnail.h>
28 #include <libopenraw++/rawdata.h>
32 #include "ifdfilecontainer.h"
37 #include "nefdiffiterator.h"
38 #include "nefcfaiterator.h"
41 using namespace Debug;
47 const IFDFile::camera_ids_t NEFFile::s_def[] = {
48 {
"NIKON D1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
49 OR_TYPEID_NIKON_D1) },
50 {
"NIKON D100 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
51 OR_TYPEID_NIKON_D100) },
52 {
"NIKON D1X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
53 OR_TYPEID_NIKON_D1X) },
54 {
"NIKON D200", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
55 OR_TYPEID_NIKON_D200) },
56 {
"NIKON D2H", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
57 OR_TYPEID_NIKON_D2H ) },
58 {
"NIKON D2X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
59 OR_TYPEID_NIKON_D2X ) },
60 {
"NIKON D3", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
61 OR_TYPEID_NIKON_D3) },
62 {
"NIKON D300", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
63 OR_TYPEID_NIKON_D300) },
64 {
"NIKON D3000", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
65 OR_TYPEID_NIKON_D3000) },
66 {
"NIKON D40", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
67 OR_TYPEID_NIKON_D40) },
68 {
"NIKON D40X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
69 OR_TYPEID_NIKON_D40X) },
70 {
"NIKON D50", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
71 OR_TYPEID_NIKON_D50) },
72 {
"NIKON D70", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
73 OR_TYPEID_NIKON_D70) },
74 {
"NIKON D70s", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
75 OR_TYPEID_NIKON_D70S) },
76 {
"NIKON D80", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
77 OR_TYPEID_NIKON_D80) },
81 RawFile *NEFFile::factory(IO::Stream* _filename)
83 return new NEFFile(_filename);
86 NEFFile::NEFFile(IO::Stream* _filename)
87 : TiffEpFile(_filename, OR_RAWFILE_TYPE_NEF)
101 size_t real_size = container.
fetchData(buf, offset,
103 if(real_size != 256) {
106 for(i = 15; i < 256; i+= 16) {
108 Trace(DEBUG1) <<
"isCompressed: true\n";
112 Trace(DEBUG1) <<
"isCompressed: false\n";
116 ::or_error NEFFile::_decompressNikonQuantized(
RawData & data)
118 NEFCompressionInfo c;
119 if (!_getCompressionCurve(data, c)) {
120 return OR_ERROR_NOT_FOUND;
122 const uint32_t rows = data.y();
123 const uint32_t raw_columns = data.x();
126 const uint32_t columns = raw_columns - 1;
129 diffs(c.huffman, data.data());
130 NefCfaIterator iter(diffs, rows, raw_columns, c.vpred);
133 uint16_t *p = (uint16_t *) newData.allocData(rows * columns * 2);
136 uint16_t bpc = data.
bpc();
138 newData.setMax((1 << bpc) - 1);
139 newData.setCfaPattern(data.cfaPattern());
141 for (
unsigned int i = 0; i < rows; i++) {
142 for (
unsigned int j = 0; j < raw_columns; j++) {
143 uint16_t t = iter.get();
145 unsigned shift = 16 - data.
bpc();
146 p[i * columns + j] = c.curve[t & 0x3fff] << shift;
152 return OR_ERROR_NONE;
155 ::or_error NEFFile::_decompressIfNeeded(RawData & data,
158 uint32_t compression = data.compression();
159 if((options & OR_OPTIONS_DONT_DECOMPRESS) ||
160 compression == IFD::COMPRESS_NONE) {
161 return OR_ERROR_NONE;
162 }
else if(compression == IFD::COMPRESS_NIKON_QUANTIZED) {
163 return _decompressNikonQuantized(data);
165 return OR_ERROR_INVALID_FORMAT;
169 int NEFFile::_getCompressionCurve(RawData & data, NEFFile::NEFCompressionInfo& c)
179 m_exifIfd->getEntry(IFD::EXIF_TAG_MAKER_NOTE);
184 uint32_t off = maker_ent->offset();
185 uint32_t base = off + 10;
187 IFDDir::Ref ref(
new IFDDir(base + 8, *
m_container));
194 size_t pos = base + curveEntry->offset();
197 file->
seek(pos, SEEK_SET);
208 if (header == 0x4410) {
209 c.huffman = NefDiffIterator::Lossy12Bit;
211 }
else if (header == 0x4630) {
212 c.huffman = NefDiffIterator::LossLess14Bit;
218 for (
int i = 0; i < 2; ++i) {
219 for (
int j = 0; j < 2; ++j) {
228 if (header == 0x4410) {
233 for (
size_t i = 0; i < nelems; ++i) {
237 c.curve.push_back(aux);
239 }
else if (header == 0x4630) {
240 for (
size_t i = 0; i <= 0x3fff; ++i) {
241 c.curve.push_back(i);
248 ::or_error NEFFile::_getRawData(RawData & data, uint32_t options)
250 ::or_error ret = OR_ERROR_NONE;
252 Trace(DEBUG1) <<
"_getRawData()\n";
256 if (ret != OR_ERROR_NONE) {
259 ret = _decompressIfNeeded(data, options);
262 ret = OR_ERROR_NOT_FOUND;