@@ -337,6 +337,7 @@ class toktxApp : public scApp {
337337
338338 void warning (const char *pFmt, va_list args);
339339 void warning (const char *pFmt, ...);
340+ void warning (const string&);
340341
341342 protected:
342343 virtual bool processOption (argparser& parser, int opt);
@@ -688,10 +689,22 @@ toktxApp::main(int argc, _TCHAR *argv[])
688689 unsigned int levelWidth=0 , levelHeight=0 , levelDepth=0 ;
689690 // These initializations are to avoid compiler warnings.
690691 khr_df_transfer_e chosenOETF = KHR_DF_TRANSFER_UNSPECIFIED;
691- khr_df_transfer_e firstImageOETF = KHR_DF_TRANSFER_UNSPECIFIED;
692692 khr_df_primaries_e chosenPrimaries = KHR_DF_PRIMARIES_UNSPECIFIED;
693- khr_df_primaries_e firstImagePrimaries = KHR_DF_PRIMARIES_UNSPECIFIED;
694- Image::colortype_e firstImageColortype = Image::eRGB;
693+ struct _imageAttribs {
694+ khr_df_transfer_e oetf;
695+ khr_df_primaries_e primaries;
696+ uint32_t componentCount;
697+ bool oetfWarned;
698+ bool primariesWarned;
699+ bool componentCountWarned;
700+ } expectedAttribs = {
701+ KHR_DF_TRANSFER_UNSPECIFIED,
702+ KHR_DF_PRIMARIES_UNSPECIFIED,
703+ 3 ,
704+ false ,
705+ false ,
706+ false
707+ };
695708 string defaultSwizzle;
696709
697710 processEnvOptions ();
@@ -735,16 +748,20 @@ toktxApp::main(int argc, _TCHAR *argv[])
735748 // If input is > 8bit and user wants LDR issue quality loss warning
736749 if (options.astc && image->getComponentSize () > 1
737750 && options.astcopts .mode == KTX_PACK_ASTC_ENCODER_MODE_LDR) {
738- cerr << name << " : Warning! input file is 16bit but LDR option is specified."
739- << " Expect quality loss in the output."
740- << endl;
751+ stringstream msg;
752+ msg << " Input file is 16-bit but LDR option is specified. "
753+ << " Expect quality loss in the output."
754+ << endl;
755+ warning (msg.str ());
741756 }
742757
743758 // If input is < 8bit and user wants HDR issue warning
744759 if (options.astc && image->getComponentSize () <= 1 &&
745760 options.astcopts .mode == KTX_PACK_ASTC_ENCODER_MODE_HDR) {
746- cerr << name << " : Warning! input file is not 16bit but HDR option is specified."
747- << endl;
761+ stringstream msg;
762+ msg << " Input file is not 16-bit but HDR option is specified."
763+ << endl;
764+ warning (msg.str ());
748765 }
749766
750767 // If no astc mode option is specified and
@@ -756,11 +773,69 @@ toktxApp::main(int argc, _TCHAR *argv[])
756773 options.astcopts .mode = KTX_PACK_ASTC_ENCODER_MODE_HDR;
757774 }
758775
776+ // Check that all input files have matching oetf, primaries and
777+ // component count. Raise error or warning depending on attribute
778+ // and assign or convert options.
759779 if (i == 0 ) {
760780 // First file.
761- firstImageOETF = image->getOetf ();
762- firstImagePrimaries = image->getPrimaries ();
763- firstImageColortype = image->getColortype ();
781+ expectedAttribs.oetf = image->getOetf ();
782+ expectedAttribs.primaries = image->getPrimaries ();
783+ expectedAttribs.componentCount = image->getComponentCount ();
784+ } else {
785+ // Subsequent files.
786+ if (image->getOetf () != expectedAttribs.oetf
787+ && options.convert_oetf == KHR_DF_TRANSFER_UNSPECIFIED)
788+ {
789+ stringstream msg;
790+ msg << " \" " << infile << " \" is encoded with a "
791+ " different transfer function (OETF) than preceding "
792+ " file(s)." << endl;
793+ if (options.assign_oetf == KHR_DF_TRANSFER_UNSPECIFIED) {
794+ cerr << name << " : " << msg.str ();
795+ exitCode = 1 ;
796+ goto cleanup;
797+ } else if (!expectedAttribs.oetfWarned ) {
798+ warning (msg.str ());
799+ expectedAttribs.oetfWarned = true ;
800+ }
801+ // Don't warn when convert_oetf is set as proper conversions
802+ // will be done so all images will be in the same space.
803+ }
804+ if (image->getPrimaries () != expectedAttribs.primaries ) {
805+ stringstream msg;
806+ msg << " \" " << infile << " \" has different color "
807+ " primaries than preceding file(s)." << endl;
808+ if (options.assign_primaries == KHR_DF_PRIMARIES_UNSPECIFIED) {
809+ cerr << name << " : " << msg.str ();
810+ exitCode = 1 ;
811+ goto cleanup;
812+ } else if (!expectedAttribs.primariesWarned ) {
813+ warning (msg.str ());
814+ expectedAttribs.primariesWarned = true ;
815+ }
816+ // There is no convert_primaries option.
817+ }
818+ if (image->getComponentCount () != expectedAttribs.componentCount ) {
819+ stringstream msg;
820+ msg << " \" " << infile
821+ << " \" has a different colortype_e"
822+ << " (component count) than preceding file(s)."
823+ << endl;
824+ if (options.targetType == commandOptions::eUnspecified) {
825+ cerr << name << " : " << msg.str ();
826+ exitCode = 1 ;
827+ goto cleanup;
828+ } else if (!expectedAttribs.componentCountWarned ) {
829+ msg << " The components of the level or layer derived "
830+ << " from this file will likely be significantly "
831+ << " different"
832+ << endl
833+ << " from those in other levels or layers."
834+ << endl;
835+ warning (msg.str ());
836+ expectedAttribs.componentCountWarned = true ;
837+ }
838+ }
764839 }
765840
766841 if (options.assign_oetf != KHR_DF_TRANSFER_UNSPECIFIED) {
@@ -832,8 +907,9 @@ toktxApp::main(int argc, _TCHAR *argv[])
832907 if (options.targetType != commandOptions::eUnspecified) {
833908 if (options.targetType != (int )image->getComponentCount ()) {
834909 Image* newImage = nullptr ;
835- // The following casts only work because the only case that will
836- // be taken at runtime is the one where image is the same
910+ // The casts in the following copyTo* definitions only work
911+ // because, thanks to the switch, at runtime we always pass
912+ // the image type being cast to.
837913 if (image->getComponentSize () == 2 ) {
838914 switch (options.targetType ) {
839915 case commandOptions::eR:
@@ -1084,26 +1160,6 @@ toktxApp::main(int argc, _TCHAR *argv[])
10841160 goto cleanup;
10851161 }
10861162 } else {
1087- // Subsequent files.
1088- if (image->getOetf () != firstImageOETF) {
1089- cerr << name << " : \" " << infile << " \" is encoded with a "
1090- " different transfer function (OETF) than preceding files."
1091- << endl;
1092- exitCode = 1 ;
1093- goto cleanup;
1094- }
1095- if (image->getPrimaries () != firstImagePrimaries) {
1096- cerr << name << " : \" " << infile << " \" has different color "
1097- " primaries than preceding files." << endl;
1098- exitCode = 1 ;
1099- goto cleanup;
1100- }
1101- if (image->getColortype () != firstImageColortype) {
1102- cerr << name << " : \" " << infile << " \" has a different colortype_e"
1103- << " (component count) than preceding files." << endl;
1104- exitCode = 1 ;
1105- goto cleanup;
1106- }
11071163 // Input file order is layer, faceSlice, level. This seems easier for
11081164 // a human to manage than the order in a KTX file. It keeps the
11091165 // base level images and their mip levels together.
@@ -1611,7 +1667,7 @@ toktxApp::processOption(argparser& parser, int opt)
16111667
16121668void toktxApp::warning (const char *pFmt, va_list args) {
16131669 if (options.warn ) {
1614- cerr << name << " warning: " ;
1670+ cerr << name << " warning! " ;
16151671 vfprintf (stderr, pFmt, args);
16161672 cerr << endl;
16171673 }
@@ -1627,12 +1683,23 @@ void toktxApp::warning(const char *pFmt, ...) {
16271683 }
16281684}
16291685
1686+ void toktxApp::warning (const string& msg) {
1687+ if (options.warn ) {
1688+ cerr << name << " warning! " ;
1689+ cerr << msg;
1690+ }
1691+ }
1692+
16301693void warning (const char *pFmt, ...) {
1631- va_list args;
1632- va_start (args, pFmt);
1694+ va_list args;
1695+ va_start (args, pFmt);
1696+
1697+ theApp.warning (pFmt, args);
1698+ va_end (args);
1699+ }
16331700
1634- theApp. warning (pFmt, args);
1635- va_end (args );
1701+ void warning (const string& msg) {
1702+ theApp. warning (msg );
16361703}
16371704
16381705static ktx_uint32_t
0 commit comments