@@ -500,7 +500,10 @@ 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+ if (aa->hasPositiveArea ())
504+ mRaw ->subFrame (*aa);
505+ else
506+ mRaw ->setError (" No positive active area" );
504507
505508 if (raw->hasEntry (TiffTag::DEFAULTCROPORIGIN) &&
506509 raw->hasEntry (TiffTag::DEFAULTCROPSIZE)) {
@@ -509,13 +512,19 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
509512 const TiffEntry* size_entry = raw->getEntry (TiffTag::DEFAULTCROPSIZE);
510513
511514 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- });
515+ std::array<unsigned , 2 > tl = {0 , 0 };
516+ try {
517+ std::transform (tl_r.begin (), tl_r.end (), tl.begin (),
518+ [](const NotARational<unsigned >& r) {
519+ if (r.den == 0 || r.num % r.den != 0 )
520+ ThrowRDE (" Error decoding default crop origin" );
521+ return r.num / r.den ;
522+ });
523+ } catch (const RawDecoderException& e) {
524+ // We push back errors from the crop parser, since the image may still
525+ // be usable
526+ mRaw ->setError (e.what ());
527+ }
519528
520529 if (iPoint2D cropOrigin (tl[0 ], tl[1 ]);
521530 cropped.isPointInsideInclusive (cropOrigin))
@@ -524,13 +533,20 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
524533 cropped.dim = mRaw ->dim - cropped.pos ;
525534
526535 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- });
536+ std::array<unsigned , 2 > sz = {static_cast <unsigned >(mRaw ->dim .x ),
537+ static_cast <unsigned >(mRaw ->dim .y )};
538+ try {
539+ std::transform (sz_r.begin (), sz_r.end (), sz.begin (),
540+ [](const NotARational<unsigned >& r) {
541+ if (r.den == 0 || r.num % r.den != 0 )
542+ ThrowRDE (" Error decoding default crop size" );
543+ return r.num / r.den ;
544+ });
545+ } catch (const RawDecoderException& e) {
546+ // We push back errors from the crop parser, since the image may still
547+ // be usable
548+ mRaw ->setError (e.what ());
549+ }
534550
535551 if (iPoint2D size (sz[0 ], sz[1 ]);
536552 size.isThisInside (mRaw ->dim ) &&
0 commit comments