@@ -499,8 +499,17 @@ RawImage DngDecoder::decodeRawInternal() {
499499
500500void DngDecoder::handleMetadata (const TiffIFD* raw) {
501501 // Crop
502- if (const std::optional<iRectangle2D> aa = parseACTIVEAREA (raw))
503- mRaw ->subFrame (*aa);
502+ if (const std::optional<iRectangle2D> aa = parseACTIVEAREA (raw)) {
503+ try {
504+ if (!aa->hasPositiveArea ())
505+ ThrowRDE (" No positive active area" );
506+ mRaw ->subFrame (*aa);
507+ } catch (const RawDecoderException& e) {
508+ // We push back errors from the active area parser, since the image may
509+ // still be usable
510+ mRaw ->setError (e.what ());
511+ }
512+ }
504513
505514 if (raw->hasEntry (TiffTag::DEFAULTCROPORIGIN) &&
506515 raw->hasEntry (TiffTag::DEFAULTCROPSIZE)) {
@@ -509,13 +518,19 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
509518 const TiffEntry* size_entry = raw->getEntry (TiffTag::DEFAULTCROPSIZE);
510519
511520 const auto tl_r = origin_entry->getRationalArray (2 );
512- std::array<unsigned , 2 > tl;
513- std::transform (tl_r.begin (), tl_r.end (), tl.begin (),
514- [](const NotARational<unsigned >& r) {
515- if (r.den == 0 || r.num % r.den != 0 )
516- ThrowRDE (" Error decoding default crop origin" );
517- return r.num / r.den ;
518- });
521+ std::array<unsigned , 2 > tl = {0 , 0 };
522+ try {
523+ std::transform (tl_r.begin (), tl_r.end (), tl.begin (),
524+ [](const NotARational<unsigned >& r) {
525+ if (r.den == 0 || r.num % r.den != 0 )
526+ ThrowRDE (" Error decoding default crop origin" );
527+ return r.num / r.den ;
528+ });
529+ } catch (const RawDecoderException& e) {
530+ // We push back errors from the crop parser, since the image may still
531+ // be usable
532+ mRaw ->setError (e.what ());
533+ }
519534
520535 if (iPoint2D cropOrigin (tl[0 ], tl[1 ]);
521536 cropped.isPointInsideInclusive (cropOrigin))
@@ -524,13 +539,20 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
524539 cropped.dim = mRaw ->dim - cropped.pos ;
525540
526541 const auto sz_r = size_entry->getRationalArray (2 );
527- std::array<unsigned , 2 > sz;
528- std::transform (sz_r.begin (), sz_r.end (), sz.begin (),
529- [](const NotARational<unsigned >& r) {
530- if (r.den == 0 || r.num % r.den != 0 )
531- ThrowRDE (" Error decoding default crop size" );
532- return r.num / r.den ;
533- });
542+ std::array<unsigned , 2 > sz = {static_cast <unsigned >(mRaw ->dim .x ),
543+ static_cast <unsigned >(mRaw ->dim .y )};
544+ try {
545+ std::transform (sz_r.begin (), sz_r.end (), sz.begin (),
546+ [](const NotARational<unsigned >& r) {
547+ if (r.den == 0 || r.num % r.den != 0 )
548+ ThrowRDE (" Error decoding default crop size" );
549+ return r.num / r.den ;
550+ });
551+ } catch (const RawDecoderException& e) {
552+ // We push back errors from the crop parser, since the image may still
553+ // be usable
554+ mRaw ->setError (e.what ());
555+ }
534556
535557 if (iPoint2D size (sz[0 ], sz[1 ]);
536558 size.isThisInside (mRaw ->dim ) &&
0 commit comments