@@ -500,7 +500,15 @@ RawImage DngDecoder::decodeRawInternal() {
500500void DngDecoder::handleMetadata (const TiffIFD* raw) {
501501 // Crop
502502 if (const std::optional<iRectangle2D> aa = parseACTIVEAREA (raw))
503- mRaw ->subFrame (*aa);
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+ }
504512
505513 if (raw->hasEntry (TiffTag::DEFAULTCROPORIGIN) &&
506514 raw->hasEntry (TiffTag::DEFAULTCROPSIZE)) {
@@ -509,13 +517,19 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
509517 const TiffEntry* size_entry = raw->getEntry (TiffTag::DEFAULTCROPSIZE);
510518
511519 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- });
520+ std::array<unsigned , 2 > tl = {0 , 0 };
521+ try {
522+ std::transform (tl_r.begin (), tl_r.end (), tl.begin (),
523+ [](const NotARational<unsigned >& r) {
524+ if (r.den == 0 || r.num % r.den != 0 )
525+ ThrowRDE (" Error decoding default crop origin" );
526+ return r.num / r.den ;
527+ });
528+ } catch (const RawDecoderException& e) {
529+ // We push back errors from the crop parser, since the image may still
530+ // be usable
531+ mRaw ->setError (e.what ());
532+ }
519533
520534 if (iPoint2D cropOrigin (tl[0 ], tl[1 ]);
521535 cropped.isPointInsideInclusive (cropOrigin))
@@ -524,13 +538,20 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
524538 cropped.dim = mRaw ->dim - cropped.pos ;
525539
526540 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- });
541+ std::array<unsigned , 2 > sz = {static_cast <unsigned >(mRaw ->dim .x ),
542+ static_cast <unsigned >(mRaw ->dim .y )};
543+ try {
544+ std::transform (sz_r.begin (), sz_r.end (), sz.begin (),
545+ [](const NotARational<unsigned >& r) {
546+ if (r.den == 0 || r.num % r.den != 0 )
547+ ThrowRDE (" Error decoding default crop size" );
548+ return r.num / r.den ;
549+ });
550+ } catch (const RawDecoderException& e) {
551+ // We push back errors from the crop parser, since the image may still
552+ // be usable
553+ mRaw ->setError (e.what ());
554+ }
534555
535556 if (iPoint2D size (sz[0 ], sz[1 ]);
536557 size.isThisInside (mRaw ->dim ) &&
0 commit comments