int main(int argc, char **argv) { int fileArg = 1; if(fileArg == argc) { PrintUsage(); exit(1); } char decompressedOutput[256]; decompressedOutput[0] = '\0'; bool bNoDecompress = false; int numJobs = 0; int quality = 50; int numThreads = 1; int numCompressions = 1; bool bUseSIMD = false; bool bSaveLog = false; bool bUseAtomics = false; bool bUsePVRTexLib = false; bool bUseNVTT = false; bool bVerbose = false; FasTC::ECompressionFormat format = FasTC::eCompressionFormat_BPTC; bool knowArg = false; do { knowArg = false; if(strcmp(argv[fileArg], "-n") == 0) { fileArg++; if(fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) { PrintUsage(); exit(1); } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-f") == 0) { fileArg++; if(fileArg == argc) { PrintUsage(); exit(1); } else { if(!strcmp(argv[fileArg], "PVRTC")) { format = FasTC::eCompressionFormat_PVRTC4; } else if(!strcmp(argv[fileArg], "PVRTCLib")) { format = FasTC::eCompressionFormat_PVRTC4; bUsePVRTexLib = true; } else if(!strcmp(argv[fileArg], "BPTCLib")) { format = FasTC::eCompressionFormat_BPTC; bUseNVTT = true; } else if(!strcmp(argv[fileArg], "ETC1")) { format = FasTC::eCompressionFormat_ETC1; } else if(!strcmp(argv[fileArg], "DXT1")) { format = FasTC::eCompressionFormat_DXT1; } else if(!strcmp(argv[fileArg], "DXT5")) { format = FasTC::eCompressionFormat_DXT5; } } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-d") == 0) { fileArg++; if(fileArg == argc) { PrintUsage(); exit(1); } else { size_t sz = 255; sz = ::std::min(sz, static_cast<size_t>(strlen(argv[fileArg]))); memcpy(decompressedOutput, argv[fileArg], sz + 1); } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-nd") == 0) { fileArg++; bNoDecompress = true; knowArg = true; continue; } if(strcmp(argv[fileArg], "-l") == 0) { fileArg++; bSaveLog = true; knowArg = true; continue; } if(strcmp(argv[fileArg], "-v") == 0) { fileArg++; bVerbose = true; knowArg = true; continue; } if(strcmp(argv[fileArg], "-simd") == 0) { fileArg++; bUseSIMD = true; knowArg = true; continue; } if(strcmp(argv[fileArg], "-t") == 0) { fileArg++; if(fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) { PrintUsage(); exit(1); } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-q") == 0) { fileArg++; if(fileArg == argc || (quality = atoi(argv[fileArg])) < 0) { PrintUsage(); exit(1); } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-j") == 0) { fileArg++; if(fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) { PrintUsage(); exit(1); } fileArg++; knowArg = true; continue; } if(strcmp(argv[fileArg], "-a") == 0) { fileArg++; bUseAtomics = true; knowArg = true; continue; } } while(knowArg && fileArg < argc); if(fileArg == argc) { PrintUsage(); exit(1); } char basename[256]; ExtractBasename(argv[fileArg], basename, 256); ImageFile file (argv[fileArg]); if(!file.Load()) { fprintf(stderr, "Error loading file: %s\n", argv[fileArg]); return 1; } FasTC::Image<> img(*file.GetImage()); if(bVerbose) { fprintf(stdout, "Entropy: %.5f\n", img.ComputeEntropy()); fprintf(stdout, "Mean Local Entropy: %.5f\n", img.ComputeMeanLocalEntropy()); } std::ofstream logFile; ThreadSafeStreambuf streamBuf(logFile); std::ostream logStream(&streamBuf); if(bSaveLog) { char logname[256]; sprintf(logname, "%s.log", basename); logFile.open(logname); } SCompressionSettings settings; settings.format = format; settings.bUseSIMD = bUseSIMD; settings.bUseAtomics = bUseAtomics; settings.iNumThreads = numThreads; settings.iQuality = quality; settings.iNumCompressions = numCompressions; settings.iJobSize = numJobs; settings.bUsePVRTexLib = bUsePVRTexLib; settings.bUseNVTT = bUseNVTT; if(bSaveLog) { settings.logStream = &logStream; } else { settings.logStream = NULL; } CompressedImage *ci = CompressImage(&img, settings); if(NULL == ci) { fprintf(stderr, "Error compressing image!\n"); return 1; } double PSNR = img.ComputePSNR(ci); if(PSNR > 0.0) { fprintf(stdout, "PSNR: %.3f\n", PSNR); } else { fprintf(stderr, "Error computing PSNR\n"); } if(bVerbose) { double SSIM = img.ComputeSSIM(ci); if(SSIM > 0.0) { fprintf(stdout, "SSIM: %.9f\n", SSIM); } else { fprintf(stderr, "Error computing SSIM\n"); } } if(!bNoDecompress) { if(decompressedOutput[0] != '\0') { memcpy(basename, decompressedOutput, 256); } else if(format == FasTC::eCompressionFormat_BPTC) { strcat(basename, "-bptc.png"); } else if(format == FasTC::eCompressionFormat_PVRTC4) { strcat(basename, "-pvrtc-4bpp.png"); } else if(format == FasTC::eCompressionFormat_DXT1) { strcat(basename, "-dxt1.png"); } else if(format == FasTC::eCompressionFormat_ETC1) { strcat(basename, "-etc1.png"); } EImageFileFormat fmt = ImageFile::DetectFileFormat(basename); ImageFile cImgFile (basename, fmt, *ci); cImgFile.Write(); } // Cleanup delete ci; if(bSaveLog) { logFile.close(); } return 0; }
int main(int argc, char **argv) { if(argc < 3 || argc > 5) { PrintUsageAndExit(); } bool diff_images = false; float diff_multiplier = 1.0; int arg = 1; if (strncmp(argv[arg], "-d", 2) == 0) { diff_images = true; arg++; if (argc == 5) { diff_multiplier = static_cast<float>(atoi(argv[arg])); if (diff_multiplier < 0) { PrintUsageAndExit(); } arg++; } } ImageFile img1f (argv[arg]); if(!img1f.Load()) { fprintf(stderr, "Error loading file: %s\n", argv[arg]); return 1; } arg++; ImageFile img2f (argv[arg]); if(!img2f.Load()) { fprintf(stderr, "Error loading file: %s\n", argv[arg]); return 1; } arg++; FasTC::Image<> &img1 = *img1f.GetImage(); FasTC::Image<> &img2 = *img2f.GetImage(); if (img1.GetWidth() != img2.GetWidth() || img1.GetHeight() != img2.GetHeight()) { std::cerr << "Images differ in dimension!" << std::endl; return 1; } if (diff_images) { FasTC::Image<> diff = img1.Diff(&img2, diff_multiplier); char fname_buf [5 + 16 + 4 + 1]; // "diff-" + hash + ".png" + null memset(fname_buf, 0, sizeof(fname_buf)); strncat(fname_buf, "diff-", 5); gen_random(fname_buf + 5, 16); strncat(fname_buf + 5 + 16, ".png", 4); EImageFileFormat fmt = ImageFile::DetectFileFormat(fname_buf); ImageFile cImgFile (fname_buf, fmt, diff); cImgFile.Write(); } double PSNR = img1.ComputePSNR(&img2); if(PSNR > 0.0) { fprintf(stdout, "PSNR: %.3f\n", PSNR); } else { fprintf(stderr, "Error computing PSNR\n"); } double SSIM = img1.ComputeSSIM(&img2); if(SSIM > 0.0) { fprintf(stdout, "SSIM: %.9f\n", SSIM); } else { fprintf(stderr, "Error computing MSSIM\n"); } return 0; }