@@ -145,7 +145,7 @@ void DngDecoder::dropUnsuportedChunks(std::vector<const TiffIFD*>* data) {
145145 }
146146}
147147
148- void DngDecoder::parseCFA (const TiffIFD* raw) const {
148+ void DngDecoder::parseCFA (const TiffIFD* raw, RawImage:: frame_ptr_t frame) {
149149
150150 // Check if layout is OK, if present
151151 if (raw->hasEntry (TiffTag::CFALAYOUT) &&
@@ -166,7 +166,7 @@ void DngDecoder::parseCFA(const TiffIFD* raw) const {
166166 cPat->count );
167167 }
168168
169- mRaw . get ( 0 ) ->cfa .setSize (cfaSize);
169+ frame ->cfa .setSize (cfaSize);
170170
171171 static const map<uint32_t , CFAColor> int2enum = {
172172 {0 , CFAColor::RED}, {1 , CFAColor::GREEN}, {2 , CFAColor::BLUE},
@@ -185,7 +185,7 @@ void DngDecoder::parseCFA(const TiffIFD* raw) const {
185185 ThrowRDE (" Unsupported CFA Color: %u" , c1);
186186 }
187187
188- mRaw . get ( 0 ) ->cfa .setColorAt (iPoint2D (x, y), c2);
188+ frame ->cfa .setColorAt (iPoint2D (x, y), c2);
189189 }
190190 }
191191
@@ -206,8 +206,8 @@ void DngDecoder::parseCFA(const TiffIFD* raw) const {
206206 }))
207207 ThrowRDE (" Error decoding active area" );
208208
209- mRaw . get ( 0 ) ->cfa .shiftLeft (aa[1 ]);
210- mRaw . get ( 0 ) ->cfa .shiftDown (aa[0 ]);
209+ frame ->cfa .shiftLeft (aa[1 ]);
210+ frame ->cfa .shiftDown (aa[0 ]);
211211}
212212
213213DngTilingDescription
@@ -269,7 +269,9 @@ DngDecoder::getTilingDescription(const TiffIFD* raw) const {
269269 return {mRaw .get (0 )->dim , static_cast <uint32_t >(mRaw .get (0 )->dim .x ), yPerSlice};
270270}
271271
272- void DngDecoder::decodeData (const TiffIFD* raw, uint32_t sample_format) const {
272+ void DngDecoder::decodeData (const TiffIFD* raw, uint32_t sample_format,
273+ int compression, int bps,
274+ RawImage::frame_ptr_t frame) {
273275 if (compression == 8 && sample_format != 3 ) {
274276 ThrowRDE (" Only float format is supported for "
275277 " deflate-compressed data." );
@@ -287,11 +289,11 @@ void DngDecoder::decodeData(const TiffIFD* raw, uint32_t sample_format) const {
287289 if (raw->hasEntry (TiffTag::WHITELEVEL)) {
288290 const TiffEntry* whitelevel = raw->getEntry (TiffTag::WHITELEVEL);
289291 if (whitelevel->isInt ())
290- mRaw . get ( 0 ) ->whitePoint = whitelevel->getU32 ();
292+ frame ->whitePoint = whitelevel->getU32 ();
291293 }
292294
293- AbstractDngDecompressor slices (mRaw .get (0 ). get () , getTilingDescription (raw), compression ,
294- mFixLjpeg , bps, predictor);
295+ AbstractDngDecompressor slices (frame .get () , getTilingDescription (raw),
296+ compression, mFixLjpeg , bps, predictor);
295297
296298 slices.slices .reserve (slices.dsc .numTiles );
297299
@@ -330,7 +332,7 @@ void DngDecoder::decodeData(const TiffIFD* raw, uint32_t sample_format) const {
330332
331333 // FIXME: should we sort the tiles, to linearize the input reading?
332334
333- mRaw . get ( 0 ) ->createData ();
335+ frame ->createData ();
334336
335337 slices.decompress ();
336338}
@@ -346,90 +348,88 @@ void DngDecoder::decodeRawInternal() {
346348 if (data.empty ())
347349 ThrowRDE (" No RAW chunks found" );
348350
349- if (data.size () > 1 ) {
350- writeLog (DEBUG_PRIO::EXTRA,
351- " Multiple RAW chunks found - using first only!" );
352- }
351+ // / TODO paralelize?
352+ for (const auto * raw : data) {
353+ int bps = raw->getEntry (TiffTag::BITSPERSAMPLE)->getU32 ();
354+ if (bps < 1 || bps > 32 )
355+ ThrowRDE (" Unsupported bit per sample count: %u." , bps);
353356
354- const TiffIFD* raw = data[0 ];
355-
356- bps = raw->getEntry (TiffTag::BITSPERSAMPLE)->getU32 ();
357- if (bps < 1 || bps > 32 )
358- ThrowRDE (" Unsupported bit per sample count: %u." , bps);
359-
360- uint32_t sample_format = 1 ;
361- if (raw->hasEntry (TiffTag::SAMPLEFORMAT))
362- sample_format = raw->getEntry (TiffTag::SAMPLEFORMAT)->getU32 ();
363-
364- compression = raw->getEntry (TiffTag::COMPRESSION)->getU16 ();
365-
366- mRaw .clear ();
367- switch (sample_format) {
368- case 1 :
369- mRaw .appendFrame (new RawImageDataU16 ());
370- break ;
371- case 3 :
372- mRaw .appendFrame (new RawImageDataFloat ());
373- break ;
374- default :
375- ThrowRDE (" Only 16 bit unsigned or float point data supported. Sample "
376- " format %u is not supported." ,
377- sample_format);
378- }
357+ uint32_t sample_format = 1 ;
358+ if (raw->hasEntry (TiffTag::SAMPLEFORMAT))
359+ sample_format = raw->getEntry (TiffTag::SAMPLEFORMAT)->getU32 ();
379360
380- mRaw .get (0 )->isCFA =
381- (raw->getEntry (TiffTag::PHOTOMETRICINTERPRETATION)->getU16 () == 32803 );
361+ int compression = raw->getEntry (TiffTag::COMPRESSION)->getU16 ();
382362
383- if (mRaw .get (0 )->isCFA )
384- writeLog (DEBUG_PRIO::EXTRA, " This is a CFA image" );
385- else {
386- writeLog (DEBUG_PRIO::EXTRA, " This is NOT a CFA image" );
387- }
363+ mRaw .clear ();
364+ switch (sample_format) {
365+ case 1 :
366+ mRaw .appendFrame (new RawImageDataU16 ());
367+ break ;
368+ case 3 :
369+ mRaw .appendFrame (new RawImageDataFloat ());
370+ break ;
371+ default :
372+ ThrowRDE (" Only 16 bit unsigned or float point data supported. Sample "
373+ " format %u is not supported." ,
374+ sample_format);
375+ }
388376
389- if (sample_format == 1 && bps > 16 )
390- ThrowRDE ( " Integer precision larger than 16 bits currently not supported. " );
377+ mRaw . get ( 0 )-> isCFA =
378+ (raw-> getEntry (TiffTag::PHOTOMETRICINTERPRETATION)-> getU16 () == 32803 );
391379
392- if (sample_format == 3 && bps != 16 && bps != 24 && bps != 32 )
393- ThrowRDE (" Floating point must be 16/24/32 bits per sample." );
380+ if (mRaw .get (0 )->isCFA )
381+ writeLog (DEBUG_PRIO::EXTRA, " This is a CFA image" );
382+ else {
383+ writeLog (DEBUG_PRIO::EXTRA, " This is NOT a CFA image" );
384+ }
385+
386+ if (sample_format == 1 && bps > 16 )
387+ ThrowRDE (
388+ " Integer precision larger than 16 bits currently not supported." );
389+
390+ if (sample_format == 3 && bps != 16 && bps != 24 && bps != 32 )
391+ ThrowRDE (" Floating point must be 16/24/32 bits per sample." );
394392
395- mRaw .get (0 )->dim .x = raw->getEntry (TiffTag::IMAGEWIDTH)->getU32 ();
396- mRaw .get (0 )->dim .y = raw->getEntry (TiffTag::IMAGELENGTH)->getU32 ();
393+ mRaw .get (0 )->dim .x = raw->getEntry (TiffTag::IMAGEWIDTH)->getU32 ();
394+ mRaw .get (0 )->dim .y = raw->getEntry (TiffTag::IMAGELENGTH)->getU32 ();
397395
398- if (!mRaw .get (0 )->dim .hasPositiveArea ())
399- ThrowRDE (" Image has zero size" );
396+ if (!mRaw .get (0 )->dim .hasPositiveArea ())
397+ ThrowRDE (" Image has zero size" );
400398
401399#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
402- // Yeah, sure, here it would be just dumb to leave this for production :)
403- if (mRaw .get (0 )->dim .x > 7424 || mRaw .get (0 )->dim .y > 5552 ) {
404- ThrowRDE (" Unexpected image dimensions found: (%u; %u)" , mRaw . get ( 0 )-> dim . x ,
405- mRaw .get (0 )->dim .y );
406- }
400+ // Yeah, sure, here it would be just dumb to leave this for production :)
401+ if (mRaw .get (0 )->dim .x > 7424 || mRaw .get (0 )->dim .y > 5552 ) {
402+ ThrowRDE (" Unexpected image dimensions found: (%u; %u)" ,
403+ mRaw . get ( 0 )-> dim . x , mRaw .get (0 )->dim .y );
404+ }
407405#endif
408406
409- if (mRaw .get (0 )->isCFA )
410- parseCFA (raw);
407+ if (mRaw .get (0 )->isCFA )
408+ parseCFA (raw, mRaw . get ( 0 ) );
411409
412- uint32_t cpp = raw->getEntry (TiffTag::SAMPLESPERPIXEL)->getU32 ();
410+ uint32_t cpp = raw->getEntry (TiffTag::SAMPLESPERPIXEL)->getU32 ();
413411
414- if (cpp < 1 || cpp > 4 )
415- ThrowRDE (" Unsupported samples per pixel count: %u." , cpp);
412+ if (cpp < 1 || cpp > 4 )
413+ ThrowRDE (" Unsupported samples per pixel count: %u." , cpp);
416414
417- mRaw .get (0 )->setCpp (cpp);
415+ mRaw .get (0 )->setCpp (cpp);
418416
419- // Now load the image
420- decodeData (raw, sample_format);
417+ // Now load the image
418+ decodeData (raw, sample_format, compression, bps, mRaw . get ( 0 ) );
421419
422- handleMetadata (raw);
420+ handleMetadata (raw, compression, bps, mRaw .get (0 ));
421+ }
423422}
424423
425- void DngDecoder::handleMetadata (const TiffIFD* raw) {
424+ void DngDecoder::handleMetadata (const TiffIFD* raw, int compression, int bps,
425+ RawImage::frame_ptr_t frame) {
426426 // Crop
427427 if (raw->hasEntry (TiffTag::ACTIVEAREA)) {
428428 const TiffEntry* active_area = raw->getEntry (TiffTag::ACTIVEAREA);
429429 if (active_area->count != 4 )
430430 ThrowRDE (" active area has %d values instead of 4" , active_area->count );
431431
432- const iRectangle2D fullImage (0 , 0 , mRaw . get ( 0 ) ->dim .x , mRaw . get ( 0 ) ->dim .y );
432+ const iRectangle2D fullImage (0 , 0 , frame ->dim .x , frame ->dim .y );
433433
434434 const auto corners = active_area->getU32Array (4 );
435435 const iPoint2D topLeft (corners[1 ], corners[0 ]);
@@ -449,12 +449,12 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
449449 crop.setBottomRightAbsolute (bottomRight);
450450 assert (fullImage.isThisInside (fullImage));
451451
452- mRaw . get ( 0 ) ->subFrame (crop);
452+ frame ->subFrame (crop);
453453 }
454454
455455 if (raw->hasEntry (TiffTag::DEFAULTCROPORIGIN) &&
456456 raw->hasEntry (TiffTag::DEFAULTCROPSIZE)) {
457- iRectangle2D cropped (0 , 0 , mRaw . get ( 0 ) ->dim .x , mRaw . get ( 0 ) ->dim .y );
457+ iRectangle2D cropped (0 , 0 , frame ->dim .x , frame ->dim .y );
458458 const TiffEntry* origin_entry = raw->getEntry (TiffTag::DEFAULTCROPORIGIN);
459459 const TiffEntry* size_entry = raw->getEntry (TiffTag::DEFAULTCROPSIZE);
460460
@@ -470,7 +470,7 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
470470 cropped.isPointInsideInclusive (cropOrigin))
471471 cropped = iRectangle2D (cropOrigin, {0 , 0 });
472472
473- cropped.dim = mRaw . get ( 0 ) ->dim - cropped.pos ;
473+ cropped.dim = frame ->dim - cropped.pos ;
474474
475475 /* Read size (sometimes is rational so use float) */
476476 const auto sz = size_entry->getFloatArray (2 );
@@ -481,16 +481,16 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
481481 ThrowRDE (" Error decoding default crop size" );
482482
483483 if (iPoint2D size (sz[0 ], sz[1 ]);
484- size.isThisInside (mRaw . get ( 0 ) ->dim ) &&
485- (size + cropped.pos ).isThisInside (mRaw . get ( 0 ) ->dim ))
484+ size.isThisInside (frame ->dim ) &&
485+ (size + cropped.pos ).isThisInside (frame ->dim ))
486486 cropped.dim = size;
487487
488488 if (!cropped.hasPositiveArea ())
489489 ThrowRDE (" No positive crop area" );
490490
491- mRaw . get ( 0 ) ->subFrame (cropped);
491+ frame ->subFrame (cropped);
492492 }
493- if (mRaw . get ( 0 ) ->dim .area () <= 0 )
493+ if (frame ->dim .area () <= 0 )
494494 ThrowRDE (" No image left after crop" );
495495
496496 // Apply stage 1 opcodes
@@ -499,13 +499,13 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
499499 const TiffEntry* opcodes = raw->getEntry (TiffTag::OPCODELIST1);
500500 // The entry might exist, but it might be empty, which means no opcodes
501501 if (opcodes->count > 0 ) {
502- DngOpcodes codes (mRaw . get ( 0 ) .get (), opcodes);
503- codes.applyOpCodes (mRaw . get ( 0 ) .get ());
502+ DngOpcodes codes (frame .get (), opcodes);
503+ codes.applyOpCodes (frame .get ());
504504 }
505505 } catch (const RawDecoderException& e) {
506506 // We push back errors from the opcode parser, since the image may still
507507 // be usable
508- mRaw . get ( 0 ) ->setError (e.what ());
508+ frame ->setError (e.what ());
509509 }
510510 }
511511
@@ -514,23 +514,23 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
514514 raw->getEntry (TiffTag::LINEARIZATIONTABLE)->count > 0 ) {
515515 const TiffEntry* lintable = raw->getEntry (TiffTag::LINEARIZATIONTABLE);
516516 auto table = lintable->getU16Array (lintable->count );
517- RawImageCurveGuard curveHandler (mRaw . get ( 0 ) .get (), table, uncorrectedRawValues);
517+ RawImageCurveGuard curveHandler (frame .get (), table, uncorrectedRawValues);
518518 if (!uncorrectedRawValues)
519- mRaw . get ( 0 ) ->sixteenBitLookup ();
519+ frame ->sixteenBitLookup ();
520520 }
521521
522- if (mRaw . get ( 0 ) ->getDataType () == RawImageType::UINT16) {
522+ if (frame ->getDataType () == RawImageType::UINT16) {
523523 // Default white level is (2 ** BitsPerSample) - 1
524- mRaw . get ( 0 ) ->whitePoint = (1UL << bps) - 1UL ;
525- } else if (mRaw . get ( 0 ) ->getDataType () == RawImageType::F32) {
524+ frame ->whitePoint = (1UL << bps) - 1UL ;
525+ } else if (frame ->getDataType () == RawImageType::F32) {
526526 // Default white level is 1.0f. But we can't represent that here.
527- mRaw . get ( 0 ) ->whitePoint = 65535 ;
527+ frame ->whitePoint = 65535 ;
528528 }
529529
530530 if (raw->hasEntry (TiffTag::WHITELEVEL)) {
531531 const TiffEntry* whitelevel = raw->getEntry (TiffTag::WHITELEVEL);
532532 if (whitelevel->isInt ())
533- mRaw . get ( 0 ) ->whitePoint = whitelevel->getU32 ();
533+ frame ->whitePoint = whitelevel->getU32 ();
534534 }
535535 // Set black
536536 setBlack (raw);
@@ -539,22 +539,22 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
539539 if (compression == 0x884c && !uncorrectedRawValues &&
540540 raw->hasEntry (TiffTag::OPCODELIST2)) {
541541 // We must apply black/white scaling
542- mRaw . get ( 0 ) ->scaleBlackWhite ();
542+ frame ->scaleBlackWhite ();
543543
544544 // Apply stage 2 codes
545545 try {
546- DngOpcodes codes (mRaw . get ( 0 ) .get (), raw->getEntry (TiffTag::OPCODELIST2));
547- codes.applyOpCodes (mRaw . get ( 0 ) .get ());
546+ DngOpcodes codes (frame .get (), raw->getEntry (TiffTag::OPCODELIST2));
547+ codes.applyOpCodes (frame .get ());
548548 } catch (const RawDecoderException& e) {
549549 // We push back errors from the opcode parser, since the image may still
550550 // be usable
551- mRaw . get ( 0 ) ->setError (e.what ());
551+ frame ->setError (e.what ());
552552 }
553- mRaw . get ( 0 ) ->blackAreas .clear ();
554- mRaw . get ( 0 ) ->blackLevel = 0 ;
555- mRaw . get ( 0 ) ->blackLevelSeparate [0 ] = mRaw . get ( 0 ) ->blackLevelSeparate [1 ] =
556- mRaw . get ( 0 ) ->blackLevelSeparate [2 ] = mRaw . get ( 0 ) ->blackLevelSeparate [3 ] = 0 ;
557- mRaw . get ( 0 ) ->whitePoint = 65535 ;
553+ frame ->blackAreas .clear ();
554+ frame ->blackLevel = 0 ;
555+ frame ->blackLevelSeparate [0 ] = frame ->blackLevelSeparate [1 ] =
556+ frame ->blackLevelSeparate [2 ] = frame ->blackLevelSeparate [3 ] = 0 ;
557+ frame ->whitePoint = 65535 ;
558558 }
559559}
560560
0 commit comments