.png-errors.txt000064400000105030150211530670007460 0ustar002020-05-31 01:46:01: empty string!!!2020-05-31 01:46:17: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:52:58: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:53:46: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 01:55:25: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:10:51: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:11:22: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:12:03: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:39:59: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:42:29: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:00: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:43:48: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:47:57: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:33: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:53:46: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!2020-05-31 02:56:19: empty string!!!phpqrcode.php000064400000347443150211530670007261 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Version: 1.1.4 * Build: 2010100721 */ //---- qrconst.php ----------------------------- /* * PHP QR Code encoder * * Common constants * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // Encoding modes define('QR_MODE_NUL', -1); define('QR_MODE_NUM', 0); define('QR_MODE_AN', 1); define('QR_MODE_8', 2); define('QR_MODE_KANJI', 3); define('QR_MODE_STRUCTURE', 4); // Levels of error correction. define('QR_ECLEVEL_L', 0); define('QR_ECLEVEL_M', 1); define('QR_ECLEVEL_Q', 2); define('QR_ECLEVEL_H', 3); // Supported output formats define('QR_FORMAT_TEXT', 0); define('QR_FORMAT_PNG', 1); class qrstr { public static function set(&$srctab, $x, $y, $repl, $replLen = false) { $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); } } //---- merged_config.php ----------------------------- /* * PHP QR Code encoder * * Config file, tuned-up for merged verion */ define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true define('QR_LOG_DIR', false); // default error logs dir define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code define('QR_FIND_FROM_RANDOM', 2); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images //---- qrtools.php ----------------------------- /* * PHP QR Code encoder * * Toolset, handy and debug utilites. * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRtools { //---------------------------------------------------------------------- public static function binarize($frame) { $len = count($frame); foreach ($frame as &$frameLine) { for($i=0; $i<$len; $i++) { $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; } } return $frame; } //---------------------------------------------------------------------- public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037') { $barcode_array = array(); if (!is_array($mode)) $mode = explode(',', $mode); $eccLevel = 'L'; if (count($mode) > 1) { $eccLevel = $mode[1]; } $qrTab = QRcode::text($code, false, $eccLevel); $size = count($qrTab); $barcode_array['num_rows'] = $size; $barcode_array['num_cols'] = $size; $barcode_array['bcode'] = array(); foreach ($qrTab as $line) { $arrAdd = array(); foreach(str_split($line) as $char) $arrAdd[] = ($char=='1')?1:0; $barcode_array['bcode'][] = $arrAdd; } return $barcode_array; } //---------------------------------------------------------------------- public static function clearCache() { self::$frames = array(); } //---------------------------------------------------------------------- public static function buildCache() { QRtools::markTime('before_build_cache'); $mask = new QRmask(); for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) { $frame = QRspec::newFrame($a); if (QR_IMAGE) { $fileName = QR_CACHE_DIR.'frame_'.$a.'.png'; QRimage::png(self::binarize($frame), $fileName, 1, 0); } $width = count($frame); $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($maskNo=0; $maskNo<8; $maskNo++) $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); } QRtools::markTime('after_build_cache'); } //---------------------------------------------------------------------- public static function log($outfile, $err) { if (QR_LOG_DIR !== false) { if ($err != '') { if ($outfile !== false) { file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); } else { file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); } } } } //---------------------------------------------------------------------- public static function dumpMask($frame) { $width = count($frame); for($y=0;$y<$width;$y++) { for($x=0;$x<$width;$x++) { echo ord($frame[$y][$x]).','; } } } //---------------------------------------------------------------------- public static function markTime($markerId) { list($usec, $sec) = explode(" ", microtime()); $time = ((float)$usec + (float)$sec); if (!isset($GLOBALS['qr_time_bench'])) $GLOBALS['qr_time_bench'] = array(); $GLOBALS['qr_time_bench'][$markerId] = $time; } //---------------------------------------------------------------------- public static function timeBenchmark() { self::markTime('finish'); $lastTime = 0; $startTime = 0; $p = 0; echo ''; foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) { if ($p > 0) { echo ''; } else { $startTime = $thisTime; } $p++; $lastTime = $thisTime; } echo '
BENCHMARK
till '.$markerId.': '.number_format($thisTime-$lastTime, 6).'s
TOTAL: '.number_format($lastTime-$startTime, 6).'s
'; } } //########################################################################## QRtools::markTime('start'); //---- qrspec.php ----------------------------- /* * PHP QR Code encoder * * QR Code specifications * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * The following data / specifications are taken from * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) * or * "Automatic identification and data capture techniques -- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('QRSPEC_VERSION_MAX', 40); define('QRSPEC_WIDTH_MAX', 177); define('QRCAP_WIDTH', 0); define('QRCAP_WORDS', 1); define('QRCAP_REMINDER', 2); define('QRCAP_EC', 3); class QRspec { public static $capacity = array( array( 0, 0, 0, array( 0, 0, 0, 0)), array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 array( 25, 44, 7, array( 10, 16, 22, 28)), array( 29, 70, 7, array( 15, 26, 36, 44)), array( 33, 100, 7, array( 20, 36, 52, 64)), array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 array( 41, 172, 7, array( 36, 64, 96, 112)), array( 45, 196, 0, array( 40, 72, 108, 130)), array( 49, 242, 0, array( 48, 88, 132, 156)), array( 53, 292, 0, array( 60, 110, 160, 192)), array( 57, 346, 0, array( 72, 130, 192, 224)), //10 array( 61, 404, 0, array( 80, 150, 224, 264)), array( 65, 466, 0, array( 96, 176, 260, 308)), array( 69, 532, 0, array( 104, 198, 288, 352)), array( 73, 581, 3, array( 120, 216, 320, 384)), array( 77, 655, 3, array( 132, 240, 360, 432)), //15 array( 81, 733, 3, array( 144, 280, 408, 480)), array( 85, 815, 3, array( 168, 308, 448, 532)), array( 89, 901, 3, array( 180, 338, 504, 588)), array( 93, 991, 3, array( 196, 364, 546, 650)), array( 97, 1085, 3, array( 224, 416, 600, 700)), //20 array(101, 1156, 4, array( 224, 442, 644, 750)), array(105, 1258, 4, array( 252, 476, 690, 816)), array(109, 1364, 4, array( 270, 504, 750, 900)), array(113, 1474, 4, array( 300, 560, 810, 960)), array(117, 1588, 4, array( 312, 588, 870, 1050)), //25 array(121, 1706, 4, array( 336, 644, 952, 1110)), array(125, 1828, 4, array( 360, 700, 1020, 1200)), array(129, 1921, 3, array( 390, 728, 1050, 1260)), array(133, 2051, 3, array( 420, 784, 1140, 1350)), array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30 array(141, 2323, 3, array( 480, 868, 1290, 1530)), array(145, 2465, 3, array( 510, 924, 1350, 1620)), array(149, 2611, 3, array( 540, 980, 1440, 1710)), array(153, 2761, 3, array( 570, 1036, 1530, 1800)), array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35 array(161, 3034, 0, array( 600, 1120, 1680, 1980)), array(165, 3196, 0, array( 630, 1204, 1770, 2100)), array(169, 3362, 0, array( 660, 1260, 1860, 2220)), array(173, 3532, 0, array( 720, 1316, 1950, 2310)), array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40 ); //---------------------------------------------------------------------- public static function getDataLength($version, $level) { return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level]; } //---------------------------------------------------------------------- public static function getECCLength($version, $level) { return self::$capacity[$version][QRCAP_EC][$level]; } //---------------------------------------------------------------------- public static function getWidth($version) { return self::$capacity[$version][QRCAP_WIDTH]; } //---------------------------------------------------------------------- public static function getRemainder($version) { return self::$capacity[$version][QRCAP_REMINDER]; } //---------------------------------------------------------------------- public static function getMinimumVersion($size, $level) { for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) { $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level]; if($words >= $size) return $i; } return -1; } //###################################################################### public static $lengthTableBits = array( array(10, 12, 14), array( 9, 11, 13), array( 8, 16, 16), array( 8, 10, 12) ); //---------------------------------------------------------------------- public static function lengthIndicator($mode, $version) { if ($mode == QR_MODE_STRUCTURE) return 0; if ($version <= 9) { $l = 0; } else if ($version <= 26) { $l = 1; } else { $l = 2; } return self::$lengthTableBits[$mode][$l]; } //---------------------------------------------------------------------- public static function maximumWords($mode, $version) { if($mode == QR_MODE_STRUCTURE) return 3; if($version <= 9) { $l = 0; } else if($version <= 26) { $l = 1; } else { $l = 2; } $bits = self::$lengthTableBits[$mode][$l]; $words = (1 << $bits) - 1; if($mode == QR_MODE_KANJI) { $words *= 2; // the number of bytes is required } return $words; } // Error correction code ----------------------------------------------- // Table of the error correction code (Reed-Solomon block) // See Table 12-16 (pp.30-36), JIS X0510:2004. public static $eccTable = array( array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40 ); //---------------------------------------------------------------------- // CACHEABLE!!! public static function getEccSpec($version, $level, array &$spec) { if (count($spec) < 5) { $spec = array(0,0,0,0,0); } $b1 = self::$eccTable[$version][$level][0]; $b2 = self::$eccTable[$version][$level][1]; $data = self::getDataLength($version, $level); $ecc = self::getECCLength($version, $level); if($b2 == 0) { $spec[0] = $b1; $spec[1] = (int)($data / $b1); $spec[2] = (int)($ecc / $b1); $spec[3] = 0; $spec[4] = 0; } else { $spec[0] = $b1; $spec[1] = (int)($data / ($b1 + $b2)); $spec[2] = (int)($ecc / ($b1 + $b2)); $spec[3] = $b2; $spec[4] = $spec[1] + 1; } } // Alignment pattern --------------------------------------------------- // Positions of alignment patterns. // This array includes only the second and the third position of the // alignment patterns. Rest of them can be calculated from the distance // between them. // See Table 1 in Appendix E (pp.71) of JIS X0510:2004. public static $alignmentPattern = array( array( 0, 0), array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40 ); /** -------------------------------------------------------------------- * Put an alignment marker. * @param frame * @param width * @param ox,oy center coordinate of the pattern */ public static function putAlignmentMarker(array &$frame, $ox, $oy) { $finder = array( "\xa1\xa1\xa1\xa1\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa0\xa1\xa0\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa1\xa1\xa1\xa1" ); $yStart = $oy-2; $xStart = $ox-2; for($y=0; $y<5; $y++) { QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]); } } //---------------------------------------------------------------------- public static function putAlignmentPattern($version, &$frame, $width) { if($version < 2) return; $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0]; if($d < 0) { $w = 2; } else { $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2); } if($w * $w - 3 == 1) { $x = self::$alignmentPattern[$version][0]; $y = self::$alignmentPattern[$version][0]; self::putAlignmentMarker($frame, $x, $y); return; } $cx = self::$alignmentPattern[$version][0]; for($x=1; $x<$w - 1; $x++) { self::putAlignmentMarker($frame, 6, $cx); self::putAlignmentMarker($frame, $cx, 6); $cx += $d; } $cy = self::$alignmentPattern[$version][0]; for($y=0; $y<$w-1; $y++) { $cx = self::$alignmentPattern[$version][0]; for($x=0; $x<$w-1; $x++) { self::putAlignmentMarker($frame, $cx, $cy); $cx += $d; } $cy += $d; } } // Version information pattern ----------------------------------------- // Version information pattern (BCH coded). // See Table 1 in Appendix D (pp.68) of JIS X0510:2004. // size: [QRSPEC_VERSION_MAX - 6] public static $versionPattern = array( 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, 0x27541, 0x28c69 ); //---------------------------------------------------------------------- public static function getVersionPattern($version) { if($version < 7 || $version > QRSPEC_VERSION_MAX) return 0; return self::$versionPattern[$version -7]; } // Format information -------------------------------------------------- // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib) public static $formatInfo = array( array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) ); public static function getFormatInfo($mask, $level) { if($mask < 0 || $mask > 7) return 0; if($level < 0 || $level > 3) return 0; return self::$formatInfo[$level][$mask]; } // Frame --------------------------------------------------------------- // Cache of initial frames. public static $frames = array(); /** -------------------------------------------------------------------- * Put a finder pattern. * @param frame * @param width * @param ox,oy upper-left coordinate of the pattern */ public static function putFinderPattern(&$frame, $ox, $oy) { $finder = array( "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" ); for($y=0; $y<7; $y++) { QRstr::set($frame, $ox, $oy+$y, $finder[$y]); } } //---------------------------------------------------------------------- public static function createFrame($version) { $width = self::$capacity[$version][QRCAP_WIDTH]; $frameLine = str_repeat ("\0", $width); $frame = array_fill(0, $width, $frameLine); // Finder pattern self::putFinderPattern($frame, 0, 0); self::putFinderPattern($frame, $width - 7, 0); self::putFinderPattern($frame, 0, $width - 7); // Separator $yOffset = $width - 7; for($y=0; $y<7; $y++) { $frame[$y][7] = "\xc0"; $frame[$y][$width - 8] = "\xc0"; $frame[$yOffset][7] = "\xc0"; $yOffset++; } $setPattern = str_repeat("\xc0", 8); QRstr::set($frame, 0, 7, $setPattern); QRstr::set($frame, $width-8, 7, $setPattern); QRstr::set($frame, 0, $width - 8, $setPattern); // Format info $setPattern = str_repeat("\x84", 9); QRstr::set($frame, 0, 8, $setPattern); QRstr::set($frame, $width - 8, 8, $setPattern, 8); $yOffset = $width - 8; for($y=0; $y<8; $y++,$yOffset++) { $frame[$y][8] = "\x84"; $frame[$yOffset][8] = "\x84"; } // Timing pattern for($i=1; $i<$width-15; $i++) { $frame[6][7+$i] = chr(0x90 | ($i & 1)); $frame[7+$i][6] = chr(0x90 | ($i & 1)); } // Alignment pattern self::putAlignmentPattern($version, $frame, $width); // Version information if($version >= 7) { $vinf = self::getVersionPattern($version); $v = $vinf; for($x=0; $x<6; $x++) { for($y=0; $y<3; $y++) { $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } $v = $vinf; for($y=0; $y<6; $y++) { for($x=0; $x<3; $x++) { $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } } // and a little bit... $frame[$width - 8][8] = "\x81"; return $frame; } //---------------------------------------------------------------------- public static function debug($frame, $binary_mode = false) { if ($binary_mode) { foreach ($frame as &$frameLine) { $frameLine = join('  ', explode('0', $frameLine)); $frameLine = join('██', explode('1', $frameLine)); } ?>


        '; echo join("
        ", $frame); echo '






'; } else { foreach ($frame as &$frameLine) { $frameLine = join(' ', explode("\xc0", $frameLine)); $frameLine = join('', explode("\xc1", $frameLine)); $frameLine = join(' ', explode("\xa0", $frameLine)); $frameLine = join('', explode("\xa1", $frameLine)); $frameLine = join('', explode("\x84", $frameLine)); //format 0 $frameLine = join('', explode("\x85", $frameLine)); //format 1 $frameLine = join('', explode("\x81", $frameLine)); //special bit $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0 $frameLine = join('', explode("\x91", $frameLine)); //clock 1 $frameLine = join(' ', explode("\x88", $frameLine)); //version $frameLine = join('', explode("\x89", $frameLine)); //version $frameLine = join('♦', explode("\x01", $frameLine)); $frameLine = join('⋅', explode("\0", $frameLine)); } ?> "; echo join("
", $frame); echo "
"; } } //---------------------------------------------------------------------- public static function serial($frame) { return gzcompress(join("\n", $frame), 9); } //---------------------------------------------------------------------- public static function unserial($code) { return explode("\n", gzuncompress($code)); } //---------------------------------------------------------------------- public static function newFrame($version) { if($version < 1 || $version > QRSPEC_VERSION_MAX) return null; if(!isset(self::$frames[$version])) { $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat'; if (QR_CACHEABLE) { if (file_exists($fileName)) { self::$frames[$version] = self::unserial(file_get_contents($fileName)); } else { self::$frames[$version] = self::createFrame($version); file_put_contents($fileName, self::serial(self::$frames[$version])); } } else { self::$frames[$version] = self::createFrame($version); } } if(is_null(self::$frames[$version])) return null; return self::$frames[$version]; } //---------------------------------------------------------------------- public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; } public static function rsBlockNum1($spec) { return $spec[0]; } public static function rsDataCodes1($spec) { return $spec[1]; } public static function rsEccCodes1($spec) { return $spec[2]; } public static function rsBlockNum2($spec) { return $spec[3]; } public static function rsDataCodes2($spec) { return $spec[4]; } public static function rsEccCodes2($spec) { return $spec[2]; } public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } } //---- qrimage.php ----------------------------- /* * PHP QR Code encoder * * Image output of code using GD2 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('QR_IMAGE', true); class QRimage { //---------------------------------------------------------------------- public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) { $image = self::image($frame, $pixelPerPoint, $outerFrame); if ($filename === false) { Header("Content-type: image/png"); ImagePng($image); } else { if($saveandprint===TRUE){ ImagePng($image, $filename); header("Content-type: image/png"); ImagePng($image); }else{ ImagePng($image, $filename); } } ImageDestroy($image); } //---------------------------------------------------------------------- public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) { $image = self::image($frame, $pixelPerPoint, $outerFrame); if ($filename === false) { Header("Content-type: image/jpeg"); ImageJpeg($image, null, $q); } else { ImageJpeg($image, $filename, $q); } ImageDestroy($image); } //---------------------------------------------------------------------- private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) { $h = count($frame); $w = strlen($frame[0]); $imgW = $w + 2*$outerFrame; $imgH = $h + 2*$outerFrame; $base_image =ImageCreate($imgW, $imgH); $col[0] = ImageColorAllocate($base_image,255,255,255); $col[1] = ImageColorAllocate($base_image,0,0,0); imagefill($base_image, 0, 0, $col[0]); for($y=0; $y<$h; $y++) { for($x=0; $x<$w; $x++) { if ($frame[$y][$x] == '1') { ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); } } } $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint); ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH); ImageDestroy($base_image); return $target_image; } } //---- qrinput.php ----------------------------- /* * PHP QR Code encoder * * Input encoding class * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('STRUCTURE_HEADER_BITS', 20); define('MAX_STRUCTURED_SYMBOLS', 16); class QRinputItem { public $mode; public $size; public $data; public $bstream; public function __construct($mode, $size, $data, $bstream = null) { $setData = array_slice($data, 0, $size); if (count($setData) < $size) { $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); } if(!QRinput::check($mode, $size, $setData)) { throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); return null; } $this->mode = $mode; $this->size = $size; $this->data = $setData; $this->bstream = $bstream; } //---------------------------------------------------------------------- public function encodeModeNum($version) { try { $words = (int)($this->size / 3); $bs = new QRbitstream(); $val = 0x1; $bs->appendNum(4, $val); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size); for($i=0; $i<$words; $i++) { $val = (ord($this->data[$i*3 ]) - ord('0')) * 100; $val += (ord($this->data[$i*3+1]) - ord('0')) * 10; $val += (ord($this->data[$i*3+2]) - ord('0')); $bs->appendNum(10, $val); } if($this->size - $words * 3 == 1) { $val = ord($this->data[$words*3]) - ord('0'); $bs->appendNum(4, $val); } else if($this->size - $words * 3 == 2) { $val = (ord($this->data[$words*3 ]) - ord('0')) * 10; $val += (ord($this->data[$words*3+1]) - ord('0')); $bs->appendNum(7, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeAn($version) { try { $words = (int)($this->size / 2); $bs = new QRbitstream(); $bs->appendNum(4, 0x02); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size); for($i=0; $i<$words; $i++) { $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45; $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1])); $bs->appendNum(11, $val); } if($this->size & 1) { $val = QRinput::lookAnTable(ord($this->data[$words * 2])); $bs->appendNum(6, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeMode8($version) { try { $bs = new QRbitstream(); $bs->appendNum(4, 0x4); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size); for($i=0; $i<$this->size; $i++) { $bs->appendNum(8, ord($this->data[$i])); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeKanji($version) { try { $bs = new QRbitrtream(); $bs->appendNum(4, 0x8); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2)); for($i=0; $i<$this->size; $i+=2) { $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]); if($val <= 0x9ffc) { $val -= 0x8140; } else { $val -= 0xc140; } $h = ($val >> 8) * 0xc0; $val = ($val & 0xff) + $h; $bs->appendNum(13, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeStructure() { try { $bs = new QRbitstream(); $bs->appendNum(4, 0x03); $bs->appendNum(4, ord($this->data[1]) - 1); $bs->appendNum(4, ord($this->data[0]) - 1); $bs->appendNum(8, ord($this->data[2])); $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function estimateBitStreamSizeOfEntry($version) { $bits = 0; if($version == 0) $version = 1; switch($this->mode) { case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break; case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break; case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break; case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break; case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS; default: return 0; } $l = QRspec::lengthIndicator($this->mode, $version); $m = 1 << $l; $num = (int)(($this->size + $m - 1) / $m); $bits += $num * (4 + $l); return $bits; } //---------------------------------------------------------------------- public function encodeBitStream($version) { try { unset($this->bstream); $words = QRspec::maximumWords($this->mode, $version); if($this->size > $words) { $st1 = new QRinputItem($this->mode, $words, $this->data); $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); $st1->encodeBitStream($version); $st2->encodeBitStream($version); $this->bstream = new QRbitstream(); $this->bstream->append($st1->bstream); $this->bstream->append($st2->bstream); unset($st1); unset($st2); } else { $ret = 0; switch($this->mode) { case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; case QR_MODE_8: $ret = $this->encodeMode8($version); break; case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break; case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; default: break; } if($ret < 0) return -1; } return $this->bstream->size(); } catch (Exception $e) { return -1; } } }; //########################################################################## class QRinput { public $items; private $version; private $level; //---------------------------------------------------------------------- public function __construct($version = 0, $level = QR_ECLEVEL_L) { if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) { throw new Exception('Invalid version no'); return NULL; } $this->version = $version; $this->level = $level; } //---------------------------------------------------------------------- public function getVersion() { return $this->version; } //---------------------------------------------------------------------- public function setVersion($version) { if($version < 0 || $version > QRSPEC_VERSION_MAX) { throw new Exception('Invalid version no'); return -1; } $this->version = $version; return 0; } //---------------------------------------------------------------------- public function getErrorCorrectionLevel() { return $this->level; } //---------------------------------------------------------------------- public function setErrorCorrectionLevel($level) { if($level > QR_ECLEVEL_H) { throw new Exception('Invalid ECLEVEL'); return -1; } $this->level = $level; return 0; } //---------------------------------------------------------------------- public function appendEntry(QRinputItem $entry) { $this->items[] = $entry; } //---------------------------------------------------------------------- public function append($mode, $size, $data) { try { $entry = new QRinputItem($mode, $size, $data); $this->items[] = $entry; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function insertStructuredAppendHeader($size, $index, $parity) { if( $size > MAX_STRUCTURED_SYMBOLS ) { throw new Exception('insertStructuredAppendHeader wrong size'); } if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) { throw new Exception('insertStructuredAppendHeader wrong index'); } $buf = array($size, $index, $parity); try { $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf); array_unshift($this->items, $entry); return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function calcParity() { $parity = 0; foreach($this->items as $item) { if($item->mode != QR_MODE_STRUCTURE) { for($i=$item->size-1; $i>=0; $i--) { $parity ^= $item->data[$i]; } } } return $parity; } //---------------------------------------------------------------------- public static function checkModeNum($size, $data) { for($i=0; $i<$size; $i++) { if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ return false; } } return true; } //---------------------------------------------------------------------- public static function estimateBitsModeNum($size) { $w = (int)$size / 3; $bits = $w * 10; switch($size - $w * 3) { case 1: $bits += 4; break; case 2: $bits += 7; break; default: break; } return $bits; } //---------------------------------------------------------------------- public static $anTable = array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ); //---------------------------------------------------------------------- public static function lookAnTable($c) { return (($c > 127)?-1:self::$anTable[$c]); } //---------------------------------------------------------------------- public static function checkModeAn($size, $data) { for($i=0; $i<$size; $i++) { if (self::lookAnTable(ord($data[$i])) == -1) { return false; } } return true; } //---------------------------------------------------------------------- public static function estimateBitsModeAn($size) { $w = (int)($size / 2); $bits = $w * 11; if($size & 1) { $bits += 6; } return $bits; } //---------------------------------------------------------------------- public static function estimateBitsMode8($size) { return $size * 8; } //---------------------------------------------------------------------- public function estimateBitsModeKanji($size) { return (int)(($size / 2) * 13); } //---------------------------------------------------------------------- public static function checkModeKanji($size, $data) { if($size & 1) return false; for($i=0; $i<$size; $i+=2) { $val = (ord($data[$i]) << 8) | ord($data[$i+1]); if( $val < 0x8140 || ($val > 0x9ffc && $val < 0xe040) || $val > 0xebbf) { return false; } } return true; } /*********************************************************************** * Validation **********************************************************************/ public static function check($mode, $size, $data) { if($size <= 0) return false; switch($mode) { case QR_MODE_NUM: return self::checkModeNum($size, $data); break; case QR_MODE_AN: return self::checkModeAn($size, $data); break; case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break; case QR_MODE_8: return true; break; case QR_MODE_STRUCTURE: return true; break; default: break; } return false; } //---------------------------------------------------------------------- public function estimateBitStreamSize($version) { $bits = 0; foreach($this->items as $item) { $bits += $item->estimateBitStreamSizeOfEntry($version); } return $bits; } //---------------------------------------------------------------------- public function estimateVersion() { $version = 0; $prev = 0; do { $prev = $version; $bits = $this->estimateBitStreamSize($prev); $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($version < 0) { return -1; } } while ($version > $prev); return $version; } //---------------------------------------------------------------------- public static function lengthOfCode($mode, $version, $bits) { $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version); switch($mode) { case QR_MODE_NUM: $chunks = (int)($payload / 10); $remain = $payload - $chunks * 10; $size = $chunks * 3; if($remain >= 7) { $size += 2; } else if($remain >= 4) { $size += 1; } break; case QR_MODE_AN: $chunks = (int)($payload / 11); $remain = $payload - $chunks * 11; $size = $chunks * 2; if($remain >= 6) $size++; break; case QR_MODE_8: $size = (int)($payload / 8); break; case QR_MODE_KANJI: $size = (int)(($payload / 13) * 2); break; case QR_MODE_STRUCTURE: $size = (int)($payload / 8); break; default: $size = 0; break; } $maxsize = QRspec::maximumWords($mode, $version); if($size < 0) $size = 0; if($size > $maxsize) $size = $maxsize; return $size; } //---------------------------------------------------------------------- public function createBitStream() { $total = 0; foreach($this->items as $item) { $bits = $item->encodeBitStream($this->version); if($bits < 0) return -1; $total += $bits; } return $total; } //---------------------------------------------------------------------- public function convertData() { $ver = $this->estimateVersion(); if($ver > $this->getVersion()) { $this->setVersion($ver); } for(;;) { $bits = $this->createBitStream(); if($bits < 0) return -1; $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); if($ver < 0) { throw new Exception('WRONG VERSION'); return -1; } else if($ver > $this->getVersion()) { $this->setVersion($ver); } else { break; } } return 0; } //---------------------------------------------------------------------- public function appendPaddingBit(&$bstream) { $bits = $bstream->size(); $maxwords = QRspec::getDataLength($this->version, $this->level); $maxbits = $maxwords * 8; if ($maxbits == $bits) { return 0; } if ($maxbits - $bits < 5) { return $bstream->appendNum($maxbits - $bits, 0); } $bits += 4; $words = (int)(($bits + 7) / 8); $padding = new QRbitstream(); $ret = $padding->appendNum($words * 8 - $bits + 4, 0); if($ret < 0) return $ret; $padlen = $maxwords - $words; if($padlen > 0) { $padbuf = array(); for($i=0; $i<$padlen; $i++) { $padbuf[$i] = ($i&1)?0x11:0xec; } $ret = $padding->appendBytes($padlen, $padbuf); if($ret < 0) return $ret; } $ret = $bstream->append($padding); return $ret; } //---------------------------------------------------------------------- public function mergeBitStream() { if($this->convertData() < 0) { return null; } $bstream = new QRbitstream(); foreach($this->items as $item) { $ret = $bstream->append($item->bstream); if($ret < 0) { return null; } } return $bstream; } //---------------------------------------------------------------------- public function getBitStream() { $bstream = $this->mergeBitStream(); if($bstream == null) { return null; } $ret = $this->appendPaddingBit($bstream); if($ret < 0) { return null; } return $bstream; } //---------------------------------------------------------------------- public function getByteStream() { $bstream = $this->getBitStream(); if($bstream == null) { return null; } return $bstream->toByte(); } } //---- qrbitstream.php ----------------------------- /* * PHP QR Code encoder * * Bitstream class * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRbitstream { public $data = array(); //---------------------------------------------------------------------- public function size() { return count($this->data); } //---------------------------------------------------------------------- public function allocate($setLength) { $this->data = array_fill(0, $setLength, 0); return 0; } //---------------------------------------------------------------------- public static function newFromNum($bits, $num) { $bstream = new QRbitstream(); $bstream->allocate($bits); $mask = 1 << ($bits - 1); for($i=0; $i<$bits; $i++) { if($num & $mask) { $bstream->data[$i] = 1; } else { $bstream->data[$i] = 0; } $mask = $mask >> 1; } return $bstream; } //---------------------------------------------------------------------- public static function newFromBytes($size, $data) { $bstream = new QRbitstream(); $bstream->allocate($size * 8); $p=0; for($i=0; $i<$size; $i++) { $mask = 0x80; for($j=0; $j<8; $j++) { if($data[$i] & $mask) { $bstream->data[$p] = 1; } else { $bstream->data[$p] = 0; } $p++; $mask = $mask >> 1; } } return $bstream; } //---------------------------------------------------------------------- public function append(QRbitstream $arg) { if (is_null($arg)) { return -1; } if($arg->size() == 0) { return 0; } if($this->size() == 0) { $this->data = $arg->data; return 0; } $this->data = array_values(array_merge($this->data, $arg->data)); return 0; } //---------------------------------------------------------------------- public function appendNum($bits, $num) { if ($bits == 0) return 0; $b = QRbitstream::newFromNum($bits, $num); if(is_null($b)) return -1; $ret = $this->append($b); unset($b); return $ret; } //---------------------------------------------------------------------- public function appendBytes($size, $data) { if ($size == 0) return 0; $b = QRbitstream::newFromBytes($size, $data); if(is_null($b)) return -1; $ret = $this->append($b); unset($b); return $ret; } //---------------------------------------------------------------------- public function toByte() { $size = $this->size(); if($size == 0) { return array(); } $data = array_fill(0, (int)(($size + 7) / 8), 0); $bytes = (int)($size / 8); $p = 0; for($i=0; $i<$bytes; $i++) { $v = 0; for($j=0; $j<8; $j++) { $v = $v << 1; $v |= $this->data[$p]; $p++; } $data[$i] = $v; } if($size & 7) { $v = 0; for($j=0; $j<($size & 7); $j++) { $v = $v << 1; $v |= $this->data[$p]; $p++; } $data[$bytes] = $v; } return $data; } } //---- qrsplit.php ----------------------------- /* * PHP QR Code encoder * * Input splitting classes * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * The following data / specifications are taken from * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) * or * "Automatic identification and data capture techniques -- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRsplit { public $dataStr = ''; public $input; public $modeHint; //---------------------------------------------------------------------- public function __construct($dataStr, $input, $modeHint) { $this->dataStr = $dataStr; $this->input = $input; $this->modeHint = $modeHint; } //---------------------------------------------------------------------- public static function isdigitat($str, $pos) { if ($pos >= strlen($str)) return false; return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); } //---------------------------------------------------------------------- public static function isalnumat($str, $pos) { if ($pos >= strlen($str)) return false; return (QRinput::lookAnTable(ord($str[$pos])) >= 0); } //---------------------------------------------------------------------- public function identifyMode($pos) { if ($pos >= strlen($this->dataStr)) return QR_MODE_NUL; $c = $this->dataStr[$pos]; if(self::isdigitat($this->dataStr, $pos)) { return QR_MODE_NUM; } else if(self::isalnumat($this->dataStr, $pos)) { return QR_MODE_AN; } else if($this->modeHint == QR_MODE_KANJI) { if ($pos+1 < strlen($this->dataStr)) { $d = $this->dataStr[$pos+1]; $word = (ord($c) << 8) | ord($d); if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) { return QR_MODE_KANJI; } } } return QR_MODE_8; } //---------------------------------------------------------------------- public function eatNum() { $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 0; while(self::isdigitat($this->dataStr, $p)) { $p++; } $run = $p; $mode = $this->identifyMode($p); if($mode == QR_MODE_8) { $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + QRinput::estimateBitsMode8(1) // + 4 + l8 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 if($dif > 0) { return $this->eat8(); } } if($mode == QR_MODE_AN) { $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + QRinput::estimateBitsModeAn(1) // + 4 + la - QRinput::estimateBitsModeAn($run + 1);// - 4 - la if($dif > 0) { return $this->eatAn(); } } $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eatAn() { $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 0; while(self::isalnumat($this->dataStr, $p)) { if(self::isdigitat($this->dataStr, $p)) { $q = $p; while(self::isdigitat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsModeAn($p) // + 4 + la + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - QRinput::estimateBitsModeAn($q); // - 4 - la if($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; if(!self::isalnumat($this->dataStr, $p)) { $dif = QRinput::estimateBitsModeAn($run) + 4 + $la + QRinput::estimateBitsMode8(1) // + 4 + l8 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 if($dif > 0) { return $this->eat8(); } } $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eatKanji() { $p = 0; while($this->identifyMode($p) == QR_MODE_KANJI) { $p += 2; } $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eat8() { $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 1; $dataStrLen = strlen($this->dataStr); while($p < $dataStrLen) { $mode = $this->identifyMode($p); if($mode == QR_MODE_KANJI) { break; } if($mode == QR_MODE_NUM) { $q = $p; while(self::isdigitat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - QRinput::estimateBitsMode8($q); // - 4 - l8 if($dif < 0) { break; } else { $p = $q; } } else if($mode == QR_MODE_AN) { $q = $p; while(self::isalnumat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + QRinput::estimateBitsModeAn($q - $p) + 4 + $la - QRinput::estimateBitsMode8($q); // - 4 - l8 if($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function splitString() { while (strlen($this->dataStr) > 0) { if($this->dataStr == '') return 0; $mode = $this->identifyMode(0); switch ($mode) { case QR_MODE_NUM: $length = $this->eatNum(); break; case QR_MODE_AN: $length = $this->eatAn(); break; case QR_MODE_KANJI: if ($hint == QR_MODE_KANJI) $length = $this->eatKanji(); else $length = $this->eat8(); break; default: $length = $this->eat8(); break; } if($length == 0) return 0; if($length < 0) return -1; $this->dataStr = substr($this->dataStr, $length); } } //---------------------------------------------------------------------- public function toUpper() { $stringLen = strlen($this->dataStr); $p = 0; while ($p<$stringLen) { $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint); if($mode == QR_MODE_KANJI) { $p += 2; } else { if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) { $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); } $p++; } } return $this->dataStr; } //---------------------------------------------------------------------- public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true) { if(is_null($string) || $string == '\0' || $string == '') { throw new Exception('empty string!!!'); } $split = new QRsplit($string, $input, $modeHint); if(!$casesensitive) $split->toUpper(); return $split->splitString(); } } //---- qrrscode.php ----------------------------- /* * PHP QR Code encoder * * Reed-Solomon error correction support * * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q * (libfec is released under the GNU Lesser General Public License.) * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRrsItem { public $mm; // Bits per symbol public $nn; // Symbols per block (= (1<= $this->nn) { $x -= $this->nn; $x = ($x >> $this->mm) + ($x & $this->nn); } return $x; } //---------------------------------------------------------------------- public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { // Common code for intializing a Reed-Solomon control block (char or int symbols) // Copyright 2004 Phil Karn, KA9Q // May be used under the terms of the GNU Lesser General Public License (LGPL) $rs = null; // Check parameter ranges if($symsize < 0 || $symsize > 8) return $rs; if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs; if($prim <= 0 || $prim >= (1<<$symsize)) return $rs; if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values! if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding $rs = new QRrsItem(); $rs->mm = $symsize; $rs->nn = (1<<$symsize)-1; $rs->pad = $pad; $rs->alpha_to = array_fill(0, $rs->nn+1, 0); $rs->index_of = array_fill(0, $rs->nn+1, 0); // PHP style macro replacement ;) $NN =& $rs->nn; $A0 =& $NN; // Generate Galois field lookup tables $rs->index_of[0] = $A0; // log(zero) = -inf $rs->alpha_to[$A0] = 0; // alpha**-inf = 0 $sr = 1; for($i=0; $i<$rs->nn; $i++) { $rs->index_of[$sr] = $i; $rs->alpha_to[$i] = $sr; $sr <<= 1; if($sr & (1<<$symsize)) { $sr ^= $gfpoly; } $sr &= $rs->nn; } if($sr != 1){ // field generator polynomial is not primitive! $rs = NULL; return $rs; } /* Form RS code generator polynomial from its roots */ $rs->genpoly = array_fill(0, $nroots+1, 0); $rs->fcr = $fcr; $rs->prim = $prim; $rs->nroots = $nroots; $rs->gfpoly = $gfpoly; /* Find prim-th root of 1, used in decoding */ for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn) ; // intentional empty-body loop! $rs->iprim = (int)($iprim / $prim); $rs->genpoly[0] = 1; for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { $rs->genpoly[$i+1] = 1; // Multiply rs->genpoly[] by @**(root + x) for ($j = $i; $j > 0; $j--) { if ($rs->genpoly[$j] != 0) { $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)]; } else { $rs->genpoly[$j] = $rs->genpoly[$j-1]; } } // rs->genpoly[0] can never be zero $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)]; } // convert rs->genpoly[] to index form for quicker encoding for ($i = 0; $i <= $nroots; $i++) $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]]; return $rs; } //---------------------------------------------------------------------- public function encode_rs_char($data, &$parity) { $MM =& $this->mm; $NN =& $this->nn; $ALPHA_TO =& $this->alpha_to; $INDEX_OF =& $this->index_of; $GENPOLY =& $this->genpoly; $NROOTS =& $this->nroots; $FCR =& $this->fcr; $PRIM =& $this->prim; $IPRIM =& $this->iprim; $PAD =& $this->pad; $A0 =& $NN; $parity = array_fill(0, $NROOTS, 0); for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) { $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; if($feedback != $A0) { // feedback term is non-zero // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must // always be for the polynomials constructed by init_rs() $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback); for($j=1;$j<$NROOTS;$j++) { $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])]; } } // Shift array_shift($parity); if($feedback != $A0) { array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]); } else { array_push($parity, 0); } } } } //########################################################################## class QRrs { public static $items = array(); //---------------------------------------------------------------------- public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { foreach(self::$items as $rs) { if($rs->pad != $pad) continue; if($rs->nroots != $nroots) continue; if($rs->mm != $symsize) continue; if($rs->gfpoly != $gfpoly) continue; if($rs->fcr != $fcr) continue; if($rs->prim != $prim) continue; return $rs; } $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); array_unshift(self::$items, $rs); return $rs; } } //---- qrmask.php ----------------------------- /* * PHP QR Code encoder * * Masking * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('N1', 3); define('N2', 3); define('N3', 40); define('N4', 10); class QRmask { public $runLength = array(); //---------------------------------------------------------------------- public function __construct() { $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); } //---------------------------------------------------------------------- public function writeFormatInformation($width, &$frame, $mask, $level) { $blacks = 0; $format = QRspec::getFormatInfo($mask, $level); for($i=0; $i<8; $i++) { if($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[8][$width - 1 - $i] = chr($v); if($i < 6) { $frame[$i][8] = chr($v); } else { $frame[$i + 1][8] = chr($v); } $format = $format >> 1; } for($i=0; $i<7; $i++) { if($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[$width - 7 + $i][8] = chr($v); if($i == 0) { $frame[8][7] = chr($v); } else { $frame[8][6 - $i] = chr($v); } $format = $format >> 1; } return $blacks; } //---------------------------------------------------------------------- public function mask0($x, $y) { return ($x+$y)&1; } public function mask1($x, $y) { return ($y&1); } public function mask2($x, $y) { return ($x%3); } public function mask3($x, $y) { return ($x+$y)%3; } public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; } public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; } public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; } public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; } //---------------------------------------------------------------------- private function generateMaskNo($maskNo, $width, $frame) { $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for($y=0; $y<$width; $y++) { for($x=0; $x<$width; $x++) { if(ord($frame[$y][$x]) & 0x80) { $bitMask[$y][$x] = 0; } else { $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); $bitMask[$y][$x] = ($maskFunc == 0)?1:0; } } } return $bitMask; } //---------------------------------------------------------------------- public static function serial($bitFrame) { $codeArr = array(); foreach ($bitFrame as $line) $codeArr[] = join('', $line); return gzcompress(join("\n", $codeArr), 9); } //---------------------------------------------------------------------- public static function unserial($code) { $codeArr = array(); $codeLines = explode("\n", gzuncompress($code)); foreach ($codeLines as $line) $codeArr[] = str_split($line); return $codeArr; } //---------------------------------------------------------------------- public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) { $b = 0; $bitMask = array(); $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; if (QR_CACHEABLE) { if (file_exists($fileName)) { $bitMask = self::unserial(file_get_contents($fileName)); } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) mkdir(QR_CACHE_DIR.'mask_'.$maskNo); file_put_contents($fileName, self::serial($bitMask)); } } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); } if ($maskGenOnly) return; $d = $s; for($y=0; $y<$width; $y++) { for($x=0; $x<$width; $x++) { if($bitMask[$y][$x] == 1) { $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); } $b += (int)(ord($d[$y][$x]) & 1); } } return $b; } //---------------------------------------------------------------------- public function makeMask($width, $frame, $maskNo, $level) { $masked = array_fill(0, $width, str_repeat("\0", $width)); $this->makeMaskNo($maskNo, $width, $frame, $masked); $this->writeFormatInformation($width, $masked, $maskNo, $level); return $masked; } //---------------------------------------------------------------------- public function calcN1N3($length) { $demerit = 0; for($i=0; $i<$length; $i++) { if($this->runLength[$i] >= 5) { $demerit += (N1 + ($this->runLength[$i] - 5)); } if($i & 1) { if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { $fact = (int)($this->runLength[$i] / 3); if(($this->runLength[$i-2] == $fact) && ($this->runLength[$i-1] == $fact) && ($this->runLength[$i+1] == $fact) && ($this->runLength[$i+2] == $fact)) { if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { $demerit += N3; } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { $demerit += N3; } } } } } return $demerit; } //---------------------------------------------------------------------- public function evaluateSymbol($width, $frame) { $head = 0; $demerit = 0; for($y=0; $y<$width; $y++) { $head = 0; $this->runLength[0] = 1; $frameY = $frame[$y]; if ($y>0) $frameYM = $frame[$y-1]; for($x=0; $x<$width; $x++) { if(($x > 0) && ($y > 0)) { $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); if(($b22 | ($w22 ^ 1))&1) { $demerit += N2; } } if(($x == 0) && (ord($frameY[$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($x > 0) { if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } for($x=0; $x<$width; $x++) { $head = 0; $this->runLength[0] = 1; for($y=0; $y<$width; $y++) { if($y == 0 && (ord($frame[$y][$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($y > 0) { if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } return $demerit; } //---------------------------------------------------------------------- public function mask($width, $frame, $level) { $minDemerit = PHP_INT_MAX; $bestMaskNum = 0; $bestMask = array(); $checked_masks = array(0,1,2,3,4,5,6,7); if (QR_FIND_FROM_RANDOM !== false) { $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9); for ($i = 0; $i < $howManuOut; $i++) { $remPos = rand (0, count($checked_masks)-1); unset($checked_masks[$remPos]); $checked_masks = array_values($checked_masks); } } $bestMask = $frame; foreach($checked_masks as $i) { $mask = array_fill(0, $width, str_repeat("\0", $width)); $demerit = 0; $blacks = 0; $blacks = $this->makeMaskNo($i, $width, $frame, $mask); $blacks += $this->writeFormatInformation($width, $mask, $i, $level); $blacks = (int)(100 * $blacks / ($width * $width)); $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); $demerit += $this->evaluateSymbol($width, $mask); if($demerit < $minDemerit) { $minDemerit = $demerit; $bestMask = $mask; $bestMaskNum = $i; } } return $bestMask; } //---------------------------------------------------------------------- } //---- qrencode.php ----------------------------- /* * PHP QR Code encoder * * Main encoder classes. * * Based on libqrencode C library distributed under LGPL 2.1 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRrsblock { public $dataLength; public $data = array(); public $eccLength; public $ecc = array(); public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs) { $rs->encode_rs_char($data, $ecc); $this->dataLength = $dl; $this->data = $data; $this->eccLength = $el; $this->ecc = $ecc; } }; //########################################################################## class QRrawcode { public $version; public $datacode = array(); public $ecccode = array(); public $blocks; public $rsblocks = array(); //of RSblock public $count; public $dataLength; public $eccLength; public $b1; //---------------------------------------------------------------------- public function __construct(QRinput $input) { $spec = array(0,0,0,0,0); $this->datacode = $input->getByteStream(); if(is_null($this->datacode)) { throw new Exception('null imput string'); } QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec); $this->version = $input->getVersion(); $this->b1 = QRspec::rsBlockNum1($spec); $this->dataLength = QRspec::rsDataLength($spec); $this->eccLength = QRspec::rsEccLength($spec); $this->ecccode = array_fill(0, $this->eccLength, 0); $this->blocks = QRspec::rsBlockNum($spec); $ret = $this->init($spec); if($ret < 0) { throw new Exception('block alloc error'); return null; } $this->count = 0; } //---------------------------------------------------------------------- public function init(array $spec) { $dl = QRspec::rsDataCodes1($spec); $el = QRspec::rsEccCodes1($spec); $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); $blockNo = 0; $dataPos = 0; $eccPos = 0; for($i=0; $iecccode,$eccPos); $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } if(QRspec::rsBlockNum2($spec) == 0) return 0; $dl = QRspec::rsDataCodes2($spec); $el = QRspec::rsEccCodes2($spec); $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); if($rs == NULL) return -1; for($i=0; $iecccode,$eccPos); $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } return 0; } //---------------------------------------------------------------------- public function getCode() { $ret; if($this->count < $this->dataLength) { $row = $this->count % $this->blocks; $col = $this->count / $this->blocks; if($col >= $this->rsblocks[0]->dataLength) { $row += $this->b1; } $ret = $this->rsblocks[$row]->data[$col]; } else if($this->count < $this->dataLength + $this->eccLength) { $row = ($this->count - $this->dataLength) % $this->blocks; $col = ($this->count - $this->dataLength) / $this->blocks; $ret = $this->rsblocks[$row]->ecc[$col]; } else { return 0; } $this->count++; return $ret; } } //########################################################################## class QRcode { public $version; public $width; public $data; //---------------------------------------------------------------------- public function encodeMask(QRinput $input, $mask) { if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { throw new Exception('wrong version'); } if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { throw new Exception('wrong level'); } $raw = new QRrawcode($input); QRtools::markTime('after_raw'); $version = $raw->version; $width = QRspec::getWidth($version); $frame = QRspec::newFrame($version); $filler = new FrameFiller($width, $frame); if(is_null($filler)) { return NULL; } // inteleaved data and ecc codes for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { $code = $raw->getCode(); $bit = 0x80; for($j=0; $j<8; $j++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); $bit = $bit >> 1; } } QRtools::markTime('after_filler'); unset($raw); // remainder bits $j = QRspec::getRemainder($version); for($i=0; $i<$j; $i++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x02); } $frame = $filler->frame; unset($filler); // masking $maskObj = new QRmask(); if($mask < 0) { if (QR_FIND_BEST_MASK) { $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); } else { $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); } } else { $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); } if($masked == NULL) { return NULL; } QRtools::markTime('after_mask'); $this->version = $version; $this->width = $width; $this->data = $masked; return $this; } //---------------------------------------------------------------------- public function encodeInput(QRinput $input) { return $this->encodeMask($input, -1); } //---------------------------------------------------------------------- public function encodeString8bit($string, $version, $level) { if(string == NULL) { throw new Exception('empty string!'); return NULL; } $input = new QRinput($version, $level); if($input == NULL) return NULL; $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); if($ret < 0) { unset($input); return NULL; } return $this->encodeInput($input); } //---------------------------------------------------------------------- public function encodeString($string, $version, $level, $hint, $casesensitive) { if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { throw new Exception('bad hint'); return NULL; } $input = new QRinput($version, $level); if($input == NULL) return NULL; $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); if($ret < 0) { return NULL; } return $this->encodeInput($input); } //---------------------------------------------------------------------- public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) { $enc = QRencode::factory($level, $size, $margin); return $enc->encodePNG($text, $outfile, $saveandprint=false); } //---------------------------------------------------------------------- public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = QRencode::factory($level, $size, $margin); return $enc->encode($text, $outfile); } //---------------------------------------------------------------------- public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = QRencode::factory($level, $size, $margin); return $enc->encodeRAW($text, $outfile); } } //########################################################################## class FrameFiller { public $width; public $frame; public $x; public $y; public $dir; public $bit; //---------------------------------------------------------------------- public function __construct($width, &$frame) { $this->width = $width; $this->frame = $frame; $this->x = $width - 1; $this->y = $width - 1; $this->dir = -1; $this->bit = -1; } //---------------------------------------------------------------------- public function setFrameAt($at, $val) { $this->frame[$at['y']][$at['x']] = chr($val); } //---------------------------------------------------------------------- public function getFrameAt($at) { return ord($this->frame[$at['y']][$at['x']]); } //---------------------------------------------------------------------- public function next() { do { if($this->bit == -1) { $this->bit = 0; return array('x'=>$this->x, 'y'=>$this->y); } $x = $this->x; $y = $this->y; $w = $this->width; if($this->bit == 0) { $x--; $this->bit++; } else { $x++; $y += $this->dir; $this->bit--; } if($this->dir < 0) { if($y < 0) { $y = 0; $x -= 2; $this->dir = 1; if($x == 6) { $x--; $y = 9; } } } else { if($y == $w) { $y = $w - 1; $x -= 2; $this->dir = -1; if($x == 6) { $x--; $y -= 8; } } } if($x < 0 || $y < 0) return null; $this->x = $x; $this->y = $y; } while(ord($this->frame[$y][$x]) & 0x80); return array('x'=>$x, 'y'=>$y); } } ; //########################################################################## class QRencode { public $casesensitive = true; public $eightbit = false; public $version = 0; public $size = 3; public $margin = 4; public $structured = 0; // not supported yet public $level = QR_ECLEVEL_L; public $hint = QR_MODE_8; //---------------------------------------------------------------------- public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = new QRencode(); $enc->size = $size; $enc->margin = $margin; switch ($level.'') { case '0': case '1': case '2': case '3': $enc->level = $level; break; case 'l': case 'L': $enc->level = QR_ECLEVEL_L; break; case 'm': case 'M': $enc->level = QR_ECLEVEL_M; break; case 'q': case 'Q': $enc->level = QR_ECLEVEL_Q; break; case 'h': case 'H': $enc->level = QR_ECLEVEL_H; break; } return $enc; } //---------------------------------------------------------------------- public function encodeRAW($intext, $outfile = false) { $code = new QRcode(); if($this->eightbit) { $code->encodeString8bit($intext, $this->version, $this->level); } else { $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); } return $code->data; } //---------------------------------------------------------------------- public function encode($intext, $outfile = false) { $code = new QRcode(); if($this->eightbit) { $code->encodeString8bit($intext, $this->version, $this->level); } else { $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); } QRtools::markTime('after_encode'); if ($outfile!== false) { file_put_contents($outfile, join("\n", QRtools::binarize($code->data))); } else { return QRtools::binarize($code->data); } } //---------------------------------------------------------------------- public function encodePNG($intext, $outfile = false,$saveandprint=false) { try { ob_start(); $tab = $this->encode($intext); $err = ob_get_contents(); ob_end_clean(); if ($err != '') QRtools::log($outfile, $err); $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin)); QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint); } catch (Exception $e) { QRtools::log($outfile, $e->getMessage()); } } } VERSION000064400000000020150211530670005604 0ustar001.1.4 2010100721cache/frame_26.png000064400000000364150211530670007721 0ustar00PNG  IHDRyy'4 PLTEٟIDATxc```E,/MDC`E߁`}PdY  G`*$R70)!f Zߎ,q;|UPU..=^c?ZܢԦ fۂ!P.&B3"IENDB`cache/mask_3/mask_57_3.dat000064400000000176150211530670011152 0ustar00x1 0 wF纄(hI!*{}WVR -ڢgjmrwp۱UlL/E.*d/͏6J#M׈R`DhR(uJaRJ(g yJ(J(v%_R̓1eڅ(qPB %PBi_%RFJt%PB %~$| ܔ4 NDo;UW,qpTicache/mask_3/mask_49_3.dat000064400000000177150211530670011154 0ustar00xA fz!MpP"ى@Opb)bE5DTYdjznSwST|;SO*PARj+j#Ig nZ :Ơcache/mask_3/mask_85_3.dat000064400000000240150211530670011143 0ustar00xK 0 EyV9):ҁF`hPry+k[>GZ}(Pڣh7ŸÛH @4#@@ ^F`z4TiQ2} kVcache/mask_3/mask_25_3.dat000064400000000113150211530670011134 0ustar00x30C.@@Ae@Y9h SpI i0qaC\5 &L3e§46 vcache/mask_3/mask_113_3.dat000064400000000310150211530670011211 0ustar00xA 0 D}NrnDFj2KCt?WݲZi.qoP %Smj7ަ:*N:@:***fW9d2*j*}S@`*j৪6Jlѿ}}էTUa24hntcache/mask_3/mask_109_3.dat000064400000000266150211530670011230 0ustar00x1 D~O3r6 O(;V6sy>)_%s_d3KO1^aL,$H"$KzRPt[I&X9$H"$I$ysI$DI$ɓI$I$Dɍ%es!=LAZ5'̓IVrn/2oƅcache/mask_3/mask_89_3.dat000064400000000245150211530670011154 0ustar00x1 ὧ) *.@U |eŵ6ۢw5*) oiK4nk>1}d>@ 4XYCo ۡ1<AhFt 4@51Wr>7G}}x7|NgNcache/mask_3/mask_29_3.dat000064400000000113150211530670011140 0ustar00x30C$\&y.|H3d8 . E\$ GMF6 _0p.$d$7a2Rhccache/mask_3/mask_33_3.dat000064400000000117150211530670011137 0ustar00x30C \U T\*8n)("`Ԗf [ u\}cache/mask_3/mask_69_3.dat000064400000000211150211530670011143 0ustar00x 0 {&2'd l=,Fy;$쇤WE-R:%T,O2g"",Ȣ/DyĈɧ{O䮳",:NvEWN#(&,,]x؅cache/mask_3/mask_101_3.dat000064400000000270150211530670011213 0ustar00xK EyWS9'D1񟾪p /9Ёu,ku9Ҥ$%ݭwALb%ClAzq۴붌b!ĤwX4`_'FWr!b&t1X%K,YdɒgY}Vgɒ%K,YdYG%+1Ydɒ%K,Y}VgYi,ɒ%K,YdVe"}kgSkgo,4.i~!_2cache/mask_3/mask_173_3.dat000064400000000463150211530670011230 0ustar00xA0}O3rnPkTTyM$&e/|"ֵdjuy[aiK{M S&z[BUBRIC!n5\w4B $@ $[”3cE^%xw  A:@ $@ $@ $BfID A:@ $@ $@ $p͒f%H@ $@ $@ $@BR %  $@ $@ $@ )$h4K$L  $@ $@ $@³_{Pg۴y>჏VMmRt(1|cache/mask_3/mask_61_3.dat000064400000000206150211530670011137 0ustar00xA 0fz4-%*dp!yZܫu(~=&ۓ)R2"/"<9FΊ=rb"/rw"2B#3-0-KWcache/mask_3/mask_53_3.dat000064400000000200150211530670011132 0ustar00xK 0Ds ! -(.Bp&|"-t&`qQ-"9_+)Be/H8D%a~}spKFN=,;;a^t4\FSNcache/mask_3/mask_177_3.dat000064400000000470150211530670011232 0ustar00xA 0}NrnJL|% ᤳi^Qg M|/~SS?3=8RT42nz60TPATPATP"Vd:Uh)*  * * *3ThX%*$ * * *[Z,-S!A$}TPATPATPA*XZ,V*$ * * * Z,-ns "A+ * **j <{s}EMkjZEZ;'HMKn!cache/mask_3/mask_149_3.dat000064400000000372150211530670011232 0ustar00xA0}Oܠ⦐H頯'Z2{oV|Ι%>yR{!8ÂI+JpI|#f5κ[P A $H Q})&X{ט+Wb`I)5%dcache/mask_3/mask_105_3.dat000064400000000263150211530670011221 0ustar00x1 D~O3r6@(1'J}4gk97A=ip}wZJo8JB=Cs= =;HzT.z衇z{{{T.z衇z{{{T.z衇zoS$PThE%Կbߞr\RL$cache/mask_3/mask_73_3.dat000064400000000231150211530670011140 0ustar00xQ 0 C{g;JJ?dԬK=RasJhTJ6exka\$nIE,-/XB*х=wee4t̒tLщtt߫b gFf qoddn-?cache/mask_3/mask_153_3.dat000064400000000373150211530670011226 0ustar00xA 0}Ns˹)7mJ,}8X=cW^GeN#3X:kԹ\FM Jhu3>TZ{PSgP'kVjժU_ۯUV=P oO:Wҝj[Wxm 5cache/mask_3/mask_21_3.dat000064400000000074150211530670011136 0ustar00x30C0. ""D)7djC$ąʅ".lM@,0&Scache/mask_3/mask_129_3.dat000064400000000316150211530670011226 0ustar00xA н6!n Gz#E)RHZ@bl-)ݿ<ߧ*OUR"5&5*ie J]+cache/mask_3/mask_165_3.dat000064400000000425150211530670011227 0ustar00xA 0}N3T #Z YuÏ:̛1ϱEUTT|S q)m-sG B.Cĉ'N8qğwv7['tg!.ե:qĉ'N8qv`_+.ե:qĉ'N8qv`R8qĉ'N8qΤ8"ե:qĉ'N8qĝIяہq&EKuĉ'N8q+9:}kFT?^ЏGo<0իCg/_cache/mask_3/mask_41_3.dat000064400000000125150211530670011135 0ustar00x30CLjUr`m'hb;gHqVE\*4}Qb;>b:C¥ \҆ʶ#HD؎D_>cache/mask_3/mask_117_3.dat000064400000000307150211530670011223 0ustar00x1 0 ]Q.xIB$?~!}o%uJV/{%O>}ӧO}K~O>}ӧO>Q=/ї>}ӧO>}u{ח>}ӧO>}u{蟪/%?}ӧO>}ׯ.N4n\>9w%kooK7ʨ]S]f%M6mڴi?V;v_bVL*M6mڴiӦڦ`mDݦM6mڴi^XtcC[%QiӦM6mKiǔws>ToǬ&z8ĬUIbJɮ=cache/mask_3/mask_125_3.dat000064400000000317150211530670011223 0ustar00x1 ~N3rۄ]BБ'?mm5kS}N\_gaV51YUUK6Mƌ3f̘1cƌ3fQ}<]q?֒/h-Y}}3f̘1cƌ3} } } } 3f̘1cƌ3f̘1>cƌ3f̘1cƌ3} } } } f̘1cƌ3fِZRJ5\P|69>1FY;Pi,Lٌ,]P7 xCcache/mask_7/mask_113_7.dat000064400000000433150211530670011227 0ustar00xQ D4p˵MPeQ6d?Ը>'rQ5+ s)c7-1nn햺qɔJtg^ʉw̘Ň-?*&Mm@ee5^ c ,b\13j4TZfŢo* :Ut* Xů0N{NϺl#6E1Z|Xi㒑[ӟ9IݒH_;2m`#F0?$yn걫ZO&cwcB9] #F0G#rD`#F#rDZF0>G#rD`#F~b$<{Hi#߅쭏O L#e ) Pr͇i9rȤ)+l Mcache/mask_7/mask_97_7.dat000064400000000376150211530670011170 0ustar00x0ܲD[V.KI`'sxy$xx"= O^&pbYʬ$Kݣ8K eÌ 3:$bI,%$Yb襶 M)T %q綦EX}jlTTKbI,%,_e[%V]R];N,%$%V@`%pam(}_%%۸4='u)ai.;M>cache/mask_7/mask_137_7.dat000064400000000513150211530670011234 0ustar00x F4/ c_ǂ+{SK<o[l Ο 07։Vl;b7fMS;1LCvR|KMH #Н(Sqdcache/mask_7/mask_89_7.dat000064400000000364150211530670011166 0ustar00x 4_n J]Df= $=|kvB计9.b{s&o֌y7WˢkXV 6^̈́13u r }G8 ;gqNkΚZl !6Io i&~7ZGL#)UF Q)bCl džEoDK+#ZTqCqC9El b6ť6 6Rz[k n`;،YWeƆ1jcache/mask_7/mask_121_7.dat000064400000000455150211530670011232 0ustar00x[ Edi;^az,#6ƞ^rh&^amY9_غ5Cr6t^^WlEز~ɿ|MmmS}( ۰ ۰ ۰}mQ]ZVq]vѲ"M1fG, qBmtaaazeF3cxIDmtaaamný$n۰ ۰ ۰ ۏa[}`[yޖ޻)n<4K/Oslnlm/Gcache/mask_7/mask_45_7.dat000064400000000255150211530670011155 0ustar00xU |1(Ҽ 6A1K!-9F0[uǹR`سܾҨ1< &,~3kרChU 輷!L9yceKdk} ꨹1Yi;Ub3xL8'ܧ?p'+%w &;5& 8TԀcache/mask_7/mask_29_7.dat000064400000000161150211530670011153 0ustar00xR9 QpX$lŲf!I2pgSMZj+g嬜,f1Yb|Y>+g嬜,f1Ylio.\Ɲo=gϙ-yk_TAcache/mask_7/mask_77_7.dat000064400000000342150211530670011157 0ustar00xK Dsk+@L⏪V`1GAd[BS dzZXn[A>'o5+]95 ,tYi;r}ͧn4"CvKJEY^N@LǙlfn=XNTmLfocjS]Roe>e)it'7?eOɔLi463+ p468L}Zy}MVmecache/mask_7/mask_73_7.dat000064400000000335150211530670011155 0ustar00xX |eKkuŪMMx ^9""RǮ@kEbCJNmL]-9cx LԺn ;?4hc/5bmq0EJsgel}⁒Y<(NYYwYw]rww7Bu6ee%w;Wc* w\L錍\)1ow^w&樻wu'QfGAcache/mask_7/mask_161_7.dat000064400000000570150211530670011234 0ustar00xю y/皨E)Ʈ1~493,˵+ZT=ZeC.~iߏ&>,6e~,lW] 2\;׵2j"e,rXݵV(c쵵ZӖ18ީ/,'t.ee,cX2߱,_|yt|]t.cX2e,cy/ɗys.eLe,cX2lo|Z{+2]bl,cX2e{+֊[A2]X2e,c9CX"te0#ԛ`_1-cha~/Eh4"~ cache/mask_7/mask_117_7.dat000064400000000430150211530670011230 0ustar00xY D4pUI>"%6ed 8rS NsUnk5XejުuVXg,l`u!hXZ\VlM|[ͬ0 0 0 #hF'c]i>Hataaa~<ÆzyqkO0 0 0 㪞Faaa)2˰fÒ%z8tO=3=3:cw V$cache/mask_7/mask_109_7.dat000064400000000362150211530670011235 0ustar00xA 0 D9Mr}* _x-d:"NJ-k"⨚d{ջגɬ|mOJ23c<6Xn0F )cache/mask_7/mask_165_7.dat000064400000000567150211530670011246 0ustar00xQ0M&A,N̨!x0&XZׇZ-Kث[ejx,.g}`;+k{~1}+k{إSGWg}ݬ@?_8퐾o+k][hW8~uMgqg|j<*q=<ۓRwƓq9.83838IUG?~snr\q98383xq㮁y979.gqgqg=)q'Eq9.gqgqwOz50Ir\838_Vvd}ax˯5)&9)fx3YH]S^*/cache/mask_7/mask_65_7.dat000064400000000273150211530670011157 0ustar00xA I*6^L!酰 i)mTT]VW\9e@4Ku^#N%:,mYJN9ඩvA2ϜH"Y +?`BXDBX̽{.wd,~΂k,^bQ~.\w ^ρOYEJmX"%cache/mask_7/mask_57_7.dat000064400000000274150211530670011161 0ustar00xA03&H)Kb&q֞[-֌ 9rYs .iӾ`~G{ciՂ\Y<.|2۟2 QQ[[^N88l[}[Pl?g+o*ϖ4W1 33[\Gosbkmmm^hcache/mask_7/mask_25_7.dat000064400000000157150211530670011154 0ustar00xڝQA 5[F@aZ̲ >;QIQH8R҈G"z,&;'o97%P8%6oǽ;]NWn[f7vcache/mask_7/mask_153_7.dat000064400000000537150211530670011240 0ustar00xQ0= 匉B5 ю惤/ͲIi^-Zkm|YDh9 \{K{y3v̻E]u`Rr"}Y e2{VV8][.n:+2_B&6Mlb&6`3i9YΌ諡yU}ԟ82f-vږ6nMI7Mlb&6l7 tnMlb&6Ml2^/nMI7Mlb&6;gxACtnOMlb&6yyfP[64̫k`v^+9 ʬO۱}攨+ZX=:iWEcache/mask_7/mask_61_7.dat000064400000000267150211530670011156 0ustar00xK Ds+-*5mcaT19Y쌧L9 糶s//i\bī-"^DH-i;bnA7fet7ٷỵE:r<46(uy{K3o"|ao?ᜟ竟p9j~NƛsTY ucache/mask_7/mask_169_7.dat000064400000000577150211530670011253 0ustar00x]0o577& -LxؔڦM[=8jh絚W~_o;ZۅC:^F*Jjc[k7U>ȫnw[p-u5D{~kV^Ug}g}/c{'Jn<䗥UOcmW-ܗr}g}gS߿x?tnϢܗr}g}g߿lܞr_}g}g}߷kyܗ>>[ˣo-=}/g}g}Oa?}_]yO ߏޗgoOe G3iA~'zcache/mask_7/mask_85_7.dat000064400000000325150211530670011157 0ustar00xK 0DsJm,$i>0 y7xFχVe`V!f.o 7^Q b@ \H/ץcQL,Xy?u$tUs@s@ 1 44Ā?c/ /B~/~:+-?`|?`9~(-ρ>s2Zp2Zcache/mask_7/mask_53_7.dat000064400000000260150211530670011150 0ustar00xK Ds&Rki&,H)tDj =QaP"ds1ZyC|hey CvaH7+OuQsZtb7 vhV ~1#~[ffHkZJtmZ6s wr&C߶fcache/mask_7/mask_173_7.dat000064400000000625150211530670011240 0ustar00xj0 {=M/ RbHrj\=,mcoZ8;mm0b_ߚt$~Wu5ǚNn'?df2(oG,L6_{z? 9wq9 S!ƌ9o2 L`pOEnv8Lv8L UY"d} Kr ' L`&0 L`B'f:O8TcTc\kr ' L`&0 L`BYgIkr ' L`&0 L`"YRc\ ' r&0 L`EڳH9AN&0 L`&'!;q+Yl*ܳ=؀9j[2 Ms¤Ԅ*cache/mask_7/mask_21_7.dat000064400000000130150211530670011137 0ustar00xڝQ 0 B=r]-?]Rl2nc [nA".j+i ~x3e>K0}y,J~2dV`+X V)}fŨƚ[+s[حH++ Bp V`+X V +Qy4GcM۔+ Bp V`+X Vu+܋^,Mݦ\!WrkV`+X Vsnsr\!W`+X V`+2qYJ0黏Bfa 1 9c7G Ol,^꽓3A:H  1A b0X4%٫#d>&C  1A bukv o40T%96U5*sI{`_>S?}(:yTl{G&E\6}"AX XϬ+m#{{eo&Y2soM)gncO9sZ3wo+{=f.zޣ{{=zGcskCQϞp^&{^NʷU e5}EwGn+ocache/mask_7/mask_129_7.dat000064400000000432150211530670011235 0ustar00x1 }?E1N F`D# nY7JiV9S Re>\_p ͏5}ݬmu& ?Ȫ{wxƂ#ڒiw55f@_/```@^ / <,,, }GXXy@^/H B3+> 7},.ږ6}玅^ξ=LwwScache/mask_7/mask_93_7.dat000064400000000370150211530670011156 0ustar00xQ 0 Cu4uYVl(}qD҈}lƱA~,QQgs?XU8(Yȯ^ 9ZJg ~d/Ii mqkRϸxo23f̘_` 333-EτL/44^;13պfBgt Hi"cache/mask_7/mask_145_7.dat000064400000000535150211530670011237 0ustar00x E5?W6Z-^2qbGX6(Ɖu"LbbGuμGk:HwA[jmHݞ3OkQ{l|TEm JfL?2"&)kRfc̉F,z=5X5X5X7F\pUs#5X5X5XFdYk!a ` ` `o8ct ]CC gM5[N%khZp?Iܣϲ^n$Y7AZP[ fȓ0cache/mask_7/mask_37_7.dat000064400000000172150211530670011154 0ustar00xT;@!9 #F1a)VҪsjG?Qg.Ⰵֿqq> C GJu4nFCGl"4)a{5=nCcache/mask_7/mask_125_7.dat000064400000000440150211530670011230 0ustar00xA ϵBm)$_pVaAjg'^o8aՃw7ZJPWm^%sh~Lܳ[-REŧ좪^iu? aaaa:ȍ<ufGVi GyyyyGyyyy+s'<:<<<%16|=Zz'6ƿ IO- 7p 7$}>ɷ7p tssrs Vmҹ}R~7&?7ԦIbh{<Mi-cache/frame_36.png000064400000000420150211530670007713 0ustar00PNG  IHDRMPLTEٟIDATx헱 0E@)eH(+ئKc ==7g7AeXz r '_6#ٓOrewP roޮFϝ&`~ǎrN4{fw]ˎeZײcnk1wK**doQˎq&h{TvLeK?,߲IENDB`cache/frame_24.dat000064400000000437150211530670007704 0ustar00xA EMX0;nVP4HSSxU3/O LiJ4V JC%6VR&DBHjDJ??BlcDZ'UXUޏ0ywįj똳3ścj{:GqGNv;笓J <]#8#8H'GqGtr:9#8#8ؓhNt_>teS^\gQe?vuo;>*wlmcache/frame_6.dat000064400000000204150211530670007614 0ustar00x1 E;{&@o7"jM:L^~`0 USajV6K#syN=EI3B%o<\Lܙ; f2trLN9ݦ1Nwcache/mask_5/mask_33_5.dat000064400000000152150211530670011142 0ustar00xSI!Mƅ8B5-!M@j_\L@;:xBІ)Hy qb?Do:Ƃ[^/+̋߷p|κcache/mask_5/mask_53_5.dat000064400000000231150211530670011142 0ustar00xVA " zYf5ƐJC A;l\,dR. \(e_ еaNi5\żaLP(;2שjN6O u+l{y6od^ C[% cache/mask_5/mask_117_5.dat000064400000000363150211530670011231 0ustar00x D|Mn/*{M+pI_&m-ѾC32u?o-kgB7wc=U%yoRhӯșDo:ֶyRJkQ^aaaqOgiJ ;qOg)ӊ0 0 0 [vö>=>0 0 0 Ofz3=>0 0 0.3Z$׷8\pw4:Zp:qX 7cache/mask_5/mask_73_5.dat000064400000000270150211530670011147 0ustar00xX[ i_Th`FM !Ҵ{$s/@ê#t~Bh79!z8u>v䷪bNgzv*61^N+uw޵!f^4T37Zn-Ny'fz~Sɻ/xGU*ѻy_3b&6^3gpiwxʌq cache/mask_5/mask_121_5.dat000064400000000400150211530670011214 0ustar00xQ Dsۏ[+'Ҿ(RbC^ѽD(ódY9$o!h9ߛꨳwT[X!gM\]6[5V4䑙sbaaaٞ`{scK<\fΉuFmtaaaMLgx/Dmtaaa6g7x,/n6l6l6l߻9Yyf;>FWyN\/Byu^ma(Ծcache/mask_5/mask_165_5.dat000064400000000514150211530670011232 0ustar00xQ PW3aVrS$ 9mDFmc\vܙe{ZԸzWsYƎZurjv\cJ-Kgqg#!=j|ޥ˘Z{nĝr\38383n\?xL-sr\qgqgq rqgqgq=9.gqgqg;)qx'Eq9:383g;ZֈuNяˠ~~ιLj_Z!ucache/mask_5/mask_81_5.dat000064400000000274150211530670011152 0ustar00x C~M?tzU4" }tMX2|.ɋ˙F\~m4Xu ٔ, w:EƄ>X̯=_]g>>zמ/)5ךkkkZsXXY{ܮ}~mt:S#&;U#)cache/mask_5/mask_45_5.dat000064400000000220150211530670011141 0ustar00xUA 5?U:N&Z":;4P1=bNvSGM1˛n'(κ J{Eѵs] ,sqcache/mask_5/mask_49_5.dat000064400000000222150211530670011147 0ustar00xVA 5?*jL+dŤν ^aAahr4٩'\GdP9ero #Ñq߫!W{EV2 ^quѡTޫP8?S\P%[cache/mask_5/mask_161_5.dat000064400000000510150211530670011222 0ustar00xI @нDp@ o|m rHk㨤~co^Jzװ#5l¦S_92 [}ZÊ=T2ƀP2[cV衆CYf'-X9>v~usK5`e,2,2,2-///o_q}K\reYfeYf峖o+/,\feYfeYfٳexB.e2,2,̲g+l\r16,2,71/34Ϊz^'[FyglgM>OTL4ϔ{&3Wy*ʧb*`<3;Vo0/s6n0ya[mcEcache/mask_5/mask_57_5.dat000064400000000233150211530670011150 0ustar00xVA 5?NlZHAbBZ0a Md`1z'"<Ր19nvͨ. )bݻ~;SB+ V`+X Vc㊛{g;^Qq5ZUݮQL0+*&YDq*6cache/mask_5/mask_173_5.dat000064400000000552150211530670011233 0ustar00x[ 0&G1gD)[CzeDѷц=RN6FJm JqP}x s_}GFy; [;]ek[QbTmy&0 L`̄Y?رw؛ fcVN9&0 L`ׄZ}0=F=F9ANL`&0 L`BzYfI=F9AN&0 L`&0 fIsr ' L`&0 L`<i͒"9AN&0 L`VaBX",Um> =wZgBΜP !8cache/mask_5/mask_113_5.dat000064400000000365150211530670011227 0ustar00x 0D^6I63[[EDqc+jy81\c 7c?u}DK4},kkg--3[UƂyUXUXSV:ϫ՝,|кS⫰ Vɫ*X[* zU*NV*JUXUXSXijTi4fZkU^_~Ux }ծZ/rcache/mask_5/mask_137_5.dat000064400000000444150211530670011233 0ustar00x 0 >M/k1mX=hsH"k M:3qOW}9ԖIH1G;- sڶ?[%M v#;zg^3d}69Ψޙ@7҄#gv`;׳ީ\$wlv`v;ލ}7wߑa;vkA#gv`=N2wxgWӤ@n?c}SQ:Zd?+9vz)Pcache/mask_5/mask_141_5.dat000064400000000451150211530670011224 0ustar00x 0 =M/t" u|Y)ԘiF[[fYlyjRf65MM}5_ M=~~LTTlu%\Gŏ~Y",7aq)La S|jԝE⤑4߄ StS0)L1%J>իk'\jN):e)La SҘO^K0)La SޡOzN):)La SUJ8fMO&ϧZT>s6P휛4 ZR&cache/mask_5/mask_125_5.dat000064400000000401150211530670011221 0ustar00xA E&fc;S$?؏Q4YahûyJ}9g==li.;nh_wz.qCWȧy uPk;<<<|*q, mkWqNl% yyyy^2䰅sX|aaaa3ϙ9lH<<<<̿웁[n`Tq8^vycache/mask_5/mask_85_5.dat000064400000000272150211530670011154 0ustar00xA 0 yMyRZj+"9%N`ܛEռ=e([QZ_Œ׾/NN j3Pci%U 1 g ܱ;O5aJb@ P=<< Ā~)n{gZ9q* .Ycache/mask_5/mask_145_5.dat000064400000000454150211530670011233 0ustar00x0>M/(xtBqCR;n!:Eup^ӈFmFlF[srD:UnRbX&_i1Q`a kXְ5aٯY뭍vDj_YCv5ְ5a kXÚ~E5ְ5a kXkg}m5?$ְ5a kX~ͽl5װ5a kXm:nmkQ?Zhӯͧ)ZFyutֆGsvH\SGcache/mask_5/mask_65_5.dat000064400000000243150211530670011150 0ustar00xWA !KK.T^B fAsVDˏaW 1 ̓`P=i> xh-Z^-~qa%2xJ ~GZ0W ϳ/*1,ֻӓmE cache/mask_5/mask_29_5.dat000064400000000150150211530670011145 0ustar00xՒ] =M_n0W .=-4myB+ R􈋆$ƃ.=s/,+B7󳝍qz~q>=GZy:DRcache/mask_5/mask_41_5.dat000064400000000157150211530670011146 0ustar00xTA 5?7XMtxҴx ?@7@~"N$Sɰ{+CA'r\Pp<ޏ- ͺ:S3sԉۻީz#qw >cache/mask_5/mask_109_5.dat000064400000000323150211530670011226 0ustar00xA 0 yMyRZzH"ԐqY!-*ݞ=mQ_k^[J~oU[]vqewJ-i5- Ik &a&a&drBN&q}C'It&a&a&I$:N$L$L$~?D'II2)zzrdR67Ԧ\>jm?UߛZKqC\cache/mask_5/mask_97_5.dat000064400000000330150211530670011152 0ustar00xA Ef!3bf5ƼB|#f=<3l6<_+xj) ݩy J yXiܻ5IzsٞcueQ KKKd)>,ͼwxDַ.,;s%g,,,=Rὓ7uKKTD<(n lYhV۹sޕyPE#ȕ0c0Q8E=F#+a X͞+cV%9W>Q]TkY-gLqD艋cache/mask_5/mask_157_5.dat000064400000000430150211530670011230 0ustar00x10Dާri( r* \~>C*vs]Ŝ_{W!zﶬ/)˙v V6V޻,f1Yb n^o>\O],,b,f1YyVgYYYb,f1+ʳ<˳<˳1YbŬ<+ʳ,,b,f1YyVgYYYb,fukys77}vmb=wsw)tW:cache/mask_5/mask_169_5.dat000064400000000520150211530670011233 0ustar00xj0|/niK'.r:T-m&Zx9yq3rOgvOO_zׯu`]ȷitاtiloc13j9%_g|ԧ)>>ϰ=te&_4=tU}/>>>Or5/u>/g}g}gOsvO}/g}g}ٷGo-w{r_{g}g}g_n=n]4Nkβ_M8m?SF<cache/mask_5/mask_61_5.dat000064400000000234150211530670011144 0ustar00xQ CwC ՖB .ݛwpKvg;|3:}ؓc0þɴjj7(lwe^WJɾSwt_eΫTMOs9ubs=?~~>9Z#tB~cache/mask_5/mask_21_5.dat000064400000000112150211530670011133 0ustar00xڝA f+(\=İH=Ԍ%*@?6+5%]^nҡScache/mask_5/mask_89_5.dat000064400000000324150211530670011156 0ustar00x 45enpQ Gcfl^^;;b5;`kU͹߮j`NsO=\[a6~nLD? !6uF%w*Ȭkf77SĆbÆXodw_—mbClNۙ ck&YVoܡ׷BעبAl6 Jjxcache/mask_5/mask_93_5.dat000064400000000327150211530670011154 0ustar00xK 0 D>&&  fP^8BY5s(imҮ=f3/wۧEyYQwf[} [90303ef̙3'3=XX*/d~A͜cfVYX,Co/ y/ H @^ /  y/ H oeuuj>n;兰]_m;NY3>JNtcache/frame_39.png000064400000000410150211530670007715 0ustar00PNG  IHDRamPLTEٟIDATx헱 1D7᧘Fu~kqO,Idx,4cf6Pw@Ne [0LXVed_>j9/mJ8R^&ᗢEAѽiyPtoZ{zW7pWP44ˮ9Ҥ/i,E27T2[wIENDB`cache/frame_16.dat000064400000000362150211530670007702 0ustar00xA E]sIX;n6`qW6`%A/3!!g̡1N) E|;>6⸏97$c]kkw1[mC͜cR>E,hʼnp#xFyWVWG3+˓S}Ğ#G8b^c^cpc&3YQ"vk9܇} ĿQL/cache/frame_35.dat000064400000000526150211530670007705 0ustar00xݱn0u%{ VԦ ~#K WGtgY3(sPKJ暪["Kݖ*`<ݴt4tzJ{{v\ և{vǮ3T?f2}nzn;vرcǎҵ]u^M/~xB;; vرcǎ;v>곞wرcǎ;v>zޱcǎ;vرc>];vرcNgY};vرcǎgL krJwyGNq&y>l]s.ޙ{6zhg҅|Ocache/frame_3.dat000064400000000174150211530670007617 0ustar00x E{v& &Y+bk'ya:TXl޶$W+ӏv9}gR@H0YPBEm?s"bt2cn:ﺭ;YzQ7cache/frame_31.dat000064400000000510150211530670007672 0ustar00xA a޺ &r4yķ!mV3Iv!Ҝ2i\NSS4EF2+65e/Ws]!?p=S~Đ?+x6r6y}ǴeR1-WllҌXz/>V櫷:ñA8-+mTbllltM&]ll&]Ill&]y 6` 6`iuyXWi\tz>.zk t77wJϔ4w҈85cache/frame_5.png000064400000000226150211530670007633 0ustar00PNG  IHDR%%P@PLTEٟKIDATxc`C?0I"~0P Vd]j d-dBIENDB`cache/frame_11.png000064400000000315150211530670007707 0ustar00PNG  IHDR==$PLTEٟIDATx͑1 0 E y@Rz6GGG7ݻ. # -+B4Ւ9"- C'.0P:~pa|L=)t:AcPu+Avem9JZIENDB`cache/frame_40.dat000064400000000626150211530670007702 0ustar00xA@Ь@o7`Qfe䕫PA><]߳bZn^AQ}[9^]ynajM܇K̘1cƌ3f̘1{W5}{7lMޚxI<Kαyl3f̘1cƌ3f̘1ۻٻ={αyl3f̘1cƌ3f̘1ۻٻ={αyl3f̘1cƌ3f̘1ۻٻ={αyl3f̘1cƌ3f̘1ۻٻ={αyl3f̘1cƌ3f̘SʑӒ7HK޼g\u_r'4[-]qL8ƝY1q!/(%cache/mask_6/mask_173_6.dat000064400000000655150211530670011241 0ustar00xa09MrM S*:a_-5hh_)uZ֭[loےsmKN{H?x`l#f9>ڟ[eЄώߓ ?^m*/Kmhy%v-nKlkKL`&& g5(gwxYܞa¬pVcZ[#O=SN9&0 L`DŽ 'tjj]QN9&0 L`sYRc@QN9 L`&0 L`"YRc\ ' r&0 L`EH9AN&0 L`& 7p6`|hms R5Ƙȉ k\X/ )g9cache/mask_6/mask_125_6.dat000064400000000461150211530670011231 0ustar00xA0Er3&H yb+Slh0Ͳ6LwEѿfǮIv;&vw,o]ud]|k棘9ԊC}s19Jw9ˡZb=PK&aaaa>ɼÆ$<>Ov'Cytaaaa~|'9liΣ<<<<Iæ<:<<<ٕWDzy:.z= ݓʯ sVöE=ll_k0_#vίmjcache/mask_6/mask_53_6.dat000064400000000303150211530670011144 0ustar00x E-M[s Z7]Y&][ O;|X8?^2N=eL><3*=Ǵd#P%t8ZzfRDK{~Djf!C3*p!VZ 弶6sYQy}֒mF <*Bcache/mask_6/mask_73_6.dat000064400000000346150211530670011155 0ustar00xX |-NM4^8Didgy旞41ibؘ,;x-2N;┹EqܹN>tL41"ˊ?JbQ_@wsg9Pq5 kY,dz⬼+#*fw?ɝ`dcT;OLfkUҺw&fqG(0wB陓=~cache/mask_6/mask_37_6.dat000064400000000200150211530670011142 0ustar00xA &T `j_ݏ`8G1`B`;+}&s]FڪWv=u׀QΛaaaevKvTKf5eool+Ån6l6l6l6l߄uvw\QK%mt݆m؆m؆m؆?gjɹ$n۰ ۰ ۰ wb;@̶vj45.nJS6\wVKj{Fl˿hSvuH%;{}cache/mask_6/mask_141_6.dat000064400000000545150211530670011232 0ustar00xa F4/c]زȐ[=[E럓sm,fn/|kj\j?g[q(NOZc5SGGP[oMVָfvL<vb'J)š}rD"Tcache/mask_6/mask_169_6.dat000064400000000607150211530670011243 0ustar00xJ0i9[Jɘk{1b!gnhHkS뉭-V?KIׁ1큏1ƣݎ/`/z)*=3ڏg6^k65CY>㵾+'{է_Vˊx-J<ӛܗr_>>i;rO}/g}g}ٿ}}xO}/g}g}ٷGo/{{r_>>o/z^#}g}ٿd'ʳ|QRNS3YڳZ'msEǷj5cache/mask_6/mask_113_6.dat000064400000000457150211530670011233 0ustar00x E5NՉbF6on,m>gS9RWcǕ9&%1_cx= GR^w-z?dzv=,}ԥ?ǹژ:9m==@U䲉UXUXVe~by4Wi:e=f{_,,K9o 4ǵ7lniJiggir<-MG xuV+zRCr9+Gq6QWb"Qe"WL+ XXXXX/|~j,nmuMۤ+ XXXXXYa,X;M+ XXXXXe)oӘf|5H늚7/Dcache/mask_6/mask_21_6.dat000064400000000127150211530670011143 0ustar00xڝQ C9M{i]X1- C!D7 W ٜ&rD)~]<M 3(>{A aScache/mask_6/mask_161_6.dat000064400000000617150211530670011234 0ustar00xQn EV\N4MedFs үMwUuy59ڇ#XЈejV(mkk)duxڸ9vԣ;vEMGlicw`Έ D,cX>>d>vNjɞYӪVub!M2]X2e,cX~e;k]t.cX2e,cQ/+/L2]2e,cXƲesEt.ccX2e,[[!_6W L2]2e,ca,'t5eIeyK{T>)_~Η{\|oEW{+,J{+f].X9?+?cache/mask_6/mask_61_6.dat000064400000000303150211530670011143 0ustar00xK DsڤE~݂ih' N'oVWjspCzοag!#WD%~˃Y?JfREKoͼǘ|Ƀˎ*OP7n뼽7s`sdDs~><iK'l'9%.7cache/mask_6/mask_65_6.dat000064400000000316150211530670011153 0ustar00xWQ i{KNLk?e$Qik41{`+!ڮM ? 1b8 .^wsnFj5EaQX|=w@2v<ŋŞ|4w\UXBQz+TTcBz/48,5`ȱ OV$ cache/mask_6/mask_145_6.dat000064400000000545150211530670011236 0ustar00x EiܖLDf6zX9^ZLSڊGT~WUıڣ߁{Fm|ڪ$uMtQ)jۭe??Ȗ(C֮ﵳM;'cU6::VotMW\gXɶq2 ` ` ` ` n7E-؜zRZ/ٮQ k!a ` ` `X_&A5t9$kkwXF5t ]c kkkk|{Z6k` ` `-~hYI_KrZ[ﯩrQ<{X_ZLF{Y~RN8aDT%#W6_yE~1yxƶ5Z!Ոmub #?;̳!|(|iAGZ0#0#0G#:G#tAGk~?#:#0#0#?02f?2lř:?r~~wÈ@:sQx#cache/mask_6/mask_153_6.dat000064400000000557150211530670011240 0ustar00xQn wN\+56Tn2>lYQ7d?Fxk}joex]?'#{>Y 9UBYyΖW~{|V_.c`DK1Јq/'(p,jq#aiY+XZ܍Mlb&6Ml`3iy,}rg6yY,- b]9;&ݤt&6MlbOf|3fy/ I7&&6MlbSik=&ݤt&6MlbC9I7&6Mlba3l'6*l^U7L^U}}^PX} g)g\讛5Ukccache/mask_6/mask_149_6.dat000064400000000562150211530670011241 0ustar00x 0 E5f478UD62zmpߞk8}GӕN}?}W:guWAˌ7 ~;)Ø{̪ǿ+WPOۢrE\jwG)y˖wAAAAM%2`2dl|p}eqP : e j想=lT5ɠ : G{ddAtDaaaaa&أ&w : 1-MRb0Wf uz5&YiIѺNрAPQSL}4cache/mask_6/mask_117_6.dat000064400000000454150211530670011234 0ustar00xa F4/#Ev3nŸ/mYTwm<~?ljGCqS/6ftݟoӔf^l'7`ZC ?heiXq4[ـԉaaa9]PYM<6a[g:0 0 0 ×gx8:Yz;7Cataaa Ʊ,CataaO U6 8=gxx\ƑXQt2JZ:g C+\cache/mask_6/mask_49_6.dat000064400000000271150211530670011155 0ustar00xVQ i{K&YX؁0̦!=tn&fpWL `/<ϓKVrU\1bGp@ӑ&fN/+ƽq`AWSRGp_5||zxν:J+WEm4h43tܭ.Ag`\ʤ*Fcache/mask_6/mask_89_6.dat000064400000000407150211530670011162 0ustar00xQ DsBn3B?&lD}630q몼Þ/O1cNBFĜZ4``93r]=55#=:ξXwX5D A6؀ wBAJ~ 2S{䙮,U3l A6AFv߉mxkQ )dlwG"Iժ7fڼcw_:ִ(߄:S6*cache/mask_6/mask_25_6.dat000064400000000161150211530670011145 0ustar00xڝQA 52)e+(XmZt*(ڹ;tJ<峂_ڤ3oڴ"̢azh}&qvSG֙,-J4}oS[}wcache/mask_6/mask_93_6.dat000064400000000424150211530670011154 0ustar00xa 0{6X]1&[l)ΚLȜu~tK1>?p]c/n˨ۂy=1w`L}bci۝4Y_9R Rb$= %3`̀`&W|Lg^Zgj6R+O̸"c:: ̀0fMٚ^ַ^i`M`̀0̤Wߘ [fQ^ER5p>}moaK*M!p&mRcache/mask_6/mask_101_6.dat000064400000000423150211530670011221 0ustar00xk 0 4/n_.2#SH6_PZf˳_,7؞+%Wd–n}_&Ok;Pf>tyY]ns ;ss,!LkԅcbL12cX91Z#XEn#;svT~L~LR11vs.1111J1&؍Ń111J1&ƞg KLƪjlk{gڞ5K1/ǐ~,ac$cache/mask_6/mask_69_6.dat000064400000000331150211530670011154 0ustar00xK @dTh hLSSEq eY@<+*|窮 %>z*7e6QS`.>sE '%@[6@P0h aFxtpl2 Q-g1Nfeo^0FdT>N_OwG3ug {3<[Ժ b?'6^cache/mask_6/mask_29_6.dat000064400000000166150211530670011156 0ustar00xRA 0 XcL(4EԈB 8Cܾ޳nM+lǝՆO1]&ڍ4UD-6-$:6dZ?ylf? 8?߲s֪r666rҟ=vڲWy -' Ο;q tQE>U϶f곭xN]Tc(s❮7tAw`v`v`v`kvwfwt;];;;;;!ޙ;ao];l;;;÷| ʷ(3}l.?"މr};\}S-Aw<9;EV'םcache/mask_6/mask_85_6.dat000064400000000345150211530670011157 0ustar00xQ ! D4/Bj6? YfA>cؘY3t>3Փmbׯ韻E nUlqs;YCrj([sŠ1 I(@7le`u$b@ (P>88 Ā+6 #F8#mjF|DjF3ĂUꆝ=^cache/mask_6/mask_81_6.dat000064400000000356150211530670011155 0ustar00xQ0D9 rRLvk`0 ;i6\|_cc1huio#2}x*.Yt& ְq/K;3ve̢ȊAH?`]5Kw!}{Zû߲W yⷾ^_ykk^Kתb-bYSڸ'֜Nu#MfHSQ?|]IAiMyyuWcache/mask_6/mask_105_6.dat000064400000000420150211530670011222 0ustar00xQ @ DskBZ#o)Sd}Gܷl쯯^)G]S4S?#BZ:+{sHKNiI!me1 RWe9!``Uyˀu:檞U=w-oԺwB}cMK蹰{{=y蹰{{=y蹰{wScaoi'fyO=CyO=Cy[{S޻=;|v4}ϯ20cache/mask_6/mask_41_6.dat000064400000000204150211530670011141 0ustar00xA!ݬZ 5 ,E;?߻e-<-9gJa#,MSM]|F%C*ht~Ž̢Yo4"`,bcɺN.s{9z @5cache/mask_6/mask_165_6.dat000064400000000620150211530670011232 0ustar00xj0y_nF"wǖ2t <~Z-/e~m/[kޗ?椋O~ڼ/۱W_Z{=gIk}/wO-Uߥ5i3|-3[RޑɽY6-dqgqƗSՏJnJ-e}^JLJ15ZݹEq9.gqgq1z<q9.83838 V179.gqgqg3)qx&Eq9.gqgqLz=0Ir\VgqgqƟd1='#`+bl]Zcache/mask_6/mask_157_6.dat000064400000000513150211530670011234 0ustar00xA@D}fDN%nç,֖SVV>WóCaz6U~һ{`nݻdvVy~rZ"qk{>g$XKU}m\bjaGx,f1Yb]z̞^.5[?嬜r,f1YY>grVb,f1Y>g,rVmYb,f,|VY9Yb,f,|VY9+g1Ybً ̦M7>2{9z϶hm3l|9xټ#f#x6 -v%N'cache/mask_0/mask_97_0.dat000064400000000226150211530670011144 0ustar00xA D}Nr]Y "<40{Hpu<cache/mask_0/mask_21_0.dat000064400000000060150211530670011123 0ustar00x30C .lH4SH3 2A&M-ep؄ZzScache/mask_0/mask_125_0.dat000064400000000262150211530670011214 0ustar00xA н_TH`3AOL4 k(ewGW. #2} \Ygggggggggg_d>j^s;;;;;;;;;;'q;;;;;;;;;'˰qu_PYw{e=dG/cache/mask_0/mask_169_0.dat000064400000000365150211530670011230 0ustar00x1 0>I9EQ=Ls I{ZtR}Sn:|R[?_*SL2eʔ)SL&ϦI O2O2eʔ)SL2e*C1PPSL2eʔ)SLP22)SL2eʔ)SLe(}2)SL2eʔ)SLe(}2)SL2eʔ)Sic7;"ޙFͦސٙvL ^2}oO'rcache/mask_0/mask_177_0.dat000064400000000410150211530670011216 0ustar00x1 0>I9+?߁iև d̹xֈxN/է|{ظ8d0h=cFf̘1cƌ3f̘qq=w6;l4cƕ<nj3f̘1cƌ3fXһ1ֻcƌ3f̘1cƌ3fXbwnj3f̘1cƌ3f̘M'X&1cƌ3f̘1cƌ3ֻnn1cƌ3f̘1cƌÍ3U< \7+(<OƌΊnj4@cache/mask_0/mask_45_0.dat000064400000000152150211530670011133 0ustar00x1 w^F- `")40COEP,[ϐm-/lGy{ŋNF933gؕl; ٗxbsN6#~`79рcache/mask_0/mask_145_0.dat000064400000000327150211530670011220 0ustar00x; 0>I9+E{$m^&uS"D6ڟ]98UMbҾY[2拉Ĉ#F1bĈ%iRN潝ѳ#;#F1bĈN1i#F1bĈ#FtZ}Nk1bĈ#F1bktZ;#F1bFV-u"IoD-*7uj>bMV+cache/mask_0/mask_41_0.dat000064400000000104150211530670011124 0ustar00x30C UrȘIƝDB.>JG5sAe&, I `3~7 V)-D?cache/mask_0/mask_49_0.dat000064400000000160150211530670011136 0ustar00xK E9o#?H/6g$-,X] xݘ; X԰9<Ѻq2AfH7/5We{#fި?4=N >cache/mask_0/mask_109_0.dat000064400000000241150211530670011213 0ustar00x= 0 нi9'b$t^#ii?bK[AUF徝Ƶijx]m]2-ĖK~ Vw}X&Oɓ666666yR'%lllll/hlm dl3+mͫcache/mask_0/mask_133_0.dat000064400000000304150211530670011210 0ustar00x1 0 нI9Ty)<4hNSҚ]Z?[H<uFI7R` ,XE޹˴]Wgy ,X`!Y# ,X`<"# ,X`Y/XLGby"pTcache/mask_0/mask_121_0.dat000064400000000265150211530670011213 0ustar00x1 О/w YMS8>2SFOEcW\ۼ{cpKGBКmxhfffffff/s22W|*d1*5̬RWas\xm~8߮r0wjsdm&ycache/mask_0/mask_61_0.dat000064400000000167150211530670011137 0ustar00x9 ! >I9+ōQ~d%òMͶd*bK滻89z]T aÆ [s8;65ذa/=؉nZsvucache/mask_0/mask_93_0.dat000064400000000231150211530670011134 0ustar00xK EyV,OmޠrPH0{2bc{tQ] {Q{{弬֒ǎ;v_ڳ}L}l߱cǎ;v̑̑̑رcǎ.Legw3qeѾ@icache/mask_0/mask_117_0.dat000064400000000252150211530670011214 0ustar00xA 0 }OrR,#3,o5Cq:;;wvNJZG=m} ѱ2iRkj_YYYYYYYYe_/WVVVVVVkd-Ϻ,#OZc]|{ž$cache/mask_0/mask_157_0.dat000064400000000343150211530670011221 0ustar00xA н_QRY k*q͵=j7~nN.p%ڵsi.رcǎ;vر{.-W2={mgy+رcǎ;vɳ2;yּcǎ;vرcNɳ;vرcǎ;v2I9+Es=ϤL1̄[FZU4?i<;7;P#W-[ݯ6ddddddc",;"sk摑Q&erw######L.摑Иy1^˲\3 vcache/mask_0/mask_77_0.dat000064400000000213150211530670011136 0ustar00xA D}Or0B/;bHp/*KE7G/_l}xMP [(筊ZޛlI6lضeϷO^ 6,,6l&l& ^Wc}m5uE;ecache/mask_0/mask_37_0.dat000064400000000101150211530670011126 0ustar00x30C, QjКP]D@.F5k,|yĥрe4 iCcache/mask_0/mask_165_0.dat000064400000000366150211530670011225 0ustar00x; 0>I9+DyI4ˠ5:Wvdqߜܴ<d2x%[U%2]&K,Ydɒ%ˡ,S՗r2yd=,k_{Xdɒ%K,Yd)0m,Ydɒ%K,Yd)0m,Ydɒ%K,Yme,e%K,Ydɒ%K,eq Ò%K,Ydɒe:֞!Ŋ+V嬪.2XbŊ+VX.kBzwձ̀gkYZcache/mask_0/mask_33_0.dat000064400000000076150211530670011135 0ustar00x30C4\ 4fq!SSɨ xfJct2BJacache/mask_0/mask_89_0.dat000064400000000224150211530670011143 0ustar00x1 ὧi9'Hl?L^"&M?bq?˸,9!z]VScƌ3_c!`n3f̘1č 3f̘1/f>.Uc˻; 2;Y+7cache/mask_0/mask_73_0.dat000064400000000202150211530670011130 0ustar00x1 /FSM(7/JTmeӕls|)YYUS%7{i(L0mo짻'wDŽ {=Όc)2֦~Lz)vZ5O2]=?cache/mask_0/mask_65_0.dat000064400000000173150211530670011140 0ustar00xA ;'`C$,(n>kx j>t<뒖G@ 4gG^y3I 45`$gH!p"$cache/mask_0/mask_57_0.dat000064400000000165150211530670011142 0ustar00xA {^s=YL՚ ( ouj)  Z7yv,ԴwVQ iGiҤDfەwo4ѤoLLȼ}4 hcache/mask_0/mask_105_0.dat000064400000000242150211530670011210 0ustar00xA SQP 2k]G (ѠvS/-SliSvQ%γ(&&&&)y?m{_sƘ'&&&&&&}O7'&&&&&&}O#^g>:&M1 TFb{:O_2-Nv+[cache/mask_0/mask_101_0.dat000064400000000235150211530670011206 0ustar00x1 /FS4`X%0"O&+*[[V/-٩EJKTKWozՔ ,f噵 B` vvvz ,XððX`l}T,E,Rd8uyE`9 cache/mask_0/mask_173_0.dat000064400000000405150211530670011216 0ustar00x10ޯT [4v2ƽok݇;Ӳ]f֞dljlG0n+߻mG˖-[lٲe"Y}oV[lٲe˖-[lٲeհՃ[2lٲe˖-[lٲeհՃ[2lٲe˖-[lٲeհՃ[lٲe˖-[lٲeValٲe˖-[lٲef[BmаE;N-ۜT/rl?*cache/mask_0/mask_129_0.dat000064400000000304150211530670011215 0ustar00x1 /*DE'hgt-}_pV \"b=s[J=8Dho۞' 0X ۴e0`  j" 0`Wf`^P0`2Ȁ  d07(XyaN230w @hZaCDP-ou*?yw̢e)o}er/pdC?'Ecache/frame_34.png000064400000000400150211530670007707 0ustar00PNG  IHDR PLTEٟIDATx헱 AEE`;&` a${Xā-؉de?gt(l̢csG`Xyr W/8#ϩ6sG^;nݞ@14(/0Ԭ.D%z\rl:FLw(_ѥ02KaNeFl{@ޓKgSy?G& ʻ#'2hBIENDB`cache/frame_10.png000064400000000312150211530670007703 0ustar00PNG  IHDR99PLTEٟIDATx͑ 0D/kd' h:بg~/U.|Ɯ YxE44d%sR?5Ues{di^';㔅9^0"]GW/8So}$zd\IENDB`cache/frame_32.png000064400000000406150211530670007713 0ustar00PNG  IHDR`PLTEٟIDATx햱 0E/` J D2F*o,@A y\>>B*yz:W|iOZ {"+M' 8upGOiX(Sfz7OS Q4|(we;~V^mޜ{=|WرTr|k4IJRgOge/`"}RIENDB`cache/frame_27.png000064400000000355150211530670007722 0ustar00PNG  IHDR}}NfPLTEٟIDATx;0Dm.(|&#"ADRfCx6X8.t^1`!GGrn@1 ;d-JYⅱ/vF[[ xե[vYgfo0IENDB`cache/frame_3.png000064400000000223150211530670007626 0ustar00PNG  IHDRl]LPLTEٟHIDATxc` `1` "f}`_ @+H$ &jA#)_lIENDB`cache/frame_18.dat000064400000000373150211530670007706 0ustar00xA 0E]օ,2;s&͚hO1&09OIv@DD &ىKXFv<dq9<%h Ys !(ds;~||b(Yůg#`KSĶsidߍLg:әt/gmkM3{4rTQes><әt3;H#љt3Y+oghٽlnF>i^#awm;g~pgNs{6zp'cache/frame_8.png000064400000000314150211530670007634 0ustar00PNG  IHDR11IR_PLTEٟIDATx 0DU@Y@) 0O`VAipGL5OO@Fa(^ٸ?9[_StO9Qy]&=2ICƖJg99Gߟ;IENDB`cache/frame_23.png000064400000000334150211530670007713 0ustar00PNG  IHDRmm6}PLTEٟIDATxc`_jW?0"q pς( ~`` EH0E G`YdU0*G Y4GSv4#;ԒmEFG +Ԑ\ze]QƭE2pOIENDB`cache/frame_8.dat000064400000000311150211530670007615 0ustar00xA E֓]Do6صU)/? -f@L  TnBNH1FNx$U8IN w2I]ƢYiacFcache/frame_13.dat000064400000000337150211530670007701 0ustar00xA E֓]Do6j& UCy&DRv{*DGr2)I\ Rvv)$"R'\:,˸.{_Du >NzIYdc}^,K2M\eQeQeyhbnbo2b+YE]eQeQ( iy}<:٘nv9-_X{.GۣU.]EjJcache/frame_37.png000064400000000427150211530670007723 0ustar00PNG  IHDR寙PLTEٟIDATx헱 0Em6``%#Pe*`MD>ŹK9w1ҡbH K`/^p& [s6".z\ Kru ]Ztcu .[!_>|߻wK]ώgR׳;=Szte{˸cҝ%=+լ8%]O)_t=IENDB`cache/frame_20.png000064400000000341150211530670007706 0ustar00PNG  IHDRaa]PLTEٟIDATx10 E*b: ѩJn+tALLl/ӓ#[2_/@P7B\N27mܱV~Ց wĦNOY rzJv"_\÷@gl[{Л%.`޴4r-=/tN3IIENDB`cache/frame_9.png000064400000000307150211530670007637 0ustar00PNG  IHDR55(13PLTEٟ|IDATx PC+[Wp(ʼn,t7Ļ L9`PNQgcԼQ P=O\ i2?}N?89z-Ͽ_}*mlO/gxx H[@$IENDB`cache/frame_38.png000064400000000427150211530670007724 0ustar00PNG  IHDRjlPLTEٟIDATx1 @E'U!#dXXXW4e-Ef0 {m(?V@ Lm ó 8w˟nBÉϽLN4C:{qI"'~8HFT]T]T]T }5i<'FYXcTMhؤ _3:tIENDB`cache/frame_35.png000064400000000363150211530670007720 0ustar00PNG  IHDRPLTEٟIDATx10O)MnnsF4^ᳶβ9IpaN(3%LfNh@0ST, X}9o4:MN{`kޥ#M&w;B 6!7\WEIENDB`cache/frame_12.png000064400000000330150211530670007705 0ustar00PNG  IHDRAA9[PLTEٟIDATxc`00ԂY\0֟`"P0p``/D bPP{zY#! ); gYS/0 A6@bpupV-cM-IENDB`cache/frame_2.png000064400000000220150211530670007622 0ustar00PNG  IHDR' PLTEٟEIDATxc`} cX@V}y)@+H$ &jA#BpekIENDB`cache/frame_39.dat000064400000000624150211530670007710 0ustar00xAn0Ьu%n7'"ta,:S{:9rniiӚrIƶSIYAڔӯiu޵vߺ;r&3ϻǙ0k=d^oe2cwbJھlٲe˖-[`nGVҎ;imڷ[-[lٲe˖-[lٲVvʚLs޲e˖-[lٲe˖-`i``z0-[lٲe˖-[lٲ VvʚLs޲e˖-[lٲe˖-`i``z0-[lٲe˖-[l9mNSmJ)Uv}ep_j; c`{ vƿp{&Ԗ6]OisoD!Ocache/mask_4/mask_141_4.dat000064400000000376150211530670011230 0ustar00x 0}&sa4j) ,0"Csp 轗cl-RL91u3t]}k?%1jvnn47 MH5l3TyOSp 7p 7Qn䩅ƍFҧnnkSr{M}Jnnq)O577p 7p 7oyrWq~S-*O%VM`5 ]lDcache/mask_4/mask_77_4.dat000064400000000242150211530670011150 0ustar00x 0E?jFe80 uN0lB6:h<Ce\, ܗ~& rd0 Sz7z+oVu:7zWo S)mo3 Oy;:*h>aCecache/mask_4/mask_105_4.dat000064400000000270150211530670011221 0ustar00xK 0 D=Mr˹A TeEFL2 #鹢_I!딤Ѻ-իkmO]sS T6*'8 N$'NZ^/#\p\p># \p\p#>qp\p.$Iq dGR_4 cache/mask_4/mask_109_4.dat000064400000000266150211530670011232 0ustar00xA нrݔl,:"_Y =Qcֹɇ#m3u[5_=߶%B^c8-ܸqƍ[-K*}qߜܸqƍ>OInܸqM'Is7nmƫ[>mzri'nf}|b6ͧcache/mask_4/mask_85_4.dat000064400000000232150211530670011146 0ustar00x1 EwOr]J !`7< jv.wOj搑>˯׷y ھK@[%"^W5ӟ."L͋R+^W20Px+^e?:f0<.zoN$Zcache/mask_4/mask_117_4.dat000064400000000317150211530670011226 0ustar00x н_s]4Dgn2Jj}ҾRsSWGRɧ)5Em#ܯk_"z3\rʕ+r Lk|/{;'Μ5g;;Y}Vgw,wqwqw>9wqwq>3gY;[ww?P3Ƙggt퐮;].3w4Acache/mask_4/mask_57_4.dat000064400000000202150211530670011142 0ustar00xK0D97 jb",X}WDյ{ fѱDx"$TgO먌d.vH~lyiy(J͍'A@UwAyX B"II"Ug㨻FE wAQoNw!%܅E>_Acache/mask_4/mask_121_4.dat000064400000000320150211530670011213 0ustar00x1 0>r6V2c,4FqkQ?vFy;c<Te9C9C9~6Sʇ겺!r!r!ۘse9C9C94_Ɯ|.r!r!s/s0 2r!r8}DwrDXΡ|x|!2cache/mask_4/mask_149_4.dat000064400000000403150211530670011227 0ustar00x !н_sm +XӋ9=.=Zka]ޒ> Kjo |SSWKZm׌j\Ъ2 W\qW\q"~ jvtv_\qW\qW\q%g3 }+++ r9ArW\qW\qŕA g3WA W\qW\qW]V~v{D3Ȝ!\W^r)r)r]yPuw 4˩|r)r)rNKT>U}N9SN9SN957^|s)r)rʩ99RPSuSN9SN9SN95w/eE>U9SN9SN9>|*9͊`?.:1~ZNK'cache/mask_4/mask_113_4.dat000064400000000312150211530670011215 0ustar00xA н_Jb)t&BBK_ֳ6C+5/q_ghfCbH+p;WK?Gt *G9r|c`c9FKHq49rȑ#DžUG*G9r>}rU*G9r|c[cN[_=׫5^J 1*qvcache/mask_4/mask_45_4.dat000064400000000170150211530670011143 0ustar00xA !EFلSL\I-3[v/v1:wt8.m4Z4gr7yA#%ֽq}srw#O<=<|&˷Re_ <>cache/mask_4/mask_29_4.dat000064400000000116150211530670011145 0ustar00x30@CCC8 \bH KEBHH$6A8I@#^X"{%^i/,6cache/mask_4/mask_173_4.dat000064400000000453150211530670011231 0ustar00xK 1}Nrna ~ZY!Jt^5(/jkz[pj_?~v:|jwՖ_mXzo6?ny%y>1Lb}};8 |퇏ʯtm8ܪsP 'pɋݟg J{qs$ΉDQw8N8Nn;;'uGN8N8h>DQw8N8Nh=Qw8N8ᄓ;}$+ɝ]FNc$N'QI|hdcache/mask_4/mask_129_4.dat000064400000000334150211530670011230 0ustar00x;0ާ4h U(\Hyu'˯ NҷDqs|>q|o} A)ppAh +]Z9&h\8}A_s8}A_s8}A_s8t釃 ^}aBxDB<ƥScache/mask_4/mask_61_4.dat000064400000000204150211530670011137 0ustar00xA 0F^Jk(C`s2I{Y:@tΡ] ]~JoR]Mozo5(y?Azěӻ^q:|ȇBy>Ay~pwscache/mask_4/mask_25_4.dat000064400000000114150211530670011137 0ustar00x30@CCCˀ D!G 9H.t8Gi7>58"Aal`A]vcache/mask_4/mask_97_4.dat000064400000000260150211530670011152 0ustar00xA 0 }My)^Z!q3mXЈgދ$P'?{vﻕru3vuijSWiM%|WKp8!AaTy?epq<08p [ɭ%8_WTϭ!ϭ.8ppH y1>cache/mask_4/mask_93_4.dat000064400000000250150211530670011145 0ustar00xK ὧIn$}PŌB]N@%sfkҫ}CzoA}aʽ2|~D&l=Ywq}q\EYjK_ywqwz$==;_݋>+pH9Dicache/mask_4/mask_165_4.dat000064400000000444150211530670011232 0ustar00xA 1 }Or."*?fPLHIkΫZQ8 Gyqk-n5+?|֎kKnEŹK.K.?2.|EJ{2<:.Ku\K.K.ǝmu)_8\r%\r%\Џ;'2!_8\r%\r%\Џ;'2!_\r%\r%\rinC?nn9 RK.K.;.HqY'ݽNF?K㕢,R| My*3cache/mask_4/mask_41_4.dat000064400000000131150211530670011134 0ustar00x30@CCC$p22UM ePDrR'IPIu;uL`ɀE%NRURN$BQTIH1F?cache/mask_4/mask_73_4.dat000064400000000225150211530670011145 0ustar00xA 0 yM顴)1-lE3=}(9TdE/eO ZOŻKY;pS5+NI| "ev+DݓNs'OWkI̞Fri9& ]?Acache/mask_4/mask_81_4.dat000064400000000231150211530670011141 0ustar00xA 0 yMyXE m7"892ѸQ1ݳ+xx;t35DIY1x\:u}e/ #Th< UBz<5G<5{G<5<饫>]Urxu cache/mask_4/mask_69_4.dat000064400000000216150211530670011152 0ustar00x;0CwN\~;C$3$<)/meΥT2 :]^VV%zAnpvs"yyy)zdu6Gȋi^/qGqGqdV_ӚkqGqG?9JxkQf{ɞnGy}D82D)66cache/mask_4/mask_153_4.dat000064400000000406150211530670011225 0ustar00x10ޯsi,')p!4.;WUmj=.NO>Tڍ[S7vۜgq? {peo383838{YXz,_OYfe3s38383\C!Ms38383r \C?37938383\C!07M8383q,mMrskWv3~W WBcache/frame_32.dat000064400000000511150211530670007674 0ustar00x ־. Dl, Mz6Ç gcJD;'.AIqމI,IrYFk%DOy|EDD(L_Y>*ߚ?aOkL_<[c>c˘uLI%#0#0#otѢ}4fv_)Eph5R881#0#0itZ#0#0#0itZ#0#0#0itZl0#09q"HܜHQ"L5}-Y׾k`>z鸳4&p!!`:5cache/frame_22.png000064400000000342150211530670007711 0ustar00PNG  IHDRiiLyPLTEٟIDATxc`00"q30".pP/2" zA,eo`^,A); gjʢr/rG +ԐdH%0HU+hZT.# JRGIENDB`cache/frame_38.dat000064400000000546150211530670007712 0ustar00xA0ЎuA2;Нk(gytp9$D\e^'t-aIFMSkIŤ:7|LkN8N7i}i,[WgӴ?31iN}}=OM:4)SL2eʔ)SL#$ JJM:}]L٧SQL2eʔ)SL2աPt(:)SL2eʔ)S:ECq2eʔ)SL2eʔECѡ8O2eʔ)SL2eTCѡPL2eʔ)SL2ݓsJCIKԂi93n_ +Ri4\g;% }ancache/frame_10.dat000064400000000314150211530670007671 0ustar00xM F]sIX;n6 : +_^JrfA2KB" dd9 $at)dOgUf.gzʜ31zMQq!,8uAUOAH|Թܧ|CNcS` 9-L8F ݙztf͓5}fzoÉdW||<cache/frame_25.png000064400000000362150211530670007716 0ustar00PNG  IHDRuuJ<PLTEٟIDATx!@E*loi$4HAMӓp+i`;T EIvdAjse9Z+Dޫw>?ȃ'Z|"0pԩc?6䎼HߟeonnrL?>.[N 1IENDB`cache/frame_11.dat000064400000000322150211530670007671 0ustar00xM F]sIXn7 F .44/ـR>CAC3t4ShD0G*߷6h̍?Өߙy7愄L1ro,UK)٢nvEװ.f^hjPý7kf74e]U7@xens~fjx؉\佤gKSw MC| zAJcache/frame_7.png000064400000000275150211530670007641 0ustar00PNG  IHDR--pPLTEٟrIDATx h{cieӄD? >&%l@PX"bnEv<!<J;Bu Z .4}~KK%aqq5[IENDB`cache/frame_28.dat000064400000000476150211530670007713 0ustar00xA E]{&.fvr ܬh$tiwI,?/@/1 SCVol+'@w+[9Pg5޽.rv~Y7RA9 ngvSuwPԗAҾ8rS}4y0Sq0 `&>^1OHG8 ͛oa``0 y;0 ` w" `0 / D0 %AM$*~OG-?frlf}+&}`3}> op`1_90'cache/frame_27.dat000064400000000434150211530670007704 0ustar00xA ᮹uNn7MZkR\㪙&/_P,&繒}hIKh69LRK-Ukstw>=ֺ';Bso>_1󩕞j\{),?ǐj~h:vرcǎ;vf?3Sٱwsyǎ;vرcǎ999;vرcǎ;ssss:رcǎ;ڝ8'2.%^d^뻽2;}8]}/r{;{~t..]}zS/{cache/frame_18.png000064400000000344150211530670007720 0ustar00PNG  IHDRYYoPLTEٟIDATxc`ja\a8w{zCah az@Ap 0a h70|DGA332!JL.2M)t XR BA2z\MC"s8ϽHIENDB`cache/mask_1/mask_141_1.dat000064400000000260150211530670011212 0ustar00x1 >946)3$`s uʮ>Wd )g'M{3\d6ubذaÆ 6lؼn]Nذ9FްaÆ 6lذa3a#oذaÆ 6lذذ5e16lذaÆ ]Sbk6lذaÆ mͤ;CcfIdsGcache/mask_1/mask_173_1.dat000064400000000332150211530670011217 0ustar00x1 Ӕ_Υ''@y]X1?"g:1犝fn˶˻mm.?lٲe˖-F>glٲ2lٲe˖-[lٲeO`˖e˖-[lٲe˖-[l lٲlٲe˖-[lٲeVO`˖e˖-[lٲe˖-[z0}[z0y˖-[lٲe˖-[Ee[hOVWö=t*|cache/mask_1/mask_149_1.dat000064400000000272150211530670011225 0ustar00x1 Ӕ_΅qH_Xci#Gd̘Ք՛gLU^ݮVR>dKVXbŊ+VXeoXJ_bŊ+VXb;ݙ+}Ŋ+VXbŊ+VAVngŊ+VXbŊ}+ +VXbŊVj>hewf*`uTqcache/mask_1/mask_49_1.dat000064400000000124150211530670011140 0ustar00x30C| Ht]JvC^ y ; FH;IpnhYvS ]b먡iMx;cache/mask_1/mask_89_1.dat000064400000000171150211530670011146 0ustar00x1 Ӕ_΅Nh}%@ iDOH*c"DTKdȩN Lk˦LsFuФ;0aJoܧ^Ďc„DŽ <}an O~SG&cache/mask_1/mask_121_1.dat000064400000000222150211530670011206 0ustar00x1 н\CPbїEVcache/mask_1/mask_65_1.dat000064400000000143150211530670011137 0ustar00x1 /D "f=)v!aWyd5e a [=*I 0d5(_V!V?_} "cache/mask_1/mask_85_1.dat000064400000000162150211530670011142 0ustar00x1 н\]4AA hM\QjsAkUjmun2RΚ5:k;jƲ[eo[o[kZcache/mask_1/mask_117_1.dat000064400000000206150211530670011215 0ustar00xֻ >ӘK$^ 8YQSV'z8jzʇ^]סekXYYYYYYYjݵ# +yeeeeeeee#WVVVVVVVV;"+yeeeeeeel'e;b&^9{/J$pcache/mask_1/mask_165_1.dat000064400000000320150211530670011215 0ustar00x1 Ӕ_ΥLK^#FYWt%ˍ4rM,QXdɒ%K,YdҼdɒ%K,Ydɒ%K%K %K,Ydɒ%Kv2$Kv,Ydɒ%K,Yʐ8K楷%K,Ydɒ%K2$K,K,Ydɒ%K,ZVK<βyy )cache/mask_1/mask_37_1.dat000064400000000070150211530670011135 0ustar00x30C,&e@ @fQSd5j 7 YQfHAcache/mask_1/mask_113_1.dat000064400000000211150211530670011205 0ustar00x1  -8fL(pBlDM9";-;?1p{\%-3:@ad4*Nadddddd########c]751xYucache/mask_1/mask_45_1.dat000064400000000122150211530670011132 0ustar00x30C\ Ht2OiNP͆DQل ?M'3PMmN)cToҀycache/mask_1/mask_81_1.dat000064400000000162150211530670011136 0ustar00x1 i6h/ 0'd+|1Bţ>`dY0bĈqӨx:FF F12k1bhT2z3?RX;rcache/mask_1/mask_177_1.dat000064400000000342150211530670011224 0ustar00x1 Ep0X,a#r}6}nj~\8ƌ3f̘1cƌ7{3f,y3f̘1cƌ3fX_`X&3f̘1cƌ3f̘M_1cy̘1cƌ3f̘1cƌ+3f,y3f̘1cƌ3fX_bX&3f̘1cƌ3fx2dX'x[cy| 3cache/mask_1/mask_93_1.dat000064400000000175150211530670011145 0ustar00x; >_.4Iy킎`)-5*(of[sm}6YM ;;;;;G{zطz1vw}=wuL%?"=~eicache/mask_1/mask_69_1.dat000064400000000146150211530670011146 0ustar00x1 /"ҐVoCQDg#-IVuy2mez.hYiv ,X$DdƩYtڅλ0$ήꝝga7yٯ痽Y??{{Dcache/mask_1/mask_101_1.dat000064400000000173150211530670011211 0ustar00x1 н\QEd  1N<#Ֆ-7u.lԦeiXXXXXRZVVeIo1,,,,,v%?gaaaaY K&K=/+ۍ˱ގcache/mask_1/mask_29_1.dat000064400000000062150211530670011137 0ustar00x30C$2Y2*6 F w2h_zcache/mask_1/mask_133_1.dat000064400000000244150211530670011215 0ustar00x1 Ӕ_΅hh|"zۉ-*dNHQĢR ,X`c9Y(na_` ,X,X,X` #:8  ,X`Bd¾` ,X|ϢY\X; 7-; `cache/mask_1/mask_105_1.dat000064400000000202150211530670011206 0ustar00x1 Ӕ_Υb KB?"*#WʘtgӎJqUM9TLLvǤLLLLLLzgG01111yiߘ4m=՛n+2cache/mask_1/mask_61_1.dat000064400000000135150211530670011134 0ustar00x30CbpPi`@&H^nadQG{nnо V/Q2'? *A )xScache/mask_1/mask_109_1.dat000064400000000202150211530670011212 0ustar00xֱ >ӘK}:!iY'*3]fsmb[JƶŖK9}cccccc'u.6Ʀs6666R[^g{/lٷ 7͂cache/mask_1/mask_157_1.dat000064400000000301150211530670011215 0ustar00x1 >94Sd/51V)SkJv7eGcǎ;vرc]Zٱc'رcǎ;vر+رg;vرcǎ;}V`N+رcǎ;v:;v;vرcǎ;;}Vޱcǎ;vص'vz#;]klwoA`cache/mask_1/mask_145_1.dat000064400000000263150211530670011221 0ustar00x!0@k 4a)q2i.YCUO{35UZFn]fN>bdwtzJF}F1bĈ#F(F6r1bĈ#F1E1ilF1bĈ#FtF#F1bĈ#FtZ}##F1bĈleHGܣ@ٝcache/mask_1/mask_21_1.dat000064400000000052150211530670011126 0ustar00x30C (Ԓ"J``` I- Scache/mask_1/mask_53_1.dat000064400000000127150211530670011136 0ustar00x30CB ]h.BvA 1$ 5jk45"AKhHi h_9Xcache/mask_1/mask_25_1.dat000064400000000060150211530670011131 0ustar00x30C( p #C=P`0bS>vcache/mask_1/mask_33_1.dat000064400000000065150211530670011135 0ustar00x30C42 *PA; qQ34CA,ftcache/mask_1/mask_97_1.dat000064400000000170150211530670011144 0ustar00x1 0н1\tncKSL2eʔ)SL2M SLSL2eʔ)SL2M}LSSL2eʔ)SLeSy)SŔ)SL2eʔ)S;ٔ)S;)SL2eʔ)Sv()Sv()SL2eʔ)SLdT6}a*3mljmzC'cache/frame_16.png000064400000000323150211530670007713 0ustar00PNG  IHDRQQAuPLTEٟIDATxc`j? P@ 6;]/C?T0@8كYC= *o`Z??#  "w#G qW$H k،6 مIENDB`cache/frame_26.dat000064400000000450150211530670007701 0ustar00xA Eօ,t77ћU E)i7*~cXEBFC6:&L,Mv.KgոYM>>mۚ?vmg?ұηdCUIkE\Msfafa>[sӈ9쬩ެ8b]LgEo w1cache/frame_5.dat000064400000000203150211530670007612 0ustar00x1 Eu7ЛZ|ND B0@R$l,->VKZ[^zmnŖ;mncache/frame_20.dat000064400000000372150211530670007676 0ustar00xM 3xެMXP{Y ^f}iTI(:!0RN׎98k;]#Y2\YUsJg=wQJuSu0`0fu]_b0 `@nEnEnŝ0w(KX yi|xnu80k s?Kw8HDvz7cache/frame_13.png000064400000000322150211530670007707 0ustar00PNG  IHDREE&CjPLTEٟIDATxݒ 0 EO^T'pHsЋEbLltA?|G4LRA4yuy &d U߬S[]5Z;a5V۞A[Z˴VՃI0ZZZZZZZZZZZZZZ=-Lhi`VFK?ݧhioJ0}ocache/mask_2/mask_53_2.dat000064400000000111150211530670011131 0ustar00x30CB p Y]TE .Cu$Q]Fu_#Ph5ur.kccache/mask_2/mask_109_2.dat000064400000000164150211530670011223 0ustar00x1 0н1\@Nֈ/&E*cQqŃ zf$rM*F>cache/mask_2/mask_141_2.dat000064400000000240150211530670011212 0ustar00x= нt*-?M[hU]WB;dwSj>l fƄȚ44& )OȚYF4444444444c4~9S:3ЌטpǮ>cache/mask_2/mask_25_2.dat000064400000000051150211530670011133 0ustar00x30C.#2 3DCCLSBvcache/mask_2/mask_45_2.dat000064400000000104150211530670011134 0ustar00x30C j4U2ېLp!hTpW5;գ1?HTS"SU5t2Tƅ+:tcache/mask_2/mask_61_2.dat000064400000000116150211530670011135 0ustar00x30Cp SM nCjƯ={TM@|Thj={T7n2ZtM\=.{cache/mask_2/mask_125_2.dat000064400000000202150211530670011212 0ustar00x! PӔ_@ U(kp@^Mڮ5-:VF_\t:NtyNqt:NtG;Nt:.8:NtzA}yNq;+n&cache/mask_2/mask_129_2.dat000064400000000221150211530670011217 0ustar00x1 0н_KVڡ'.!w]A0X~  !࣠fK# xFy4 vey@^+  ~  L#veIcache/mask_2/mask_29_2.dat000064400000000055150211530670011143 0ustar00x30C$\[d8 Tbp7L!cache/mask_2/mask_73_2.dat000064400000000136150211530670011142 0ustar00x! CQi_CFRT`Ʒ2ؗe&ϐ !!!MP?!L$$$zGBBʖߐR4} Ocache/mask_2/mask_105_2.dat000064400000000167150211530670011222 0ustar00x! @\Mip4s 6ꙑYs"7&)=; ܌"H$ҏ;|IH$Dt#}OH$DHH$IZ#HgKJt$cache/mask_2/mask_33_2.dat000064400000000057150211530670011140 0ustar00x30C \CO.@[ChTTO48S`Q ]Tujwcache/mask_2/mask_145_2.dat000064400000000245150211530670011223 0ustar00x1 нr] ,tQ^&C~ щj~mɾ.FgMDDDDDDDDDDDST׈DHdZL+ɴDDDDDDDDDDD2-'"""""""":BתEYDd cache/mask_2/mask_93_2.dat000064400000000147150211530670011146 0ustar00x1 1^ckµxX F̌-=VD"%CR NA請w:Nz$]t:nCzGݽ/jccache/mask_2/mask_97_2.dat000064400000000157150211530670011153 0ustar00x1 0н_KivH4 s6MqUH1X&U̘f/u-'.[KGGGGGGGGGGH|NG(ttttttttttNF;::::::::::}Nz$ >n A#^AG(t =3{cache/mask_2/mask_177_2.dat000064400000000321150211530670011223 0ustar00x1 E>Y4V$~ ,C&U;Ook5bϙGx9%&&&&&&&&&&&n$OL|v#&&&&&&&&&&&&&bbݍXw#&l7bbbbbbbbbbbbbbM"l7bbbbbbbbbbbbbbMa!&݈3)UGt ѫe+FWZEm&gއFѶhF+t/FYvFj[*7acache/mask_2/mask_117_2.dat000064400000000175150211530670011224 0ustar00x1 >94!m dOs\0X,la5#E>Z[ַRT*JR?Q-*T*JR?UW*JRTݟ+JRԤ~m5;S&+cache/mask_2/mask_113_2.dat000064400000000175150211530670011220 0ustar00x10_šЪ0ځD\5*{#bH'o+vUR1PD"H$>D"H$DH$D"Q&WerH$D"*x[(?/'ndcache/frame_14.png000064400000000325150211530670007713 0ustar00PNG  IHDRIIKPLTEٟIDATxݒ 0 Y؂&P &AT(Y (ii $6aɀuTDÍĘq,lŬiDa<$v~ 򽅧P[VqGc-ܭT;"|uvjtfnxh2^f7rIENDB`cache/frame_21.dat000064400000000404150211530670007673 0ustar00xA E]sIX;n6Upв]٘< i-eW)ŕ…H\jvqHL\6ЅrILܹ%@Vv(P4|Xngɝ~]Du1Us S\,2N?DKF-:eJ]p_,a0` X` w,` X]5 Y4{2vJs9)u۹,]^_7$_cache/frame_30.png000064400000000377150211530670007720 0ustar00PNG  IHDR"ꉊPLTEٟIDATx햱 0E/B(PD1RE.L(+ 8'|a_e== U 2ht"Md Z>+WR/+uT廯 ӯ嗴u[Sa[kv5+5nJ%+VXbŊ߬u'SRtzZ++VXbŊٟٟٟ+VXb}Ŋ+VXVI+kq[toVZvoNVw}{r<ýR"R] Wr}cache/frame_40.png000064400000000413150211530670007710 0ustar00PNG  IHDRΆPLTEٟIDATxA 0EV9Co.=FW\[ =nUg %aB!o&HReΌ=3oHlZfӑ )XX}8ousPpE?eWW g-[#G>9 -?Nޒ|y|:B};{qzqyIENDB`cache/frame_6.png000064400000000227150211530670007635 0ustar00PNG  IHDR))PLTEٟLIDATxc`Z uH]Dr A/\!rPB1)E/BrIENDB`cache/frame_30.dat000064400000000504150211530670007674 0ustar00xA aܺ f'7͊Vte!6/_0q%N 8/IJ$IN$\' K5߾sN'aqE}IvX?aJϽ+~vR:&Ʈ>IeKsԫ$$L04i+Fԝm_)IB#I8}++tO8O8c1L0L0<L0L0z@z@z@L0L0L0<L0L0uq`H&K9 nPx;d&=Duq΄9~;=%ќT%Qt7w0cache/frame_22.dat000064400000000422150211530670007674 0ustar00xA 0 E]{.]{{{ZBepwe@VERZ3"*2o4y)i#dbdF҅I"4WIu45x.ZS{8k={o.q[:帒qy )t#N8dCj-OOG}:/:sz!)^3kS:}%j{]B+\ W>tZW#giPWSy+\ W>p+\$J ⮔uDgg4~m4b{r;zfQvq UloX {cache/frame_33.dat000064400000000527150211530670007704 0ustar00xA a޺@n7+*L++柮bb*LCc kHrjJ5Yi~0_TT}e>5b_w͟?\Rai+7W\wLUNL + +jOkc\˩|%o} 8 + + + 3g + + +3g@ + + +:RXB9I=ko/Swؘٯ`gr_ٙYVSYzIefnmQoz >cache/frame_19.dat000064400000000403150211530670007701 0ustar00xA E.No7ћiiRN2W%x@ڜ' u6.*S;}àT zrt%,};)ZLP$qgLdJ;w.]z#[͝Og" B}};w#1Gb;w_C+w@Dfu2N9R7|pWkkcache/frame_29.dat000064400000000465150211530670007712 0ustar00xA a޺ @n7+*4!?J 抮]STf)sI"Ȕb0|"Luٸ,E1\6*uQ?>aυR-rn.ꯋ\T:*)|) , ,x_}:^RUoɢu~މX`XЏЏЏЏ_`X`XЏЏЏ_`X`XЏЏЏЏwbX`PU)D"c{z3<}^?bm잃a.] {Q6uT,9cache/frame_31.png000064400000000404150211530670007710 0ustar00PNG  IHDRkPLTEٟIDATx햱 0E/m6`6Q2nPb XIq Ql*D|rt/ L"^V]wLKX@k7ثg/&bhv)˲Z_[{'O$t;B*7Vjsjsja9:('稍Ϧm[Zy5>l{Td;&n!IENDB`cache/frame_9.dat000064400000000316150211530670007623 0ustar00xA E]sIX;n60+>+X!Dy>5!Dn' v)w>Ers<=E:2?ITzܷ!1e嵼UۥfM=mƔt4jxM͵ލN/8E zBݫ_o3!lSxsT>RR)˻oy#oK,Ydɒ%K,6666,Ydɒ%K,Ydadɒ%K,Ydɒކކކކކ%K,Ydɒ%KzzzzK=,Ydɒ%K,Y24[.!StX>ׅ"91::YtZ3#Fp`MIOIIq}NO8!B>Na"NNi_A33؉qޮsb>vbI8Îg6yZ׷wcache/frame_4.png000064400000000225150211530670007631 0ustar00PNG  IHDR!!m*P,PLTEٟJIDATxc`C\JBCCA_0IS6;]lW+X  6~˴IENDB`cache/frame_1.png000064400000000176150211530670007633 0ustar00PNG  IHDR7PLTEٟ3IDATxc`P_8C1 @]0O-ݐRIENDB`cache/frame_2.dat000064400000000167150211530670007620 0ustar00x͒ F{v& &Y+?Z1S'y!a815&۴HٞclF1#6 f6O7C֏8gIfB\DԻ(cache/frame_36.dat000064400000000562150211530670007706 0ustar00xAn0Ьu%n7 R0Q߰,'c`x5Hs`s3O 0K.-aJyɂ&̿&ux9#{ãy8?OYyXP?8ky˰3X>ocRmfVM؇OȐ!C 'm֑)u&_oM&wUOOq1ٯ,k \4Dl3}qpȈM|$GqAܧxq)82_9Ծrj_e98CZCn4w6]8[p[̆8Mި.qIENDB`cache/frame_29.png000064400000000350150211530670007717 0ustar00PNG  IHDROPLTEٟIDATxc`00Ԣ*U].XC=]~`` E! Q4V&2T5ȁ B B _ lj0~jFkhf4E k  Z|Ij\1qŰ SC]mT(IENDB`cache/frame_33.png000064400000000375150211530670007721 0ustar00PNG  IHDRkl* PLTEٟIDATx1 @EV7PYBsj7j&=jFٷ1֜ @qS^✖9uaT[KƊ~ܱ{˼$;.\%OsdoBcs}Wzo㜞"-IENDB`LICENSE000064400000016742150211530670005563 0ustar00 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. qrmask.php000064400000027740150211530670006565 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('N1', 3); define('N2', 3); define('N3', 40); define('N4', 10); class QRmask { public $runLength = array(); //---------------------------------------------------------------------- public function __construct() { $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); } //---------------------------------------------------------------------- public function writeFormatInformation($width, &$frame, $mask, $level) { $blacks = 0; $format = QRspec::getFormatInfo($mask, $level); for($i=0; $i<8; $i++) { if($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[8][$width - 1 - $i] = chr($v); if($i < 6) { $frame[$i][8] = chr($v); } else { $frame[$i + 1][8] = chr($v); } $format = $format >> 1; } for($i=0; $i<7; $i++) { if($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[$width - 7 + $i][8] = chr($v); if($i == 0) { $frame[8][7] = chr($v); } else { $frame[8][6 - $i] = chr($v); } $format = $format >> 1; } return $blacks; } //---------------------------------------------------------------------- public function mask0($x, $y) { return ($x+$y)&1; } public function mask1($x, $y) { return ($y&1); } public function mask2($x, $y) { return ($x%3); } public function mask3($x, $y) { return ($x+$y)%3; } public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; } public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; } public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; } public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; } //---------------------------------------------------------------------- private function generateMaskNo($maskNo, $width, $frame) { $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for($y=0; $y<$width; $y++) { for($x=0; $x<$width; $x++) { if(ord($frame[$y][$x]) & 0x80) { $bitMask[$y][$x] = 0; } else { $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); $bitMask[$y][$x] = ($maskFunc == 0)?1:0; } } } return $bitMask; } //---------------------------------------------------------------------- public static function serial($bitFrame) { $codeArr = array(); foreach ($bitFrame as $line) $codeArr[] = join('', $line); return gzcompress(join("\n", $codeArr), 9); } //---------------------------------------------------------------------- public static function unserial($code) { $codeArr = array(); $codeLines = explode("\n", gzuncompress($code)); foreach ($codeLines as $line) $codeArr[] = str_split($line); return $codeArr; } //---------------------------------------------------------------------- public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) { $b = 0; $bitMask = array(); $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; if (QR_CACHEABLE) { if (file_exists($fileName)) { $bitMask = self::unserial(file_get_contents($fileName)); } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) mkdir(QR_CACHE_DIR.'mask_'.$maskNo); file_put_contents($fileName, self::serial($bitMask)); } } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); } if ($maskGenOnly) return; $d = $s; for($y=0; $y<$width; $y++) { for($x=0; $x<$width; $x++) { if($bitMask[$y][$x] == 1) { $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); } $b += (int)(ord($d[$y][$x]) & 1); } } return $b; } //---------------------------------------------------------------------- public function makeMask($width, $frame, $maskNo, $level) { $masked = array_fill(0, $width, str_repeat("\0", $width)); $this->makeMaskNo($maskNo, $width, $frame, $masked); $this->writeFormatInformation($width, $masked, $maskNo, $level); return $masked; } //---------------------------------------------------------------------- public function calcN1N3($length) { $demerit = 0; for($i=0; $i<$length; $i++) { if($this->runLength[$i] >= 5) { $demerit += (N1 + ($this->runLength[$i] - 5)); } if($i & 1) { if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { $fact = (int)($this->runLength[$i] / 3); if(($this->runLength[$i-2] == $fact) && ($this->runLength[$i-1] == $fact) && ($this->runLength[$i+1] == $fact) && ($this->runLength[$i+2] == $fact)) { if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { $demerit += N3; } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { $demerit += N3; } } } } } return $demerit; } //---------------------------------------------------------------------- public function evaluateSymbol($width, $frame) { $head = 0; $demerit = 0; for($y=0; $y<$width; $y++) { $head = 0; $this->runLength[0] = 1; $frameY = $frame[$y]; if ($y>0) $frameYM = $frame[$y-1]; for($x=0; $x<$width; $x++) { if(($x > 0) && ($y > 0)) { $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); if(($b22 | ($w22 ^ 1))&1) { $demerit += N2; } } if(($x == 0) && (ord($frameY[$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($x > 0) { if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } for($x=0; $x<$width; $x++) { $head = 0; $this->runLength[0] = 1; for($y=0; $y<$width; $y++) { if($y == 0 && (ord($frame[$y][$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($y > 0) { if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } return $demerit; } //---------------------------------------------------------------------- public function mask($width, $frame, $level) { $minDemerit = PHP_INT_MAX; $bestMaskNum = 0; $bestMask = array(); $checked_masks = array(0,1,2,3,4,5,6,7); if (QR_FIND_FROM_RANDOM !== false) { $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9); for ($i = 0; $i < $howManuOut; $i++) { $remPos = rand (0, count($checked_masks)-1); unset($checked_masks[$remPos]); $checked_masks = array_values($checked_masks); } } $bestMask = $frame; foreach($checked_masks as $i) { $mask = array_fill(0, $width, str_repeat("\0", $width)); $demerit = 0; $blacks = 0; $blacks = $this->makeMaskNo($i, $width, $frame, $mask); $blacks += $this->writeFormatInformation($width, $mask, $i, $level); $blacks = (int)(100 * $blacks / ($width * $width)); $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); $demerit += $this->evaluateSymbol($width, $mask); if($demerit < $minDemerit) { $minDemerit = $demerit; $bestMask = $mask; $bestMaskNum = $i; } } return $bestMask; } //---------------------------------------------------------------------- } CHANGELOG000064400000002307150211530670005760 0ustar00* 1.0.0 build 2010031920 - first public release - help in readme, install - cleanup ans separation of QRtools and QRspec - now TCPDF binding requires minimal changes in TCPDF, having most of job done in QRtools tcpdfBarcodeArray - nicer QRtools::timeBenchmark output - license and copyright notices in files - indent cleanup - from tab to 4spc, keep it that way please :) - sf project, repository, wiki - simple code generator in index.php * 1.1.0 build 2010032113 - added merge tool wich generate merged version of code located in phpqrcode.php - splited qrconst.php from qrlib.php * 1.1.1 build 2010032405 - patch by Rick Seymour allowing saving PNG and displaying it at the same time - added version info in VERSION file - modified merge tool to include version info into generated file - fixed e-mail in almost all head comments * 1.1.2 build 2010032722 - full integration with TCPDF thanks to Nicola Asuni, it's author - fixed bug with alphanumeric encoding detection * 1.1.3 build 2010081807 - short opening tags replaced with standard ones * 1.1.4 build 2010100721 - added missing static keyword QRinput::check (found by Luke Brookhart, Onjax LLC) INSTALL000064400000003667150211530670005611 0ustar00== REQUIREMENTS == * PHP5 * PHP GD2 extension with JPEG and PNG support == INSTALLATION == If you want to recreate cache by yourself make sure cache directory is writable and you have permisions to write into it. Also make sure you are able to read files in it if you have cache option enabled == CONFIGURATION == Feel free to modify config constants in qrconfig.php file. Read about it in provided comments and project wiki page (links in README file) == QUICK START == Notice: probably you should'nt use all of this in same script :) encode('PHP QR Code :)'); QRspec::debug($tab, true); == TCPDF INTEGRATION == Inside bindings/tcpdf you will find slightly modified 2dbarcodes.php. Instal phpqrcode liblaty inside tcpdf folder, then overwrite (or merge) 2dbarcodes.php Then use similar as example #50 from TCPDF examples: true, 'padding' => 4, 'fgcolor' => array(0,0,0), 'bgcolor' => false, //array(255,255,255) ); //code name: QR, specify error correction level after semicolon (L,M,Q,H) $pdf->write2DBarcode('PHP QR Code :)', 'QR,L', '', '', 30, 30, $style, 'N'); qrencode.php000064400000041154150211530670007062 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRrsblock { public $dataLength; public $data = array(); public $eccLength; public $ecc = array(); public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs) { $rs->encode_rs_char($data, $ecc); $this->dataLength = $dl; $this->data = $data; $this->eccLength = $el; $this->ecc = $ecc; } }; //########################################################################## class QRrawcode { public $version; public $datacode = array(); public $ecccode = array(); public $blocks; public $rsblocks = array(); //of RSblock public $count; public $dataLength; public $eccLength; public $b1; //---------------------------------------------------------------------- public function __construct(QRinput $input) { $spec = array(0,0,0,0,0); $this->datacode = $input->getByteStream(); if(is_null($this->datacode)) { throw new Exception('null imput string'); } QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec); $this->version = $input->getVersion(); $this->b1 = QRspec::rsBlockNum1($spec); $this->dataLength = QRspec::rsDataLength($spec); $this->eccLength = QRspec::rsEccLength($spec); $this->ecccode = array_fill(0, $this->eccLength, 0); $this->blocks = QRspec::rsBlockNum($spec); $ret = $this->init($spec); if($ret < 0) { throw new Exception('block alloc error'); return null; } $this->count = 0; } //---------------------------------------------------------------------- public function init(array $spec) { $dl = QRspec::rsDataCodes1($spec); $el = QRspec::rsEccCodes1($spec); $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); $blockNo = 0; $dataPos = 0; $eccPos = 0; for($i=0; $iecccode,$eccPos); $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } if(QRspec::rsBlockNum2($spec) == 0) return 0; $dl = QRspec::rsDataCodes2($spec); $el = QRspec::rsEccCodes2($spec); $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); if($rs == NULL) return -1; for($i=0; $iecccode,$eccPos); $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } return 0; } //---------------------------------------------------------------------- public function getCode() { $ret; if($this->count < $this->dataLength) { $row = $this->count % $this->blocks; $col = $this->count / $this->blocks; if($col >= $this->rsblocks[0]->dataLength) { $row += $this->b1; } $ret = $this->rsblocks[$row]->data[$col]; } else if($this->count < $this->dataLength + $this->eccLength) { $row = ($this->count - $this->dataLength) % $this->blocks; $col = ($this->count - $this->dataLength) / $this->blocks; $ret = $this->rsblocks[$row]->ecc[$col]; } else { return 0; } $this->count++; return $ret; } } //########################################################################## class QRcode { public $version; public $width; public $data; //---------------------------------------------------------------------- public function encodeMask(QRinput $input, $mask) { if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { throw new Exception('wrong version'); } if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { throw new Exception('wrong level'); } $raw = new QRrawcode($input); QRtools::markTime('after_raw'); $version = $raw->version; $width = QRspec::getWidth($version); $frame = QRspec::newFrame($version); $filler = new FrameFiller($width, $frame); if(is_null($filler)) { return NULL; } // inteleaved data and ecc codes for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { $code = $raw->getCode(); $bit = 0x80; for($j=0; $j<8; $j++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); $bit = $bit >> 1; } } QRtools::markTime('after_filler'); unset($raw); // remainder bits $j = QRspec::getRemainder($version); for($i=0; $i<$j; $i++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x02); } $frame = $filler->frame; unset($filler); // masking $maskObj = new QRmask(); if($mask < 0) { if (QR_FIND_BEST_MASK) { $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); } else { $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); } } else { $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); } if($masked == NULL) { return NULL; } QRtools::markTime('after_mask'); $this->version = $version; $this->width = $width; $this->data = $masked; return $this; } //---------------------------------------------------------------------- public function encodeInput(QRinput $input) { return $this->encodeMask($input, -1); } //---------------------------------------------------------------------- public function encodeString8bit($string, $version, $level) { if(string == NULL) { throw new Exception('empty string!'); return NULL; } $input = new QRinput($version, $level); if($input == NULL) return NULL; $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); if($ret < 0) { unset($input); return NULL; } return $this->encodeInput($input); } //---------------------------------------------------------------------- public function encodeString($string, $version, $level, $hint, $casesensitive) { if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { throw new Exception('bad hint'); return NULL; } $input = new QRinput($version, $level); if($input == NULL) return NULL; $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); if($ret < 0) { return NULL; } return $this->encodeInput($input); } //---------------------------------------------------------------------- public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) { $enc = QRencode::factory($level, $size, $margin); return $enc->encodePNG($text, $outfile, $saveandprint=false); } //---------------------------------------------------------------------- public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = QRencode::factory($level, $size, $margin); return $enc->encode($text, $outfile); } //---------------------------------------------------------------------- public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = QRencode::factory($level, $size, $margin); return $enc->encodeRAW($text, $outfile); } } //########################################################################## class FrameFiller { public $width; public $frame; public $x; public $y; public $dir; public $bit; //---------------------------------------------------------------------- public function __construct($width, &$frame) { $this->width = $width; $this->frame = $frame; $this->x = $width - 1; $this->y = $width - 1; $this->dir = -1; $this->bit = -1; } //---------------------------------------------------------------------- public function setFrameAt($at, $val) { $this->frame[$at['y']][$at['x']] = chr($val); } //---------------------------------------------------------------------- public function getFrameAt($at) { return ord($this->frame[$at['y']][$at['x']]); } //---------------------------------------------------------------------- public function next() { do { if($this->bit == -1) { $this->bit = 0; return array('x'=>$this->x, 'y'=>$this->y); } $x = $this->x; $y = $this->y; $w = $this->width; if($this->bit == 0) { $x--; $this->bit++; } else { $x++; $y += $this->dir; $this->bit--; } if($this->dir < 0) { if($y < 0) { $y = 0; $x -= 2; $this->dir = 1; if($x == 6) { $x--; $y = 9; } } } else { if($y == $w) { $y = $w - 1; $x -= 2; $this->dir = -1; if($x == 6) { $x--; $y -= 8; } } } if($x < 0 || $y < 0) return null; $this->x = $x; $this->y = $y; } while(ord($this->frame[$y][$x]) & 0x80); return array('x'=>$x, 'y'=>$y); } } ; //########################################################################## class QRencode { public $casesensitive = true; public $eightbit = false; public $version = 0; public $size = 3; public $margin = 4; public $structured = 0; // not supported yet public $level = QR_ECLEVEL_L; public $hint = QR_MODE_8; //---------------------------------------------------------------------- public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4) { $enc = new QRencode(); $enc->size = $size; $enc->margin = $margin; switch ($level.'') { case '0': case '1': case '2': case '3': $enc->level = $level; break; case 'l': case 'L': $enc->level = QR_ECLEVEL_L; break; case 'm': case 'M': $enc->level = QR_ECLEVEL_M; break; case 'q': case 'Q': $enc->level = QR_ECLEVEL_Q; break; case 'h': case 'H': $enc->level = QR_ECLEVEL_H; break; } return $enc; } //---------------------------------------------------------------------- public function encodeRAW($intext, $outfile = false) { $code = new QRcode(); if($this->eightbit) { $code->encodeString8bit($intext, $this->version, $this->level); } else { $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); } return $code->data; } //---------------------------------------------------------------------- public function encode($intext, $outfile = false) { $code = new QRcode(); if($this->eightbit) { $code->encodeString8bit($intext, $this->version, $this->level); } else { $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); } QRtools::markTime('after_encode'); if ($outfile!== false) { file_put_contents($outfile, join("\n", QRtools::binarize($code->data))); } else { return QRtools::binarize($code->data); } } //---------------------------------------------------------------------- public function encodePNG($intext, $outfile = false,$saveandprint=false) { try { ob_start(); $tab = $this->encode($intext); $err = ob_get_contents(); ob_end_clean(); if ($err != '') QRtools::log($outfile, $err); $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin)); QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint); } catch (Exception $e) { QRtools::log($outfile, $e->getMessage()); } } } index.php000064400000006773150211530670006401 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ echo "

PHP QR Code


"; //set it to writable location, a place for temp generated PNG files $PNG_TEMP_DIR = dirname(__FILE__).DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR; //html PNG location prefix $PNG_WEB_DIR = 'temp/'; include "qrlib.php"; //ofcourse we need rights to create temp dir if (!file_exists($PNG_TEMP_DIR)) mkdir($PNG_TEMP_DIR); $filename = $PNG_TEMP_DIR.'test.png'; //processing form input //remember to sanitize user input in real-life solution !!! $errorCorrectionLevel = 'L'; if (isset($_REQUEST['level']) && in_array($_REQUEST['level'], array('L','M','Q','H'))) $errorCorrectionLevel = $_REQUEST['level']; $matrixPointSize = 4; if (isset($_REQUEST['size'])) $matrixPointSize = min(max((int)$_REQUEST['size'], 1), 10); if (isset($_REQUEST['data'])) { //it's very important! if (trim($_REQUEST['data']) == '') die('data cannot be empty! back'); // user data $filename = $PNG_TEMP_DIR.'test'.md5($_REQUEST['data'].'|'.$errorCorrectionLevel.'|'.$matrixPointSize).'.png'; QRcode::png($_REQUEST['data'], $filename, $errorCorrectionLevel, $matrixPointSize, 2); } else { //default data echo 'You can provide data in GET parameter: like that
'; QRcode::png('PHP QR Code :)', $filename, $errorCorrectionLevel, $matrixPointSize, 2); } //display generated file echo '
'; //config form echo '
Data:   ECC:   Size:  

'; // benchmark QRtools::timeBenchmark(); qrinput.php000064400000057013150211530670006765 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('STRUCTURE_HEADER_BITS', 20); define('MAX_STRUCTURED_SYMBOLS', 16); class QRinputItem { public $mode; public $size; public $data; public $bstream; public function __construct($mode, $size, $data, $bstream = null) { $setData = array_slice($data, 0, $size); if (count($setData) < $size) { $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); } if(!QRinput::check($mode, $size, $setData)) { throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); return null; } $this->mode = $mode; $this->size = $size; $this->data = $setData; $this->bstream = $bstream; } //---------------------------------------------------------------------- public function encodeModeNum($version) { try { $words = (int)($this->size / 3); $bs = new QRbitstream(); $val = 0x1; $bs->appendNum(4, $val); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size); for($i=0; $i<$words; $i++) { $val = (ord($this->data[$i*3 ]) - ord('0')) * 100; $val += (ord($this->data[$i*3+1]) - ord('0')) * 10; $val += (ord($this->data[$i*3+2]) - ord('0')); $bs->appendNum(10, $val); } if($this->size - $words * 3 == 1) { $val = ord($this->data[$words*3]) - ord('0'); $bs->appendNum(4, $val); } else if($this->size - $words * 3 == 2) { $val = (ord($this->data[$words*3 ]) - ord('0')) * 10; $val += (ord($this->data[$words*3+1]) - ord('0')); $bs->appendNum(7, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeAn($version) { try { $words = (int)($this->size / 2); $bs = new QRbitstream(); $bs->appendNum(4, 0x02); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size); for($i=0; $i<$words; $i++) { $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45; $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1])); $bs->appendNum(11, $val); } if($this->size & 1) { $val = QRinput::lookAnTable(ord($this->data[$words * 2])); $bs->appendNum(6, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeMode8($version) { try { $bs = new QRbitstream(); $bs->appendNum(4, 0x4); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size); for($i=0; $i<$this->size; $i++) { $bs->appendNum(8, ord($this->data[$i])); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeKanji($version) { try { $bs = new QRbitrtream(); $bs->appendNum(4, 0x8); $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2)); for($i=0; $i<$this->size; $i+=2) { $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]); if($val <= 0x9ffc) { $val -= 0x8140; } else { $val -= 0xc140; } $h = ($val >> 8) * 0xc0; $val = ($val & 0xff) + $h; $bs->appendNum(13, $val); } $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function encodeModeStructure() { try { $bs = new QRbitstream(); $bs->appendNum(4, 0x03); $bs->appendNum(4, ord($this->data[1]) - 1); $bs->appendNum(4, ord($this->data[0]) - 1); $bs->appendNum(8, ord($this->data[2])); $this->bstream = $bs; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function estimateBitStreamSizeOfEntry($version) { $bits = 0; if($version == 0) $version = 1; switch($this->mode) { case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break; case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break; case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break; case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break; case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS; default: return 0; } $l = QRspec::lengthIndicator($this->mode, $version); $m = 1 << $l; $num = (int)(($this->size + $m - 1) / $m); $bits += $num * (4 + $l); return $bits; } //---------------------------------------------------------------------- public function encodeBitStream($version) { try { unset($this->bstream); $words = QRspec::maximumWords($this->mode, $version); if($this->size > $words) { $st1 = new QRinputItem($this->mode, $words, $this->data); $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); $st1->encodeBitStream($version); $st2->encodeBitStream($version); $this->bstream = new QRbitstream(); $this->bstream->append($st1->bstream); $this->bstream->append($st2->bstream); unset($st1); unset($st2); } else { $ret = 0; switch($this->mode) { case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; case QR_MODE_8: $ret = $this->encodeMode8($version); break; case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break; case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; default: break; } if($ret < 0) return -1; } return $this->bstream->size(); } catch (Exception $e) { return -1; } } }; //########################################################################## class QRinput { public $items; private $version; private $level; //---------------------------------------------------------------------- public function __construct($version = 0, $level = QR_ECLEVEL_L) { if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) { throw new Exception('Invalid version no'); return NULL; } $this->version = $version; $this->level = $level; } //---------------------------------------------------------------------- public function getVersion() { return $this->version; } //---------------------------------------------------------------------- public function setVersion($version) { if($version < 0 || $version > QRSPEC_VERSION_MAX) { throw new Exception('Invalid version no'); return -1; } $this->version = $version; return 0; } //---------------------------------------------------------------------- public function getErrorCorrectionLevel() { return $this->level; } //---------------------------------------------------------------------- public function setErrorCorrectionLevel($level) { if($level > QR_ECLEVEL_H) { throw new Exception('Invalid ECLEVEL'); return -1; } $this->level = $level; return 0; } //---------------------------------------------------------------------- public function appendEntry(QRinputItem $entry) { $this->items[] = $entry; } //---------------------------------------------------------------------- public function append($mode, $size, $data) { try { $entry = new QRinputItem($mode, $size, $data); $this->items[] = $entry; return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function insertStructuredAppendHeader($size, $index, $parity) { if( $size > MAX_STRUCTURED_SYMBOLS ) { throw new Exception('insertStructuredAppendHeader wrong size'); } if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) { throw new Exception('insertStructuredAppendHeader wrong index'); } $buf = array($size, $index, $parity); try { $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf); array_unshift($this->items, $entry); return 0; } catch (Exception $e) { return -1; } } //---------------------------------------------------------------------- public function calcParity() { $parity = 0; foreach($this->items as $item) { if($item->mode != QR_MODE_STRUCTURE) { for($i=$item->size-1; $i>=0; $i--) { $parity ^= $item->data[$i]; } } } return $parity; } //---------------------------------------------------------------------- public static function checkModeNum($size, $data) { for($i=0; $i<$size; $i++) { if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ return false; } } return true; } //---------------------------------------------------------------------- public static function estimateBitsModeNum($size) { $w = (int)$size / 3; $bits = $w * 10; switch($size - $w * 3) { case 1: $bits += 4; break; case 2: $bits += 7; break; default: break; } return $bits; } //---------------------------------------------------------------------- public static $anTable = array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ); //---------------------------------------------------------------------- public static function lookAnTable($c) { return (($c > 127)?-1:self::$anTable[$c]); } //---------------------------------------------------------------------- public static function checkModeAn($size, $data) { for($i=0; $i<$size; $i++) { if (self::lookAnTable(ord($data[$i])) == -1) { return false; } } return true; } //---------------------------------------------------------------------- public static function estimateBitsModeAn($size) { $w = (int)($size / 2); $bits = $w * 11; if($size & 1) { $bits += 6; } return $bits; } //---------------------------------------------------------------------- public static function estimateBitsMode8($size) { return $size * 8; } //---------------------------------------------------------------------- public function estimateBitsModeKanji($size) { return (int)(($size / 2) * 13); } //---------------------------------------------------------------------- public static function checkModeKanji($size, $data) { if($size & 1) return false; for($i=0; $i<$size; $i+=2) { $val = (ord($data[$i]) << 8) | ord($data[$i+1]); if( $val < 0x8140 || ($val > 0x9ffc && $val < 0xe040) || $val > 0xebbf) { return false; } } return true; } /*********************************************************************** * Validation **********************************************************************/ public static function check($mode, $size, $data) { if($size <= 0) return false; switch($mode) { case QR_MODE_NUM: return self::checkModeNum($size, $data); break; case QR_MODE_AN: return self::checkModeAn($size, $data); break; case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break; case QR_MODE_8: return true; break; case QR_MODE_STRUCTURE: return true; break; default: break; } return false; } //---------------------------------------------------------------------- public function estimateBitStreamSize($version) { $bits = 0; foreach($this->items as $item) { $bits += $item->estimateBitStreamSizeOfEntry($version); } return $bits; } //---------------------------------------------------------------------- public function estimateVersion() { $version = 0; $prev = 0; do { $prev = $version; $bits = $this->estimateBitStreamSize($prev); $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($version < 0) { return -1; } } while ($version > $prev); return $version; } //---------------------------------------------------------------------- public static function lengthOfCode($mode, $version, $bits) { $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version); switch($mode) { case QR_MODE_NUM: $chunks = (int)($payload / 10); $remain = $payload - $chunks * 10; $size = $chunks * 3; if($remain >= 7) { $size += 2; } else if($remain >= 4) { $size += 1; } break; case QR_MODE_AN: $chunks = (int)($payload / 11); $remain = $payload - $chunks * 11; $size = $chunks * 2; if($remain >= 6) $size++; break; case QR_MODE_8: $size = (int)($payload / 8); break; case QR_MODE_KANJI: $size = (int)(($payload / 13) * 2); break; case QR_MODE_STRUCTURE: $size = (int)($payload / 8); break; default: $size = 0; break; } $maxsize = QRspec::maximumWords($mode, $version); if($size < 0) $size = 0; if($size > $maxsize) $size = $maxsize; return $size; } //---------------------------------------------------------------------- public function createBitStream() { $total = 0; foreach($this->items as $item) { $bits = $item->encodeBitStream($this->version); if($bits < 0) return -1; $total += $bits; } return $total; } //---------------------------------------------------------------------- public function convertData() { $ver = $this->estimateVersion(); if($ver > $this->getVersion()) { $this->setVersion($ver); } for(;;) { $bits = $this->createBitStream(); if($bits < 0) return -1; $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); if($ver < 0) { throw new Exception('WRONG VERSION'); return -1; } else if($ver > $this->getVersion()) { $this->setVersion($ver); } else { break; } } return 0; } //---------------------------------------------------------------------- public function appendPaddingBit(&$bstream) { $bits = $bstream->size(); $maxwords = QRspec::getDataLength($this->version, $this->level); $maxbits = $maxwords * 8; if ($maxbits == $bits) { return 0; } if ($maxbits - $bits < 5) { return $bstream->appendNum($maxbits - $bits, 0); } $bits += 4; $words = (int)(($bits + 7) / 8); $padding = new QRbitstream(); $ret = $padding->appendNum($words * 8 - $bits + 4, 0); if($ret < 0) return $ret; $padlen = $maxwords - $words; if($padlen > 0) { $padbuf = array(); for($i=0; $i<$padlen; $i++) { $padbuf[$i] = ($i&1)?0x11:0xec; } $ret = $padding->appendBytes($padlen, $padbuf); if($ret < 0) return $ret; } $ret = $bstream->append($padding); return $ret; } //---------------------------------------------------------------------- public function mergeBitStream() { if($this->convertData() < 0) { return null; } $bstream = new QRbitstream(); foreach($this->items as $item) { $ret = $bstream->append($item->bstream); if($ret < 0) { return null; } } return $bstream; } //---------------------------------------------------------------------- public function getBitStream() { $bstream = $this->mergeBitStream(); if($bstream == null) { return null; } $ret = $this->appendPaddingBit($bstream); if($ret < 0) { return null; } return $bstream; } //---------------------------------------------------------------------- public function getByteStream() { $bstream = $this->getBitStream(); if($bstream == null) { return null; } return $bstream->toByte(); } } qrtools.php000064400000014021150211530670006756 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRtools { //---------------------------------------------------------------------- public static function binarize($frame) { $len = count($frame); foreach ($frame as &$frameLine) { for($i=0; $i<$len; $i++) { $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; } } return $frame; } //---------------------------------------------------------------------- public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037') { $barcode_array = array(); if (!is_array($mode)) $mode = explode(',', $mode); $eccLevel = 'L'; if (count($mode) > 1) { $eccLevel = $mode[1]; } $qrTab = QRcode::text($code, false, $eccLevel); $size = count($qrTab); $barcode_array['num_rows'] = $size; $barcode_array['num_cols'] = $size; $barcode_array['bcode'] = array(); foreach ($qrTab as $line) { $arrAdd = array(); foreach(str_split($line) as $char) $arrAdd[] = ($char=='1')?1:0; $barcode_array['bcode'][] = $arrAdd; } return $barcode_array; } //---------------------------------------------------------------------- public static function clearCache() { self::$frames = array(); } //---------------------------------------------------------------------- public static function buildCache() { QRtools::markTime('before_build_cache'); $mask = new QRmask(); for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) { $frame = QRspec::newFrame($a); if (QR_IMAGE) { $fileName = QR_CACHE_DIR.'frame_'.$a.'.png'; QRimage::png(self::binarize($frame), $fileName, 1, 0); } $width = count($frame); $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($maskNo=0; $maskNo<8; $maskNo++) $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); } QRtools::markTime('after_build_cache'); } //---------------------------------------------------------------------- public static function log($outfile, $err) { if (QR_LOG_DIR !== false) { if ($err != '') { if ($outfile !== false) { file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); } else { file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); } } } } //---------------------------------------------------------------------- public static function dumpMask($frame) { $width = count($frame); for($y=0;$y<$width;$y++) { for($x=0;$x<$width;$x++) { echo ord($frame[$y][$x]).','; } } } //---------------------------------------------------------------------- public static function markTime($markerId) { list($usec, $sec) = explode(" ", microtime()); $time = ((float)$usec + (float)$sec); if (!isset($GLOBALS['qr_time_bench'])) $GLOBALS['qr_time_bench'] = array(); $GLOBALS['qr_time_bench'][$markerId] = $time; } //---------------------------------------------------------------------- public static function timeBenchmark() { self::markTime('finish'); $lastTime = 0; $startTime = 0; $p = 0; echo ''; foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) { if ($p > 0) { echo ''; } else { $startTime = $thisTime; } $p++; $lastTime = $thisTime; } echo '
BENCHMARK
till '.$markerId.': '.number_format($thisTime-$lastTime, 6).'s
TOTAL: '.number_format($lastTime-$startTime, 6).'s
'; } } //########################################################################## QRtools::markTime('start'); qrimage.php000064400000006713150211530670006711 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('QR_IMAGE', true); class QRimage { //---------------------------------------------------------------------- public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) { $image = self::image($frame, $pixelPerPoint, $outerFrame); if ($filename === false) { Header("Content-type: image/png"); ImagePng($image); } else { if($saveandprint===TRUE){ ImagePng($image, $filename); header("Content-type: image/png"); ImagePng($image); }else{ ImagePng($image, $filename); } } ImageDestroy($image); } //---------------------------------------------------------------------- public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) { $image = self::image($frame, $pixelPerPoint, $outerFrame); if ($filename === false) { Header("Content-type: image/jpeg"); ImageJpeg($image, null, $q); } else { ImageJpeg($image, $filename, $q); } ImageDestroy($image); } //---------------------------------------------------------------------- private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) { $h = count($frame); $w = strlen($frame[0]); $imgW = $w + 2*$outerFrame; $imgH = $h + 2*$outerFrame; $base_image =ImageCreate($imgW, $imgH); $col[0] = ImageColorAllocate($base_image,255,255,255); $col[1] = ImageColorAllocate($base_image,0,0,0); imagefill($base_image, 0, 0, $col[0]); for($y=0; $y<$h; $y++) { for($x=0; $x<$w; $x++) { if ($frame[$y][$x] == '1') { ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); } } } $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint); ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH); ImageDestroy($base_image); return $target_image; } }qrconfig.php000064400000002626150211530670007073 0ustar00 // http://phpqrcode.sourceforge.net/ // https://sourceforge.net/projects/phpqrcode/ // // The "PHP QR Code encoder" is based on // "C libqrencode library" (ver. 3.1.1) // License: GNU-LGPL 2.1 // Copyright (C) 2006-2010 by Kentaro Fukuchi // http://megaui.net/fukuchi/works/qrencode/index.en.html // // Reed-Solomon code encoder is written by Phil Karn, KA9Q. // Copyright (C) 2002-2006 Phil Karn, KA9Q // // QR Code is registered trademark of DENSO WAVE INCORPORATED // http://www.denso-wave.com/qrcode/index-e.html // --------------------------------------------------------- // // Author: Nicola Asuni // // (c) Copyright 2010: // Nicola Asuni // Tecnick.com S.r.l. // Via della Pace, 11 // 09044 Quartucciu (CA) // ITALY // www.tecnick.com // info@tecnick.com //============================================================+ /** * Class to create QR-code arrays for TCPDF class. * QR Code symbol is a 2D barcode that can be scanned by handy terminals such as a mobile phone with CCD. * The capacity of QR Code is up to 7000 digits or 4000 characters, and has high robustness. * This class supports QR Code model 2, described in JIS (Japanese Industrial Standards) X0510:2004 or ISO/IEC 18004. * Currently the following features are not supported: ECI and FNC1 mode, Micro QR Code, QR Code model 1, Structured mode. * * This class is derived from "PHP QR Code encoder" by Dominik Dzienia (http://phpqrcode.sourceforge.net/) based on "libqrencode C library 3.1.1." by Kentaro Fukuchi (http://megaui.net/fukuchi/works/qrencode/index.en.html), contains Reed-Solomon code written by Phil Karn, KA9Q. QR Code is registered trademark of DENSO WAVE INCORPORATED (http://www.denso-wave.com/qrcode/index-e.html). * Please read comments on this class source file for full copyright and license information. * * @package com.tecnick.tcpdf * @abstract Class for generating QR-code array for TCPDF. * @author Nicola Asuni * @copyright 2010 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com * @link http://www.tcpdf.org * @license http://www.gnu.org/copyleft/lesser.html LGPL * @version 1.0.002 */ // definitions if (!defined('QRCODEDEFS')) { /** * Indicate that definitions for this class are set */ define('QRCODEDEFS', true); // ----------------------------------------------------- // Encoding modes (characters which can be encoded in QRcode) /** * Encoding mode */ define('QR_MODE_NL', -1); /** * Encoding mode numeric (0-9). 3 characters are encoded to 10bit length. In theory, 7089 characters or less can be stored in a QRcode. */ define('QR_MODE_NM', 0); /** * Encoding mode alphanumeric (0-9A-Z $%*+-./:) 45characters. 2 characters are encoded to 11bit length. In theory, 4296 characters or less can be stored in a QRcode. */ define('QR_MODE_AN', 1); /** * Encoding mode 8bit byte data. In theory, 2953 characters or less can be stored in a QRcode. */ define('QR_MODE_8B', 2); /** * Encoding mode KANJI. A KANJI character (multibyte character) is encoded to 13bit length. In theory, 1817 characters or less can be stored in a QRcode. */ define('QR_MODE_KJ', 3); /** * Encoding mode STRUCTURED (currently unsupported) */ define('QR_MODE_ST', 4); // ----------------------------------------------------- // Levels of error correction. // QRcode has a function of an error correcting for miss reading that white is black. // Error correcting is defined in 4 level as below. /** * Error correction level L : About 7% or less errors can be corrected. */ define('QR_ECLEVEL_L', 0); /** * Error correction level M : About 15% or less errors can be corrected. */ define('QR_ECLEVEL_M', 1); /** * Error correction level Q : About 25% or less errors can be corrected. */ define('QR_ECLEVEL_Q', 2); /** * Error correction level H : About 30% or less errors can be corrected. */ define('QR_ECLEVEL_H', 3); // ----------------------------------------------------- // Version. Size of QRcode is defined as version. // Version is from 1 to 40. // Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases. // So version 40 is 177*177 matrix. /** * Maximum QR Code version. */ define('QRSPEC_VERSION_MAX', 40); /** * Maximum matrix size for maximum version (version 40 is 177*177 matrix). */ define('QRSPEC_WIDTH_MAX', 177); // ----------------------------------------------------- /** * Matrix index to get width from $capacity array. */ define('QRCAP_WIDTH', 0); /** * Matrix index to get number of words from $capacity array. */ define('QRCAP_WORDS', 1); /** * Matrix index to get remainder from $capacity array. */ define('QRCAP_REMINDER', 2); /** * Matrix index to get error correction level from $capacity array. */ define('QRCAP_EC', 3); // ----------------------------------------------------- // Structure (currently usupported) /** * Number of header bits for structured mode */ define('STRUCTURE_HEADER_BITS', 20); /** * Max number of symbols for structured mode */ define('MAX_STRUCTURED_SYMBOLS', 16); // ----------------------------------------------------- // Masks /** * Down point base value for case 1 mask pattern (concatenation of same color in a line or a column) */ define('N1', 3); /** * Down point base value for case 2 mask pattern (module block of same color) */ define('N2', 3); /** * Down point base value for case 3 mask pattern (1:1:3:1:1(dark:bright:dark:bright:dark)pattern in a line or a column) */ define('N3', 40); /** * Down point base value for case 4 mask pattern (ration of dark modules in whole) */ define('N4', 10); // ----------------------------------------------------- // Optimization settings /** * if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code */ define('QR_FIND_BEST_MASK', true); /** * if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly */ define('QR_FIND_FROM_RANDOM', 2); /** * when QR_FIND_BEST_MASK === false */ define('QR_DEFAULT_MASK', 2); // ----------------------------------------------------- } // end of definitions // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# if (!class_exists('QRcode', false)) { // for compaibility with PHP4 if (!function_exists('str_split')) { /** * Convert a string to an array (needed for PHP4 compatibility) * @param string $string The input string. * @param int $split_length Maximum length of the chunk. * @return If the optional split_length parameter is specified, the returned array will be broken down into chunks with each being split_length in length, otherwise each chunk will be one character in length. FALSE is returned if split_length is less than 1. If the split_length length exceeds the length of string , the entire string is returned as the first (and only) array element. */ function str_split($string, $split_length=1) { if ((strlen($string) > $split_length) OR (!$split_length)) { do { $c = strlen($string); $parts[] = substr($string, 0, $split_length); $string = substr($string, $split_length); } while ($string !== false); } else { $parts = array($string); } return $parts; } } // ##################################################### /** * Class to create QR-code arrays for TCPDF class. * QR Code symbol is a 2D barcode that can be scanned by handy terminals such as a mobile phone with CCD. * The capacity of QR Code is up to 7000 digits or 4000 characters, and has high robustness. * This class supports QR Code model 2, described in JIS (Japanese Industrial Standards) X0510:2004 or ISO/IEC 18004. * Currently the following features are not supported: ECI and FNC1 mode, Micro QR Code, QR Code model 1, Structured mode. * * This class is derived from "PHP QR Code encoder" by Dominik Dzienia (http://phpqrcode.sourceforge.net/) based on "libqrencode C library 3.1.1." by Kentaro Fukuchi (http://megaui.net/fukuchi/works/qrencode/index.en.html), contains Reed-Solomon code written by Phil Karn, KA9Q. QR Code is registered trademark of DENSO WAVE INCORPORATED (http://www.denso-wave.com/qrcode/index-e.html). * Please read comments on this class source file for full copyright and license information. * * @name QRcode * @package com.tecnick.tcpdf * @abstract Class for generating QR-code array for TCPDF. * @author Nicola Asuni * @copyright 2010 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com * @link http://www.tcpdf.org * @license http://www.gnu.org/copyleft/lesser.html LGPL * @version 1.0.002 */ class QRcode { /** * @var barcode array to be returned which is readable by TCPDF * @access protected */ protected $barcode_array = array(); /** * @var QR code version. Size of QRcode is defined as version. Version is from 1 to 40. Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases. So version 40 is 177*177 matrix. * @access protected */ protected $version = 0; /** * @var Levels of error correction. See definitions for possible values. * @access protected */ protected $level = QR_ECLEVEL_L; /** * @var Encoding mode * @access protected */ protected $hint = QR_MODE_8B; /** * @var if true the input string will be converted to uppercase * @access protected */ protected $casesensitive = true; /** * @var structured QR code (not supported yet) * @access protected */ protected $structured = 0; /** * @var mask data * @access protected */ protected $data; // FrameFiller /** * @var width * @access protected */ protected $width; /** * @var frame * @access protected */ protected $frame; /** * @var X position of bit * @access protected */ protected $x; /** * @var Y position of bit * @access protected */ protected $y; /** * @var direction * @access protected */ protected $dir; /** * @var single bit * @access protected */ protected $bit; // ---- QRrawcode ---- /** * @var data code * @access protected */ protected $datacode = array(); /** * @var error correction code * @access protected */ protected $ecccode = array(); /** * @var blocks * @access protected */ protected $blocks; /** * @var Reed-Solomon blocks * @access protected */ protected $rsblocks = array(); //of RSblock /** * @var counter * @access protected */ protected $count; /** * @var data length * @access protected */ protected $dataLength; /** * @var error correction length * @access protected */ protected $eccLength; /** * @var b1 * @access protected */ protected $b1; // ---- QRmask ---- /** * @var run length * @access protected */ protected $runLength = array(); // ---- QRsplit ---- /** * @var input data string * @access protected */ protected $dataStr = ''; /** * @var input items * @access protected */ protected $items; // Reed-Solomon items /** * @var Reed-Solomon items * @access protected */ protected $rsitems = array(); /** * @var array of frames * @access protected */ protected $frames = array(); /** * @var alphabet-numeric convesion table * @access protected */ protected $anTable = array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, // -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // ); /** * @var array Table of the capacity of symbols * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004. * @access protected */ protected $capacity = array( array( 0, 0, 0, array( 0, 0, 0, 0)), // array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 array( 25, 44, 7, array( 10, 16, 22, 28)), // array( 29, 70, 7, array( 15, 26, 36, 44)), // array( 33, 100, 7, array( 20, 36, 52, 64)), // array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 array( 41, 172, 7, array( 36, 64, 96, 112)), // array( 45, 196, 0, array( 40, 72, 108, 130)), // array( 49, 242, 0, array( 48, 88, 132, 156)), // array( 53, 292, 0, array( 60, 110, 160, 192)), // array( 57, 346, 0, array( 72, 130, 192, 224)), // 10 array( 61, 404, 0, array( 80, 150, 224, 264)), // array( 65, 466, 0, array( 96, 176, 260, 308)), // array( 69, 532, 0, array( 104, 198, 288, 352)), // array( 73, 581, 3, array( 120, 216, 320, 384)), // array( 77, 655, 3, array( 132, 240, 360, 432)), // 15 array( 81, 733, 3, array( 144, 280, 408, 480)), // array( 85, 815, 3, array( 168, 308, 448, 532)), // array( 89, 901, 3, array( 180, 338, 504, 588)), // array( 93, 991, 3, array( 196, 364, 546, 650)), // array( 97, 1085, 3, array( 224, 416, 600, 700)), // 20 array(101, 1156, 4, array( 224, 442, 644, 750)), // array(105, 1258, 4, array( 252, 476, 690, 816)), // array(109, 1364, 4, array( 270, 504, 750, 900)), // array(113, 1474, 4, array( 300, 560, 810, 960)), // array(117, 1588, 4, array( 312, 588, 870, 1050)), // 25 array(121, 1706, 4, array( 336, 644, 952, 1110)), // array(125, 1828, 4, array( 360, 700, 1020, 1200)), // array(129, 1921, 3, array( 390, 728, 1050, 1260)), // array(133, 2051, 3, array( 420, 784, 1140, 1350)), // array(137, 2185, 3, array( 450, 812, 1200, 1440)), // 30 array(141, 2323, 3, array( 480, 868, 1290, 1530)), // array(145, 2465, 3, array( 510, 924, 1350, 1620)), // array(149, 2611, 3, array( 540, 980, 1440, 1710)), // array(153, 2761, 3, array( 570, 1036, 1530, 1800)), // array(157, 2876, 0, array( 570, 1064, 1590, 1890)), // 35 array(161, 3034, 0, array( 600, 1120, 1680, 1980)), // array(165, 3196, 0, array( 630, 1204, 1770, 2100)), // array(169, 3362, 0, array( 660, 1260, 1860, 2220)), // array(173, 3532, 0, array( 720, 1316, 1950, 2310)), // array(177, 3706, 0, array( 750, 1372, 2040, 2430)) // 40 ); /** * @var array Length indicator * @access protected */ protected $lengthTableBits = array( array(10, 12, 14), array( 9, 11, 13), array( 8, 16, 16), array( 8, 10, 12) ); /** * @var array Table of the error correction code (Reed-Solomon block) * See Table 12-16 (pp.30-36), JIS X0510:2004. * @access protected */ protected $eccTable = array( array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), // array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), // array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), // array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), // array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), // array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), // array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), // array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), // 10 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), // array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), // array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), // array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), // array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), // 15 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), // array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), // array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), // array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), // array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), // 20 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), // array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), // array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), // array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), // array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), // 25 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), // array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), // array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), // array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), // array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), // 30 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), // array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), // array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), // array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), // array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), // 35 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), // array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), // array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), // array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), // array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)) // 40 ); /** * @var array Positions of alignment patterns. * This array includes only the second and the third position of the alignment patterns. Rest of them can be calculated from the distance between them. * See Table 1 in Appendix E (pp.71) of JIS X0510:2004. * @access protected */ protected $alignmentPattern = array( array( 0, 0), array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), // 11-15 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), // 16-20 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), // 21-25 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), // 26-30 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), // 31-35 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58) // 35-40 ); /** * @var array Version information pattern (BCH coded). * See Table 1 in Appendix D (pp.68) of JIS X0510:2004. * size: [QRSPEC_VERSION_MAX - 6] * @access protected */ protected $versionPattern = array( 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, // 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, // 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, // 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, // 0x27541, 0x28c69 ); /** * @var array Format information * @access protected */ protected $formatInfo = array( array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), // array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), // array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), // array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) // ); // ------------------------------------------------- // ------------------------------------------------- /** * This is the class constructor. * Creates a QRcode object * @param string $code code to represent using QRcode * @param string $eclevel error level:
  • L : About 7% or less errors can be corrected.
  • M : About 15% or less errors can be corrected.
  • Q : About 25% or less errors can be corrected.
  • H : About 30% or less errors can be corrected.
* @access public * @since 1.0.000 */ public function __construct($code, $eclevel = 'L') { $barcode_array = array(); if ((is_null($code)) OR ($code == '\0') OR ($code == '')) { return false; } // set error correction level $this->level = array_search($eclevel, array('L', 'M', 'Q', 'H')); if ($this->level === false) { $this->level = QR_ECLEVEL_L; } if (($this->hint != QR_MODE_8B) AND ($this->hint != QR_MODE_KJ)) { return false; } if (($this->version < 0) OR ($this->version > QRSPEC_VERSION_MAX)) { return false; } $this->items = array(); $this->encodeString($code); $qrTab = $this->binarize($this->data); $size = count($qrTab); $barcode_array['num_rows'] = $size; $barcode_array['num_cols'] = $size; $barcode_array['bcode'] = array(); foreach ($qrTab as $line) { $arrAdd = array(); foreach (str_split($line) as $char) { $arrAdd[] = ($char=='1')?1:0; } $barcode_array['bcode'][] = $arrAdd; } $this->barcode_array = $barcode_array; } /** * Returns a barcode array which is readable by TCPDF * @return array barcode array readable by TCPDF; * @access public */ public function getBarcodeArray() { return $this->barcode_array; } /** * Convert the frame in binary form * @param array $frame array to binarize * @return array frame in binary form */ protected function binarize($frame) { $len = count($frame); // the frame is square (width = height) foreach ($frame as &$frameLine) { for ($i=0; $i<$len; $i++) { $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; } } return $frame; } /** * Encode the input string to QR code * @param string $string input string to encode */ protected function encodeString($string) { $this->dataStr = $string; if (!$this->casesensitive) { $this->toUpper(); } $ret = $this->splitString(); if ($ret < 0) { return NULL; } $this->encodeMask(-1); } /** * Encode mask * @param int $mask masking mode */ protected function encodeMask($mask) { $spec = array(0, 0, 0, 0, 0); $this->datacode = $this->getByteStream($this->items); if (is_null($this->datacode)) { return NULL; } $spec = $this->getEccSpec($this->version, $this->level, $spec); $this->b1 = $this->rsBlockNum1($spec); $this->dataLength = $this->rsDataLength($spec); $this->eccLength = $this->rsEccLength($spec); $this->ecccode = array_fill(0, $this->eccLength, 0); $this->blocks = $this->rsBlockNum($spec); $ret = $this->init($spec); if ($ret < 0) { return NULL; } $this->count = 0; $this->width = $this->getWidth($this->version); $this->frame = $this->newFrame($this->version); $this->x = $this->width - 1; $this->y = $this->width - 1; $this->dir = -1; $this->bit = -1; // inteleaved data and ecc codes for ($i=0; $i < ($this->dataLength + $this->eccLength); $i++) { $code = $this->getCode(); $bit = 0x80; for ($j=0; $j<8; $j++) { $addr = $this->getNextPosition(); $this->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); $bit = $bit >> 1; } } // remainder bits $j = $this->getRemainder($this->version); for ($i=0; $i<$j; $i++) { $addr = $this->getNextPosition(); $this->setFrameAt($addr, 0x02); } // masking $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); if ($mask < 0) { if (QR_FIND_BEST_MASK) { $masked = $this->mask($this->width, $this->frame, $this->level); } else { $masked = $this->makeMask($this->width, $this->frame, (intval(QR_DEFAULT_MASK) % 8), $this->level); } } else { $masked = $this->makeMask($this->width, $this->frame, $mask, $this->level); } if ($masked == NULL) { return NULL; } $this->data = $masked; } // - - - - - - - - - - - - - - - - - - - - - - - - - // FrameFiller /** * Set frame value at specified position * @param array $at x,y position * @param int $val value of the character to set */ protected function setFrameAt($at, $val) { $this->frame[$at['y']][$at['x']] = chr($val); } /** * Get frame value at specified position * @param array $at x,y position * @return value at specified position */ protected function getFrameAt($at) { return ord($this->frame[$at['y']][$at['x']]); } /** * Return the next frame position * @return array of x,y coordinates */ protected function getNextPosition() { do { if ($this->bit == -1) { $this->bit = 0; return array('x'=>$this->x, 'y'=>$this->y); } $x = $this->x; $y = $this->y; $w = $this->width; if ($this->bit == 0) { $x--; $this->bit++; } else { $x++; $y += $this->dir; $this->bit--; } if ($this->dir < 0) { if ($y < 0) { $y = 0; $x -= 2; $this->dir = 1; if ($x == 6) { $x--; $y = 9; } } } else { if ($y == $w) { $y = $w - 1; $x -= 2; $this->dir = -1; if ($x == 6) { $x--; $y -= 8; } } } if (($x < 0) OR ($y < 0)) { return NULL; } $this->x = $x; $this->y = $y; } while(ord($this->frame[$y][$x]) & 0x80); return array('x'=>$x, 'y'=>$y); } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrawcode /** * Initialize code. * @param array $spec array of ECC specification * @return 0 in case of success, -1 in case of error */ protected function init($spec) { $dl = $this->rsDataCodes1($spec); $el = $this->rsEccCodes1($spec); $rs = $this->init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); $blockNo = 0; $dataPos = 0; $eccPos = 0; $endfor = $this->rsBlockNum1($spec); for ($i=0; $i < $endfor; ++$i) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = array(); $this->rsblocks[$blockNo]['dataLength'] = $dl; $this->rsblocks[$blockNo]['data'] = array_slice($this->datacode, $dataPos); $this->rsblocks[$blockNo]['eccLength'] = $el; $ecc = $this->encode_rs_char($rs, $this->rsblocks[$blockNo]['data'], $ecc); $this->rsblocks[$blockNo]['ecc'] = $ecc; $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } if ($this->rsBlockNum2($spec) == 0) { return 0; } $dl = $this->rsDataCodes2($spec); $el = $this->rsEccCodes2($spec); $rs = $this->init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); if ($rs == NULL) { return -1; } $endfor = $this->rsBlockNum2($spec); for ($i=0; $i < $endfor; ++$i) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = array(); $this->rsblocks[$blockNo]['dataLength'] = $dl; $this->rsblocks[$blockNo]['data'] = array_slice($this->datacode, $dataPos); $this->rsblocks[$blockNo]['eccLength'] = $el; $ecc = $this->encode_rs_char($rs, $this->rsblocks[$blockNo]['data'], $ecc); $this->rsblocks[$blockNo]['ecc'] = $ecc; $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } return 0; } /** * Return Reed-Solomon block code. * @return array rsblocks */ protected function getCode() { if ($this->count < $this->dataLength) { $row = $this->count % $this->blocks; $col = $this->count / $this->blocks; if ($col >= $this->rsblocks[0]['dataLength']) { $row += $this->b1; } $ret = $this->rsblocks[$row]['data'][$col]; } elseif ($this->count < $this->dataLength + $this->eccLength) { $row = ($this->count - $this->dataLength) % $this->blocks; $col = ($this->count - $this->dataLength) / $this->blocks; $ret = $this->rsblocks[$row]['ecc'][$col]; } else { return 0; } $this->count++; return $ret; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRmask /** * Write Format Information on frame and returns the number of black bits * @param int $width frame width * @param array $frame frame * @param array $mask masking mode * @param int $level error correction level * @return int blacks */ protected function writeFormatInformation($width, &$frame, $mask, $level) { $blacks = 0; $format = $this->getFormatInfo($mask, $level); for ($i=0; $i<8; ++$i) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[8][$width - 1 - $i] = chr($v); if ($i < 6) { $frame[$i][8] = chr($v); } else { $frame[$i + 1][8] = chr($v); } $format = $format >> 1; } for ($i=0; $i<7; ++$i) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[$width - 7 + $i][8] = chr($v); if ($i == 0) { $frame[8][7] = chr($v); } else { $frame[8][6 - $i] = chr($v); } $format = $format >> 1; } return $blacks; } /** * mask0 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask0($x, $y) { return ($x + $y) & 1; } /** * mask1 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask1($x, $y) { return ($y & 1); } /** * mask2 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask2($x, $y) { return ($x % 3); } /** * mask3 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask3($x, $y) { return ($x + $y) % 3; } /** * mask4 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask4($x, $y) { return (((int)($y / 2)) + ((int)($x / 3))) & 1; } /** * mask5 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask5($x, $y) { return (($x * $y) & 1) + ($x * $y) % 3; } /** * mask6 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask6($x, $y) { return ((($x * $y) & 1) + ($x * $y) % 3) & 1; } /** * mask7 * @param int $x X position * @param int $y Y position * @return int mask */ protected function mask7($x, $y) { return ((($x * $y) % 3) + (($x + $y) & 1)) & 1; } /** * Return bitmask * @param int $maskNo mask number * @param int $width width * @param array $frame frame * @return array bitmask */ protected function generateMaskNo($maskNo, $width, $frame) { $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($y=0; $y<$width; ++$y) { for ($x=0; $x<$width; ++$x) { if (ord($frame[$y][$x]) & 0x80) { $bitMask[$y][$x] = 0; } else { $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); $bitMask[$y][$x] = ($maskFunc == 0)?1:0; } } } return $bitMask; } /** * makeMaskNo * @param int $maskNo * @param int $width * @param int $s * @param int $d * @param boolean $maskGenOnly * @return int b */ protected function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly=false) { $b = 0; $bitMask = array(); $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); if ($maskGenOnly) { return; } $d = $s; for ($y=0; $y<$width; ++$y) { for ($x=0; $x<$width; ++$x) { if ($bitMask[$y][$x] == 1) { $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); } $b += (int)(ord($d[$y][$x]) & 1); } } return $b; } /** * makeMask * @param int $width * @param array $frame * @param int $maskNo * @param int $level * @return array mask */ protected function makeMask($width, $frame, $maskNo, $level) { $masked = array_fill(0, $width, str_repeat("\0", $width)); $this->makeMaskNo($maskNo, $width, $frame, $masked); $this->writeFormatInformation($width, $masked, $maskNo, $level); return $masked; } /** * calcN1N3 * @param int $length * @return int demerit */ protected function calcN1N3($length) { $demerit = 0; for ($i=0; $i<$length; ++$i) { if ($this->runLength[$i] >= 5) { $demerit += (N1 + ($this->runLength[$i] - 5)); } if ($i & 1) { if (($i >= 3) AND ($i < ($length-2)) AND ($this->runLength[$i] % 3 == 0)) { $fact = (int)($this->runLength[$i] / 3); if (($this->runLength[$i-2] == $fact) AND ($this->runLength[$i-1] == $fact) AND ($this->runLength[$i+1] == $fact) AND ($this->runLength[$i+2] == $fact)) { if (($this->runLength[$i-3] < 0) OR ($this->runLength[$i-3] >= (4 * $fact))) { $demerit += N3; } elseif ((($i+3) >= $length) OR ($this->runLength[$i+3] >= (4 * $fact))) { $demerit += N3; } } } } } return $demerit; } /** * evaluateSymbol * @param int $width * @param array $frame * @return int demerit */ protected function evaluateSymbol($width, $frame) { $head = 0; $demerit = 0; for ($y=0; $y<$width; ++$y) { $head = 0; $this->runLength[0] = 1; $frameY = $frame[$y]; if ($y > 0) { $frameYM = $frame[$y-1]; } for ($x=0; $x<$width; ++$x) { if (($x > 0) AND ($y > 0)) { $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); if (($b22 | ($w22 ^ 1)) & 1) { $demerit += N2; } } if (($x == 0) AND (ord($frameY[$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } elseif ($x > 0) { if ((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } for ($x=0; $x<$width; ++$x) { $head = 0; $this->runLength[0] = 1; for ($y=0; $y<$width; ++$y) { if (($y == 0) AND (ord($frame[$y][$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } elseif ($y > 0) { if ((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } return $demerit; } /** * mask * @param int $width * @param array $frame * @param int $level * @return array best mask */ protected function mask($width, $frame, $level) { $minDemerit = PHP_INT_MAX; $bestMaskNum = 0; $bestMask = array(); $checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7); if (QR_FIND_FROM_RANDOM !== false) { $howManuOut = 8 - (QR_FIND_FROM_RANDOM % 9); for ($i = 0; $i < $howManuOut; ++$i) { $remPos = rand (0, count($checked_masks)-1); unset($checked_masks[$remPos]); $checked_masks = array_values($checked_masks); } } $bestMask = $frame; foreach ($checked_masks as $i) { $mask = array_fill(0, $width, str_repeat("\0", $width)); $demerit = 0; $blacks = 0; $blacks = $this->makeMaskNo($i, $width, $frame, $mask); $blacks += $this->writeFormatInformation($width, $mask, $i, $level); $blacks = (int)(100 * $blacks / ($width * $width)); $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); $demerit += $this->evaluateSymbol($width, $mask); if ($demerit < $minDemerit) { $minDemerit = $demerit; $bestMask = $mask; $bestMaskNum = $i; } } return $bestMask; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRsplit /** * Return true if the character at specified position is a number * @param string $str string * @param int $pos characted position * @return boolean true of false */ protected function isdigitat($str, $pos) { if ($pos >= strlen($str)) { return false; } return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); } /** * Return true if the character at specified position is an alphanumeric character * @param string $str string * @param int $pos characted position * @return boolean true of false */ protected function isalnumat($str, $pos) { if ($pos >= strlen($str)) { return false; } return ($this->lookAnTable(ord($str[$pos])) >= 0); } /** * identifyMode * @param int $pos * @return int mode */ protected function identifyMode($pos) { if ($pos >= strlen($this->dataStr)) { return QR_MODE_NL; } $c = $this->dataStr[$pos]; if ($this->isdigitat($this->dataStr, $pos)) { return QR_MODE_NM; } elseif ($this->isalnumat($this->dataStr, $pos)) { return QR_MODE_AN; } elseif ($this->hint == QR_MODE_KJ) { if ($pos+1 < strlen($this->dataStr)) { $d = $this->dataStr[$pos+1]; $word = (ord($c) << 8) | ord($d); if (($word >= 0x8140 && $word <= 0x9ffc) OR ($word >= 0xe040 && $word <= 0xebbf)) { return QR_MODE_KJ; } } } return QR_MODE_8B; } /** * eatNum * @return int run */ protected function eatNum() { $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p = 0; while($this->isdigitat($this->dataStr, $p)) { $p++; } $run = $p; $mode = $this->identifyMode($p); if ($mode == QR_MODE_8B) { $dif = $this->estimateBitsModeNum($run) + 4 + $ln + $this->estimateBitsMode8(1) // + 4 + l8 - $this->estimateBitsMode8($run + 1); // - 4 - l8 if ($dif > 0) { return $this->eat8(); } } if ($mode == QR_MODE_AN) { $dif = $this->estimateBitsModeNum($run) + 4 + $ln + $this->estimateBitsModeAn(1) // + 4 + la - $this->estimateBitsModeAn($run + 1);// - 4 - la if ($dif > 0) { return $this->eatAn(); } } $this->items = $this->appendNewInputItem($this->items, QR_MODE_NM, $run, str_split($this->dataStr)); return $run; } /** * eatAn * @return int run */ protected function eatAn() { $la = $this->lengthIndicator(QR_MODE_AN, $this->version); $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p = 0; while($this->isalnumat($this->dataStr, $p)) { if ($this->isdigitat($this->dataStr, $p)) { $q = $p; while($this->isdigitat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsModeAn($p) // + 4 + la + $this->estimateBitsModeNum($q - $p) + 4 + $ln - $this->estimateBitsModeAn($q); // - 4 - la if ($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; if (!$this->isalnumat($this->dataStr, $p)) { $dif = $this->estimateBitsModeAn($run) + 4 + $la + $this->estimateBitsMode8(1) // + 4 + l8 - $this->estimateBitsMode8($run + 1); // - 4 - l8 if ($dif > 0) { return $this->eat8(); } } $this->items = $this->appendNewInputItem($this->items, QR_MODE_AN, $run, str_split($this->dataStr)); return $run; } /** * eatKanji * @return int run */ protected function eatKanji() { $p = 0; while($this->identifyMode($p) == QR_MODE_KJ) { $p += 2; } $this->items = $this->appendNewInputItem($this->items, QR_MODE_KJ, $p, str_split($this->dataStr)); return $run; } /** * eat8 * @return int run */ protected function eat8() { $la = $this->lengthIndicator(QR_MODE_AN, $this->version); $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p = 1; $dataStrLen = strlen($this->dataStr); while($p < $dataStrLen) { $mode = $this->identifyMode($p); if ($mode == QR_MODE_KJ) { break; } if ($mode == QR_MODE_NM) { $q = $p; while($this->isdigitat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsMode8($p) // + 4 + l8 + $this->estimateBitsModeNum($q - $p) + 4 + $ln - $this->estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } elseif ($mode == QR_MODE_AN) { $q = $p; while($this->isalnumat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsMode8($p) // + 4 + l8 + $this->estimateBitsModeAn($q - $p) + 4 + $la - $this->estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; $this->items = $this->appendNewInputItem($this->items, QR_MODE_8B, $run, str_split($this->dataStr)); return $run; } /** * splitString */ protected function splitString() { while (strlen($this->dataStr) > 0) { if ($this->dataStr == '') { return 0; } $mode = $this->identifyMode(0); switch ($mode) { case QR_MODE_NM: { $length = $this->eatNum(); break; } case QR_MODE_AN: { $length = $this->eatAn(); break; } case QR_MODE_KJ: { if ($hint == QR_MODE_KJ) { $length = $this->eatKanji(); } else { $length = $this->eat8(); } break; } default: { $length = $this->eat8(); break; } } if ($length == 0) { return 0; } if ($length < 0) { return -1; } $this->dataStr = substr($this->dataStr, $length); } } /** * toUpper */ protected function toUpper() { $stringLen = strlen($this->dataStr); $p = 0; while ($p < $stringLen) { $mode = $this->identifyMode(substr($this->dataStr, $p), $this->hint); if ($mode == QR_MODE_KJ) { $p += 2; } else { if ((ord($this->dataStr[$p]) >= ord('a')) AND (ord($this->dataStr[$p]) <= ord('z'))) { $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); } $p++; } } return $this->dataStr; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRinputItem /** * newInputItem * @param int $mode * @param int $size * @param array $data * @param array $bstream * @return array input item */ protected function newInputItem($mode, $size, $data, $bstream=null) { $setData = array_slice($data, 0, $size); if (count($setData) < $size) { $setData = array_merge($setData, array_fill(0, ($size - count($setData)), 0)); } if (!$this->check($mode, $size, $setData)) { return NULL; } $inputitem = array(); $inputitem['mode'] = $mode; $inputitem['size'] = $size; $inputitem['data'] = $setData; $inputitem['bstream'] = $bstream; return $inputitem; } /** * encodeModeNum * @param array $inputitem * @param int $version * @return array input item */ protected function encodeModeNum($inputitem, $version) { $words = (int)($inputitem['size'] / 3); $inputitem['bstream'] = array(); $val = 0x1; $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_NM, $version), $inputitem['size']); for ($i=0; $i < $words; ++$i) { $val = (ord($inputitem['data'][$i*3 ]) - ord('0')) * 100; $val += (ord($inputitem['data'][$i*3+1]) - ord('0')) * 10; $val += (ord($inputitem['data'][$i*3+2]) - ord('0')); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 10, $val); } if ($inputitem['size'] - $words * 3 == 1) { $val = ord($inputitem['data'][$words*3]) - ord('0'); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val); } elseif (($inputitem['size'] - ($words * 3)) == 2) { $val = (ord($inputitem['data'][$words*3 ]) - ord('0')) * 10; $val += (ord($inputitem['data'][$words*3+1]) - ord('0')); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 7, $val); } return $inputitem; } /** * encodeModeAn * @param array $inputitem * @param int $version * @return array input item */ protected function encodeModeAn($inputitem, $version) { $words = (int)($inputitem['size'] / 2); $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x02); $inputitem['bstream'] = $this->appendNum(v, $this->lengthIndicator(QR_MODE_AN, $version), $inputitem['size']); for ($i=0; $i < $words; ++$i) { $val = (int)$this->lookAnTable(ord($inputitem['data'][$i*2 ])) * 45; $val += (int)$this->lookAnTable(ord($inputitem['data'][$i*2+1])); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 11, $val); } if ($inputitem['size'] & 1) { $val = $this->lookAnTable(ord($inputitem['data'][($words * 2)])); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 6, $val); } return $inputitem; } /** * encodeMode8 * @param array $inputitem * @param int $version * @return array input item */ protected function encodeMode8($inputitem, $version) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x4); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_8B, $version), $inputitem['size']); for ($i=0; $i < $inputitem['size']; ++$i) { $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][$i])); } return $inputitem; } /** * encodeModeKanji * @param array $inputitem * @param int $version * @return array input item */ protected function encodeModeKanji($inputitem, $version) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x8); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_KJ, $version), (int)($inputitem['size'] / 2)); for ($i=0; $i<$inputitem['size']; $i+=2) { $val = (ord($inputitem['data'][$i]) << 8) | ord($inputitem['data'][$i+1]); if ($val <= 0x9ffc) { $val -= 0x8140; } else { $val -= 0xc140; } $h = ($val >> 8) * 0xc0; $val = ($val & 0xff) + $h; $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 13, $val); } return $inputitem; } /** * encodeModeStructure * @param array $inputitem * @return array input item */ protected function encodeModeStructure($inputitem) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x03); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][1]) - 1); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][0]) - 1); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][2])); return $inputitem; } /** * encodeBitStream * @param array $inputitem * @param int $version * @return array input item */ protected function encodeBitStream($inputitem, $version) { $inputitem['bstream'] = array(); $words = $this->maximumWords($inputitem['mode'], $version); if ($inputitem['size'] > $words) { $st1 = $this->newInputItem($inputitem['mode'], $words, $inputitem['data']); $st2 = $this->newInputItem($inputitem['mode'], $inputitem['size'] - $words, array_slice($inputitem['data'], $words)); $st1 = $this->encodeBitStream($st1, $version); $st2 = $this->encodeBitStream($st2, $version); $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st1['bstream']); $inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st2['bstream']); } else { switch($inputitem['mode']) { case QR_MODE_NM: { $inputitem = $this->encodeModeNum($inputitem, $version); break; } case QR_MODE_AN: { $inputitem = $this->encodeModeAn($inputitem, $version); break; } case QR_MODE_8B: { $inputitem = $this->encodeMode8($inputitem, $version); break; } case QR_MODE_KJ: { $inputitem = $this->encodeModeKanji($inputitem, $version); break; } case QR_MODE_ST: { $inputitem = $this->encodeModeStructure($inputitem); break; } default: { break; } } } return $inputitem; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRinput /** * Append data to an input object. * The data is copied and appended to the input object. * @param array items input items * @param int $mode encoding mode. * @param int $size size of data (byte). * @param array $data array of input data. * @return items * */ protected function appendNewInputItem($items, $mode, $size, $data) { $items[] = $this->newInputItem($mode, $size, $data); return $items; } /** * insertStructuredAppendHeader * @param array $items * @param int $size * @param int $index * @param int $parity * @return array items */ protected function insertStructuredAppendHeader($items, $size, $index, $parity) { if ($size > MAX_STRUCTURED_SYMBOLS) { return -1; } if (($index <= 0) OR ($index > MAX_STRUCTURED_SYMBOLS)) { return -1; } $buf = array($size, $index, $parity); $entry = $this->newInputItem(QR_MODE_ST, 3, buf); array_unshift($items, $entry); return $items; } /** * calcParity * @param array $items * @return int parity */ protected function calcParity($items) { $parity = 0; foreach ($items as $item) { if ($item['mode'] != QR_MODE_ST) { for ($i=$item['size']-1; $i>=0; --$i) { $parity ^= $item['data'][$i]; } } } return $parity; } /** * checkModeNum * @param int $size * @param array $data * @return boolean true or false */ protected function checkModeNum($size, $data) { for ($i=0; $i<$size; ++$i) { if ((ord($data[$i]) < ord('0')) OR (ord($data[$i]) > ord('9'))){ return false; } } return true; } /** * estimateBitsModeNum * @param int $size * @return int number of bits */ protected function estimateBitsModeNum($size) { $w = (int)$size / 3; $bits = $w * 10; switch($size - $w * 3) { case 1: { $bits += 4; break; } case 2: { $bits += 7; break; } default: { break; } } return $bits; } /** * Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19). * @param int $c character value * @return value */ protected function lookAnTable($c) { return (($c > 127)?-1:$this->anTable[$c]); } /** * checkModeAn * @param int $size * @param array $data * @return boolean true or false */ protected function checkModeAn($size, $data) { for ($i=0; $i<$size; ++$i) { if ($this->lookAnTable(ord($data[$i])) == -1) { return false; } } return true; } /** * estimateBitsModeAn * @param int $size * @return int number of bits */ protected function estimateBitsModeAn($size) { $w = (int)($size / 2); $bits = $w * 11; if ($size & 1) { $bits += 6; } return $bits; } /** * estimateBitsMode8 * @param int $size * @return int number of bits */ protected function estimateBitsMode8($size) { return $size * 8; } /** * estimateBitsModeKanji * @param int $size * @return int number of bits */ protected function estimateBitsModeKanji($size) { return (int)(($size / 2) * 13); } /** * checkModeKanji * @param int $size * @param array $data * @return boolean true or false */ protected function checkModeKanji($size, $data) { if ($size & 1) { return false; } for ($i=0; $i<$size; $i+=2) { $val = (ord($data[$i]) << 8) | ord($data[$i+1]); if (($val < 0x8140) OR (($val > 0x9ffc) AND ($val < 0xe040)) OR ($val > 0xebbf)) { return false; } } return true; } /** * Validate the input data. * @param int $mode encoding mode. * @param int $size size of data (byte). * @param array data data to validate * @return boolean true in case of valid data, false otherwise */ protected function check($mode, $size, $data) { if ($size <= 0) { return false; } switch($mode) { case QR_MODE_NM: { return $this->checkModeNum($size, $data); } case QR_MODE_AN: { return $this->checkModeAn($size, $data); } case QR_MODE_KJ: { return $this->checkModeKanji($size, $data); } case QR_MODE_8B: { return true; } case QR_MODE_ST: { return true; } default: { break; } } return false; } /** * estimateBitStreamSize * @param array $items * @param int $version * @return int bits */ protected function estimateBitStreamSize($items, $version) { $bits = 0; if ($version == 0) { $version = 1; } foreach ($items as $item) { switch($item['mode']) { case QR_MODE_NM: { $bits = $this->estimateBitsModeNum($item['size']); break; } case QR_MODE_AN: { $bits = $this->estimateBitsModeAn($item['size']); break; } case QR_MODE_8B: { $bits = $this->estimateBitsMode8($item['size']); break; } case QR_MODE_KJ: { $bits = $this->estimateBitsModeKanji($item['size']); break; } case QR_MODE_ST: { return STRUCTURE_HEADER_BITS; } default: { return 0; } } $l = $this->lengthIndicator($item['mode'], $version); $m = 1 << $l; $num = (int)(($item['size'] + $m - 1) / $m); $bits += $num * (4 + $l); } return $bits; } /** * estimateVersion * @param array $items * @return int version */ protected function estimateVersion($items) { $version = 0; $prev = 0; do { $prev = $version; $bits = $this->estimateBitStreamSize($items, $prev); $version = $this->getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($version < 0) { return -1; } } while ($version > $prev); return $version; } /** * lengthOfCode * @param int $mode * @param int $version * @param int $bits * @return int size */ protected function lengthOfCode($mode, $version, $bits) { $payload = $bits - 4 - $this->lengthIndicator($mode, $version); switch($mode) { case QR_MODE_NM: { $chunks = (int)($payload / 10); $remain = $payload - $chunks * 10; $size = $chunks * 3; if ($remain >= 7) { $size += 2; } elseif ($remain >= 4) { $size += 1; } break; } case QR_MODE_AN: { $chunks = (int)($payload / 11); $remain = $payload - $chunks * 11; $size = $chunks * 2; if ($remain >= 6) { ++$size; } break; } case QR_MODE_8B: { $size = (int)($payload / 8); break; } case QR_MODE_KJ: { $size = (int)(($payload / 13) * 2); break; } case QR_MODE_ST: { $size = (int)($payload / 8); break; } default: { $size = 0; break; } } $maxsize = $this->maximumWords($mode, $version); if ($size < 0) { $size = 0; } if ($size > $maxsize) { $size = $maxsize; } return $size; } /** * createBitStream * @param array $items * @return array of items and total bits */ protected function createBitStream($items) { $total = 0; foreach ($items as $key => $item) { $items[$key] = $this->encodeBitStream($item, $this->version); $bits = count($items[$key]['bstream']); $total += $bits; } return array($items, $total); } /** * convertData * @param array $items * @return array items */ protected function convertData($items) { $ver = $this->estimateVersion($items); if ($ver > $this->version) { $this->version = $ver; } for (;;) { $cbs = $this->createBitStream($items); $items = $cbs[0]; $bits = $cbs[1]; if ($bits < 0) { return -1; } $ver = $this->getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($ver < 0) { return -1; } elseif ($ver > $this->version) { $this->version = $ver; } else { break; } } return $items; } /** * Append Padding Bit to bitstream * @param array $bstream * @return array bitstream */ protected function appendPaddingBit($bstream) { $bits = count($bstream); $maxwords = $this->getDataLength($this->version, $this->level); $maxbits = $maxwords * 8; if ($maxbits == $bits) { return 0; } if ($maxbits - $bits < 5) { return $this->appendNum($bstream, $maxbits - $bits, 0); } $bits += 4; $words = (int)(($bits + 7) / 8); $padding = array(); $padding = $this->appendNum($padding, $words * 8 - $bits + 4, 0); $padlen = $maxwords - $words; if ($padlen > 0) { $padbuf = array(); for ($i=0; $i<$padlen; ++$i) { $padbuf[$i] = ($i&1)?0x11:0xec; } $padding = $this->appendBytes($padding, $padlen, $padbuf); } return $this->appendBitstream($bstream, $padding); } /** * mergeBitStream * @param array $bstream * @return array bitstream */ protected function mergeBitStream($items) { $items = $this->convertData($items); $bstream = array(); foreach ($items as $item) { $bstream = $this->appendBitstream($bstream, $item['bstream']); } return $bstream; } /** * Returns a stream of bits. * @param int $items * @return array padded merged byte stream */ protected function getBitStream($items) { $bstream = $this->mergeBitStream($items); return $this->appendPaddingBit($bstream); } /** * Pack all bit streams padding bits into a byte array. * @param int $items * @return array padded merged byte stream */ protected function getByteStream($items) { $bstream = $this->getBitStream($items); return $this->bitstreamToByte($bstream); } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRbitstream /** * Return an array with zeros * @param int $setLength array size * @return array */ protected function allocate($setLength) { return array_fill(0, $setLength, 0); } /** * Return new bitstream from number * @param int $bits number of bits * @param int $num number * @return array bitstream */ protected function newFromNum($bits, $num) { $bstream = $this->allocate($bits); $mask = 1 << ($bits - 1); for ($i=0; $i<$bits; ++$i) { if ($num & $mask) { $bstream[$i] = 1; } else { $bstream[$i] = 0; } $mask = $mask >> 1; } return $bstream; } /** * Return new bitstream from bytes * @param int $size size * @param array $data bytes * @return array bitstream */ protected function newFromBytes($size, $data) { $bstream = $this->allocate($size * 8); $p=0; for ($i=0; $i<$size; ++$i) { $mask = 0x80; for ($j=0; $j<8; ++$j) { if ($data[$i] & $mask) { $bstream[$p] = 1; } else { $bstream[$p] = 0; } $p++; $mask = $mask >> 1; } } return $bstream; } /** * Append one bitstream to another * @param array $bitstream original bitstream * @param array $append bitstream to append * @return array bitstream */ protected function appendBitstream($bitstream, $append) { if ((!is_array($append)) OR (count($append) == 0)) { return $bitstream; } if (count($bitstream) == 0) { return $append; } return array_values(array_merge($bitstream, $append)); } /** * Append one bitstream created from number to another * @param array $bitstream original bitstream * @param int $bits number of bits * @param int $num number * @return array bitstream */ protected function appendNum($bitstream, $bits, $num) { if ($bits == 0) { return 0; } $b = $this->newFromNum($bits, $num); return $this->appendBitstream($bitstream, $b); } /** * Append one bitstream created from bytes to another * @param array $bitstream original bitstream * @param int $size size * @param array $data bytes * @return array bitstream */ protected function appendBytes($bitstream, $size, $data) { if ($size == 0) { return 0; } $b = $this->newFromBytes($size, $data); return $this->appendBitstream($bitstream, $b); } /** * Convert bitstream to bytes * @param array $bitstream original bitstream * @return array of bytes */ protected function bitstreamToByte($bstream) { $size = count($bstream); if ($size == 0) { return array(); } $data = array_fill(0, (int)(($size + 7) / 8), 0); $bytes = (int)($size / 8); $p = 0; for ($i=0; $i<$bytes; $i++) { $v = 0; for ($j=0; $j<8; $j++) { $v = $v << 1; $v |= $bstream[$p]; $p++; } $data[$i] = $v; } if ($size & 7) { $v = 0; for ($j=0; $j<($size & 7); $j++) { $v = $v << 1; $v |= $bstream[$p]; $p++; } $data[$bytes] = $v; } return $data; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRspec /** * Replace a value on the array at the specified position * @param array $srctab * @param int $x X position * @param int $y Y position * @param string $repl value to replace * @param int $replLen length of the repl string * @return array srctab */ protected function qrstrset($srctab, $x, $y, $repl, $replLen=false) { $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); return $srctab; } /** * Return maximum data code length (bytes) for the version. * @param int $version version * @param int $level error correction level * @return int maximum size (bytes) */ protected function getDataLength($version, $level) { return $this->capacity[$version][QRCAP_WORDS] - $this->capacity[$version][QRCAP_EC][$level]; } /** * Return maximum error correction code length (bytes) for the version. * @param int $version version * @param int $level error correction level * @return int ECC size (bytes) */ protected function getECCLength($version, $level){ return $this->capacity[$version][QRCAP_EC][$level]; } /** * Return the width of the symbol for the version. * @param int $version version * @return int width */ protected function getWidth($version) { return $this->capacity[$version][QRCAP_WIDTH]; } /** * Return the numer of remainder bits. * @param int $version version * @return int number of remainder bits */ protected function getRemainder($version) { return $this->capacity[$version][QRCAP_REMINDER]; } /** * Return a version number that satisfies the input code length. * @param int $size input code length (byte) * @param int $level error correction level * @return int version number */ protected function getMinimumVersion($size, $level) { for ($i=1; $i <= QRSPEC_VERSION_MAX; ++$i) { $words = $this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][$level]; if ($words >= $size) { return $i; } } return -1; } /** * Return the size of length indicator for the mode and version. * @param int $mode encoding mode * @param int $version version * @return int the size of the appropriate length indicator (bits). */ protected function lengthIndicator($mode, $version) { if ($mode == QR_MODE_ST) { return 0; } if ($version <= 9) { $l = 0; } elseif ($version <= 26) { $l = 1; } else { $l = 2; } return $this->lengthTableBits[$mode][$l]; } /** * Return the maximum length for the mode and version. * @param int $mode encoding mode * @param int $version version * @return int the maximum length (bytes) */ protected function maximumWords($mode, $version) { if ($mode == QR_MODE_ST) { return 3; } if ($version <= 9) { $l = 0; } else if ($version <= 26) { $l = 1; } else { $l = 2; } $bits = $this->lengthTableBits[$mode][$l]; $words = (1 << $bits) - 1; if ($mode == QR_MODE_KJ) { $words *= 2; // the number of bytes is required } return $words; } /** * Return an array of ECC specification. * @param int $version version * @param int $level error correction level * @param array $spec an array of ECC specification contains as following: {# of type1 blocks, # of data code, # of ecc code, # of type2 blocks, # of data code} * @return array spec */ protected function getEccSpec($version, $level, $spec) { if (count($spec) < 5) { $spec = array(0, 0, 0, 0, 0); } $b1 = $this->eccTable[$version][$level][0]; $b2 = $this->eccTable[$version][$level][1]; $data = $this->getDataLength($version, $level); $ecc = $this->getECCLength($version, $level); if ($b2 == 0) { $spec[0] = $b1; $spec[1] = (int)($data / $b1); $spec[2] = (int)($ecc / $b1); $spec[3] = 0; $spec[4] = 0; } else { $spec[0] = $b1; $spec[1] = (int)($data / ($b1 + $b2)); $spec[2] = (int)($ecc / ($b1 + $b2)); $spec[3] = $b2; $spec[4] = $spec[1] + 1; } return $spec; } /** * Put an alignment marker. * @param array $frame frame * @param int $width width * @param int $ox X center coordinate of the pattern * @param int $oy Y center coordinate of the pattern * @return array frame */ protected function putAlignmentMarker($frame, $ox, $oy) { $finder = array( "\xa1\xa1\xa1\xa1\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa0\xa1\xa0\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa1\xa1\xa1\xa1" ); $yStart = $oy - 2; $xStart = $ox - 2; for ($y=0; $y < 5; $y++) { $frame = $this->qrstrset($frame, $xStart, $yStart+$y, $finder[$y]); } return $frame; } /** * Put an alignment pattern. * @param int $version version * @param array $fram frame * @param int $width width * @return array frame */ protected function putAlignmentPattern($version, $frame, $width) { if ($version < 2) { return $frame; } $d = $this->alignmentPattern[$version][1] - $this->alignmentPattern[$version][0]; if ($d < 0) { $w = 2; } else { $w = (int)(($width - $this->alignmentPattern[$version][0]) / $d + 2); } if ($w * $w - 3 == 1) { $x = $this->alignmentPattern[$version][0]; $y = $this->alignmentPattern[$version][0]; $frame = $this->putAlignmentMarker($frame, $x, $y); return $frame; } $cx = $this->alignmentPattern[$version][0]; $wo = $w - 1; for ($x=1; $x < $wo; ++$x) { $frame = $this->putAlignmentMarker($frame, 6, $cx); $frame = $this->putAlignmentMarker($frame, $cx, 6); $cx += $d; } $cy = $this->alignmentPattern[$version][0]; for ($y=0; $y < $wo; ++$y) { $cx = $this->alignmentPattern[$version][0]; for ($x=0; $x < $wo; ++$x) { $frame = $this->putAlignmentMarker($frame, $cx, $cy); $cx += $d; } $cy += $d; } return $frame; } /** * Return BCH encoded version information pattern that is used for the symbol of version 7 or greater. Use lower 18 bits. * @param int $version version * @return BCH encoded version information pattern */ protected function getVersionPattern($version) { if (($version < 7) OR ($version > QRSPEC_VERSION_MAX)) { return 0; } return $this->versionPattern[($version - 7)]; } /** * Return BCH encoded format information pattern. * @param array $mask * @param int $level error correction level * @return BCH encoded format information pattern */ protected function getFormatInfo($mask, $level) { if (($mask < 0) OR ($mask > 7)) { return 0; } if (($level < 0) OR ($level > 3)) { return 0; } return $this->formatInfo[$level][$mask]; } /** * Put a finder pattern. * @param array $frame frame * @param int $width width * @param int $ox X center coordinate of the pattern * @param int $oy Y center coordinate of the pattern * @return array frame */ protected function putFinderPattern($frame, $ox, $oy) { $finder = array( "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" ); for ($y=0; $y < 7; $y++) { $frame = $this->qrstrset($frame, $ox, ($oy + $y), $finder[$y]); } return $frame; } /** * Return a copy of initialized frame. * @param int $version version * @return Array of unsigned char. */ protected function createFrame($version) { $width = $this->capacity[$version][QRCAP_WIDTH]; $frameLine = str_repeat ("\0", $width); $frame = array_fill(0, $width, $frameLine); // Finder pattern $frame = $this->putFinderPattern($frame, 0, 0); $frame = $this->putFinderPattern($frame, $width - 7, 0); $frame = $this->putFinderPattern($frame, 0, $width - 7); // Separator $yOffset = $width - 7; for ($y=0; $y < 7; ++$y) { $frame[$y][7] = "\xc0"; $frame[$y][$width - 8] = "\xc0"; $frame[$yOffset][7] = "\xc0"; ++$yOffset; } $setPattern = str_repeat("\xc0", 8); $frame = $this->qrstrset($frame, 0, 7, $setPattern); $frame = $this->qrstrset($frame, $width-8, 7, $setPattern); $frame = $this->qrstrset($frame, 0, $width - 8, $setPattern); // Format info $setPattern = str_repeat("\x84", 9); $frame = $this->qrstrset($frame, 0, 8, $setPattern); $frame = $this->qrstrset($frame, $width - 8, 8, $setPattern, 8); $yOffset = $width - 8; for ($y=0; $y < 8; ++$y,++$yOffset) { $frame[$y][8] = "\x84"; $frame[$yOffset][8] = "\x84"; } // Timing pattern $wo = $width - 15; for ($i=1; $i < $wo; ++$i) { $frame[6][7+$i] = chr(0x90 | ($i & 1)); $frame[7+$i][6] = chr(0x90 | ($i & 1)); } // Alignment pattern $frame = $this->putAlignmentPattern($version, $frame, $width); // Version information if ($version >= 7) { $vinf = $this->getVersionPattern($version); $v = $vinf; for ($x=0; $x<6; ++$x) { for ($y=0; $y<3; ++$y) { $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } $v = $vinf; for ($y=0; $y<6; ++$y) { for ($x=0; $x<3; ++$x) { $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } } // and a little bit... $frame[$width - 8][8] = "\x81"; return $frame; } /** * Set new frame for the specified version. * @param int $version version * @return Array of unsigned char. */ protected function newFrame($version) { if (($version < 1) OR ($version > QRSPEC_VERSION_MAX)) { return NULL; } if (!isset($this->frames[$version])) { $this->frames[$version] = $this->createFrame($version); } if (is_null($this->frames[$version])) { return NULL; } return $this->frames[$version]; } /** * Return block number 0 * @param array $spec * @return int value */ protected function rsBlockNum($spec) { return ($spec[0] + $spec[3]); } /** * Return block number 1 * @param array $spec * @return int value */ protected function rsBlockNum1($spec) { return $spec[0]; } /** * Return data codes 1 * @param array $spec * @return int value */ protected function rsDataCodes1($spec) { return $spec[1]; } /** * Return ecc codes 1 * @param array $spec * @return int value */ protected function rsEccCodes1($spec) { return $spec[2]; } /** * Return block number 2 * @param array $spec * @return int value */ protected function rsBlockNum2($spec) { return $spec[3]; } /** * Return data codes 2 * @param array $spec * @return int value */ protected function rsDataCodes2($spec) { return $spec[4]; } /** * Return ecc codes 2 * @param array $spec * @return int value */ protected function rsEccCodes2($spec) { return $spec[2]; } /** * Return data length * @param array $spec * @return int value */ protected function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } /** * Return ecc length * @param array $spec * @return int value */ protected function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrs /** * Initialize a Reed-Solomon codec and add it to existing rsitems * @param int $symsize symbol size, bits * @param int $gfpoly Field generator polynomial coefficients * @param int $fcr first root of RS code generator polynomial, index form * @param int $prim primitive element to generate polynomial roots * @param int $nroots RS code generator polynomial degree (number of roots) * @param int $pad padding bytes at front of shortened block * @return array Array of RS values:
  • mm = Bits per symbol;
  • nn = Symbols per block;
  • alpha_to = log lookup table array;
  • index_of = Antilog lookup table array;
  • genpoly = Generator polynomial array;
  • nroots = Number of generator;
  • roots = number of parity symbols;
  • fcr = First consecutive root, index form;
  • prim = Primitive element, index form;
  • iprim = prim-th root of 1, index form;
  • pad = Padding bytes in shortened block;
  • gfpoly
. */ protected function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { foreach ($this->rsitems as $rs) { if (($rs['pad'] != $pad) OR ($rs['nroots'] != $nroots) OR ($rs['mm'] != $symsize) OR ($rs['gfpoly'] != $gfpoly) OR ($rs['fcr'] != $fcr) OR ($rs['prim'] != $prim)) { continue; } return $rs; } $rs = $this->init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); array_unshift($this->rsitems, $rs); return $rs; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrsItem /** * modnn * @param array RS values * @param int $x X position * @return int X osition */ protected function modnn($rs, $x) { while ($x >= $rs['nn']) { $x -= $rs['nn']; $x = ($x >> $rs['mm']) + ($x & $rs['nn']); } return $x; } /** * Initialize a Reed-Solomon codec and returns an array of values. * @param int $symsize symbol size, bits * @param int $gfpoly Field generator polynomial coefficients * @param int $fcr first root of RS code generator polynomial, index form * @param int $prim primitive element to generate polynomial roots * @param int $nroots RS code generator polynomial degree (number of roots) * @param int $pad padding bytes at front of shortened block * @return array Array of RS values:
  • mm = Bits per symbol;
  • nn = Symbols per block;
  • alpha_to = log lookup table array;
  • index_of = Antilog lookup table array;
  • genpoly = Generator polynomial array;
  • nroots = Number of generator;
  • roots = number of parity symbols;
  • fcr = First consecutive root, index form;
  • prim = Primitive element, index form;
  • iprim = prim-th root of 1, index form;
  • pad = Padding bytes in shortened block;
  • gfpoly
. */ protected function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { // Based on Reed solomon encoder by Phil Karn, KA9Q (GNU-LGPLv2) $rs = null; // Check parameter ranges if (($symsize < 0) OR ($symsize > 8)) { return $rs; } if (($fcr < 0) OR ($fcr >= (1<<$symsize))) { return $rs; } if (($prim <= 0) OR ($prim >= (1<<$symsize))) { return $rs; } if (($nroots < 0) OR ($nroots >= (1<<$symsize))) { return $rs; } if (($pad < 0) OR ($pad >= ((1<<$symsize) -1 - $nroots))) { return $rs; } $rs = array(); $rs['mm'] = $symsize; $rs['nn'] = (1 << $symsize) - 1; $rs['pad'] = $pad; $rs['alpha_to'] = array_fill(0, ($rs['nn'] + 1), 0); $rs['index_of'] = array_fill(0, ($rs['nn'] + 1), 0); // PHP style macro replacement ;) $NN =& $rs['nn']; $A0 =& $NN; // Generate Galois field lookup tables $rs['index_of'][0] = $A0; // log(zero) = -inf $rs['alpha_to'][$A0] = 0; // alpha**-inf = 0 $sr = 1; for ($i=0; $i<$rs['nn']; ++$i) { $rs['index_of'][$sr] = $i; $rs['alpha_to'][$i] = $sr; $sr <<= 1; if ($sr & (1 << $symsize)) { $sr ^= $gfpoly; } $sr &= $rs['nn']; } if ($sr != 1) { // field generator polynomial is not primitive! return NULL; } // Form RS code generator polynomial from its roots $rs['genpoly'] = array_fill(0, ($nroots + 1), 0); $rs['fcr'] = $fcr; $rs['prim'] = $prim; $rs['nroots'] = $nroots; $rs['gfpoly'] = $gfpoly; // Find prim-th root of 1, used in decoding for ($iprim=1; ($iprim % $prim) != 0; $iprim += $rs['nn']) { ; // intentional empty-body loop! } $rs['iprim'] = (int)($iprim / $prim); $rs['genpoly'][0] = 1; for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { $rs['genpoly'][$i+1] = 1; // Multiply rs->genpoly[] by @**(root + x) for ($j = $i; $j > 0; --$j) { if ($rs['genpoly'][$j] != 0) { $rs['genpoly'][$j] = $rs['genpoly'][$j-1] ^ $rs['alpha_to'][$this->modnn($rs, $rs['index_of'][$rs['genpoly'][$j]] + $root)]; } else { $rs['genpoly'][$j] = $rs['genpoly'][$j-1]; } } // rs->genpoly[0] can never be zero $rs['genpoly'][0] = $rs['alpha_to'][$this->modnn($rs, $rs['index_of'][$rs['genpoly'][0]] + $root)]; } // convert rs->genpoly[] to index form for quicker encoding for ($i = 0; $i <= $nroots; ++$i) { $rs['genpoly'][$i] = $rs['index_of'][$rs['genpoly'][$i]]; } return $rs; } /** * Encode a Reed-Solomon codec and returns the parity array * @param array $rs RS values * @param array $data data * @param array $parity parity * @return parity array */ protected function encode_rs_char($rs, $data, $parity) { $MM =& $rs['mm']; // bits per symbol $NN =& $rs['nn']; // the total number of symbols in a RS block $ALPHA_TO =& $rs['alpha_to']; // the address of an array of NN elements to convert Galois field elements in index (log) form to polynomial form $INDEX_OF =& $rs['index_of']; // the address of an array of NN elements to convert Galois field elements in polynomial form to index (log) form $GENPOLY =& $rs['genpoly']; // an array of NROOTS+1 elements containing the generator polynomial in index form $NROOTS =& $rs['nroots']; // the number of roots in the RS code generator polynomial, which is the same as the number of parity symbols in a block $FCR =& $rs['fcr']; // first consecutive root, index form $PRIM =& $rs['prim']; // primitive element, index form $IPRIM =& $rs['iprim']; // prim-th root of 1, index form $PAD =& $rs['pad']; // the number of pad symbols in a block $A0 =& $NN; $parity = array_fill(0, $NROOTS, 0); for ($i=0; $i < ($NN - $NROOTS - $PAD); $i++) { $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; if ($feedback != $A0) { // feedback term is non-zero // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must // always be for the polynomials constructed by init_rs() $feedback = $this->modnn($rs, $NN - $GENPOLY[$NROOTS] + $feedback); for ($j=1; $j < $NROOTS; ++$j) { $parity[$j] ^= $ALPHA_TO[$this->modnn($rs, $feedback + $GENPOLY[($NROOTS - $j)])]; } } // Shift array_shift($parity); if ($feedback != $A0) { array_push($parity, $ALPHA_TO[$this->modnn($rs, $feedback + $GENPOLY[0])]); } else { array_push($parity, 0); } } return $parity; } } // end QRcode class } // END OF "class_exists QRcode" ?> tools/merge.sh000064400000000031150211530670007331 0ustar00#!/bin/sh php ./merge.phptools/merged_header.php000064400000002526150211530670011175 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ tools/merged_config.php000064400000002364150211530670011212 0ustar00 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ $QR_BASEDIR = dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR; $QR_TOOLSDIR = dirname(__FILE__).DIRECTORY_SEPARATOR; $outputFile = $QR_BASEDIR.'phpqrcode.php'; // Required libs $fileList = array( $QR_BASEDIR.'qrconst.php', $QR_TOOLSDIR.'merged_config.php', $QR_BASEDIR.'qrtools.php', $QR_BASEDIR.'qrspec.php', $QR_BASEDIR.'qrimage.php', $QR_BASEDIR.'qrinput.php', $QR_BASEDIR.'qrbitstream.php', $QR_BASEDIR.'qrsplit.php', $QR_BASEDIR.'qrrscode.php', $QR_BASEDIR.'qrmask.php', $QR_BASEDIR.'qrencode.php' ); $headerFile = $QR_TOOLSDIR.'merged_header.php'; $versionFile = $QR_BASEDIR.'VERSION'; $outputCode = ''; foreach($fileList as $fileName) { $outputCode .= "\n\n".'//---- '.basename($fileName).' -----------------------------'."\n\n"; $anotherCode = file_get_contents($fileName); $anotherCode = preg_replace ('/^<\?php/', '', $anotherCode); $anotherCode = preg_replace ('/\?>\*$/', '', $anotherCode); $outputCode .= "\n\n".$anotherCode."\n\n"; } $versionDataEx = explode("\n", file_get_contents($versionFile)); $outputContents = file_get_contents($headerFile); $outputContents .= "\n\n/*\n * Version: ".trim($versionDataEx[0])."\n * Build: ".trim($versionDataEx[1])."\n */\n\n"; $outputContents .= $outputCode; file_put_contents($outputFile, $outputContents); qrconst.php000064400000003254150211530670006752 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // Encoding modes define('QR_MODE_NUL', -1); define('QR_MODE_NUM', 0); define('QR_MODE_AN', 1); define('QR_MODE_8', 2); define('QR_MODE_KANJI', 3); define('QR_MODE_STRUCTURE', 4); // Levels of error correction. define('QR_ECLEVEL_L', 0); define('QR_ECLEVEL_M', 1); define('QR_ECLEVEL_Q', 2); define('QR_ECLEVEL_H', 3); // Supported output formats define('QR_FORMAT_TEXT', 0); define('QR_FORMAT_PNG', 1); class qrstr { public static function set(&$srctab, $x, $y, $repl, $replLen = false) { $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); } } qrbitstream.php000064400000012126150211530670007614 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRbitstream { public $data = array(); //---------------------------------------------------------------------- public function size() { return count($this->data); } //---------------------------------------------------------------------- public function allocate($setLength) { $this->data = array_fill(0, $setLength, 0); return 0; } //---------------------------------------------------------------------- public static function newFromNum($bits, $num) { $bstream = new QRbitstream(); $bstream->allocate($bits); $mask = 1 << ($bits - 1); for($i=0; $i<$bits; $i++) { if($num & $mask) { $bstream->data[$i] = 1; } else { $bstream->data[$i] = 0; } $mask = $mask >> 1; } return $bstream; } //---------------------------------------------------------------------- public static function newFromBytes($size, $data) { $bstream = new QRbitstream(); $bstream->allocate($size * 8); $p=0; for($i=0; $i<$size; $i++) { $mask = 0x80; for($j=0; $j<8; $j++) { if($data[$i] & $mask) { $bstream->data[$p] = 1; } else { $bstream->data[$p] = 0; } $p++; $mask = $mask >> 1; } } return $bstream; } //---------------------------------------------------------------------- public function append(QRbitstream $arg) { if (is_null($arg)) { return -1; } if($arg->size() == 0) { return 0; } if($this->size() == 0) { $this->data = $arg->data; return 0; } $this->data = array_values(array_merge($this->data, $arg->data)); return 0; } //---------------------------------------------------------------------- public function appendNum($bits, $num) { if ($bits == 0) return 0; $b = QRbitstream::newFromNum($bits, $num); if(is_null($b)) return -1; $ret = $this->append($b); unset($b); return $ret; } //---------------------------------------------------------------------- public function appendBytes($size, $data) { if ($size == 0) return 0; $b = QRbitstream::newFromBytes($size, $data); if(is_null($b)) return -1; $ret = $this->append($b); unset($b); return $ret; } //---------------------------------------------------------------------- public function toByte() { $size = $this->size(); if($size == 0) { return array(); } $data = array_fill(0, (int)(($size + 7) / 8), 0); $bytes = (int)($size / 8); $p = 0; for($i=0; $i<$bytes; $i++) { $v = 0; for($j=0; $j<8; $j++) { $v = $v << 1; $v |= $this->data[$p]; $p++; } $data[$i] = $v; } if($size & 7) { $v = 0; for($j=0; $j<($size & 7); $j++) { $v = $v << 1; $v |= $this->data[$p]; $p++; } $data[$bytes] = $v; } return $data; } } qrrscode.php000064400000020124150211530670007076 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRrsItem { public $mm; // Bits per symbol public $nn; // Symbols per block (= (1<= $this->nn) { $x -= $this->nn; $x = ($x >> $this->mm) + ($x & $this->nn); } return $x; } //---------------------------------------------------------------------- public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { // Common code for intializing a Reed-Solomon control block (char or int symbols) // Copyright 2004 Phil Karn, KA9Q // May be used under the terms of the GNU Lesser General Public License (LGPL) $rs = null; // Check parameter ranges if($symsize < 0 || $symsize > 8) return $rs; if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs; if($prim <= 0 || $prim >= (1<<$symsize)) return $rs; if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values! if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding $rs = new QRrsItem(); $rs->mm = $symsize; $rs->nn = (1<<$symsize)-1; $rs->pad = $pad; $rs->alpha_to = array_fill(0, $rs->nn+1, 0); $rs->index_of = array_fill(0, $rs->nn+1, 0); // PHP style macro replacement ;) $NN =& $rs->nn; $A0 =& $NN; // Generate Galois field lookup tables $rs->index_of[0] = $A0; // log(zero) = -inf $rs->alpha_to[$A0] = 0; // alpha**-inf = 0 $sr = 1; for($i=0; $i<$rs->nn; $i++) { $rs->index_of[$sr] = $i; $rs->alpha_to[$i] = $sr; $sr <<= 1; if($sr & (1<<$symsize)) { $sr ^= $gfpoly; } $sr &= $rs->nn; } if($sr != 1){ // field generator polynomial is not primitive! $rs = NULL; return $rs; } /* Form RS code generator polynomial from its roots */ $rs->genpoly = array_fill(0, $nroots+1, 0); $rs->fcr = $fcr; $rs->prim = $prim; $rs->nroots = $nroots; $rs->gfpoly = $gfpoly; /* Find prim-th root of 1, used in decoding */ for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn) ; // intentional empty-body loop! $rs->iprim = (int)($iprim / $prim); $rs->genpoly[0] = 1; for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { $rs->genpoly[$i+1] = 1; // Multiply rs->genpoly[] by @**(root + x) for ($j = $i; $j > 0; $j--) { if ($rs->genpoly[$j] != 0) { $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)]; } else { $rs->genpoly[$j] = $rs->genpoly[$j-1]; } } // rs->genpoly[0] can never be zero $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)]; } // convert rs->genpoly[] to index form for quicker encoding for ($i = 0; $i <= $nroots; $i++) $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]]; return $rs; } //---------------------------------------------------------------------- public function encode_rs_char($data, &$parity) { $MM =& $this->mm; $NN =& $this->nn; $ALPHA_TO =& $this->alpha_to; $INDEX_OF =& $this->index_of; $GENPOLY =& $this->genpoly; $NROOTS =& $this->nroots; $FCR =& $this->fcr; $PRIM =& $this->prim; $IPRIM =& $this->iprim; $PAD =& $this->pad; $A0 =& $NN; $parity = array_fill(0, $NROOTS, 0); for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) { $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; if($feedback != $A0) { // feedback term is non-zero // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must // always be for the polynomials constructed by init_rs() $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback); for($j=1;$j<$NROOTS;$j++) { $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])]; } } // Shift array_shift($parity); if($feedback != $A0) { array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]); } else { array_push($parity, 0); } } } } //########################################################################## class QRrs { public static $items = array(); //---------------------------------------------------------------------- public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { foreach(self::$items as $rs) { if($rs->pad != $pad) continue; if($rs->nroots != $nroots) continue; if($rs->mm != $symsize) continue; if($rs->gfpoly != $gfpoly) continue; if($rs->fcr != $fcr) continue; if($rs->prim != $prim) continue; return $rs; } $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); array_unshift(self::$items, $rs); return $rs; } }myimage.png-errors.txt000064400000000044150211530670011030 0ustar002019-11-11 14:56:06: empty string!!!qrspec.php000064400000062645150211530670006567 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * The following data / specifications are taken from * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) * or * "Automatic identification and data capture techniques -- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ define('QRSPEC_VERSION_MAX', 40); define('QRSPEC_WIDTH_MAX', 177); define('QRCAP_WIDTH', 0); define('QRCAP_WORDS', 1); define('QRCAP_REMINDER', 2); define('QRCAP_EC', 3); class QRspec { public static $capacity = array( array( 0, 0, 0, array( 0, 0, 0, 0)), array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 array( 25, 44, 7, array( 10, 16, 22, 28)), array( 29, 70, 7, array( 15, 26, 36, 44)), array( 33, 100, 7, array( 20, 36, 52, 64)), array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 array( 41, 172, 7, array( 36, 64, 96, 112)), array( 45, 196, 0, array( 40, 72, 108, 130)), array( 49, 242, 0, array( 48, 88, 132, 156)), array( 53, 292, 0, array( 60, 110, 160, 192)), array( 57, 346, 0, array( 72, 130, 192, 224)), //10 array( 61, 404, 0, array( 80, 150, 224, 264)), array( 65, 466, 0, array( 96, 176, 260, 308)), array( 69, 532, 0, array( 104, 198, 288, 352)), array( 73, 581, 3, array( 120, 216, 320, 384)), array( 77, 655, 3, array( 132, 240, 360, 432)), //15 array( 81, 733, 3, array( 144, 280, 408, 480)), array( 85, 815, 3, array( 168, 308, 448, 532)), array( 89, 901, 3, array( 180, 338, 504, 588)), array( 93, 991, 3, array( 196, 364, 546, 650)), array( 97, 1085, 3, array( 224, 416, 600, 700)), //20 array(101, 1156, 4, array( 224, 442, 644, 750)), array(105, 1258, 4, array( 252, 476, 690, 816)), array(109, 1364, 4, array( 270, 504, 750, 900)), array(113, 1474, 4, array( 300, 560, 810, 960)), array(117, 1588, 4, array( 312, 588, 870, 1050)), //25 array(121, 1706, 4, array( 336, 644, 952, 1110)), array(125, 1828, 4, array( 360, 700, 1020, 1200)), array(129, 1921, 3, array( 390, 728, 1050, 1260)), array(133, 2051, 3, array( 420, 784, 1140, 1350)), array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30 array(141, 2323, 3, array( 480, 868, 1290, 1530)), array(145, 2465, 3, array( 510, 924, 1350, 1620)), array(149, 2611, 3, array( 540, 980, 1440, 1710)), array(153, 2761, 3, array( 570, 1036, 1530, 1800)), array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35 array(161, 3034, 0, array( 600, 1120, 1680, 1980)), array(165, 3196, 0, array( 630, 1204, 1770, 2100)), array(169, 3362, 0, array( 660, 1260, 1860, 2220)), array(173, 3532, 0, array( 720, 1316, 1950, 2310)), array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40 ); //---------------------------------------------------------------------- public static function getDataLength($version, $level) { return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level]; } //---------------------------------------------------------------------- public static function getECCLength($version, $level) { return self::$capacity[$version][QRCAP_EC][$level]; } //---------------------------------------------------------------------- public static function getWidth($version) { return self::$capacity[$version][QRCAP_WIDTH]; } //---------------------------------------------------------------------- public static function getRemainder($version) { return self::$capacity[$version][QRCAP_REMINDER]; } //---------------------------------------------------------------------- public static function getMinimumVersion($size, $level) { for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) { $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level]; if($words >= $size) return $i; } return -1; } //###################################################################### public static $lengthTableBits = array( array(10, 12, 14), array( 9, 11, 13), array( 8, 16, 16), array( 8, 10, 12) ); //---------------------------------------------------------------------- public static function lengthIndicator($mode, $version) { if ($mode == QR_MODE_STRUCTURE) return 0; if ($version <= 9) { $l = 0; } else if ($version <= 26) { $l = 1; } else { $l = 2; } return self::$lengthTableBits[$mode][$l]; } //---------------------------------------------------------------------- public static function maximumWords($mode, $version) { if($mode == QR_MODE_STRUCTURE) return 3; if($version <= 9) { $l = 0; } else if($version <= 26) { $l = 1; } else { $l = 2; } $bits = self::$lengthTableBits[$mode][$l]; $words = (1 << $bits) - 1; if($mode == QR_MODE_KANJI) { $words *= 2; // the number of bytes is required } return $words; } // Error correction code ----------------------------------------------- // Table of the error correction code (Reed-Solomon block) // See Table 12-16 (pp.30-36), JIS X0510:2004. public static $eccTable = array( array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40 ); //---------------------------------------------------------------------- // CACHEABLE!!! public static function getEccSpec($version, $level, array &$spec) { if (count($spec) < 5) { $spec = array(0,0,0,0,0); } $b1 = self::$eccTable[$version][$level][0]; $b2 = self::$eccTable[$version][$level][1]; $data = self::getDataLength($version, $level); $ecc = self::getECCLength($version, $level); if($b2 == 0) { $spec[0] = $b1; $spec[1] = (int)($data / $b1); $spec[2] = (int)($ecc / $b1); $spec[3] = 0; $spec[4] = 0; } else { $spec[0] = $b1; $spec[1] = (int)($data / ($b1 + $b2)); $spec[2] = (int)($ecc / ($b1 + $b2)); $spec[3] = $b2; $spec[4] = $spec[1] + 1; } } // Alignment pattern --------------------------------------------------- // Positions of alignment patterns. // This array includes only the second and the third position of the // alignment patterns. Rest of them can be calculated from the distance // between them. // See Table 1 in Appendix E (pp.71) of JIS X0510:2004. public static $alignmentPattern = array( array( 0, 0), array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40 ); /** -------------------------------------------------------------------- * Put an alignment marker. * @param frame * @param width * @param ox,oy center coordinate of the pattern */ public static function putAlignmentMarker(array &$frame, $ox, $oy) { $finder = array( "\xa1\xa1\xa1\xa1\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa0\xa1\xa0\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa1\xa1\xa1\xa1" ); $yStart = $oy-2; $xStart = $ox-2; for($y=0; $y<5; $y++) { QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]); } } //---------------------------------------------------------------------- public static function putAlignmentPattern($version, &$frame, $width) { if($version < 2) return; $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0]; if($d < 0) { $w = 2; } else { $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2); } if($w * $w - 3 == 1) { $x = self::$alignmentPattern[$version][0]; $y = self::$alignmentPattern[$version][0]; self::putAlignmentMarker($frame, $x, $y); return; } $cx = self::$alignmentPattern[$version][0]; for($x=1; $x<$w - 1; $x++) { self::putAlignmentMarker($frame, 6, $cx); self::putAlignmentMarker($frame, $cx, 6); $cx += $d; } $cy = self::$alignmentPattern[$version][0]; for($y=0; $y<$w-1; $y++) { $cx = self::$alignmentPattern[$version][0]; for($x=0; $x<$w-1; $x++) { self::putAlignmentMarker($frame, $cx, $cy); $cx += $d; } $cy += $d; } } // Version information pattern ----------------------------------------- // Version information pattern (BCH coded). // See Table 1 in Appendix D (pp.68) of JIS X0510:2004. // size: [QRSPEC_VERSION_MAX - 6] public static $versionPattern = array( 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, 0x27541, 0x28c69 ); //---------------------------------------------------------------------- public static function getVersionPattern($version) { if($version < 7 || $version > QRSPEC_VERSION_MAX) return 0; return self::$versionPattern[$version -7]; } // Format information -------------------------------------------------- // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib) public static $formatInfo = array( array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) ); public static function getFormatInfo($mask, $level) { if($mask < 0 || $mask > 7) return 0; if($level < 0 || $level > 3) return 0; return self::$formatInfo[$level][$mask]; } // Frame --------------------------------------------------------------- // Cache of initial frames. public static $frames = array(); /** -------------------------------------------------------------------- * Put a finder pattern. * @param frame * @param width * @param ox,oy upper-left coordinate of the pattern */ public static function putFinderPattern(&$frame, $ox, $oy) { $finder = array( "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" ); for($y=0; $y<7; $y++) { QRstr::set($frame, $ox, $oy+$y, $finder[$y]); } } //---------------------------------------------------------------------- public static function createFrame($version) { $width = self::$capacity[$version][QRCAP_WIDTH]; $frameLine = str_repeat ("\0", $width); $frame = array_fill(0, $width, $frameLine); // Finder pattern self::putFinderPattern($frame, 0, 0); self::putFinderPattern($frame, $width - 7, 0); self::putFinderPattern($frame, 0, $width - 7); // Separator $yOffset = $width - 7; for($y=0; $y<7; $y++) { $frame[$y][7] = "\xc0"; $frame[$y][$width - 8] = "\xc0"; $frame[$yOffset][7] = "\xc0"; $yOffset++; } $setPattern = str_repeat("\xc0", 8); QRstr::set($frame, 0, 7, $setPattern); QRstr::set($frame, $width-8, 7, $setPattern); QRstr::set($frame, 0, $width - 8, $setPattern); // Format info $setPattern = str_repeat("\x84", 9); QRstr::set($frame, 0, 8, $setPattern); QRstr::set($frame, $width - 8, 8, $setPattern, 8); $yOffset = $width - 8; for($y=0; $y<8; $y++,$yOffset++) { $frame[$y][8] = "\x84"; $frame[$yOffset][8] = "\x84"; } // Timing pattern for($i=1; $i<$width-15; $i++) { $frame[6][7+$i] = chr(0x90 | ($i & 1)); $frame[7+$i][6] = chr(0x90 | ($i & 1)); } // Alignment pattern self::putAlignmentPattern($version, $frame, $width); // Version information if($version >= 7) { $vinf = self::getVersionPattern($version); $v = $vinf; for($x=0; $x<6; $x++) { for($y=0; $y<3; $y++) { $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } $v = $vinf; for($y=0; $y<6; $y++) { for($x=0; $x<3; $x++) { $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } } // and a little bit... $frame[$width - 8][8] = "\x81"; return $frame; } //---------------------------------------------------------------------- public static function debug($frame, $binary_mode = false) { if ($binary_mode) { foreach ($frame as &$frameLine) { $frameLine = join('  ', explode('0', $frameLine)); $frameLine = join('██', explode('1', $frameLine)); } ?>


        '; echo join("
        ", $frame); echo '






'; } else { foreach ($frame as &$frameLine) { $frameLine = join(' ', explode("\xc0", $frameLine)); $frameLine = join('', explode("\xc1", $frameLine)); $frameLine = join(' ', explode("\xa0", $frameLine)); $frameLine = join('', explode("\xa1", $frameLine)); $frameLine = join('', explode("\x84", $frameLine)); //format 0 $frameLine = join('', explode("\x85", $frameLine)); //format 1 $frameLine = join('', explode("\x81", $frameLine)); //special bit $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0 $frameLine = join('', explode("\x91", $frameLine)); //clock 1 $frameLine = join(' ', explode("\x88", $frameLine)); //version $frameLine = join('', explode("\x89", $frameLine)); //version $frameLine = join('♦', explode("\x01", $frameLine)); $frameLine = join('⋅', explode("\0", $frameLine)); } ?> "; echo join("
", $frame); echo "
"; } } //---------------------------------------------------------------------- public static function serial($frame) { return gzcompress(join("\n", $frame), 9); } //---------------------------------------------------------------------- public static function unserial($code) { return explode("\n", gzuncompress($code)); } //---------------------------------------------------------------------- public static function newFrame($version) { if($version < 1 || $version > QRSPEC_VERSION_MAX) return null; if(!isset(self::$frames[$version])) { $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat'; if (QR_CACHEABLE) { if (file_exists($fileName)) { self::$frames[$version] = self::unserial(file_get_contents($fileName)); } else { self::$frames[$version] = self::createFrame($version); file_put_contents($fileName, self::serial(self::$frames[$version])); } } else { self::$frames[$version] = self::createFrame($version); } } if(is_null(self::$frames[$version])) return null; return self::$frames[$version]; } //---------------------------------------------------------------------- public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; } public static function rsBlockNum1($spec) { return $spec[0]; } public static function rsDataCodes1($spec) { return $spec[1]; } public static function rsEccCodes1($spec) { return $spec[2]; } public static function rsBlockNum2($spec) { return $spec[3]; } public static function rsDataCodes2($spec) { return $spec[4]; } public static function rsEccCodes2($spec) { return $spec[2]; } public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } }qrlib.php000064400000003027150211530670006370 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ $QR_BASEDIR = dirname(__FILE__).DIRECTORY_SEPARATOR; // Required libs include $QR_BASEDIR."qrconst.php"; include $QR_BASEDIR."qrconfig.php"; include $QR_BASEDIR."qrtools.php"; include $QR_BASEDIR."qrspec.php"; include $QR_BASEDIR."qrimage.php"; include $QR_BASEDIR."qrinput.php"; include $QR_BASEDIR."qrbitstream.php"; include $QR_BASEDIR."qrsplit.php"; include $QR_BASEDIR."qrrscode.php"; include $QR_BASEDIR."qrmask.php"; include $QR_BASEDIR."qrencode.php"; README000064400000003066150211530670005431 0ustar00This is PHP implementation of QR Code 2-D barcode generator. It is pure-php LGPL-licensed implementation based on C libqrencode by Kentaro Fukuchi. == LICENSING == Copyright (C) 2010 by Dominik Dzienia This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License (LICENSE file) for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA == INSTALATION AND USAGE == * INSTALL file * http://sourceforge.net/apps/mediawiki/phpqrcode/index.php?title=Main_Page == CONTACT == Fell free to contact me via e-mail (deltalab at poczta dot fm) or using folowing project pages: * http://sourceforge.net/projects/phpqrcode/ * http://phpqrcode.sourceforge.net/ == ACKNOWLEDGMENTS == Based on C libqrencode library (ver. 3.1.1) Copyright (C) 2006-2010 by Kentaro Fukuchi http://megaui.net/fukuchi/works/qrencode/index.en.html QR Code is registered trademarks of DENSO WAVE INCORPORATED in JAPAN and other countries. Reed-Solomon code encoder is written by Phil Karn, KA9Q. Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q qrsplit.php000064400000025477150211530670006772 0ustar00 * * PHP QR Code is distributed under LGPL 3 * Copyright (C) 2010 Dominik Dzienia * * The following data / specifications are taken from * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) * or * "Automatic identification and data capture techniques -- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class QRsplit { public $dataStr = ''; public $input; public $modeHint; //---------------------------------------------------------------------- public function __construct($dataStr, $input, $modeHint) { $this->dataStr = $dataStr; $this->input = $input; $this->modeHint = $modeHint; } //---------------------------------------------------------------------- public static function isdigitat($str, $pos) { if ($pos >= strlen($str)) return false; return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); } //---------------------------------------------------------------------- public static function isalnumat($str, $pos) { if ($pos >= strlen($str)) return false; return (QRinput::lookAnTable(ord($str[$pos])) >= 0); } //---------------------------------------------------------------------- public function identifyMode($pos) { if ($pos >= strlen($this->dataStr)) return QR_MODE_NUL; $c = $this->dataStr[$pos]; if(self::isdigitat($this->dataStr, $pos)) { return QR_MODE_NUM; } else if(self::isalnumat($this->dataStr, $pos)) { return QR_MODE_AN; } else if($this->modeHint == QR_MODE_KANJI) { if ($pos+1 < strlen($this->dataStr)) { $d = $this->dataStr[$pos+1]; $word = (ord($c) << 8) | ord($d); if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) { return QR_MODE_KANJI; } } } return QR_MODE_8; } //---------------------------------------------------------------------- public function eatNum() { $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 0; while(self::isdigitat($this->dataStr, $p)) { $p++; } $run = $p; $mode = $this->identifyMode($p); if($mode == QR_MODE_8) { $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + QRinput::estimateBitsMode8(1) // + 4 + l8 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 if($dif > 0) { return $this->eat8(); } } if($mode == QR_MODE_AN) { $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + QRinput::estimateBitsModeAn(1) // + 4 + la - QRinput::estimateBitsModeAn($run + 1);// - 4 - la if($dif > 0) { return $this->eatAn(); } } $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eatAn() { $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 0; while(self::isalnumat($this->dataStr, $p)) { if(self::isdigitat($this->dataStr, $p)) { $q = $p; while(self::isdigitat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsModeAn($p) // + 4 + la + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - QRinput::estimateBitsModeAn($q); // - 4 - la if($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; if(!self::isalnumat($this->dataStr, $p)) { $dif = QRinput::estimateBitsModeAn($run) + 4 + $la + QRinput::estimateBitsMode8(1) // + 4 + l8 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 if($dif > 0) { return $this->eat8(); } } $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eatKanji() { $p = 0; while($this->identifyMode($p) == QR_MODE_KANJI) { $p += 2; } $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function eat8() { $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 1; $dataStrLen = strlen($this->dataStr); while($p < $dataStrLen) { $mode = $this->identifyMode($p); if($mode == QR_MODE_KANJI) { break; } if($mode == QR_MODE_NUM) { $q = $p; while(self::isdigitat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - QRinput::estimateBitsMode8($q); // - 4 - l8 if($dif < 0) { break; } else { $p = $q; } } else if($mode == QR_MODE_AN) { $q = $p; while(self::isalnumat($this->dataStr, $q)) { $q++; } $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + QRinput::estimateBitsModeAn($q - $p) + 4 + $la - QRinput::estimateBitsMode8($q); // - 4 - l8 if($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); if($ret < 0) return -1; return $run; } //---------------------------------------------------------------------- public function splitString() { while (strlen($this->dataStr) > 0) { if($this->dataStr == '') return 0; $mode = $this->identifyMode(0); switch ($mode) { case QR_MODE_NUM: $length = $this->eatNum(); break; case QR_MODE_AN: $length = $this->eatAn(); break; case QR_MODE_KANJI: if ($hint == QR_MODE_KANJI) $length = $this->eatKanji(); else $length = $this->eat8(); break; default: $length = $this->eat8(); break; } if($length == 0) return 0; if($length < 0) return -1; $this->dataStr = substr($this->dataStr, $length); } } //---------------------------------------------------------------------- public function toUpper() { $stringLen = strlen($this->dataStr); $p = 0; while ($p<$stringLen) { $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint); if($mode == QR_MODE_KANJI) { $p += 2; } else { if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) { $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); } $p++; } } return $this->dataStr; } //---------------------------------------------------------------------- public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true) { if(is_null($string) || $string == '\0' || $string == '') { throw new Exception('empty string!!!'); } $split = new QRsplit($string, $input, $modeHint); if(!$casesensitive) $split->toUpper(); return $split->splitString(); } }