75 lines
3.6 KiB
Plaintext
75 lines
3.6 KiB
Plaintext
// Downloads the files models.config names into models/, checking each one's SHA-256. The models
|
|
// are not in git; run this after cloning. Files already there with the right hash are skipped.
|
|
//
|
|
// jai fetch_models.jai every model
|
|
// jai fetch_models.jai - mobile only the files ppocr-v5-mobile needs (about 22 MB)
|
|
//
|
|
// From RapidOCR's conversions of PaddleOCR's PP-OCRv5 (both Apache 2.0):
|
|
// https://www.modelscope.cn/models/RapidAI/RapidOCR
|
|
|
|
SOURCE :: "https://www.modelscope.cn/models/RapidAI/RapidOCR/resolve/master";
|
|
|
|
Model_File :: struct { name: string; source_path: string; sha256: string; server: bool; }
|
|
|
|
FILES :: Model_File.[
|
|
.{"ch_PP-OCRv5_det_mobile.onnx", "onnx/PP-OCRv5/det/ch_PP-OCRv5_det_mobile.onnx", "4d97c44a20d30a81aad087d6a396b08f786c4635742afc391f6621f5c6ae78ae", false},
|
|
.{"ch_PP-OCRv5_rec_mobile.onnx", "onnx/PP-OCRv5/rec/ch_PP-OCRv5_rec_mobile.onnx", "5825fc7ebf84ae7a412be049820b4d86d77620f204a041697b0494669b1742c5", false},
|
|
.{"ppocrv5_dict.txt", "paddle/PP-OCRv5/rec/ch_PP-OCRv5_rec_mobile/ppocrv5_dict.txt", "d1979e9f794c464c0d2e0b70a7fe14dd978e9dc644c0e71f14158cdf8342af1b", false},
|
|
.{"ch_PP-LCNet_x0_25_textline_ori_cls_mobile.onnx", "onnx/PP-OCRv5/cls/ch_PP-LCNet_x0_25_textline_ori_cls_mobile.onnx", "54379ae5174d026780215fc748a7f31910dee36818e63d49e17dc598ecc82df7", false},
|
|
.{"ch_PP-OCRv5_det_server.onnx", "onnx/PP-OCRv5/det/ch_PP-OCRv5_det_server.onnx", "0f8846b1d4bba223a2a2f9d9b44022fbc22cc019051a602b41a7fda9667e4cad", true},
|
|
.{"ch_PP-OCRv5_rec_server.onnx", "onnx/PP-OCRv5/rec/ch_PP-OCRv5_rec_server.onnx", "e09385400eaaaef34ceff54aeb7c4f0f1fe014c27fa8b9905d4709b65746562a", true},
|
|
];
|
|
|
|
#run,stallable { if !fetch() exit(1); }
|
|
|
|
fetch :: () -> bool {
|
|
set_build_options_dc(.{do_output = false});
|
|
mobile_only := array_find(get_build_options().compile_time_command_line, "mobile");
|
|
|
|
here := trim_right(path_strip_filename(#file), "/\\");
|
|
folder := tprint("%/models", here);
|
|
make_directory_if_it_does_not_exist(folder);
|
|
|
|
for FILES {
|
|
if mobile_only && it.server continue;
|
|
path := tprint("%/%", folder, it.name);
|
|
if file_exists(path) && sha256_of(path) == it.sha256 { log("% is already here.", it.name); continue; }
|
|
|
|
url := tprint("%/%", SOURCE, it.source_path);
|
|
log("Downloading %...", url);
|
|
result := run_command("curl", "-L", "--fail", "--progress-bar", "-o", path, url);
|
|
if result.exit_code != 0 { log_error("curl failed for % (exit code %).", it.name, result.exit_code); return false; }
|
|
hash := sha256_of(path);
|
|
if hash != it.sha256 {
|
|
log_error("% has SHA-256 %, expected %; it was deleted.", it.name, hash, it.sha256);
|
|
file_delete(path);
|
|
return false;
|
|
}
|
|
}
|
|
log("The models are in %.", folder);
|
|
return true;
|
|
}
|
|
|
|
// Lowercase hex, or "" when it could not be worked out.
|
|
sha256_of :: (path: string) -> string {
|
|
#if OS == .WINDOWS {
|
|
result, output := run_command("certutil", "-hashfile", path, "SHA256", capture_and_return_output = true);
|
|
if result.exit_code != 0 return "";
|
|
lines := split(output, "\n");
|
|
if lines.count < 2 return "";
|
|
return to_lower_copy(replace(trim(lines[1]), " ", "")); // line 2 is the hash
|
|
} else {
|
|
command := ifx OS == .MACOS then string.["shasum", "-a", "256", path] else string.["sha256sum", path];
|
|
result, output := run_command(..command, capture_and_return_output = true);
|
|
if result.exit_code != 0 return "";
|
|
return to_lower_copy(trim(split(output, " ")[0]));
|
|
}
|
|
}
|
|
|
|
#import "Basic";
|
|
#import "Compiler";
|
|
#import "File";
|
|
#import "File_Utilities";
|
|
#import "Process";
|
|
#import "String";
|