aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp.test/src/match.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp.test/src/match.cpp')
-rw-r--r--meowpp.test/src/match.cpp547
1 files changed, 328 insertions, 219 deletions
diff --git a/meowpp.test/src/match.cpp b/meowpp.test/src/match.cpp
index c69b958..8fec09b 100644
--- a/meowpp.test/src/match.cpp
+++ b/meowpp.test/src/match.cpp
@@ -1,35 +1,103 @@
#include <cstdio>
+#include <string>
+#include <cstdlib>
-#include "match.h"
+struct Job;
-#include "meowpp/Usage.h"
-#include "meowpp/colors/RGB_Space.h"
-#include "meowpp/geo/Vectors.h"
-#include "meowpp/gra/Bitmap.h"
-#include "meowpp/oo/ObjBase.h"
-#include "meowpp/oo/ObjSelector.h"
+void init ( );
+void setup(int argc, char** argv);
+void end ( );
-#include <opencv/cv.h>
-#include <opencv/highgui.h>
+Job* get(size_t counter);
-extern "C"{
-#include <sys/types.h>
-#include <dirent.h>
+void input (Job* job);
+void handle(Job* job);
+void output(Job* job);
+void clear (Job* job);
+
+void info0 (Job* job);
+void info1 (Job* job);
+void info2 (Job* job);
+
+int main(int argc, char** argv) {
+ Job* now;
+ try {
+ init();
+ setup(argc, argv);
+ for (size_t counter = 0; (now = get(counter)) != NULL; clear(now), ++counter) {
+ try {
+ input (now); info0(now);
+ handle(now); info1(now);
+ output(now); info2(now);
+ }
+ catch (std::string reason) {
+ throw reason.c_str();
+ }
+ catch (char const* reason) {
+ printf("fail '%s', ignore.\n\n", reason);
+ continue;
+ }
+ printf("\n");
+ }
+ end();
+ }
+ catch (int num) {
+ return num;
+ }
+ return 0;
}
+///////////////////////////////////////////////////////////
+
+#include "test_utility.h"
+#include "match.h"
+
+#include "meowpp/utility.h"
+#include "meowpp/Usage.h"
+#include "meowpp/oo/ObjSelector.h"
+#include "meowpp/gra/IdentityPoints.h"
+
#include <vector>
#include <algorithm>
#include <string>
+#include <cstdio>
using namespace meow;
+///////////////////////////////////////////////////////////
+
Usage usg("match");
-std::vector<bool> fg;
+MatchAll* match_all;
+MatchOne* match_one;
+MatchChk* match_chk;
+
+struct Job {
+ struct Picture {
+ std::string fname;
+ size_t width;
+ size_t height;
+ std::vector<FP> features;
+ std::vector<Vector2D<double> > fvs;
+ IdentityPoints<int, double, Vector2D<double> > fps;
+ Picture(): fps(2) {
+ }
+ };
+ std::vector<Picture> pictures;
+ std::vector<std::vector<std::vector<Pair> > > pairs;
+ std::vector<std::vector<MatchInfo> > matches;
+};
+
+std::vector<Job> jobs;
+
std::vector<std::string> names;
-std::vector<std::vector<FeaturePoint<double, double> > > fps;
-int setup(int argc, char** argv) {
+std::string out_pre;
+
+
+///////////////////////////////////////////////////////////
+
+void init() {
usg.optionAdd("h" , "Display this help document");
usg.optionAdd("help", "Display this help document");
usg.optionAdd("i",
@@ -38,264 +106,305 @@ int setup(int argc, char** argv) {
"pathname",
"",
false);
+ usg.optionAdd("r",
+ "recur");
usg.optionAdd("o",
- "Output images with denoting aligement points",
+ "Output images with denoting matches",
"filename",
"",
false);
- usg.optionAdd("f",
- "Output text file name (prefix)",
- "filename",
- "output",
- false);
+ usg.optionAdd("a",
+ "Specify which feature match algorithm to use",
+ "name",
+ "",
+ true);
usg.optionAdd("m",
- "Specify which match algorithm to use",
+ "Specify which match detect algorithm to use",
"name",
"",
true);
usg.optionAdd("c",
- "Specify which check algorithm to use",
+ "Specify which match match_chk algorithm to use",
"name",
"",
true);
- std::vector<std::string> nlist;
- nlist = (ObjSelector<kMatchAllsID>::names());
- for (size_t i = 0, I = nlist.size(); i < I; ++i) {
- MatchAlls const* m;
- m = (MatchAlls const*)ObjSelector<kMatchAllsID>::get(nlist[i]);
- usg.optionValueAcceptAdd("m", nlist[i], m->description());
- usg.import(m->usage());
+ std::vector<std::string> algo_list;
+ algo_list = ObjSelector<kMatchAll_ID>::names();
+ for (size_t i = 0, I = algo_list.size(); i < I; ++i) {
+ MatchAll const* f = (MatchAll const*)ObjSelector<kMatchAll_ID>::get(algo_list[i]);
+ usg.optionValueAcceptAdd("a", algo_list[i], f->description());
+ if (usg.import(f->usage()) == false)
+ throw -1;
+ }
+ algo_list = ObjSelector<kMatchOne_ID>::names();
+ for (size_t i = 0, I = algo_list.size(); i < I; ++i) {
+ MatchOne const* f = (MatchOne const*)ObjSelector<kMatchOne_ID>::get(algo_list[i]);
+ usg.optionValueAcceptAdd("m", algo_list[i], f->description());
+ if (usg.import(f->usage()) == false)
+ throw -1;
}
- nlist = ObjSelector<kMatchAllsID>::names();
- for (size_t i = 0, I = nlist.size(); i < I; ++i) {
- TryAndChecks const* m;
- m = (TryAndChecks const*)ObjSelector<kTryAndChecks>::get(nlist[i]);
- usg.optionValueAcceptAdd("c", nlist[i], m->description());
- usg.import(m->usage());
+ algo_list = ObjSelector<kMatchChk_ID>::names();
+ for (size_t i = 0, I = algo_list.size(); i < I; ++i) {
+ MatchChk const* f = (MatchChk const*)ObjSelector<kMatchChk_ID>::get(algo_list[i]);
+ usg.optionValueAcceptAdd("c", algo_list[i], f->description());
+ if (usg.import(f->usage()) == false)
+ throw -1;
}
+}
+
+void setup(int argc, char** argv) {
std::string err;
bool ret = usg.arguments(argc, argv, &err);
if (usg.hasOptionSetup("h") || usg.hasOptionSetup("help")) {
fprintf(stderr, "%s\n", usg.usage().c_str());
- return 0;
+ throw 0;
}
if (ret == false) {
fprintf(stderr, "%s\n", err.c_str());
- return -1;
+ throw -2;
}
- return 1;
-}
-int getName() {
- if (usg.hasOptionSetup("i") == false) {
- names = usg.procArgs();
+ match_all = (MatchAll*)ObjSelector<kMatchAll_ID>::create(usg.optionValue("a", 0));
+ match_one = (MatchOne*)ObjSelector<kMatchOne_ID>::create(usg.optionValue("m", 0));
+ match_chk = (MatchChk*)ObjSelector<kMatchChk_ID>::create(usg.optionValue("c", 0));
+ if (match_all->usage(usg) == false) throw -3;
+ if (match_one->usage(usg) == false) throw -4;
+ if (match_chk->usage(usg) == false) throw -5;
+
+ if (usg.hasOptionSetup("i")) {
+ names = cgetFiles(usg.optionValue("i", 0).c_str(), usg.hasOptionSetup("r"),
+ 4, ".jpg", ".jpeg", ".JPG", ".JPEG");
}
else {
- std::string base = usg.optionValue("i", 0);
- if (base.length() == 0 || base[base.length() - 1] != '/') {
- base += "/";
- }
- DIR* dir = opendir(base.c_str());
- if (!dir) {
- fprintf(stderr, "can't open dir '%s'\n", base.c_str());
- return -1;
- }
- for (dirent* ent; (ent = readdir(dir)) != NULL; ) {
- if (!cstringEndWith(ent->d_name, 4, ".jpeg", ".jpg", ".JPG", ".JPEG")) {
- continue;
- }
- names.push_back(base + std::string(ent->d_name) + ".txt");
- }
+ names = usg.procArgs();
}
- fg.resize(names.size(), true);
- return 1;
+ std::sort(names.begin(), names.end(), filenameCompare);
+ out_pre = usg.optionValue("o", 0);
+}
+
+void end() {
+ delete match_all;
+ delete match_one;
+ delete match_chk;
}
-int readIn() {
- std::vector<std::string> nn(names);
- names.clear();
- for (int i = 0, I = nn.size(); i < I; ++i) {
- messagePrintf(1, "read '%s'", nn[i].c_str());
- FILE* f = fopen(nn[i].c_str(), "r");
+///////////////////////////////////////////////////////////
+
+Job* get(size_t counter) {
+ if (counter >= 1) return NULL;
+ Job* job = new Job;
+ for (size_t i = 0, I = names.size(); i < I; ++i) {
+ Job::Picture pic;
+ pic.fname = names[i];
+ job->pictures.push_back(pic);
+ }
+ return job;
+}
+
+///////////////////////////////////////////////////////////
+
+void input(Job* job) {
+ for (int i = 0, I = job->pictures.size(); i < I; ++i) {
+ bool ok = true;
+ std::string fname = job->pictures[i].fname + ".fps";
+ FILE* f = fopen(fname.c_str(), "r");
if (f == NULL) {
- messagePrintf(-1, "cannot open, ignore");
- continue;
+ printf("cannot open %s, ignore\n", fname.c_str());
+ ok = false;
}
- std::vector<FeaturePoint<double, double> > tmp;
- bool succ = true;
- int N = 0, M;
- if (fscanf(f, "%d %d", &N, &M) < 1) succ = false;
- if (succ) {
- tmp.resize(N);
- for (size_t i = 0; i < N; ++i) {
- if (tmp[i].read(f, false, 0) == false) {
- succ = false;
- break;
- }
- if ((int)tmp[i].description().diemnsion() != M) {
- succ = false;
- break;
- }
+ else {
+ size_t N;
+ if (fscanf(f, "%lu %lu %lu", &(job->pictures[i].width), &(job->pictures[i].height), &N) < 3)
+ ok = false;
+ for (size_t j = 0; ok && j < N; ++j) {
+ FeaturePoint<double, double, Vector2D<double> > fp;
+ if (fp.read(f, false, 0) == false)
+ ok = false;
+ job->pictures[i].features.push_back(fp);
}
+ fclose(f);
}
- fclose(f);
- if (succ) {
- names.push_back(nn[i]);
- fps .push_back(tmp);
- messagePrintf(-1, "ok");
- }
- else {
- messagePrintf(-1, "file format error");
+ if (!ok) {
+ if (i != I - 1)
+ std::swap(job->pictures[i], job->pictures[I - 1]);
+ --I;
+ --i;
+ printf("format error '%s'\n", fname.c_str());
}
+ else
+ printf("loaded %s\n", fname.c_str());
+ }
+ job->pairs .resize(job->pictures.size());
+ job->matches.resize(job->pictures.size());
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i) {
+ job->pairs [i].resize(job->pictures.size());
+ job->matches[i].resize(job->pictures.size());
}
- return fps.size();
}
-int match() {
- MatchAlls* algo = ObjSelector<kMatchAllsID>::create(usg.optionValeu("m", 0));
- if (algo->usage(usg) == false) {
- delete algo;
- messagePrintf(0, "usage error");
- return -1;
+void handle(Job* job) {
+ // match all
+ printf("match all\n");
+ std::vector<std::vector<FP> > fpss(job->pictures.size());
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
+ fpss[i] = job->pictures[i].features;
+ std::vector<PairToPair<size_t> > pps = match_all->match(fpss);
+ for (size_t i = 0, I = pps.size(); i < I; ++i) {
+ job->pairs[pps[i].from.first][pps[i].to.first].push_back(Pair(pps[i].from.second, pps[i].to.second));
}
- std::vector<PairToPair<size_t> > p = algo->match(fps);
- for (size_t i = 0, I = p.size(); i < I; ++i) {
- std::pair<size_t, size_t> pr(p[i].from.second, p[i].to.second);
- pairs[p[i].from.first][p[i].to.first].push_back(pr);
+ printf("pairs: \n");
+ for (size_t i = 0, I = job->pairs.size(); i < I; ++i, printf("\n")) {
+ for (size_t j = 0; j < I; ++j) {
+ printf("%3d ", (int)job->pairs[i][j].size());
+ }
}
- delete algo;
- return 1;
-}
-int check() {
- TryAndChecks*chk=ObjSelector<kTryAndChecksID>::create(usg.optionValue("c",0));
- for (size_t i = 0, I = names.size(); i < I; ++i) {
+ // match one
+ printf("match one\n");
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
+ for (size_t j = 0, J = job->pictures[i].features.size(); j < J; ++j)
+ job->pictures[i].fvs.push_back(job->pictures[i].features[j].position());
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
for (size_t j = 0; j < I; ++j) {
- match[i][j].pairs.clear();
- if (i != j && pairs[i][j].size() >= chk->minNumber()) {
- match[i][j] = chk->run(fps[i], width[i], height[i],
- fps[j], width[j], height[j],
- pairs[i][j]);
+ if (i == j)
+ continue;
+ job->matches[i][j] = match_one->match(job->pictures[i].fvs,
+ job->pictures[j].fvs,
+ job->pairs[i][j],
+ job->pictures[i].width,
+ job->pictures[i].height);
+ if (job->matches[i][j].ok) {
+ printf("ok for %3lu -- %3lu (%3d)\n", i, j, (int)job->matches[i][j].pairs.size());
}
}
- }
- delete chk;
- return 1;
-}
-
-Bitmap<RGBf_Space> readOne(std::string name) {
- Bitmap<RGBf_Space> ret;
- messagePrintf(1, "Loading image...");
- cv::Mat img = cv::imread(name, CV_LOAD_IMAGE_COLOR);
- if (img.data) {
- size_t height = img.size().height;
- size_t width = img.size().width ;
- ret.size(height, width, RGBf_Space(0));
- for (size_t y = 0; y < height; ++y) {
- for (size_t x = 0; x < width; ++x) {
- Vector3D<int> v;
- for (size_t i = 0; i < 3; ++i)
- v.scalar(i, img.at<cv::Vec3b>(y, x)[2 - i]);
- RGBf_Space p;
- colorTransformate(RGBi_Space(v), &p);
- ret.pixel(y, x, p);
+
+ // match_chk
+ printf("match check\n");
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
+ for (size_t j = 0; j < I; ++j) {
+ if (i == j || job->matches[i][j].ok == false)
+ continue;
+ job->matches[i][j].ok = match_chk->check(job->pictures[i].fvs,
+ job->pictures[i].width,
+ job->pictures[i].height,
+ job->pictures[j].fvs,
+ job->pictures[j].width,
+ job->pictures[j].height,
+ job->pairs[i][j],
+ job->matches[i][j]);
+ if (job->matches[i][j].ok == true) {
+ printf("accept %lu %lu (%lu)\n", i, j, job->matches[i][j].pairs.size());
+ }
+ }
+
+ // 整理
+ int ct = 0;
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
+ for (size_t j = 0; j < I; ++j) {
+ if (i == j || job->matches[i][j].ok == false)
+ continue;
+ for (size_t k = 0; k < job->matches[i][j].pairs.size(); ++k) {
+ job->pictures[i].fps.pointAdd(ct, job->pictures[i].fvs[job->matches[i][j].pairs[k].first ]);
+ job->pictures[j].fps.pointAdd(ct, job->pictures[j].fvs[job->matches[i][j].pairs[k].second]);
+ ct++;
}
}
- }
- messagePrintf(-1, (ret.size() > 0 ? "ok" : "fail"));
- return ret;
}
-int writeBmpOne(std::string name, Bitmap<RGBf_Space> const& bmp) {
- size_t height = bmp.height();
- size_t width = bmp.width ();
- messagePrintf(1, "write to image '%s' (%lu x %lu)",
- name.c_str(), height, width);
- cv::Mat img(height, width, CV_8UC3);
- for (size_t y = 0; y < height; y++) {
- for (size_t x = 0; x < width; x++) {
- RGBi_Space tmp;
- colorTransformate(bmp.pixel(y, x), &tmp);
- for (size_t i = 0; i < 3; ++i)
- img.at<cv::Vec3b>(y, x)[i] = tmp.rgb(2 - i);
- }
+void output(Job *job) {
+ printf("output...\n");
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i) {
+ FILE* f = fopen((job->pictures[i].fname + ".fp2ds").c_str(), "w");
+ job->pictures[i].fps.write(f, false, 0);
+ fclose(f);
}
- if (imwrite(name, img) == false) {
- messagePrintf(-1, "fail");
- return -1;
+ if (out_pre.size() > 0) {
+ printf("output pictures\n");
+ int ct = 0;
+ for (size_t i = 0, I = job->pictures.size(); i < I; ++i)
+ for (size_t j = 0; j < I; ++j) {
+ if (i == j || job->matches[i][j].ok == false) continue;
+ Bitmap<RGBf_Space> bmp1, bmp2;
+ if (readBitmap(job->pictures[i].fname, &bmp1) == false) continue;
+ if (readBitmap(job->pictures[j].fname, &bmp2) == false) continue;
+ Bitmap<RGBf_Space> out(bmp2);
+ Bitmap<double> sum(bmp2.height(), bmp2.width(), 1.0);
+ Matrix<double> m(3, 3, 0.0);
+ m.entry(0, 0, job->matches[i][j].x_axis.scalar(0));
+ m.entry(0, 1, job->matches[i][j].x_axis.scalar(1));
+ m.entry(0, 2, job->matches[i][j].x_offset);
+ m.entry(1, 0, job->matches[i][j].y_axis.scalar(0));
+ m.entry(1, 1, job->matches[i][j].y_axis.scalar(1));
+ m.entry(1, 2, job->matches[i][j].y_offset);
+ m.entry(2, 0, job->matches[i][j].depth(0));
+ m.entry(2, 1, job->matches[i][j].depth(1));
+ m.entry(2, 2, 1);
+ m.inversed();
+ for (size_t y = 0, Y = bmp1.height(); y < Y; ++y)
+ for (size_t x = 0, X = bmp1.width(); x < X; ++x) {
+ RGBf_Space tmp(bmp1.pixel(y, x));
+ tmp.b(0);
+ tmp.r(0);
+ bmp1.pixel(y, x, tmp);
+ }
+ for (size_t y = 0, Y = bmp2.height(); y < Y; ++y)
+ for (size_t x = 0, X = bmp2.width(); x < X; ++x) {
+ Vector3D<double> v2(x, y, 1.0), v1(m * v2.matrix());
+ int x1 = v1(0) / v1(2);
+ int y1 = v1(1) / v1(2);
+ if (x1 < 0 || (int)bmp1.width() <= x1 || y1 < 0 || (int)bmp1.height() <= y1) continue;
+ sum.pixel(y, x, sum.pixel(y, x) + 1);
+ out.pixel(y, x, out.pixel(y, x) + bmp1.pixel(y1, x1));
+ }
+ for (size_t y = 0, Y = out.height(); y < Y; ++y)
+ for (size_t x = 0, X = out.width(); x < X; ++x)
+ out.pixel(y, x, out.pixel(y, x) / sum.pixel(y, x));
+ int w = std::min(out.height() , out.width()) / 32;
+ for (size_t k = 0, K = job->matches[i][j].pairs.size(); k < K; ++k) {
+ int id_j = job->matches[i][j].pairs[k].second;
+ int x0 = job->pictures[j].fvs[id_j].x();
+ int y0 = job->pictures[j].fvs[id_j].y();
+ for (int d = -w; d <= w; ++d) {
+ if (0 <= x0 + d && x0 + d < (int)out.width ()) out.pixel(y0, x0 + d, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
+ if (0 <= y0 + d && y0 + d < (int)out.height()) out.pixel(y0 + d, x0, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
+ }
+ }
+ for (size_t k = 0, K = job->pictures[i].fvs.size(); k < K; ++k) {
+ Vector2D<double> v_tr(
+ (job->pictures[i].fvs[k].dot(job->matches[i][j].x_axis) + job->matches[i][j].x_offset) / (job->pictures[i].fvs[k].dot(job->matches[i][j].depth) + 1),
+ (job->pictures[i].fvs[k].dot(job->matches[i][j].y_axis) + job->matches[i][j].y_offset) / (job->pictures[i].fvs[k].dot(job->matches[i][j].depth) + 1)
+ );
+ if (v_tr.x() < 0 || out.width () <= v_tr.x()) continue;
+ if (v_tr.y() < 0 || out.height() <= v_tr.y()) continue;
+ for (size_t l = 0, L = job->pairs[i][j].size(); l < L; ++l) {
+ if (job->pairs[i][j][l].first == k) {
+ Vector2D<double> v2(job->pictures[j].fvs[job->pairs[i][j][l].second]);
+ Vector2D<double> delta(v2 - v_tr);
+ for (int z = 0, Z = delta.length(); z <= Z; ++z) {
+ Vector2D<double> v(v_tr + delta * (double)z / (double)Z);
+ if (v.x() < 0 || out.width () <= v.x()) continue;
+ if (v.y() < 0 || out.height() <= v.y()) continue;
+ out.pixel(v.y(), v.x(), RGBf_Space(Vector3D<double>(0.0, 0.0, 1.0 * (Z - z) / Z)));
+ }
+ }
+ }
+ }
+ writeBitmap(stringPrintf("%s%d.jpg", out_pre.c_str(), ct), out);
+ printf("write to bmp '%s%d.jpg'\n", out_pre.c_str(), ct);
+ ct++;
+ }
}
- messagePrintf(-1, "ok");
- return 1;
}
-int writeBmp(size_t id) {
- if (usg.hasOptionSetup("o") == false)
- return 1;
- std::string name2;
- name2 = stringPrintf("%s%lu.jpg", usg.optionValue("o", 0).c_str(), id);
- messagePrintf(1, "Write img file to '%s'", name2.c_str());
- Bitmap<RGBf_Space> bmp(readOne(names[id]));
- bool succ;
- if ((succ = (bmp.size() > 0))) {
- int wh = std::min(bmp.height(), bmp.width()) / 32;
- for (size_t j = 0, J = fps[id].size(); j < J; ++j) {
- int x0 = fps[id][j].position()(0);
- int y0 = fps[id][j].position()(1);
- for (int dx = -wh; dx <= wh; ++dx)
- if (0 <= x0 + dx && x0 + dx < (int)bmp.width())
- bmp.pixel(y0, x0 + dx, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
- for (int dy = -wh; dy <= wh; ++dy)
- if (0 <= y0 + dy && y0 + dy < (int)bmp.height())
- bmp.pixel(y0 + dy, x0, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
- }
- succ = (writeBmpOne(name2, bmp) > 0);
- }
- messagePrintf(-1, succ ? "ok" : "fail");
- return 1;
+void clear(Job *job) {
+ delete job;
}
-int writeOne(FILE* f, size_t i) {
- if (fprintf(f, "%d\n", (int)fps[i].size()) < 1) return -1;
- for (size_t j = 0, J = fps[i].size(); j < J; ++j) {
- if (fps[i][j].write(f, false, 0) == false) return -1;
- }
- return 1;
+void info0(Job* job) {
}
-int writeText() {
- for(size_t i = 0, I = fps.size(); i < I; ++i) {
- if (!fg[i]) continue;
- std::string name2;
- if (usg.hasOptionSetup("f")) { name2 = usg.optionValue("f", i); }
- else { name2 = names[i] + ".txt"; }
- messagePrintf(1, "Write text file to '%s'", name2.c_str());
- FILE* f = fopen(name2.c_str(), "w");
- if (f == NULL) {
- messagePrintf(-1, "fail to open file!, ignore");
- continue;
- }
- if (writeOne(f, i) < 0) {
- messagePrintf(-1, "write fail");
- fclose(f);
- continue;
- }
- fclose(f);
- messagePrintf(-1, "ok");
- }
- return 1;
+void info1(Job* job) {
}
-int main(int argc, char** argv) {
- int ret;
- if ((ret = setup(argc, argv)) <= 0) return ret;
- if ((ret = getName()) <= 0) return ret;
- if ((ret = readIn()) <= 0) return ret;
- if ((ret = match()) <= 0) return ret;
- if ((ret = check()) <= 0) return ret;
- if ((ret = writeText()) <= 0) return ret;
- if ((ret = writeBmp()) <= 0) return ret;
- return 0;
+void info2(Job* job) {
}
-
-
-