00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026 #include <vector>
00027 #include <libopenraw++/thumbnail.h>
00028 #include <libopenraw++/rawdata.h>
00029
00030 #include "debug.h"
00031 #include "ifd.h"
00032 #include "ifdfilecontainer.h"
00033 #include "ifddir.h"
00034 #include "ifdentry.h"
00035 #include "io/file.h"
00036 #include "huffman.h"
00037 #include "nefdiffiterator.h"
00038 #include "nefcfaiterator.h"
00039 #include "neffile.h"
00040
00041 using namespace Debug;
00042
00043 namespace OpenRaw {
00044
00045
00046 namespace Internals {
00047 const IFDFile::camera_ids_t NEFFile::s_def[] = {
00048 { "NIKON D1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00049 OR_TYPEID_NIKON_D1) },
00050 { "NIKON D100 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00051 OR_TYPEID_NIKON_D100) },
00052 { "NIKON D1X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00053 OR_TYPEID_NIKON_D1X) },
00054 { "NIKON D200", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00055 OR_TYPEID_NIKON_D200) },
00056 { "NIKON D2H", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00057 OR_TYPEID_NIKON_D2H ) },
00058 { "NIKON D2X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00059 OR_TYPEID_NIKON_D2X ) },
00060 { "NIKON D3", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00061 OR_TYPEID_NIKON_D3) },
00062 { "NIKON D300", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00063 OR_TYPEID_NIKON_D300) },
00064 { "NIKON D40", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00065 OR_TYPEID_NIKON_D40) },
00066 { "NIKON D40X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00067 OR_TYPEID_NIKON_D40X) },
00068 { "NIKON D50", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00069 OR_TYPEID_NIKON_D50) },
00070 { "NIKON D70", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00071 OR_TYPEID_NIKON_D70) },
00072 { "NIKON D70s", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00073 OR_TYPEID_NIKON_D70S) },
00074 { "NIKON D80", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON,
00075 OR_TYPEID_NIKON_D80) },
00076 { 0, 0 }
00077 };
00078
00079 RawFile *NEFFile::factory(IO::Stream* _filename)
00080 {
00081 return new NEFFile(_filename);
00082 }
00083
00084 NEFFile::NEFFile(IO::Stream* _filename)
00085 : TiffEpFile(_filename, OR_RAWFILE_TYPE_NEF)
00086 {
00087 _setIdMap(s_def);
00088 }
00089
00090
00091 NEFFile::~NEFFile()
00092 {
00093 }
00094
00095 bool NEFFile::isCompressed(RawContainer & container, uint32_t offset)
00096 {
00097 int i;
00098 uint8_t buf[256];
00099 size_t real_size = container.fetchData(buf, offset,
00100 256);
00101 if(real_size != 256) {
00102 return true;
00103 }
00104 for(i = 15; i < 256; i+= 16) {
00105 if(buf[i]) {
00106 Trace(DEBUG1) << "isCompressed: true\n";
00107 return true;
00108 }
00109 }
00110 Trace(DEBUG1) << "isCompressed: false\n";
00111 return false;
00112 }
00113
00114 ::or_error NEFFile::_decompressNikonQuantized(RawData & data)
00115 {
00116 NEFCompressionInfo c;
00117 if (!_getCompressionCurve(data, c)) {
00118 return OR_ERROR_NOT_FOUND;
00119 }
00120 const uint32_t rows = data.y();
00121 const uint32_t raw_columns = data.x();
00122
00123
00124 const uint32_t columns = raw_columns - 1;
00125
00126 NefDiffIterator
00127 diffs(c.huffman, data.data());
00128 NefCfaIterator iter(diffs, rows, raw_columns, c.vpred);
00129
00130 RawData newData;
00131 uint16_t *p = (uint16_t *) newData.allocData(rows * columns * 2);
00132 newData.setDimensions(columns, rows);
00133 newData.setDataType(OR_DATA_TYPE_CFA);
00134 uint16_t bpc = data.bpc();
00135 newData.setBpc(bpc);
00136 newData.setMax((1 << bpc) - 1);
00137 newData.setCfaPattern(data.cfaPattern());
00138
00139 for (unsigned int i = 0; i < rows; i++) {
00140 for (unsigned int j = 0; j < raw_columns; j++) {
00141 uint16_t t = iter.get();
00142 if (j < columns) {
00143 unsigned shift = 16 - data.bpc();
00144 p[i * columns + j] = c.curve[t & 0x3fff] << shift;
00145 }
00146 }
00147 }
00148
00149 data.swap(newData);
00150 return OR_ERROR_NONE;
00151 }
00152
00153 ::or_error NEFFile::_decompressIfNeeded(RawData & data,
00154 uint32_t options)
00155 {
00156 uint32_t compression = data.compression();
00157 if((options & OR_OPTIONS_DONT_DECOMPRESS) ||
00158 compression == IFD::COMPRESS_NONE) {
00159 return OR_ERROR_NONE;
00160 } else if(compression == IFD::COMPRESS_NIKON_QUANTIZED) {
00161 return _decompressNikonQuantized(data);
00162 } else {
00163 return OR_ERROR_INVALID_FORMAT;
00164 }
00165 }
00166
00167 int NEFFile::_getCompressionCurve(RawData & data, NEFFile::NEFCompressionInfo& c)
00168 {
00169 if(!m_exifIfd) {
00170 m_exifIfd = _locateExifIfd();
00171 }
00172 if(!m_exifIfd) {
00173 return 0;
00174 }
00175
00176 IFDEntry::Ref maker_ent =
00177 m_exifIfd->getEntry(IFD::EXIF_TAG_MAKER_NOTE);
00178 if(!maker_ent) {
00179 return 0;
00180 }
00181
00182 uint32_t off = maker_ent->offset();
00183 uint32_t base = off + 10;
00184
00185 IFDDir::Ref ref(new IFDDir(base + 8, *m_container));
00186 ref->load();
00187 IFDEntry::Ref curveEntry = ref->getEntry(0x0096);
00188 if(!curveEntry) {
00189 return 0;
00190 }
00191
00192 size_t pos = base + curveEntry->offset();
00193
00194 IO::Stream *file = m_container->file();
00195 file->seek(pos, SEEK_SET);
00196
00197 int16_t aux;
00198
00199 uint16_t header;
00200 bool read = m_container->readInt16(file, aux);
00201 header = aux;
00202 if(!read) {
00203 return 0;
00204 }
00205
00206 if (header == 0x4410) {
00207 c.huffman = NefDiffIterator::Lossy12Bit;
00208 data.setBpc(12);
00209 } else if (header == 0x4630) {
00210 c.huffman = NefDiffIterator::LossLess14Bit;
00211 data.setBpc(14);
00212 } else {
00213 return 0;
00214 }
00215
00216 for (int i = 0; i < 2; ++i) {
00217 for (int j = 0; j < 2; ++j) {
00218 read = m_container->readInt16(file, aux);
00219 if(!read) {
00220 return 0;
00221 }
00222 c.vpred[i][j] = aux;
00223 }
00224 }
00225
00226 if (header == 0x4410) {
00227 size_t nelems;
00228 read = m_container->readInt16(file, aux);
00229 nelems = aux;
00230
00231 for (size_t i = 0; i < nelems; ++i) {
00232 read = m_container->readInt16(file, aux);
00233 if (!read)
00234 return 0;
00235 c.curve.push_back(aux);
00236 }
00237 } else if (header == 0x4630) {
00238 for (size_t i = 0; i <= 0x3fff; ++i) {
00239 c.curve.push_back(i);
00240 }
00241 }
00242
00243 return 1;
00244 }
00245
00246 ::or_error NEFFile::_getRawData(RawData & data, uint32_t options)
00247 {
00248 ::or_error ret = OR_ERROR_NONE;
00249 m_cfaIfd = _locateCfaIfd();
00250 Trace(DEBUG1) << "_getRawData()\n";
00251
00252 if(m_cfaIfd) {
00253 ret = _getRawDataFromDir(data, m_cfaIfd);
00254 if (ret != OR_ERROR_NONE) {
00255 return ret;
00256 }
00257 ret = _decompressIfNeeded(data, options);
00258 }
00259 else {
00260 ret = OR_ERROR_NOT_FOUND;
00261 }
00262 return ret;
00263 }
00264
00265 }
00266 }
00267