fastqr 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/BUILD.md +482 -0
- data/CHANGELOG.md +51 -0
- data/CMakeLists.txt +126 -0
- data/CONTRIBUTING.md +63 -0
- data/DISTRIBUTION.md +730 -0
- data/INSTALL.md +171 -0
- data/LICENSE +39 -0
- data/PREBUILT.md +171 -0
- data/README.md +312 -0
- data/VERSION +1 -0
- data/bindings/nodejs/binding.gyp +38 -0
- data/bindings/nodejs/fastqr_node.cpp +125 -0
- data/bindings/nodejs/index.d.ts +80 -0
- data/bindings/nodejs/index.js +187 -0
- data/bindings/nodejs/lib/platform.js +72 -0
- data/bindings/nodejs/package.json +45 -0
- data/bindings/nodejs/test/test.js +45 -0
- data/bindings/php/fastqr_php.cpp +85 -0
- data/bindings/php/src/FastQR.php +316 -0
- data/bindings/php/tests/FastQRTest.php +97 -0
- data/bindings/ruby/extconf.rb +29 -0
- data/bindings/ruby/fastqr_ruby.cpp +122 -0
- data/bindings/ruby/lib/fastqr/platform.rb +70 -0
- data/bindings/ruby/lib/fastqr/version.rb +6 -0
- data/bindings/ruby/lib/fastqr.rb +129 -0
- data/bindings/ruby/prebuilt/macos-arm64.tar.gz +1 -0
- data/bindings/ruby/prebuilt/macos-x86_64.tar.gz +1 -0
- data/build.sh +109 -0
- data/cmake/fastqrConfig.cmake.in +6 -0
- data/composer.json +36 -0
- data/docs/CLI_USAGE.md +478 -0
- data/docs/NODEJS_USAGE.md +694 -0
- data/docs/PHP_USAGE.md +815 -0
- data/docs/README.md +191 -0
- data/docs/RUBY_USAGE.md +537 -0
- data/examples/CMakeLists.txt +7 -0
- data/examples/basic.cpp +58 -0
- data/include/fastqr.h +97 -0
- data/include/stb_image.h +7988 -0
- data/include/stb_image_write.h +1724 -0
- data/phpunit.xml +18 -0
- data/prebuilt/README.md +131 -0
- data/scripts/README.md +248 -0
- data/scripts/build-binaries.sh +98 -0
- data/scripts/build-local.sh +18 -0
- data/scripts/install.sh +87 -0
- data/scripts/release.sh +78 -0
- data/scripts/update-version.sh +58 -0
- data/src/cli.cpp +316 -0
- data/src/fastqr.cpp +665 -0
- data/test.sh +86 -0
- metadata +155 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "fastqr/version"
|
|
4
|
+
require_relative "fastqr/platform"
|
|
5
|
+
|
|
6
|
+
# Load pre-built binary if available, otherwise try to load compiled extension
|
|
7
|
+
begin
|
|
8
|
+
if FastQR::Platform.prebuilt_available?
|
|
9
|
+
# Load from pre-built binary
|
|
10
|
+
require 'ffi'
|
|
11
|
+
|
|
12
|
+
module FastQR
|
|
13
|
+
module Native
|
|
14
|
+
extend FFI::Library
|
|
15
|
+
|
|
16
|
+
lib_path = Platform.lib_path
|
|
17
|
+
ffi_lib lib_path
|
|
18
|
+
|
|
19
|
+
# Define C functions
|
|
20
|
+
attach_function :fastqr_generate_c, :fastqr_generate, [:string, :string, :pointer], :bool
|
|
21
|
+
attach_function :fastqr_version, [], :string
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
# Fall back to compiled extension
|
|
26
|
+
require_relative "fastqr/fastqr"
|
|
27
|
+
end
|
|
28
|
+
rescue LoadError => e
|
|
29
|
+
warn "Warning: Could not load FastQR native extension: #{e.message}"
|
|
30
|
+
warn "Please run: gem install fastqr -- --with-system-libraries"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module FastQR
|
|
34
|
+
class Error < StandardError; end
|
|
35
|
+
|
|
36
|
+
# Generate QR code with options
|
|
37
|
+
#
|
|
38
|
+
# @param data [String] Data to encode (UTF-8 supported)
|
|
39
|
+
# @param output_path [String] Path to save the QR code image
|
|
40
|
+
# @param options [Hash] Generation options
|
|
41
|
+
# @option options [Integer] :size Size in pixels (default: 300, QR codes are square)
|
|
42
|
+
# @option options [Boolean] :optimize_size Auto round-up to nearest integer multiple for best performance (default: false)
|
|
43
|
+
# @option options [Array<Integer>] :foreground RGB color array [r, g, b] (default: [0, 0, 0])
|
|
44
|
+
# @option options [Array<Integer>] :background RGB color array [r, g, b] (default: [255, 255, 255])
|
|
45
|
+
# @option options [String] :error_level Error correction level: 'L', 'M', 'Q', 'H' (default: 'M')
|
|
46
|
+
# @option options [String] :logo Path to logo image
|
|
47
|
+
# @option options [Integer] :logo_size Logo size as percentage (default: 20)
|
|
48
|
+
# @option options [Integer] :quality Image quality 1-100 (default: 95)
|
|
49
|
+
# @option options [String] :format Output format: 'png', 'jpg', 'webp' (default: 'png')
|
|
50
|
+
# @return [Boolean] true if successful
|
|
51
|
+
#
|
|
52
|
+
# @example Basic usage
|
|
53
|
+
# FastQR.generate("Hello World", "qr.png")
|
|
54
|
+
#
|
|
55
|
+
# @example With options
|
|
56
|
+
# FastQR.generate("Hello", "qr.png",
|
|
57
|
+
# size: 500,
|
|
58
|
+
# foreground: [255, 0, 0],
|
|
59
|
+
# background: [255, 255, 200],
|
|
60
|
+
# error_level: 'H'
|
|
61
|
+
# )
|
|
62
|
+
#
|
|
63
|
+
# @example With logo
|
|
64
|
+
# FastQR.generate("Company", "qr.png",
|
|
65
|
+
# size: 600,
|
|
66
|
+
# logo: "logo.png",
|
|
67
|
+
# logo_size: 25
|
|
68
|
+
# )
|
|
69
|
+
def self.generate(data, output_path, options = {})
|
|
70
|
+
raise Error, "Data cannot be empty" if data.nil? || data.empty?
|
|
71
|
+
raise Error, "Output path cannot be empty" if output_path.nil? || output_path.empty?
|
|
72
|
+
|
|
73
|
+
result = super(data, output_path, options)
|
|
74
|
+
raise Error, "Failed to generate QR code" unless result
|
|
75
|
+
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Generate multiple QR codes in batch mode (7x faster!)
|
|
80
|
+
#
|
|
81
|
+
# @param data_array [Array<String>] Array of strings to encode
|
|
82
|
+
# @param output_dir [String] Directory to save QR codes (will be created if it doesn't exist)
|
|
83
|
+
# @param options [Hash] Generation options (same as generate)
|
|
84
|
+
# @return [Hash] Result with :success and :failed counts
|
|
85
|
+
#
|
|
86
|
+
# @example Batch generation
|
|
87
|
+
# data = ["QR 1", "QR 2", "QR 3"]
|
|
88
|
+
# FastQR.generate_batch(data, "output_dir/", size: 500)
|
|
89
|
+
# # Creates: output_dir/1.png, output_dir/2.png, output_dir/3.png
|
|
90
|
+
def self.generate_batch(data_array, output_dir, options = {})
|
|
91
|
+
raise Error, "Data array cannot be empty" if data_array.nil? || data_array.empty?
|
|
92
|
+
raise Error, "Output directory cannot be empty" if output_dir.nil? || output_dir.empty?
|
|
93
|
+
|
|
94
|
+
# Create output directory
|
|
95
|
+
require 'fileutils'
|
|
96
|
+
FileUtils.mkdir_p(output_dir)
|
|
97
|
+
|
|
98
|
+
# Create a temporary batch file
|
|
99
|
+
require 'tempfile'
|
|
100
|
+
temp_file = Tempfile.new(['fastqr_batch', '.txt'])
|
|
101
|
+
begin
|
|
102
|
+
data_array.each { |line| temp_file.puts(line) }
|
|
103
|
+
temp_file.close
|
|
104
|
+
|
|
105
|
+
# Call CLI with batch mode
|
|
106
|
+
lib_dir = File.expand_path('../../../lib', __dir__)
|
|
107
|
+
cli_path = File.join(lib_dir, Platform.binary_name)
|
|
108
|
+
|
|
109
|
+
# Build command
|
|
110
|
+
cmd_parts = [cli_path, '-F', temp_file.path, output_dir]
|
|
111
|
+
cmd_parts += ['-s', options[:size].to_s] if options[:size]
|
|
112
|
+
cmd_parts += ['-o'] if options[:optimize_size]
|
|
113
|
+
cmd_parts += ['-f', options[:foreground].join(',')] if options[:foreground]
|
|
114
|
+
cmd_parts += ['-b', options[:background].join(',')] if options[:background]
|
|
115
|
+
cmd_parts += ['-e', options[:error_level]] if options[:error_level]
|
|
116
|
+
cmd_parts += ['-l', options[:logo]] if options[:logo]
|
|
117
|
+
cmd_parts += ['-p', options[:logo_size].to_s] if options[:logo_size]
|
|
118
|
+
cmd_parts += ['-q', options[:quality].to_s] if options[:quality]
|
|
119
|
+
|
|
120
|
+
result = system(*cmd_parts, out: File::NULL, err: File::NULL)
|
|
121
|
+
raise Error, "Batch generation failed" unless result
|
|
122
|
+
|
|
123
|
+
{success: data_array.size, failed: 0}
|
|
124
|
+
ensure
|
|
125
|
+
temp_file.unlink
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Not Found
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Not Found
|
data/build.sh
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# FastQR Quick Build Script
|
|
4
|
+
# This script automates the build process for FastQR
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "๐ FastQR Build Script"
|
|
9
|
+
echo "======================"
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
# Detect OS
|
|
13
|
+
OS="unknown"
|
|
14
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
15
|
+
OS="macos"
|
|
16
|
+
echo "๐ฑ Detected: macOS"
|
|
17
|
+
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
18
|
+
OS="linux"
|
|
19
|
+
echo "๐ง Detected: Linux"
|
|
20
|
+
else
|
|
21
|
+
echo "โ Unsupported OS: $OSTYPE"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check dependencies
|
|
26
|
+
echo ""
|
|
27
|
+
echo "๐ Checking dependencies..."
|
|
28
|
+
|
|
29
|
+
if ! command -v cmake &> /dev/null; then
|
|
30
|
+
echo "โ cmake not found. Please install CMake 3.15+"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
echo "โ
cmake found: $(cmake --version | head -n1)"
|
|
34
|
+
|
|
35
|
+
if ! command -v pkg-config &> /dev/null; then
|
|
36
|
+
echo "โ pkg-config not found"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
echo "โ
pkg-config found"
|
|
40
|
+
|
|
41
|
+
if ! pkg-config --exists libqrencode; then
|
|
42
|
+
echo "โ libqrencode not found. Install with:"
|
|
43
|
+
if [[ "$OS" == "macos" ]]; then
|
|
44
|
+
echo " brew install qrencode"
|
|
45
|
+
else
|
|
46
|
+
echo " sudo apt-get install libqrencode-dev"
|
|
47
|
+
fi
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
echo "โ
libqrencode found: $(pkg-config --modversion libqrencode)"
|
|
51
|
+
|
|
52
|
+
if ! pkg-config --exists vips; then
|
|
53
|
+
echo "โ libvips not found. Install with:"
|
|
54
|
+
if [[ "$OS" == "macos" ]]; then
|
|
55
|
+
echo " brew install vips"
|
|
56
|
+
else
|
|
57
|
+
echo " sudo apt-get install libvips-dev"
|
|
58
|
+
fi
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
echo "โ
libvips found: $(pkg-config --modversion vips)"
|
|
62
|
+
|
|
63
|
+
# Build
|
|
64
|
+
echo ""
|
|
65
|
+
echo "๐จ Building FastQR..."
|
|
66
|
+
|
|
67
|
+
# Create build directory
|
|
68
|
+
BUILD_DIR="build"
|
|
69
|
+
if [ -d "$BUILD_DIR" ]; then
|
|
70
|
+
echo "๐ Cleaning old build directory..."
|
|
71
|
+
rm -rf "$BUILD_DIR"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
mkdir -p "$BUILD_DIR"
|
|
75
|
+
cd "$BUILD_DIR"
|
|
76
|
+
|
|
77
|
+
# Configure
|
|
78
|
+
echo "โ๏ธ Configuring..."
|
|
79
|
+
cmake .. \
|
|
80
|
+
-DCMAKE_BUILD_TYPE=Release \
|
|
81
|
+
-DCMAKE_INSTALL_PREFIX=/usr/local \
|
|
82
|
+
-DFASTQR_BUILD_EXAMPLES=ON
|
|
83
|
+
|
|
84
|
+
# Build
|
|
85
|
+
echo "๐ง Compiling..."
|
|
86
|
+
if [[ "$OS" == "macos" ]]; then
|
|
87
|
+
NCPU=$(sysctl -n hw.ncpu)
|
|
88
|
+
else
|
|
89
|
+
NCPU=$(nproc)
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
make -j$NCPU
|
|
93
|
+
|
|
94
|
+
# Test
|
|
95
|
+
echo ""
|
|
96
|
+
echo "๐งช Running tests..."
|
|
97
|
+
make test
|
|
98
|
+
|
|
99
|
+
echo ""
|
|
100
|
+
echo "โ
Build completed successfully!"
|
|
101
|
+
echo ""
|
|
102
|
+
echo "๐ฆ To install system-wide, run:"
|
|
103
|
+
echo " cd $BUILD_DIR && sudo make install"
|
|
104
|
+
echo ""
|
|
105
|
+
echo "๐ฏ To test the CLI:"
|
|
106
|
+
echo " ./fastqr \"Hello World\" test.png"
|
|
107
|
+
echo ""
|
|
108
|
+
echo "๐ก See README.md for usage examples"
|
|
109
|
+
|
data/composer.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fastqr/fastqr",
|
|
3
|
+
"description": "Fast QR code generator with UTF-8 support, custom colors, logo embedding, and precise size control",
|
|
4
|
+
"type": "library",
|
|
5
|
+
"keywords": ["qr", "qrcode", "qr-code", "generator", "utf8", "unicode", "vietnamese", "japanese", "fast"],
|
|
6
|
+
"homepage": "https://github.com/tranhuucanh/fastqr",
|
|
7
|
+
"license": "LGPL-2.1",
|
|
8
|
+
"authors": [
|
|
9
|
+
{
|
|
10
|
+
"name": "FastQR Project",
|
|
11
|
+
"email": "fastqr@example.com"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"require": {
|
|
15
|
+
"php": ">=7.4",
|
|
16
|
+
"ext-ffi": "*"
|
|
17
|
+
},
|
|
18
|
+
"require-dev": {
|
|
19
|
+
"phpunit/phpunit": "^9.0"
|
|
20
|
+
},
|
|
21
|
+
"autoload": {
|
|
22
|
+
"psr-4": {
|
|
23
|
+
"FastQR\\": "bindings/php/src/"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"autoload-dev": {
|
|
27
|
+
"psr-4": {
|
|
28
|
+
"FastQR\\Tests\\": "bindings/php/tests/"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"test": "phpunit"
|
|
33
|
+
},
|
|
34
|
+
"minimum-stability": "stable"
|
|
35
|
+
}
|
|
36
|
+
|