libopenraw
ifdfile.cpp
1 /*
2  * libopenraw - ifdfile.cpp
3  *
4  * Copyright (C) 2006-2008 Hubert Figuiere
5  * Copyright (C) 2008 Novell, Inc.
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <algorithm>
23 #include <numeric>
24 #include <boost/scoped_ptr.hpp>
25 #include <boost/scoped_array.hpp>
26 
27 #include <libopenraw++/thumbnail.h>
28 #include <libopenraw++/rawdata.h>
29 
30 #include "trace.h"
31 #include "io/stream.h"
32 #include "io/streamclone.h"
33 #include "io/file.h"
34 #include "ifd.h"
35 #include "ifdfile.h"
36 #include "ifdfilecontainer.h"
37 #include "jfifcontainer.h"
38 #include "neffile.h" // I wonder if this is smart as it break the abstraction.
39 #include "metavalue.h"
40 #include "unpack.h"
41 
42 using namespace Debug;
43 using boost::scoped_ptr;
44 
45 
46 namespace OpenRaw {
47 namespace Internals {
48 
49 
50 IFDFile::IFDFile(IO::Stream *s, Type _type,
51  bool instantiateContainer)
52  : RawFile(s, _type),
53  m_thumbLocations(),
54  m_io(s),
55  m_container(NULL)
56 {
57  if(instantiateContainer) {
58  m_container = new IFDFileContainer(m_io, 0);
59  }
60 }
61 
62 IFDFile::~IFDFile()
63 {
64  delete m_container;
65  delete m_io;
66 }
67 
68 // this one seems to be pretty much the same for all the
69 // IFD based raw files
70 IFDDir::Ref IFDFile::_locateExifIfd()
71 {
72  m_mainIfd = _locateMainIfd();
73  if (!m_mainIfd) {
74  Trace(ERROR) << "IFDFile::_locateExifIfd() "
75  "main IFD not found\n";
76  return IFDDir::Ref();
77  }
78  return m_mainIfd->getExifIFD();
79 }
80 
81 
82 void IFDFile::_identifyId()
83 {
84  if(!m_mainIfd) {
85  m_mainIfd = _locateMainIfd();
86  }
87  if(!m_mainIfd) {
88  Trace(ERROR) << "Main IFD not found to identify the file.\n";
89  return;
90  }
91  std::string model;
92  if(m_mainIfd->getValue(IFD::EXIF_TAG_MODEL, model)) {
93  _setTypeId(_typeIdFromModel(model));
94  }
95 }
96 
97 
98 
99 ::or_error IFDFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
100 {
101  ::or_error err = OR_ERROR_NONE;
102 
103  Trace(DEBUG1) << "_enumThumbnailSizes()\n";
104  std::vector<IFDDir::Ref> & dirs = m_container->directories();
105  std::vector<IFDDir::Ref>::iterator iter;
106 
107  Trace(DEBUG1) << "num of dirs " << dirs.size() << "\n";
108  for(iter = dirs.begin(); iter != dirs.end(); ++iter)
109  {
110  IFDDir::Ref & dir = *iter;
111  dir->load();
112  or_error ret = _locateThumbnail(dir, list);
113  if (ret == OR_ERROR_NONE)
114  {
115  Trace(DEBUG1) << "Found " << list.back() << " pixels\n";
116  }
117  std::vector<IFDDir::Ref> subdirs;
118  if(dir->getSubIFDs(subdirs)) {
119  Trace(DEBUG1) << "Iterating subdirs\n";
120  std::vector<IFDDir::Ref>::iterator iter2;
121  for(iter2 = subdirs.begin(); iter2 != subdirs.end();
122  ++iter2)
123  {
124  IFDDir::Ref & dir2 = *iter2;
125  dir2->load();
126  ret = _locateThumbnail(dir2, list);
127  if (ret == OR_ERROR_NONE)
128  {
129  Trace(DEBUG1) << "Found " << list.back() << " pixels\n";
130  }
131  }
132  }
133  }
134  if (list.size() <= 0) {
135  err = OR_ERROR_NOT_FOUND;
136  }
137  return err;
138 }
139 
140 
141 ::or_error IFDFile::_locateThumbnail(const IFDDir::Ref & dir,
142  std::vector<uint32_t> &list)
143 {
144  ::or_error ret = OR_ERROR_NOT_FOUND;
145  bool got_it;
146  uint32_t x = 0;
147  uint32_t y = 0;
148  ::or_data_type _type = OR_DATA_TYPE_NONE;
149  uint32_t subtype = 0;
150 
151  Trace(DEBUG1) << "_locateThumbnail\n";
152 
153  got_it = dir->getValue(IFD::EXIF_TAG_NEW_SUBFILE_TYPE, subtype);
154  Trace(DEBUG1) << "subtype " << subtype << "\n";
155  if(!got_it) {
156  if(!m_cfaIfd) {
157  m_cfaIfd = _locateCfaIfd();
158  }
159  if(m_cfaIfd == dir) {
160  return OR_ERROR_NOT_FOUND;
161  }
162  else {
163  subtype = 1;
164  }
165  }
166  if (subtype == 1) {
167 
168  uint16_t photom_int = 0;
169  got_it = dir->getValue(IFD::EXIF_TAG_PHOTOMETRIC_INTERPRETATION,
170  photom_int);
171 
172  if (got_it) {
173  Trace(DEBUG1) << "photometric int " << photom_int << "\n";
174  }
175  // photometric interpretation is RGB by default
176  else {
177  photom_int = 2;
178  Trace(DEBUG1) << "assume photometric int is RGB\n";
179  }
180 
181  got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH, x);
182  got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH, y);
183 
184  uint16_t compression = 0;
185  got_it = dir->getValue(IFD::EXIF_TAG_COMPRESSION, compression);
186 
187  uint32_t offset = 0;
188  got_it = dir->getValue(IFD::EXIF_TAG_STRIP_OFFSETS, offset);
189  if (!got_it || (compression == 6) || (compression == 7)) {
190  if(!got_it) {
191  got_it = dir->getValue(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT,
192  offset);
193  }
194  if (got_it) {
195  // workaround for CR2 files where 8RGB data is marked
196  // as JPEG. Check the real data size.
197  uint32_t byte_count = 0;
198  if(x && y && dir->getValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS, byte_count)) {
199  if(byte_count >= (x * y * 3)) {
200  _type = OR_DATA_TYPE_PIXMAP_8RGB;
201  }
202  else {
203  _type = OR_DATA_TYPE_JPEG;
204  }
205  }
206  else {
207  _type = OR_DATA_TYPE_JPEG;
208  Trace(DEBUG1) << "looking for JPEG at " << offset << "\n";
209  if (x == 0 || y == 0) {
210  scoped_ptr<IO::StreamClone> s(new IO::StreamClone(m_io, offset));
211  scoped_ptr<JFIFContainer> jfif(new JFIFContainer(s.get(), 0));
212  if (jfif->getDimensions(x,y)) {
213  Trace(DEBUG1) << "JPEG dimensions x=" << x
214  << " y=" << y << "\n";
215  }
216  else {
217  _type = OR_DATA_TYPE_NONE;
218  Trace(WARNING) << "Couldn't get JPEG "
219  "dimensions.\n";
220  }
221  }
222  else {
223  Trace(DEBUG1) << "JPEG (supposed) dimensions x=" << x
224  << " y=" << y << "\n";
225  }
226  }
227 
228  }
229  }
230  else if (photom_int == 6) {
231  Trace(WARNING) << "Unsupported YCbCr photometric "
232  "interpretation in non JPEG.\n";
233  ret = OR_ERROR_INVALID_FORMAT;
234  }
235  else {
236  Trace(DEBUG1) << "found strip offsets\n";
237  if (x != 0 && y != 0) {
238  _type = OR_DATA_TYPE_PIXMAP_8RGB;
239  }
240  }
241  if(_type != OR_DATA_TYPE_NONE) {
242  uint32_t dim = std::max(x, y);
243  m_thumbLocations[dim] = IFDThumbDesc(x, y, _type, dir);
244  list.push_back(dim);
245  ret = OR_ERROR_NONE;
246  }
247  }
248 
249  return ret;
250 }
251 
252 
253 ::or_error IFDFile::_getThumbnail(uint32_t size, Thumbnail & thumbnail)
254 {
255  ::or_error ret = OR_ERROR_NOT_FOUND;
256  ThumbLocations::iterator iter = m_thumbLocations.find(size);
257  if(iter != m_thumbLocations.end())
258  {
259  bool got_it;
260 
261  IFDThumbDesc & desc = iter->second;
262  thumbnail.setDataType(desc.type);
263  uint32_t byte_length= 0;
264  uint32_t offset = 0;
265  uint32_t x = desc.x;
266  uint32_t y = desc.y;
267 
268  switch(desc.type)
269  {
270  case OR_DATA_TYPE_JPEG:
271  got_it = desc.ifddir
272  ->getValue(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
273  byte_length);
274  if(got_it) {
275  got_it = desc.ifddir
276  ->getValue(IFD::EXIF_TAG_JPEG_INTERCHANGE_FORMAT,
277  offset);
278  }
279  else {
280  // some case it is STRIP_OFFSETS for JPEG
281  got_it = desc.ifddir
282  ->getValue(IFD::EXIF_TAG_STRIP_OFFSETS, offset);
283  got_it = desc.ifddir
284  ->getValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS, byte_length);
285  }
286  break;
287  case OR_DATA_TYPE_PIXMAP_8RGB:
288  got_it = desc.ifddir
289  ->getValue(IFD::EXIF_TAG_STRIP_OFFSETS, offset);
290  got_it = desc.ifddir
291  ->getValue(IFD::EXIF_TAG_STRIP_BYTE_COUNTS, byte_length);
292 
293  got_it = desc.ifddir
294  ->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH, x);
295  got_it = desc.ifddir
296  ->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH, y);
297  break;
298  default:
299  break;
300  }
301  if (byte_length != 0) {
302  void *p = thumbnail.allocData(byte_length);
303  size_t real_size = m_container->fetchData(p, offset,
304  byte_length);
305  if (real_size < byte_length) {
306  Trace(WARNING) << "Size mismatch for data: ignoring.\n";
307  }
308 
309  thumbnail.setDimensions(x, y);
310  ret = OR_ERROR_NONE;
311  }
312  }
313 
314  return ret;
315 }
316 
317 
318 MetaValue *IFDFile::_getMetaValue(int32_t meta_index)
319 {
320  MetaValue * val = NULL;
321  IFDDir::Ref ifd;
322  if(META_INDEX_MASKOUT(meta_index) == META_NS_TIFF) {
323  if(!m_mainIfd) {
324  m_mainIfd = _locateMainIfd();
325  }
326  ifd = m_mainIfd;
327  }
328  else if(META_INDEX_MASKOUT(meta_index) == META_NS_EXIF) {
329  if(!m_exifIfd) {
330  m_exifIfd = _locateExifIfd();
331  }
332  ifd = m_exifIfd;
333  }
334  else {
335  Trace(ERROR) << "Unknown Meta Namespace\n";
336  }
337  if(ifd) {
338  Trace(DEBUG1) << "Meta value for "
339  << META_NS_MASKOUT(meta_index) << "\n";
340 
341  IFDEntry::Ref e = ifd->getEntry(META_NS_MASKOUT(meta_index));
342  if(e) {
343  val = new MetaValue(e);
344  }
345  }
346  return val;
347 }
348 
349 
350 namespace {
351 
352 RawData::CfaPattern
353 _convertArrayToCfaPattern(const std::vector<uint8_t> &cfaPattern)
354 {
355  RawData::CfaPattern cfa_pattern = OR_CFA_PATTERN_NON_RGB22;
356  if(cfaPattern.size() != 4) {
357  Trace(WARNING) << "Unsupported bayer pattern\n";
358  }
359  else {
360  Trace(DEBUG2) << "patter is = " << cfaPattern[0] << ", "
361  << cfaPattern[1] << ", " << cfaPattern[2]
362  << ", " << cfaPattern[3] << "\n";
363  switch(cfaPattern[0]) {
364  case IFD::CFA_RED:
365  switch(cfaPattern[1]) {
366  case IFD::CFA_GREEN:
367  if((cfaPattern[2] == IFD::CFA_GREEN)
368  && (cfaPattern[3] == IFD::CFA_BLUE))
369  {
370  cfa_pattern = OR_CFA_PATTERN_RGGB;
371  }
372  break;
373  }
374  break;
375  case IFD::CFA_GREEN:
376  switch(cfaPattern[1]) {
377  case IFD::CFA_RED:
378  if((cfaPattern[2] == 2)
379  && (cfaPattern[3] == IFD::CFA_GREEN))
380  {
381  cfa_pattern = OR_CFA_PATTERN_GRBG;
382  }
383  break;
384  case 2:
385  if((cfaPattern[2] == IFD::CFA_RED)
386  && (cfaPattern[3] == IFD::CFA_GREEN))
387  {
388  cfa_pattern = OR_CFA_PATTERN_GBRG;
389  }
390  break;
391  }
392  break;
393  case IFD::CFA_BLUE:
394  switch(cfaPattern[1]) {
395  case IFD::CFA_GREEN:
396  if((cfaPattern[2] == IFD::CFA_GREEN)
397  && (cfaPattern[3] == IFD::CFA_RED))
398  {
399  cfa_pattern = OR_CFA_PATTERN_BGGR;
400  }
401  break;
402  }
403  break;
404  }
405  //
406  }
407  return cfa_pattern;
408 }
409 
410 RawData::CfaPattern _convertNewCfaPattern(const IFDEntry::Ref & e)
411 {
412  RawData::CfaPattern cfa_pattern = OR_CFA_PATTERN_NONE;
413  if(!e || (e->count() < 4)) {
414  return cfa_pattern;
415  }
416 
417  uint16_t hdim = IFDTypeTrait<uint16_t>::get(*e, 0, true);
418  uint16_t vdim = IFDTypeTrait<uint16_t>::get(*e, 1, true);
419  if(hdim != 2 && vdim != 2) {
420  cfa_pattern = OR_CFA_PATTERN_NON_RGB22;
421  }
422  else {
423  std::vector<uint8_t> cfaPattern;
424  cfaPattern.push_back(IFDTypeTrait<uint8_t>::get(*e, 4, true));
425  cfaPattern.push_back(IFDTypeTrait<uint8_t>::get(*e, 5, true));
426  cfaPattern.push_back(IFDTypeTrait<uint8_t>::get(*e, 6, true));
427  cfaPattern.push_back(IFDTypeTrait<uint8_t>::get(*e, 7, true));
428  cfa_pattern = _convertArrayToCfaPattern(cfaPattern);
429  }
430  return cfa_pattern;
431 }
432 
433 
435 RawData::CfaPattern _convertCfaPattern(const IFDEntry::Ref & e)
436 {
437  std::vector<uint8_t> cfaPattern;
438  RawData::CfaPattern cfa_pattern = OR_CFA_PATTERN_NONE;
439 
440  e->getArray(cfaPattern);
441  if(!cfaPattern.empty()) {
442  cfa_pattern = _convertArrayToCfaPattern(cfaPattern);
443  }
444  return cfa_pattern;
445 }
446 
452 static RawData::CfaPattern _getCfaPattern(const IFDDir::Ref & dir)
453 {
454  Trace(DEBUG1) << __FUNCTION__ << "\n";
455  RawData::CfaPattern cfa_pattern = OR_CFA_PATTERN_NONE;
456  try {
457  IFDEntry::Ref e = dir->getEntry(IFD::EXIF_TAG_CFA_PATTERN);
458  if(e) {
459  cfa_pattern = _convertCfaPattern(e);
460  }
461  else {
462  e = dir->getEntry(IFD::EXIF_TAG_NEW_CFA_PATTERN);
463  if(e) {
464  cfa_pattern = _convertNewCfaPattern(e);
465  }
466  }
467  }
468  catch(...)
469  {
470  Trace(ERROR) << "Exception in _getCfaPattern().\n";
471  }
472  return cfa_pattern;
473 }
474 
475 } // end anon namespace
476 
477 ::or_error IFDFile::_getRawDataFromDir(RawData & data, IFDDir::Ref & dir)
478 {
479  ::or_error ret = OR_ERROR_NONE;
480 
481  uint16_t bpc = 0;
482  uint32_t offset = 0;
483  uint32_t byte_length = 0;
484  bool got_it;
485  uint32_t x, y;
486  x = 0;
487  y = 0;
488 
489  if(!dir) {
490  Trace(ERROR) << "dir is NULL\n";
491  return OR_ERROR_NOT_FOUND;
492  }
493  got_it = dir->getValue(IFD::EXIF_TAG_BITS_PER_SAMPLE, bpc);
494  if(!got_it) {
495  Trace(ERROR) << "unable to guess Bits per sample\n";
496  }
497 
498  got_it = dir->getValue(IFD::EXIF_TAG_STRIP_OFFSETS, offset);
499  if(got_it) {
500  IFDEntry::Ref e = dir->getEntry(IFD::EXIF_TAG_STRIP_BYTE_COUNTS);
501  if(e) {
502  std::vector<uint32_t> counts;
503  e->getArray(counts);
504  Trace(DEBUG1) << "counting tiles\n";
505  byte_length = std::accumulate(counts.begin(), counts.end(), 0);
506  }
507  else {
508  Trace(DEBUG1) << "byte len not found\n";
509  return OR_ERROR_NOT_FOUND;
510  }
511  }
512  else {
513  // the tile are individual JPEGS....
514  // TODO extract all of them.
515  IFDEntry::Ref e = dir->getEntry(IFD::TIFF_TAG_TILE_OFFSETS);
516  if(e) {
517  std::vector<uint32_t> offsets;
518  e->getArray(offsets);
519  if(offsets.size() > 1) {
520  offset = offsets[0];
521  }
522  else {
523  Trace(DEBUG1) << "tile offsets empty\n";
524  return OR_ERROR_NOT_FOUND;
525  }
526  }
527  else {
528  Trace(DEBUG1) << "tile offsets not found\n";
529  return OR_ERROR_NOT_FOUND;
530  }
531  e = dir->getEntry(IFD::TIFF_TAG_TILE_BYTECOUNTS);
532  if(e) {
533  std::vector<uint32_t> counts;
534  e->getArray(counts);
535  Trace(DEBUG1) << "counting tiles\n";
536  byte_length = std::accumulate(counts.begin(), counts.end(), 0);
537  }
538  else {
539  Trace(DEBUG1) << "tile byte counts not found\n";
540  return OR_ERROR_NOT_FOUND;
541  }
542  }
543  got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_WIDTH, x);
544  if(!got_it) {
545  Trace(DEBUG1) << "X not found\n";
546  return OR_ERROR_NOT_FOUND;
547  }
548  got_it = dir->getIntegerValue(IFD::EXIF_TAG_IMAGE_LENGTH, y);
549  if(!got_it) {
550  Trace(DEBUG1) << "Y not found\n";
551  return OR_ERROR_NOT_FOUND;
552  }
553 
554  uint32_t compression = 0;
555  got_it = dir->getIntegerValue(IFD::EXIF_TAG_COMPRESSION, compression);
556  if(!got_it)
557  {
558  Trace(DEBUG1) << "Compression type not found\n";
559  }
560  BitmapData::DataType data_type = OR_DATA_TYPE_NONE;
561 
562  switch(compression)
563  {
564  case IFD::COMPRESS_NONE:
565  data_type = OR_DATA_TYPE_CFA;
566  break;
567  case IFD::COMPRESS_NIKON_PACK:
568  data_type = OR_DATA_TYPE_CFA;
569  break;
570  case IFD::COMPRESS_NIKON_QUANTIZED:
571  // must check whether it is really compressed
572  // only for D100
573  if( !NEFFile::isCompressed(*m_container, offset) ) {
574  compression = IFD::COMPRESS_NIKON_PACK;
575  data_type = OR_DATA_TYPE_CFA;
576  // this is a hack. we should check if
577  // we have a D100 instead, but that case is already
578  // a D100 corner case. WILL BREAK on compressed files.
579  // according to dcraw we must increase the size by 6.
580  x += 6;
581  break;
582  }
583  default:
584  data_type = OR_DATA_TYPE_COMPRESSED_CFA;
585  break;
586  }
587 
588  Trace(DEBUG1) << "RAW Compression is " << compression << "\n";
589 
590  RawData::CfaPattern cfa_pattern = _getCfaPattern(dir);
591  if(cfa_pattern == OR_CFA_PATTERN_NONE) {
592  // some file have it in the exif IFD instead.
593  if(!m_exifIfd) {
594  m_exifIfd = _locateExifIfd();
595  }
596  cfa_pattern = _getCfaPattern(m_exifIfd);
597  }
598 
599 
600  if((bpc == 12 || bpc == 14) && (compression == 1)
601  && (byte_length == (x * y * 2)))
602  {
603  Trace(DEBUG1) << "setting bpc from " << bpc
604  << " to 16\n";
605  bpc = 16;
606  }
607  if((bpc == 16) || (data_type == OR_DATA_TYPE_COMPRESSED_CFA)) {
608  void *p = data.allocData(byte_length);
609  size_t real_size = m_container->fetchData(p, offset,
610  byte_length);
611  if (real_size < byte_length) {
612  Trace(WARNING) << "Size mismatch for data: ignoring.\n";
613  }
614  }
615  else if((bpc == 12) || (bpc == 8)) {
616  size_t fetched = 0;
617  Unpack unpack(x, compression);
618  const size_t blocksize = (bpc == 8 ? x : unpack.block_size());
619  Trace(DEBUG1) << "Block size = " << blocksize << "\n";
620  Trace(DEBUG1) << "dimensions (x, y) " << x << ", "
621  << y << "\n";
622  boost::scoped_array<uint8_t> block(new uint8_t[blocksize]);
623  uint8_t * outdata = (uint8_t*)data.allocData(x * y * 2);
624  size_t got;
625  Trace(DEBUG1) << "offset of RAW data = " << offset << "\n";
626  do {
627  got = m_container->fetchData (block.get(),
628  offset, blocksize);
629  fetched += got;
630  offset += got;
631  if(got) {
632  if(bpc == 12) {
633  size_t out = unpack.unpack_be12to16(outdata,
634  block.get(),
635  got);
636  outdata += out;
637  }
638  else {
639  // outdata point to uint16_t
640  std::copy(block.get(), block.get()+got,
641  (uint16_t*)outdata);
642  outdata += (got << 1);
643  }
644  }
645  } while((got != 0) && (fetched < byte_length));
646  }
647  else {
648  Trace(ERROR) << "Unsupported bpc " << bpc << "\n";
649  return OR_ERROR_INVALID_FORMAT;
650  }
651  data.setCfaPattern(cfa_pattern);
652  data.setDataType(data_type);
653  data.setCompression(data_type == OR_DATA_TYPE_COMPRESSED_CFA
654  ? compression : 1);
655  if((data_type == OR_DATA_TYPE_CFA) && (data.max() == 0)) {
656  data.setMax((1 << bpc) - 1);
657  }
658  data.setDimensions(x, y);
659 
660  return ret;
661 }
662 
663 }
664 }
665 
666 /*
667  Local Variables:
668  mode:c++
669  c-file-style:"stroustrup"
670  c-file-offsets:((innamespace . 0))
671  indent-tabs-mode:nil
672  fill-column:80
673  End:
674 */
static T get(IFDEntry &e, uint32_t idx=0, bool ignore_type=false)
Definition: ifdentry.h:211
IFDFileContainer * m_container
Definition: ifdfile.h:95
virtual ::or_error _locateThumbnail(const IFDDir::Ref &dir, std::vector< uint32_t > &list)
Definition: ifdfile.cpp:141
size_t fetchData(void *buf, const off_t offset, const size_t buf_size)
virtual void setDimensions(uint32_t x, uint32_t y)
Definition: rawdata.cpp:132
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list)
Definition: ifdfile.cpp:99
void _setTypeId(TypeId _type_id)
Definition: rawfile.cpp:304
cloned stream. Allow reading from a different offset
Definition: streamclone.h:35
virtual void setDimensions(uint32_t x, uint32_t y)
Definition: bitmapdata.cpp:148
std::vector< IFDDir::Ref > & directories()
void setDataType(DataType _type)
Definition: bitmapdata.cpp:92
size_t unpack_be12to16(uint8_t *dest, const uint8_t *src, size_t size)
Definition: unpack.cpp:56
boost::shared_ptr< IFDEntry > Ref
Definition: ifdentry.h:122
static bool isCompressed(RawContainer &container, uint32_t offset)
Definition: neffile.cpp:97
::or_error _getRawDataFromDir(RawData &data, IFDDir::Ref &dir)
Definition: ifdfile.cpp:477