libopenraw
neffile.cpp
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