22 #include <boost/scoped_ptr.hpp>
23 #include <boost/any.hpp>
24 #include <libopenraw/libopenraw.h>
25 #include <libopenraw++/thumbnail.h>
26 #include <libopenraw++/rawdata.h>
30 #include "io/memstream.h"
31 #include "ifdfilecontainer.h"
34 #include "jfifcontainer.h"
35 #include "ljpegdecompressor.h"
36 #include "rawfilefactory.h"
38 using namespace Debug;
43 const IFDFile::camera_ids_t Cr2File::s_def[] = {
44 {
"Canon EOS-1D Mark II", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
45 OR_TYPEID_CANON_1DMKII) },
46 {
"Canon EOS-1D Mark III", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
47 OR_TYPEID_CANON_1DMKIII) },
48 {
"Canon EOS-1D Mark IV", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
49 OR_TYPEID_CANON_1DMKIV) },
50 {
"Canon EOS-1Ds Mark II", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
51 OR_TYPEID_CANON_1DSMKII) },
52 {
"Canon EOS-1Ds Mark III", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
53 OR_TYPEID_CANON_1DSMKIII) },
54 {
"Canon EOS 20D" , OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
55 OR_TYPEID_CANON_20D) },
56 {
"Canon EOS 20Da", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
57 OR_TYPEID_CANON_20DA) },
58 {
"Canon EOS 30D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
59 OR_TYPEID_CANON_30D) },
60 {
"Canon EOS 350D DIGITAL", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
61 OR_TYPEID_CANON_350D) },
62 {
"Canon EOS DIGITAL REBEL XT", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
63 OR_TYPEID_CANON_350D) },
64 {
"Canon EOS 40D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
65 OR_TYPEID_CANON_40D) },
66 {
"Canon EOS 400D DIGITAL", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
67 OR_TYPEID_CANON_400D) },
68 {
"Canon EOS 450D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
69 OR_TYPEID_CANON_450D) },
70 {
"Canon EOS 50D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
71 OR_TYPEID_CANON_50D) },
72 {
"Canon EOS 500D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
73 OR_TYPEID_CANON_500D) },
74 {
"Canon EOS 550D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
75 OR_TYPEID_CANON_550D) },
76 {
"Canon EOS 60D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
77 OR_TYPEID_CANON_60D) },
78 {
"Canon EOS 1000D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
79 OR_TYPEID_CANON_1000D) },
80 {
"Canon EOS 5D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
81 OR_TYPEID_CANON_5D) },
82 {
"Canon EOS 5D Mark II", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
83 OR_TYPEID_CANON_5DMKII) },
84 {
"Canon EOS 7D", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
85 OR_TYPEID_CANON_7D) },
86 {
"Canon PowerShot G9", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
87 OR_TYPEID_CANON_G9) },
88 {
"Canon PowerShot G10", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
89 OR_TYPEID_CANON_G11) },
90 {
"Canon PowerShot G11", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,
91 OR_TYPEID_CANON_G11) },
95 RawFile *Cr2File::factory(IO::Stream * s)
97 return new Cr2File(s);
100 Cr2File::Cr2File(IO::Stream * s)
101 : IFDFile(s, OR_RAWFILE_TYPE_CR2)
111 IFDDir::Ref Cr2File::_locateCfaIfd()
117 IFDDir::Ref Cr2File::_locateMainIfd()
122 ::or_error Cr2File::_getRawData(RawData & data, uint32_t options)
124 ::or_error ret = OR_ERROR_NONE;
129 Trace(DEBUG1) <<
"cfa IFD not found\n";
130 return OR_ERROR_NOT_FOUND;
133 Trace(DEBUG1) <<
"_getRawData()\n";
135 uint32_t byte_length = 0;
137 got_it =
m_cfaIfd->getValue(IFD::EXIF_TAG_STRIP_OFFSETS, offset);
139 Trace(DEBUG1) <<
"offset not found\n";
140 return OR_ERROR_NOT_FOUND;
142 got_it =
m_cfaIfd->getValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS, byte_length);
144 Trace(DEBUG1) <<
"byte len not found\n";
145 return OR_ERROR_NOT_FOUND;
148 std::vector<uint16_t> slices;
152 Trace(DEBUG1) <<
"Found slice entry " << slices <<
"\n";
162 got_it =
m_exifIfd->getValue(IFD::EXIF_TAG_PIXEL_X_DIMENSION, x);
164 Trace(DEBUG1) <<
"X not found\n";
165 return OR_ERROR_NOT_FOUND;
167 got_it =
m_exifIfd->getValue(IFD::EXIF_TAG_PIXEL_Y_DIMENSION, y);
169 Trace(DEBUG1) <<
"Y not found\n";
170 return OR_ERROR_NOT_FOUND;
173 void *p = data.allocData(byte_length);
176 if (real_size < byte_length) {
177 Trace(WARNING) <<
"Size mismatch for data: ignoring.\n";
179 data.setCfaPattern(OR_CFA_PATTERN_RGGB);
180 data.setDataType(OR_DATA_TYPE_COMPRESSED_CFA);
181 data.setDimensions(x, y);
182 Trace(DEBUG1) <<
"In size is " << data.x()
183 <<
"x" << data.y() <<
"\n";
185 if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
186 boost::scoped_ptr<IO::Stream> s(
new IO::MemStream(data.data(),
189 boost::scoped_ptr<JFIFContainer> jfif(
new JFIFContainer(s.get(), 0));
190 LJpegDecompressor decomp(s.get(), jfif.get());
193 if(slices.size() > 1) {
194 decomp.setSlices(slices);
196 RawData *dData = decomp.decompress();
198 Trace(DEBUG1) <<
"Out size is " << dData->x()
199 <<
"x" << dData->y() <<
"\n";
201 dData->setCfaPattern(data.cfaPattern());
208 Trace(ERROR) <<
"unable to find ExifIFD\n";
209 ret = OR_ERROR_NOT_FOUND;