int main(int argc, char *argv[]) { DIR *fromdir; char fullFromName[MAXPATHLEN]; char fullDestName[MAXPATHLEN]; char baseSrcPath[MAXPATHLEN]; char baseFromPath[MAXPATHLEN]; char baseToPath[MAXPATHLEN]; struct stat st; int allowAppend = 0; int allowLongerDest = 0; char archiveExtension[MAXPATHLEN]; baseSrcPath[0] = '\0'; archiveExtension[0] = '\0'; argv++; argc--; while (argc && argv[0][0] == '-') { if (strlen(argv[0]) != 2) printUsageAndDie(); switch (argv[0][1]) { case 's': argv++; argc--; if (!argc || argv[0][0] == '-') printUsageAndDie(); strcpy(baseSrcPath,argv[0]); printf("Source directory set to %s\n",baseSrcPath); argv++; argc--; break; case 'a': printf("Allowing append\n"); allowAppend = 1; argv++; argc--; break; case 'l': printf("Allowing destination to be longer than source\n"); allowLongerDest = 1; argv++; argc--; break; case 'r': argv++; argc--; if (!argc || argv[0][0] == '-') printUsageAndDie(); sprintf(archiveExtension,".%s",argv[0]); printf("Archive extension set to %s\n",archiveExtension); argv++; argc--; break; default: fprintf(stderr,"Error: Unknown option %s\n",argv[0]); printUsageAndDie(); break; } } if (argc != 2) { fprintf(stderr,"Error: Didn't end up with two dirs\n"); printUsageAndDie(); } if ((fromdir = opendir(argv[0])) == NULL) { fprintf(stderr,"Error: Couldn't open source perl directory %s\n",argv[0]); exit(1); } if ((opendir(argv[1])) != NULL) { if (!allowAppend) { fprintf(stderr,"Error: Destination perl directory already exists\n"); exit(1); } } else if (allowAppend) { fprintf(stderr,"Error: -a (append) specified but destination dir doesn't exist\n"); } /* if (!realpath(argv[0],fullFromName)) { fprintf(stderr,"Error: Couldn't get realpath to fromdir\n"); exit(1); } if (!realpath(argv[1],fullDestName)) { fprintf(stderr,"Error: Couldn't get realpath to destdir\n"); exit(1); } */ strcpy(fullFromName,argv[0]); strcpy(fullDestName,argv[1]); if (!allowAppend) { stat(fullFromName,&st); if (mkdir(fullDestName,st.st_mode)) { fprintf(stderr, "Error: Failed making directory %s\n",fullDestName); exit(1); } } strcpy(baseFromPath,fullFromName); strcpy(baseToPath,fullDestName); if (baseSrcPath[0]=='\0') { strcpy(baseSrcPath,fullFromName); } if (strlen(baseSrcPath) < strlen(baseToPath) && !allowLongerDest) { fprintf(stderr,"Error: Length of to path can't be longer than from path\n"); exit(1); } descendAndDo(fromdir,fullFromName,fullDestName, baseSrcPath,baseFromPath,baseToPath, allowAppend,archiveExtension,doFuncInp); }
int main(int argc, char **argv) try { if (argc != 3) { printUsageAndDie(argv[0]); } std::ifstream origFile(argv[1]); if (! origFile) { throw std::runtime_error("Cannot open " + std::string(argv[1])); } std::ifstream splitFile(argv[2]); if (! splitFile) { throw std::runtime_error("Cannot open " + std::string(argv[2])); } unsigned startPos = 0; int origPos = 0; std::string line; unsigned lineNo = 0; while (std::getline(splitFile, line)) { ++lineNo; unsigned endPos = startPos + line.size(); unsigned origStartPos; if (line.size() == 0) { /// empty line origStartPos = origPos; } else { /// collect heading spaces std::string headingWs; for (std::string::const_iterator ch = line.begin(); ch != line.end(); ++ch) { if (std::isspace(*ch)) { headingWs += *ch; } else { break; } } // if (line[0] == ' ') { // throw std::runtime_error( // "Error: Split text contains a heading space"); // } /// skip newlines in the original file char origChar; while (origFile.get(origChar)) { ++origPos; if (origChar != '\n') { origFile.unget(); --origPos; break; } } /// collect spaces in the original file std::string origWs; while (origFile.get(origChar)) { ++origPos; if (origChar == ' ' || origChar == '\t') { origWs += origChar; } else { origFile.unget(); --origPos; break; } } #if 0 /// skip spaces and newlines in the original file char origChar; do { if (! origFile.get(origChar)) { throw std::runtime_error( "Split/original text do not match"); } ++origPos; } while (origChar == ' ' || origChar == '\n'); origFile.unget(); --origPos; #endif /// check if the heading space part has a corresponding region /// in the original file if (origWs.size() < headingWs.size()) { throw std::runtime_error("Split/original text do not match"); } unsigned skipLen = origWs.size() - headingWs.size(); if (! headingWs.empty() && headingWs != origWs.substr(skipLen)) { throw std::runtime_error("Split/original text do not match"); } origStartPos = origPos - headingWs.size(); /// Check the identity for the rest of the line for (unsigned i = headingWs.size(); i < line.size(); ++i) { if (! origFile.get(origChar) || origChar != line[i]) { std::string msg = errorMsgLong( origPos, origChar, lineNo, i, line[i]); throw std::runtime_error(msg); } ++origPos; } } std::cout << startPos << '\t' << endPos << '\t' << origStartPos << std::endl; /// +1 to skip the new line character startPos = endPos + 1; } return 0; } catch (std::runtime_error &e) { std::cerr << e.what() << std::endl; exit(1); } catch (...) { std::cerr << "Unknown exception" << std::endl; exit(1); }
int main(int argc, char** argv) { if(argc < 4) { printUsageAndDie(); } FileHashGrouper fileHashGrouper; bool enableHtmlOutput = false; char* targetFolder; char* algoArg; char* thresholdArg; float threshold = -1.0f; HashAlgorithm selectedAlgorithm = DCT; #ifdef DEBUG std::cout << "Running in debug mode" << std::endl; #endif if(*argv[1] == '-') { if(argc < 5) printUsageAndDie(); targetFolder = argv[4]; algoArg = argv[2]; thresholdArg = argv[3]; if(argv[1][1] == 'a') { #ifndef DEBUG fileHashGrouper.thresholdRequiredForAll = false; std::cout << "Threshold will be required to be satisfied for only ONE hash." << std::endl; #else std::cout << "Threshold behaviour argument ignored because of debug mode." << std::endl; #endif } } else { targetFolder = argv[3]; algoArg = argv[1]; thresholdArg = argv[2]; } enableHtmlOutput = true; std::cout << "HTML Output enabled." << std::endl; std::string tmpSelectedAlgorithm(algoArg); boost::algorithm::to_lower(tmpSelectedAlgorithm); if(boost::iequals(tmpSelectedAlgorithm, "dct")) selectedAlgorithm = DCT; if(boost::iequals(tmpSelectedAlgorithm, "mh")) selectedAlgorithm = MH; if(boost::iequals(tmpSelectedAlgorithm, "radish")) selectedAlgorithm = RADISH; if(boost::iequals(tmpSelectedAlgorithm, "all")) selectedAlgorithm = ALL; fileHashGrouper.algorithm = selectedAlgorithm; try { threshold = boost::lexical_cast<int>(thresholdArg); if(threshold > 100.0f || threshold < 1.0f) throw 33; //No specific reason for 33, just felt like it } catch (std::exception& e) { std::cout << "error : threshold must be between 1 and 100\n\n"; printUsageAndDie(); } std::cout << "Algorithm : " << tmpSelectedAlgorithm; std::cout << ", Threshold : " << threshold << " %" << std::endl; fileHashGrouper.threshold = 1-threshold/100; std::cout << "Scanning target folder : " << targetFolder << std::endl; std::vector<FileHash> fileList; listImages(bf::path(targetFolder), fileList); std::cout << "Done. " << fileList.size() << " file(s) to scan.\nScanning ...\n"; int scanned = 0; for(int i = 0; i < fileList.size(); i++) { fileList[i].compute(selectedAlgorithm); printProgressBar(std::floor(((i+1)/static_cast<float>(fileList.size()))*100)); } std::cout << std::endl; ofstream outputHtml; if(enableHtmlOutput) { outputHtml.open("results.html"); if(!outputHtml.is_open()) { std::cout << "Error : Could not open 'result.html' for writing, disabling HTML output."; std::cout << std::endl; enableHtmlOutput = false; } outputHtml << "<!DOCTYPE html>\n"; outputHtml << "<html>\n\t<head>\n\t\t<title>Image comparaison result</title>\n"; outputHtml << "\t\t<link href='style.css' rel='stylesheet' type='text/css'>\n\t</head>\n"; outputHtml << "\t<body>\n"; outputHtml << "\t\t<h1>Image comparaison result for " << targetFolder << "</h1>\n"; outputHtml << "\t\t<h2>" << fileList.size() << " image(s)</h2>\n"; outputHtml << "\t\t<table>\n"; } std::vector<FileHashGroup> groups = fileHashGrouper.computeGroups(fileList); for(int i = 0; i < groups.size(); i++) { if(enableHtmlOutput) { outputHtml << "\t\t\t<tr>\n"; outputHtml << "\t\t\t\t<td>\n"; groups[i][0].file.printHtml(outputHtml, 4); outputHtml << "\t\t\t\t</td>\n"; } #ifdef DEBUG std::cout << groups[i][0].file.path() << " "; #endif for(int j = 1; j < groups[i].elements().size(); j++) { if(enableHtmlOutput) { outputHtml << "\t\t\t\t<td>\n"; groups[i][j].file.printHtml(outputHtml, 5); outputHtml << "\t\t\t\t<br/><span class='similarity'>"; outputHtml << groups[i][j].similarity.percentage(); outputHtml << " %</span>\n"; outputHtml << "\t\t\t\t</td>\n"; } #ifdef DEBUG std::cout << groups[i][j].file.path() << " "; std::cout << "dct : " << groups[i][j].similarity.dct << " | "; std::cout << "mh : " << groups[i][j].similarity.mh << " | "; std::cout << "radish : " << groups[i][j].similarity.radish << " | "; std::cout << std::endl; #endif } if(enableHtmlOutput) outputHtml << "\t\t\t</tr>\n"; } if(enableHtmlOutput) { outputHtml << "\t\t</table>\n\t</body>\n</html>"; outputHtml.close(); std::cout << "Results saved to 'results.html'" << std::endl; } std::cout << "Done." << std::endl; return 0; }