@@ -219,7 +219,7 @@ ImageCodecInitializer& getCodecs()
219219 *
220220 * @return Image decoder to parse image file.
221221*/
222- static ImageDecoderfindDecoder (const String& filename ) {
222+ static ImageDecoderfindDecoder (const String& filename, int & exception_code ) {
223223
224224size_t i, maxlen =0 ;
225225
@@ -236,7 +236,10 @@ static ImageDecoder findDecoder( const String& filename ) {
236236
237237// / in the event of a failure, return an empty image decoder
238238if ( !f )
239+ {
240+ exception_code = IMREAD_FILE_NOT_OPENED;
239241return ImageDecoder ();
242+ }
240243
241244// read the file signature
242245 Stringsignature (maxlen,' ' );
@@ -252,6 +255,7 @@ static ImageDecoder findDecoder( const String& filename ) {
252255 }
253256
254257// / If no decoder was found, return base type
258+ exception_code = IMREAD_UNKNOWN_FILE_TYPE;
255259return ImageDecoder ();
256260}
257261
@@ -377,32 +381,34 @@ static void ApplyExifOrientation(ExifEntry_t orientationTag, Mat& img)
377381 *
378382 * @param[in] filename File to load
379383 * @param[in] flags Flags
380- * @param[in] hdrtype { LOAD_CVMAT=0,
381- * LOAD_IMAGE=1,
382- * LOAD_MAT=2
383- * }
384- * @param[in] mat Reference to C++ Mat object (If LOAD_MAT)
384+ * @param[in] mat Reference to C++ Mat object
385+ * @param index a variable used when loading multipage images
385386 *
386387*/
387- static bool
388- imread_ (const String& filename,int flags, Mat& mat )
388+ static int
389+ imread_ (const String& filename,int flags, Mat& mat, int index )
389390{
390391// / Search for the relevant decoder to handle the imagery
391392 ImageDecoder decoder;
393+ int exception_code;
392394
393395#ifdef HAVE_GDAL
394396if (flags != IMREAD_UNCHANGED && (flags & IMREAD_LOAD_GDAL) == IMREAD_LOAD_GDAL ){
395397 decoder =GdalDecoder ().newDecoder ();
396398 }else {
397399#endif
398- decoder =findDecoder ( filename );
400+ decoder =findDecoder ( filename, exception_code );
399401#ifdef HAVE_GDAL
400402 }
401403#endif
402404
403405// / if no decoder was found, return nothing.
404406if ( !decoder ){
405- return 0 ;
407+ if (!mat.empty ())
408+ {
409+ mat.at <int >(0 ,0 ) =0 ;
410+ }
411+ return exception_code;
406412 }
407413
408414int scale_denom =1 ;
@@ -417,7 +423,7 @@ imread_( const String& filename, int flags, Mat& mat )
417423 }
418424
419425// / set the scale_denom in the driver
420- decoder->setScale ( scale_denom );
426+ int initial_scale_denom = decoder->setScale ( scale_denom );
421427
422428// / set the filename in the driver
423429 decoder->setSource ( filename );
@@ -426,23 +432,45 @@ imread_( const String& filename, int flags, Mat& mat )
426432 {
427433// read the header to make sure it succeeds
428434if ( !decoder->readHeader () )
429- return 0 ;
435+ return IMREAD_READ_HEADER_ERROR ;
430436 }
431437catch (const cv::Exception& e)
432438 {
433439 std::cerr <<" imread_('" << filename <<" '): can't read header:" << e.what () << std::endl << std::flush;
434- return 0 ;
440+ return IMREAD_READ_HEADER_ERROR ;
435441 }
436442catch (...)
437443 {
438444 std::cerr <<" imread_('" << filename <<" '): can't read header: unknown exception" << std::endl << std::flush;
439- return 0 ;
445+ return IMREAD_READ_HEADER_ERROR ;
440446 }
441447
442448
443449// established the required input image size
444450 Size size =validateInputImageSize (Size (decoder->width (), decoder->height ()));
445451
452+ if (index <0 )// if index is -1 that means the function called only for reading header
453+ {
454+ int pageCount = decoder->getPageCount ();
455+ mat.at <int >(0 ,0 ) = pageCount;
456+
457+ for (int i =0 ; i < pageCount; i++)
458+ {
459+ mat.push_back (decoder->type ());
460+ mat.push_back (decoder->width ());
461+ mat.push_back (decoder->height ());
462+ mat.push_back (initial_scale_denom <0 ?1 :0 );
463+ decoder->nextPage ();
464+ }
465+ return IMREAD_SUCCESS;
466+ }
467+
468+ int counter =0 ;
469+
470+ for (;;)
471+ {
472+ if ((index <1 ) || (counter == index))
473+ {
446474// grab the decoded type
447475int type = decoder->type ();
448476if ( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
@@ -477,7 +505,7 @@ imread_( const String& filename, int flags, Mat& mat )
477505if (!success)
478506 {
479507 mat.release ();
480- return false ;
508+ return IMREAD_READ_DATA_ERROR + decoder-> getErrorCode () ;
481509 }
482510
483511if ( decoder->setScale ( scale_denom ) >1 )// if decoder is JpegDecoder then decoder->setScale always returns 1
@@ -491,10 +519,43 @@ imread_( const String& filename, int flags, Mat& mat )
491519ApplyExifOrientation (decoder->getExifTag (ORIENTATION), mat);
492520 }
493521
494- return true ;
522+ return IMREAD_SUCCESS + decoder->getErrorCode ();
523+ }
524+
525+ if (!decoder->nextPage ())
526+ {
527+ break ;
528+ }
529+ else
530+ counter++;
531+ }
532+
533+ return IMREAD_SUCCESS + decoder->getErrorCode ();
495534}
496535
497536
537+ imInfoimquery (const String& filename)
538+ {
539+ CV_TRACE_FUNCTION ();
540+
541+ imInfo iminfo;
542+ Matinfo (1 ,1 , CV_32S,Scalar (0 ));
543+ int ret =imread_ (filename, IMREAD_UNCHANGED, info, -1 );
544+ iminfo.errorcode = ret;
545+ iminfo.page_count = info.at <int >(0 ,0 );
546+
547+ for (int i =0 ; i < iminfo.page_count ; i ++)
548+ {
549+ pageInfo pageinfo;
550+ pageinfo.type = info.at <int >(i *4 +1 ,0 );
551+ pageinfo.width = info.at <int >(i *4 +2 ,0 );
552+ pageinfo.height = info.at <int >(i *4 +3 ,0 );
553+ pageinfo.scalable = info.at <int >(i *4 +4 ,0 );
554+ iminfo.pages .push_back (pageinfo);
555+ }
556+ return iminfo;
557+ }
558+
498559static bool
499560imreadmulti_ (const String& filename,int flags, std::vector<Mat>& mats,int start,int count)
500561{
@@ -509,7 +570,8 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats, int star
509570 }
510571else {
511572#endif
512- decoder =findDecoder (filename);
573+ int exception_code;
574+ decoder =cv::findDecoder (filename, exception_code);
513575#ifdef HAVE_GDAL
514576 }
515577#endif
@@ -626,12 +688,30 @@ Mat imread( const String& filename, int flags )
626688 Mat img;
627689
628690// / load the data
629- imread_ ( filename, flags, img );
691+ imread_ ( filename, flags, img, 0 );
630692
631693// / return a reference to the data
632694return img;
633695}
634696
697+ /* *
698+ * Read an image into specified OutputArray
699+ *
700+ * @param[in] filename Name of file to be loaded.
701+ * @param[in] image OutputArray where the image data will be loaded.
702+ * @param[in] flags Flag that can take values of cv::ImreadModes
703+ * @param index page index to be loaded for multipage image files.
704+ */
705+ int imread (const String& filename, OutputArray image,int flags,int index)
706+ {
707+ CV_TRACE_FUNCTION ();
708+
709+ Mat img = image.getMat ();
710+ int ret =imread_ (filename, flags, img, index);
711+ image.assign (img);
712+ return ret;
713+ }
714+
635715/* *
636716* Read a multi-page image
637717*
@@ -646,7 +726,18 @@ bool imreadmulti(const String& filename, std::vector<Mat>& mats, int flags)
646726{
647727CV_TRACE_FUNCTION ();
648728
649- return imreadmulti_ (filename, flags, mats,0 , -1 );
729+ imInfo info =imquery (filename);
730+
731+ for (int i =0 ; i < info.page_count ; i++)
732+ {
733+ Mat page;
734+ imread_ (filename, flags, page, i);
735+
736+ if (page.empty ())
737+ break ;
738+ mats.push_back (page);
739+ }
740+ return !mats.empty ();
650741}
651742
652743
@@ -671,7 +762,8 @@ size_t imcount_(const String& filename, int flags)
671762#else
672763CV_UNUSED (flags);
673764#endif
674- decoder =findDecoder (filename);
765+ int exception_code;
766+ decoder =cv::findDecoder (filename, exception_code);
675767#ifdef HAVE_GDAL
676768 }
677769#endif
@@ -1024,7 +1116,8 @@ bool imencode( const String& ext, InputArray _image,
10241116
10251117bool haveImageReader (const String& filename )
10261118{
1027- ImageDecoder decoder =cv::findDecoder (filename);
1119+ int exception_code;
1120+ ImageDecoder decoder =cv::findDecoder (filename, exception_code);
10281121return !decoder.empty ();
10291122}
10301123