libopenraw
|
00001 /* -*- tab-width:4; c-basic-offset:4 -*- */ 00002 00003 /* 00004 * libopenraw - neffile.cpp 00005 * 00006 * Copyright (C) 2006-2008 Hubert Figuiere 00007 * Copyright (C) 2008 Novell, Inc. 00008 * 00009 * This library is free software: you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public License 00011 * as published by the Free Software Foundation, either version 3 of 00012 * the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library. If not, see 00021 * <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 00025 #include <iostream> 00026 #include <vector> 00027 #include <libopenraw++/thumbnail.h> 00028 #include <libopenraw++/rawdata.h> 00029 00030 #include "trace.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 D3000", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00065 OR_TYPEID_NIKON_D3000) }, 00066 { "NIKON D40", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00067 OR_TYPEID_NIKON_D40) }, 00068 { "NIKON D40X", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00069 OR_TYPEID_NIKON_D40X) }, 00070 { "NIKON D50", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00071 OR_TYPEID_NIKON_D50) }, 00072 { "NIKON D70", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00073 OR_TYPEID_NIKON_D70) }, 00074 { "NIKON D70s", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00075 OR_TYPEID_NIKON_D70S) }, 00076 { "NIKON D80", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 00077 OR_TYPEID_NIKON_D80) }, 00078 { 0, 0 } 00079 }; 00080 00081 RawFile *NEFFile::factory(IO::Stream* _filename) 00082 { 00083 return new NEFFile(_filename); 00084 } 00085 00086 NEFFile::NEFFile(IO::Stream* _filename) 00087 : TiffEpFile(_filename, OR_RAWFILE_TYPE_NEF) 00088 { 00089 _setIdMap(s_def); 00090 } 00091 00092 00093 NEFFile::~NEFFile() 00094 { 00095 } 00096 00097 bool NEFFile::isCompressed(RawContainer & container, uint32_t offset) 00098 { 00099 int i; 00100 uint8_t buf[256]; 00101 size_t real_size = container.fetchData(buf, offset, 00102 256); 00103 if(real_size != 256) { 00104 return true; 00105 } 00106 for(i = 15; i < 256; i+= 16) { 00107 if(buf[i]) { 00108 Trace(DEBUG1) << "isCompressed: true\n"; 00109 return true; 00110 } 00111 } 00112 Trace(DEBUG1) << "isCompressed: false\n"; 00113 return false; 00114 } 00115 00116 ::or_error NEFFile::_decompressNikonQuantized(RawData & data) 00117 { 00118 NEFCompressionInfo c; 00119 if (!_getCompressionCurve(data, c)) { 00120 return OR_ERROR_NOT_FOUND; 00121 } 00122 const uint32_t rows = data.y(); 00123 const uint32_t raw_columns = data.x(); 00124 00125 //FIXME: not always true 00126 const uint32_t columns = raw_columns - 1; 00127 00128 NefDiffIterator 00129 diffs(c.huffman, data.data()); 00130 NefCfaIterator iter(diffs, rows, raw_columns, c.vpred); 00131 00132 RawData newData; 00133 uint16_t *p = (uint16_t *) newData.allocData(rows * columns * 2); 00134 newData.setDimensions(columns, rows); 00135 newData.setDataType(OR_DATA_TYPE_CFA); 00136 uint16_t bpc = data.bpc(); 00137 newData.setBpc(bpc); 00138 newData.setMax((1 << bpc) - 1); 00139 newData.setCfaPattern(data.cfaPattern()); 00140 00141 for (unsigned int i = 0; i < rows; i++) { 00142 for (unsigned int j = 0; j < raw_columns; j++) { 00143 uint16_t t = iter.get(); 00144 if (j < columns) { 00145 unsigned shift = 16 - data.bpc(); 00146 p[i * columns + j] = c.curve[t & 0x3fff] << shift; 00147 } 00148 } 00149 } 00150 00151 data.swap(newData); 00152 return OR_ERROR_NONE; 00153 } 00154 00155 ::or_error NEFFile::_decompressIfNeeded(RawData & data, 00156 uint32_t options) 00157 { 00158 uint32_t compression = data.compression(); 00159 if((options & OR_OPTIONS_DONT_DECOMPRESS) || 00160 compression == IFD::COMPRESS_NONE) { 00161 return OR_ERROR_NONE; 00162 } else if(compression == IFD::COMPRESS_NIKON_QUANTIZED) { 00163 return _decompressNikonQuantized(data); 00164 } else { 00165 return OR_ERROR_INVALID_FORMAT; 00166 } 00167 } 00168 00169 int NEFFile::_getCompressionCurve(RawData & data, NEFFile::NEFCompressionInfo& c) 00170 { 00171 if(!m_exifIfd) { 00172 m_exifIfd = _locateExifIfd(); 00173 } 00174 if(!m_exifIfd) { 00175 return 0; 00176 } 00177 00178 IFDEntry::Ref maker_ent = 00179 m_exifIfd->getEntry(IFD::EXIF_TAG_MAKER_NOTE); 00180 if(!maker_ent) { 00181 return 0; 00182 } 00183 00184 uint32_t off = maker_ent->offset(); 00185 uint32_t base = off + 10; 00186 00187 IFDDir::Ref ref(new IFDDir(base + 8, *m_container)); 00188 ref->load(); 00189 IFDEntry::Ref curveEntry = ref->getEntry(0x0096); 00190 if(!curveEntry) { 00191 return 0; 00192 } 00193 00194 size_t pos = base + curveEntry->offset(); 00195 00196 IO::Stream *file = m_container->file(); 00197 file->seek(pos, SEEK_SET); 00198 00199 int16_t aux; 00200 00201 uint16_t header; 00202 bool read = m_container->readInt16(file, aux); 00203 header = aux; 00204 if(!read) { 00205 return 0; 00206 } 00207 00208 if (header == 0x4410) { 00209 c.huffman = NefDiffIterator::Lossy12Bit; 00210 data.setBpc(12); 00211 } else if (header == 0x4630) { 00212 c.huffman = NefDiffIterator::LossLess14Bit; 00213 data.setBpc(14); 00214 } else { 00215 return 0; 00216 } 00217 00218 for (int i = 0; i < 2; ++i) { 00219 for (int j = 0; j < 2; ++j) { 00220 read = m_container->readInt16(file, aux); 00221 if(!read) { 00222 return 0; 00223 } 00224 c.vpred[i][j] = aux; 00225 } 00226 } 00227 00228 if (header == 0x4410) { 00229 size_t nelems; 00230 read = m_container->readInt16(file, aux); 00231 nelems = aux; 00232 00233 for (size_t i = 0; i < nelems; ++i) { 00234 read = m_container->readInt16(file, aux); 00235 if (!read) 00236 return 0; 00237 c.curve.push_back(aux); 00238 } 00239 } else if (header == 0x4630) { 00240 for (size_t i = 0; i <= 0x3fff; ++i) { 00241 c.curve.push_back(i); 00242 } 00243 } 00244 00245 return 1; 00246 } 00247 00248 ::or_error NEFFile::_getRawData(RawData & data, uint32_t options) 00249 { 00250 ::or_error ret = OR_ERROR_NONE; 00251 m_cfaIfd = _locateCfaIfd(); 00252 Trace(DEBUG1) << "_getRawData()\n"; 00253 00254 if(m_cfaIfd) { 00255 ret = _getRawDataFromDir(data, m_cfaIfd); 00256 if (ret != OR_ERROR_NONE) { 00257 return ret; 00258 } 00259 ret = _decompressIfNeeded(data, options); 00260 } 00261 else { 00262 ret = OR_ERROR_NOT_FOUND; 00263 } 00264 return ret; 00265 } 00266 00267 } 00268 } 00269