png_conform 0.1.3 → 0.1.4
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 +4 -4
- data/.rubocop_todo.yml +101 -80
- data/benchmarks/lib/benchmark_runner.rb +1 -1
- data/benchmarks/lib/metrics_collector.rb +3 -3
- data/benchmarks/lib/report_generator.rb +8 -9
- data/lib/png_conform/analyzers/comparison_analyzer.rb +5 -5
- data/lib/png_conform/analyzers/optimization_analyzer.rb +6 -6
- data/lib/png_conform/bindata/chunk_structure.rb +1 -1
- data/lib/png_conform/cli.rb +0 -7
- data/lib/png_conform/commands/check_command.rb +3 -2
- data/lib/png_conform/models/chunk_info.rb +1 -1
- data/lib/png_conform/models/validation_result.rb +1 -1
- data/lib/png_conform/services/chunk_processor.rb +1 -1
- data/lib/png_conform/services/file_signature.rb +2 -2
- data/lib/png_conform/services/result_builder.rb +1 -1
- data/lib/png_conform/services/zlib_validator.rb +2 -2
- data/lib/png_conform/validators/ancillary/trns_validator.rb +1 -1
- data/lib/png_conform/validators/base_validator.rb +1 -1
- data/lib/png_conform/validators/critical/ihdr_validator.rb +2 -2
- data/lib/png_conform/version.rb +1 -1
- data/lib/png_conform.rb +38 -0
- data/png_conform.gemspec +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f40907ca0fa307f62da38b9fecdd97fa05e6f9953315d3bc197a6c1385c1c490
|
|
4
|
+
data.tar.gz: 27891ced82861b1ff72ac09ef12fcc6801c1f28b46cb849e1a4d6100a6ad9f6c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f58ca78ca13ca9934b677118c06cd67d362b96af38863b943dc0f60b757d0685435c450261ee1107d4eebbc5aa95e494c877cf6f55faccccb0dc89fdb0dd9bfc
|
|
7
|
+
data.tar.gz: 4479d1b4a79ee5d97fc49c297297f11818443e1f7c29e612131520d7037293951488a8fc8ec6af8772d7b49f833d45973ee21817e4bcaa34f98a4f88117818ff
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,92 +1,63 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-
|
|
3
|
+
# on 2026-04-04 06:26:35 UTC using RuboCop version 1.86.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count: 6
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
12
|
-
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
13
|
-
Layout/ArgumentAlignment:
|
|
14
|
-
Exclude:
|
|
15
|
-
- 'lib/png_conform/commands/check_command.rb'
|
|
16
|
-
- 'lib/png_conform/services/chunk_processor.rb'
|
|
17
|
-
- 'lib/png_conform/services/profile_manager.rb'
|
|
18
|
-
- 'lib/png_conform/services/validator_pool.rb'
|
|
19
|
-
|
|
20
|
-
# Offense count: 4
|
|
21
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
22
|
-
# Configuration parameters: EnforcedStyleAlignWith.
|
|
23
|
-
# SupportedStylesAlignWith: either, start_of_block, start_of_line
|
|
24
|
-
Layout/BlockAlignment:
|
|
25
|
-
Exclude:
|
|
26
|
-
- 'lib/png_conform/analyzers/comparison_analyzer.rb'
|
|
27
|
-
- 'lib/png_conform/analyzers/optimization_analyzer.rb'
|
|
28
|
-
- 'lib/png_conform/services/file_signature.rb'
|
|
29
|
-
- 'lib/png_conform/services/lru_cache.rb'
|
|
30
|
-
|
|
31
|
-
# Offense count: 4
|
|
32
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
33
|
-
Layout/BlockEndNewline:
|
|
34
|
-
Exclude:
|
|
35
|
-
- 'lib/png_conform/analyzers/comparison_analyzer.rb'
|
|
36
|
-
- 'lib/png_conform/analyzers/optimization_analyzer.rb'
|
|
37
|
-
- 'lib/png_conform/services/file_signature.rb'
|
|
38
|
-
- 'lib/png_conform/services/lru_cache.rb'
|
|
39
|
-
|
|
40
9
|
# Offense count: 1
|
|
41
10
|
# This cop supports safe autocorrection (--autocorrect).
|
|
42
|
-
|
|
11
|
+
Gemspec/RequireMFA:
|
|
43
12
|
Exclude:
|
|
44
|
-
- '
|
|
13
|
+
- 'png_conform.gemspec'
|
|
45
14
|
|
|
46
15
|
# Offense count: 1
|
|
47
16
|
# This cop supports safe autocorrection (--autocorrect).
|
|
48
|
-
# Configuration parameters:
|
|
49
|
-
|
|
50
|
-
Layout/EndAlignment:
|
|
17
|
+
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
|
|
18
|
+
Layout/ExtraSpacing:
|
|
51
19
|
Exclude:
|
|
52
|
-
- '
|
|
20
|
+
- 'spec/png_conform/validators/ancillary/bkgd_validator_spec.rb'
|
|
53
21
|
|
|
54
|
-
# Offense count:
|
|
22
|
+
# Offense count: 1
|
|
55
23
|
# This cop supports safe autocorrection (--autocorrect).
|
|
56
|
-
# Configuration parameters:
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
|
60
|
-
Layout/HashAlignment:
|
|
24
|
+
# Configuration parameters: EnforcedStyle.
|
|
25
|
+
# SupportedStyles: normal, indented_internal_methods
|
|
26
|
+
Layout/IndentationConsistency:
|
|
61
27
|
Exclude:
|
|
62
|
-
- '
|
|
28
|
+
- 'png_conform.gemspec'
|
|
63
29
|
|
|
64
|
-
# Offense count:
|
|
30
|
+
# Offense count: 6
|
|
65
31
|
# This cop supports safe autocorrection (--autocorrect).
|
|
66
|
-
# Configuration parameters:
|
|
67
|
-
|
|
32
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
33
|
+
# SupportedStyles: aligned, indented
|
|
34
|
+
Layout/LineEndStringConcatenationIndentation:
|
|
68
35
|
Exclude:
|
|
69
|
-
- 'lib/png_conform/analyzers/comparison_analyzer.rb'
|
|
70
36
|
- 'lib/png_conform/analyzers/optimization_analyzer.rb'
|
|
71
|
-
- 'lib/png_conform/services/file_signature.rb'
|
|
72
|
-
- 'lib/png_conform/services/lru_cache.rb'
|
|
73
|
-
- 'lib/png_conform/services/validation_cache.rb'
|
|
74
37
|
|
|
75
|
-
# Offense count:
|
|
38
|
+
# Offense count: 263
|
|
76
39
|
# This cop supports safe autocorrection (--autocorrect).
|
|
77
|
-
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes,
|
|
40
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
78
41
|
# URISchemes: http, https
|
|
79
42
|
Layout/LineLength:
|
|
80
43
|
Enabled: false
|
|
81
44
|
|
|
82
|
-
# Offense count:
|
|
45
|
+
# Offense count: 1
|
|
83
46
|
# This cop supports safe autocorrection (--autocorrect).
|
|
84
47
|
# Configuration parameters: AllowInHeredoc.
|
|
85
48
|
Layout/TrailingWhitespace:
|
|
86
49
|
Exclude:
|
|
87
|
-
- '
|
|
88
|
-
|
|
89
|
-
|
|
50
|
+
- 'spec/png_conform/validators/ancillary/bkgd_validator_spec.rb'
|
|
51
|
+
|
|
52
|
+
# Offense count: 14
|
|
53
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
54
|
+
Lint/AmbiguousOperatorPrecedence:
|
|
55
|
+
Exclude:
|
|
56
|
+
- 'benchmarks/lib/benchmark_runner.rb'
|
|
57
|
+
- 'benchmarks/lib/report_generator.rb'
|
|
58
|
+
- 'lib/png_conform/services/result_builder.rb'
|
|
59
|
+
- 'lib/png_conform/services/zlib_validator.rb'
|
|
60
|
+
- 'lib/png_conform/validators/critical/ihdr_validator.rb'
|
|
90
61
|
|
|
91
62
|
# Offense count: 1
|
|
92
63
|
Lint/BinaryOperatorWithIdenticalOperands:
|
|
@@ -102,6 +73,12 @@ Lint/DuplicateBranch:
|
|
|
102
73
|
- 'lib/png_conform/validators/ancillary/sbit_validator.rb'
|
|
103
74
|
- 'spec/pngsuite/helpers/semantic_validator.rb'
|
|
104
75
|
|
|
76
|
+
# Offense count: 1
|
|
77
|
+
# Configuration parameters: AllowComments, AllowEmptyLambdas.
|
|
78
|
+
Lint/EmptyBlock:
|
|
79
|
+
Exclude:
|
|
80
|
+
- 'spec/png_conform/validators/ancillary/bkgd_validator_spec.rb'
|
|
81
|
+
|
|
105
82
|
# Offense count: 4
|
|
106
83
|
# Configuration parameters: AllowedParentClasses.
|
|
107
84
|
Lint/MissingSuper:
|
|
@@ -142,6 +119,13 @@ Metrics/ParameterLists:
|
|
|
142
119
|
Metrics/PerceivedComplexity:
|
|
143
120
|
Enabled: false
|
|
144
121
|
|
|
122
|
+
# Offense count: 132
|
|
123
|
+
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
124
|
+
# AllowedMethods: call
|
|
125
|
+
# WaywardPredicates: infinite?, nonzero?
|
|
126
|
+
Naming/PredicateMethod:
|
|
127
|
+
Enabled: false
|
|
128
|
+
|
|
145
129
|
# Offense count: 1
|
|
146
130
|
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
|
147
131
|
# SupportedStyles: snake_case, normalcase, non_integer
|
|
@@ -156,6 +140,13 @@ Performance/CollectionLiteralInLoop:
|
|
|
156
140
|
Exclude:
|
|
157
141
|
- 'examples/advanced_usage.rb'
|
|
158
142
|
|
|
143
|
+
# Offense count: 4
|
|
144
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
145
|
+
Performance/MapCompact:
|
|
146
|
+
Exclude:
|
|
147
|
+
- 'benchmarks/lib/metrics_collector.rb'
|
|
148
|
+
- 'lib/png_conform/services/file_signature.rb'
|
|
149
|
+
|
|
159
150
|
# Offense count: 70
|
|
160
151
|
# Configuration parameters: Prefixes, AllowedPatterns.
|
|
161
152
|
# Prefixes: when, with, without
|
|
@@ -187,51 +178,81 @@ RSpec/MultipleMemoizedHelpers:
|
|
|
187
178
|
Max: 6
|
|
188
179
|
|
|
189
180
|
# Offense count: 2
|
|
190
|
-
#
|
|
181
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
182
|
+
RSpec/Output:
|
|
183
|
+
Exclude:
|
|
184
|
+
- 'spec/png_conform/validators/ancillary/bkgd_validator_spec.rb'
|
|
185
|
+
|
|
186
|
+
# Offense count: 2
|
|
187
|
+
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
188
|
+
# SupportedInflectors: default, active_support
|
|
191
189
|
RSpec/SpecFilePathFormat:
|
|
192
190
|
Exclude:
|
|
193
191
|
- 'spec/png_conform/bindata/chunk_structure_spec.rb'
|
|
194
192
|
- 'spec/png_conform/bindata/png_file_spec.rb'
|
|
195
193
|
|
|
196
|
-
# Offense count:
|
|
194
|
+
# Offense count: 44
|
|
197
195
|
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
|
|
198
196
|
RSpec/VerifiedDoubles:
|
|
199
197
|
Enabled: false
|
|
200
198
|
|
|
201
|
-
# Offense count:
|
|
202
|
-
# This cop supports
|
|
203
|
-
|
|
204
|
-
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
|
205
|
-
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
|
206
|
-
# FunctionalMethods: let, let!, subject, watch
|
|
207
|
-
# AllowedMethods: lambda, proc, it
|
|
208
|
-
Style/BlockDelimiters:
|
|
199
|
+
# Offense count: 2
|
|
200
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
201
|
+
Style/BitwisePredicate:
|
|
209
202
|
Exclude:
|
|
210
|
-
- 'lib/png_conform/
|
|
211
|
-
- 'lib/png_conform/
|
|
212
|
-
- 'lib/png_conform/services/file_signature.rb'
|
|
213
|
-
- 'lib/png_conform/services/lru_cache.rb'
|
|
203
|
+
- 'lib/png_conform/bindata/chunk_structure.rb'
|
|
204
|
+
- 'lib/png_conform/services/chunk_processor.rb'
|
|
214
205
|
|
|
215
|
-
# Offense count:
|
|
206
|
+
# Offense count: 2
|
|
207
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
208
|
+
Style/ComparableBetween:
|
|
209
|
+
Exclude:
|
|
210
|
+
- 'lib/png_conform/validators/ancillary/trns_validator.rb'
|
|
211
|
+
- 'lib/png_conform/validators/base_validator.rb'
|
|
212
|
+
|
|
213
|
+
# Offense count: 1
|
|
214
|
+
Style/FileOpen:
|
|
215
|
+
Exclude:
|
|
216
|
+
- 'lib/png_conform/container.rb'
|
|
217
|
+
|
|
218
|
+
# Offense count: 36
|
|
216
219
|
# This cop supports safe autocorrection (--autocorrect).
|
|
217
220
|
# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
|
|
218
221
|
# SupportedStyles: annotated, template, unannotated
|
|
219
222
|
Style/FormatStringToken:
|
|
220
223
|
EnforcedStyle: unannotated
|
|
221
224
|
|
|
222
|
-
# Offense count:
|
|
223
|
-
|
|
225
|
+
# Offense count: 4
|
|
226
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
227
|
+
Style/MapToSet:
|
|
224
228
|
Exclude:
|
|
225
|
-
- 'lib/png_conform/
|
|
229
|
+
- 'lib/png_conform/analyzers/comparison_analyzer.rb'
|
|
226
230
|
|
|
227
231
|
# Offense count: 1
|
|
232
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
233
|
+
Style/RedundantFormat:
|
|
234
|
+
Exclude:
|
|
235
|
+
- 'benchmarks/lib/report_generator.rb'
|
|
236
|
+
|
|
237
|
+
# Offense count: 2
|
|
238
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
239
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
240
|
+
Style/ReturnNilInPredicateMethodDefinition:
|
|
241
|
+
Exclude:
|
|
242
|
+
- 'lib/png_conform/analyzers/comparison_analyzer.rb'
|
|
243
|
+
- 'spec/pngsuite/helpers/pngcheck_parser.rb'
|
|
244
|
+
|
|
245
|
+
# Offense count: 2
|
|
228
246
|
# This cop supports safe autocorrection (--autocorrect).
|
|
229
|
-
|
|
247
|
+
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
|
248
|
+
# SupportedStyles: single_quotes, double_quotes
|
|
249
|
+
Style/StringLiterals:
|
|
230
250
|
Exclude:
|
|
231
|
-
- '
|
|
251
|
+
- 'png_conform.gemspec'
|
|
232
252
|
|
|
233
253
|
# Offense count: 2
|
|
234
254
|
# This cop supports safe autocorrection (--autocorrect).
|
|
235
|
-
Style/
|
|
255
|
+
Style/SuperArguments:
|
|
236
256
|
Exclude:
|
|
237
|
-
- 'lib/png_conform/
|
|
257
|
+
- 'lib/png_conform/models/chunk_info.rb'
|
|
258
|
+
- 'lib/png_conform/models/validation_result.rb'
|
|
@@ -165,7 +165,7 @@ class BenchmarkRunner
|
|
|
165
165
|
pct = (current.to_f / total * 100).round(1)
|
|
166
166
|
bar_width = 40
|
|
167
167
|
filled = (bar_width * current / total).to_i
|
|
168
|
-
bar = "=" * filled + " " * (bar_width - filled)
|
|
168
|
+
bar = ("=" * filled) + (" " * (bar_width - filled))
|
|
169
169
|
|
|
170
170
|
print "\r [#{bar}] #{pct}% (#{current}/#{total}) #{label} "
|
|
171
171
|
$stdout.flush
|
|
@@ -46,8 +46,8 @@ class MetricsCollector
|
|
|
46
46
|
tool_runs = runs_for_tool(tool)
|
|
47
47
|
return nil if tool_runs.empty?
|
|
48
48
|
|
|
49
|
-
execution_times = tool_runs.
|
|
50
|
-
memory_values = tool_runs.
|
|
49
|
+
execution_times = tool_runs.filter_map { |r| r[:execution_time] }
|
|
50
|
+
memory_values = tool_runs.filter_map { |r| r[:peak_memory] }
|
|
51
51
|
|
|
52
52
|
{
|
|
53
53
|
tool: tool,
|
|
@@ -118,7 +118,7 @@ class MetricsCollector
|
|
|
118
118
|
total_runs: @runs.size,
|
|
119
119
|
tools: tools,
|
|
120
120
|
files_tested: @runs.map { |r| r[:file] }.uniq.size,
|
|
121
|
-
tool_statistics: tools.
|
|
121
|
+
tool_statistics: tools.filter_map { |tool| calculate_statistics(tool) },
|
|
122
122
|
}
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -42,9 +42,9 @@ class ReportGenerator
|
|
|
42
42
|
return "No benchmark data available.\n" if tools.empty?
|
|
43
43
|
|
|
44
44
|
output = []
|
|
45
|
-
output << "=" * 80
|
|
45
|
+
output << ("=" * 80)
|
|
46
46
|
output << "PNG Validation Tool Benchmark Comparison"
|
|
47
|
-
output << "=" * 80
|
|
47
|
+
output << ("=" * 80)
|
|
48
48
|
output << ""
|
|
49
49
|
output << "Configuration:"
|
|
50
50
|
output << " Files tested: #{summary[:files_tested]} PNG files"
|
|
@@ -62,9 +62,9 @@ class ReportGenerator
|
|
|
62
62
|
# Performance comparison (if we have 2 tools)
|
|
63
63
|
if tools.size == 2
|
|
64
64
|
comparison = metrics_collector.compare_tools(tools[0], tools[1])
|
|
65
|
-
output << "-" * 80
|
|
65
|
+
output << ("-" * 80)
|
|
66
66
|
output << "PERFORMANCE SUMMARY"
|
|
67
|
-
output << "-" * 80
|
|
67
|
+
output << ("-" * 80)
|
|
68
68
|
output << ""
|
|
69
69
|
output << format_comparison_table(comparison)
|
|
70
70
|
output << ""
|
|
@@ -73,9 +73,9 @@ class ReportGenerator
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Detailed statistics per tool
|
|
76
|
-
output << "-" * 80
|
|
76
|
+
output << ("-" * 80)
|
|
77
77
|
output << "DETAILED STATISTICS"
|
|
78
|
-
output << "-" * 80
|
|
78
|
+
output << ("-" * 80)
|
|
79
79
|
output << ""
|
|
80
80
|
|
|
81
81
|
tools.each do |tool|
|
|
@@ -176,9 +176,8 @@ class ReportGenerator
|
|
|
176
176
|
# Format comparison table for text output.
|
|
177
177
|
def format_comparison_table(comparison)
|
|
178
178
|
lines = []
|
|
179
|
-
lines <<
|
|
180
|
-
|
|
181
|
-
lines << "-" * 80
|
|
179
|
+
lines << "Tool Avg Time Files/sec Peak Memory Winner"
|
|
180
|
+
lines << ("-" * 80)
|
|
182
181
|
|
|
183
182
|
[comparison[:tool1], comparison[:tool2]].each do |tool|
|
|
184
183
|
stats = comparison[:stats][tool]
|
|
@@ -175,19 +175,19 @@ module PngConform
|
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
def new_errors
|
|
178
|
-
errors1 = @result1.errors.
|
|
179
|
-
errors2 = @result2.errors.
|
|
178
|
+
errors1 = @result1.errors.to_set(&:message)
|
|
179
|
+
errors2 = @result2.errors.to_set(&:message)
|
|
180
180
|
(errors2 - errors1).to_a
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def resolved_errors
|
|
184
|
-
errors1 = @result1.errors.
|
|
185
|
-
errors2 = @result2.errors.
|
|
184
|
+
errors1 = @result1.errors.to_set(&:message)
|
|
185
|
+
errors2 = @result2.errors.to_set(&:message)
|
|
186
186
|
(errors1 - errors2).to_a
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
def compression_improved?
|
|
190
|
-
return
|
|
190
|
+
return false unless @result1.compression_ratio && @result2.compression_ratio
|
|
191
191
|
|
|
192
192
|
@result2.compression_ratio > @result1.compression_ratio
|
|
193
193
|
end
|
|
@@ -42,7 +42,7 @@ module PngConform
|
|
|
42
42
|
priority: :medium,
|
|
43
43
|
savings_bytes: savings,
|
|
44
44
|
description: "Remove #{unnecessary.count} unnecessary chunks " \
|
|
45
|
-
|
|
45
|
+
"(#{unnecessary.map(&:type).join(', ')})",
|
|
46
46
|
chunks: unnecessary.map(&:type),
|
|
47
47
|
}
|
|
48
48
|
end
|
|
@@ -65,7 +65,7 @@ module PngConform
|
|
|
65
65
|
priority: :high,
|
|
66
66
|
savings_bytes: estimated_savings,
|
|
67
67
|
description: "Convert from 16-bit to 8-bit depth " \
|
|
68
|
-
|
|
68
|
+
"(estimated ~#{@config.optimization_percentages[:bit_depth_reduction]}% file size reduction)",
|
|
69
69
|
current: "16-bit",
|
|
70
70
|
recommended: "8-bit",
|
|
71
71
|
}
|
|
@@ -87,7 +87,7 @@ module PngConform
|
|
|
87
87
|
@config.optimization_percentages[:palette_conversion] / 100.0
|
|
88
88
|
).to_i,
|
|
89
89
|
description: "Consider converting to palette mode if using limited colors " \
|
|
90
|
-
|
|
90
|
+
"(potential ~#{@config.optimization_percentages[:palette_conversion]}% reduction)",
|
|
91
91
|
current: "RGB (Truecolor)",
|
|
92
92
|
recommended: "Indexed (Palette)",
|
|
93
93
|
}
|
|
@@ -109,7 +109,7 @@ module PngConform
|
|
|
109
109
|
priority: :low,
|
|
110
110
|
savings_bytes: savings,
|
|
111
111
|
description: "Remove interlacing for smaller file size " \
|
|
112
|
-
|
|
112
|
+
"(~#{@config.optimization_percentages[:interlace_removal]}% reduction, but slower initial display)",
|
|
113
113
|
current: "Adam7 interlaced",
|
|
114
114
|
recommended: "Non-interlaced",
|
|
115
115
|
}
|
|
@@ -129,7 +129,7 @@ module PngConform
|
|
|
129
129
|
priority: :low,
|
|
130
130
|
savings_bytes: total_text_size,
|
|
131
131
|
description: "#{text_chunks.count} text chunks using #{total_text_size} bytes " \
|
|
132
|
-
|
|
132
|
+
"(consider removing non-essential metadata)",
|
|
133
133
|
chunks: text_chunks.map(&:type),
|
|
134
134
|
}
|
|
135
135
|
end
|
|
@@ -151,7 +151,7 @@ module PngConform
|
|
|
151
151
|
priority: :medium,
|
|
152
152
|
savings_bytes: total_metadata,
|
|
153
153
|
description: "Metadata comprises #{(total_metadata.to_f / file_size * 100).round(1)}% " \
|
|
154
|
-
|
|
154
|
+
"of file size (#{total_metadata} bytes)",
|
|
155
155
|
recommendation: "Review if all metadata is necessary",
|
|
156
156
|
}
|
|
157
157
|
end
|
data/lib/png_conform/cli.rb
CHANGED
|
@@ -117,12 +117,5 @@ module PngConform
|
|
|
117
117
|
def self.exit_on_failure?
|
|
118
118
|
true
|
|
119
119
|
end
|
|
120
|
-
|
|
121
|
-
# Provide helpful error message for unknown commands
|
|
122
|
-
def method_missing(method, *_args)
|
|
123
|
-
puts "Error: Unknown command '#{method}'"
|
|
124
|
-
puts "Run 'png_conform help' for usage information"
|
|
125
|
-
exit(1)
|
|
126
|
-
end
|
|
127
120
|
end
|
|
128
121
|
end
|
|
@@ -39,14 +39,15 @@ module PngConform
|
|
|
39
39
|
if files.empty?
|
|
40
40
|
puts "Error: No files specified"
|
|
41
41
|
puts "Usage: png_conform check [OPTIONS] FILES"
|
|
42
|
-
|
|
42
|
+
raise PngConform::NoFilesSpecifiedError.new
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
# Check if profile exists (if specified)
|
|
46
46
|
if options[:profile] && !Services::ProfileManager.profile_exists?(options[:profile])
|
|
47
47
|
puts "Error: Unknown profile '#{options[:profile]}'"
|
|
48
48
|
puts "Available profiles: #{Services::ProfileManager.available_profiles.join(', ')}"
|
|
49
|
-
|
|
49
|
+
raise PngConform::UnknownProfileError.new(options[:profile],
|
|
50
|
+
Services::ProfileManager.available_profiles)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
# Check for conflicting options
|
|
@@ -172,7 +172,7 @@ module PngConform
|
|
|
172
172
|
first_byte = chunk_type.bytes[0]
|
|
173
173
|
|
|
174
174
|
# Bit 5 (0x20) of first byte indicates ancillary vs critical
|
|
175
|
-
if (
|
|
175
|
+
if first_byte.nobits?(0x20)
|
|
176
176
|
# Critical chunk - must be recognized
|
|
177
177
|
@context.add_error(
|
|
178
178
|
chunk_type: chunk_type,
|
|
@@ -103,9 +103,9 @@ module PngConform
|
|
|
103
103
|
chunk_count: @result.chunks.count,
|
|
104
104
|
chunk_types: @result.chunks.map(&:type).sort,
|
|
105
105
|
chunk_sizes: @result.chunks.map(&:length).sort,
|
|
106
|
-
crcs: @result.chunks.
|
|
106
|
+
crcs: @result.chunks.filter_map do |c|
|
|
107
107
|
c.crc_actual || c.crc_expected
|
|
108
|
-
end
|
|
108
|
+
end,
|
|
109
109
|
}
|
|
110
110
|
end
|
|
111
111
|
|
|
@@ -225,7 +225,7 @@ module PngConform
|
|
|
225
225
|
|
|
226
226
|
# Calculate percentage: (compressed/original - 1) * 100
|
|
227
227
|
# Negative means compression, positive means expansion
|
|
228
|
-
((compressed_size.to_f / original_size - 1) * 100).round(1)
|
|
228
|
+
(((compressed_size.to_f / original_size) - 1) * 100).round(1)
|
|
229
229
|
rescue StandardError
|
|
230
230
|
# If decompression fails, we can't calculate ratio
|
|
231
231
|
0.0
|
|
@@ -148,7 +148,7 @@ module PngConform
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# Bytes per pixel (rounded up)
|
|
151
|
-
((samples_per_pixel * bit_depth + 7) / 8.0).ceil
|
|
151
|
+
(((samples_per_pixel * bit_depth) + 7) / 8.0).ceil
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
# Calculate expected decompressed data size
|
|
@@ -158,7 +158,7 @@ module PngConform
|
|
|
158
158
|
|
|
159
159
|
if interlace_method.zero?
|
|
160
160
|
# Non-interlaced: (scanline_width + 1 filter byte) * height
|
|
161
|
-
scanline_width = ((width * bit_depth * samples_for_color_type(color_type) + 7) / 8.0).ceil
|
|
161
|
+
scanline_width = (((width * bit_depth * samples_for_color_type(color_type)) + 7) / 8.0).ceil
|
|
162
162
|
(scanline_width + 1) * height
|
|
163
163
|
else
|
|
164
164
|
# Adam7 interlaced: calculate for all 7 passes
|
|
@@ -82,7 +82,7 @@ module PngConform
|
|
|
82
82
|
# @param name [String] Name of the value for error message
|
|
83
83
|
# @return [Boolean] True if value is in range
|
|
84
84
|
def check_range(value, min, max, name)
|
|
85
|
-
return true if value
|
|
85
|
+
return true if value.between?(min, max)
|
|
86
86
|
|
|
87
87
|
add_error("invalid #{name} (#{value}, must be #{min}-#{max})")
|
|
88
88
|
false
|
|
@@ -90,12 +90,12 @@ module PngConform
|
|
|
90
90
|
valid = false
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
if width > 2**31 - 1
|
|
93
|
+
if width > (2**31) - 1
|
|
94
94
|
add_warning("image width (#{width}) exceeds maximum " \
|
|
95
95
|
"recommended value")
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
if height > 2**31 - 1
|
|
98
|
+
if height > (2**31) - 1
|
|
99
99
|
add_warning("image height (#{height}) exceeds maximum " \
|
|
100
100
|
"recommended value")
|
|
101
101
|
end
|
data/lib/png_conform/version.rb
CHANGED
data/lib/png_conform.rb
CHANGED
|
@@ -19,6 +19,44 @@ module PngConform
|
|
|
19
19
|
|
|
20
20
|
class ParseError < Error; end
|
|
21
21
|
|
|
22
|
+
# CLI argument errors - inherit from Thor::Error for Thor integration
|
|
23
|
+
class CliArgumentError < Thor::Error; end
|
|
24
|
+
|
|
25
|
+
class NoFilesSpecifiedError < CliArgumentError
|
|
26
|
+
def message
|
|
27
|
+
"No files specified. Usage: png_conform check [OPTIONS] FILES"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class UnknownProfileError < CliArgumentError
|
|
32
|
+
attr_reader :profile_name, :available_profiles
|
|
33
|
+
|
|
34
|
+
def initialize(profile_name, available_profiles)
|
|
35
|
+
@profile_name = profile_name
|
|
36
|
+
@available_profiles = available_profiles
|
|
37
|
+
super(build_message)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def message
|
|
41
|
+
"Unknown profile '#{profile_name}'. Available profiles: #{available_profiles.join(', ')}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def build_message
|
|
47
|
+
"Unknown profile '#{profile_name}'. Available profiles: #{available_profiles.join(', ')}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class UnknownCommandError < Thor::Error
|
|
52
|
+
attr_reader :command_name
|
|
53
|
+
|
|
54
|
+
def initialize(command_name)
|
|
55
|
+
@command_name = command_name
|
|
56
|
+
super("Unknown command '#{command_name}'. Run 'png_conform help' for usage information.")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
22
60
|
# Load BinData structures (Phase 2 - implemented)
|
|
23
61
|
require_relative "png_conform/bindata/chunk_structure"
|
|
24
62
|
require_relative "png_conform/bindata/png_file"
|
data/png_conform.gemspec
CHANGED
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
26
26
|
spec.metadata["source_code_uri"] = "https://github.com/claricle/png_conform"
|
|
27
27
|
spec.metadata["changelog_uri"] = "https://github.com/claricle/png_conform"
|
|
28
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
28
29
|
|
|
29
30
|
# Specify which files should be added to the gem when it is released.
|
|
30
31
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: png_conform
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bindata
|
|
@@ -232,6 +232,7 @@ metadata:
|
|
|
232
232
|
homepage_uri: https://github.com/claricle/png_conform
|
|
233
233
|
source_code_uri: https://github.com/claricle/png_conform
|
|
234
234
|
changelog_uri: https://github.com/claricle/png_conform
|
|
235
|
+
rubygems_mfa_required: 'true'
|
|
235
236
|
post_install_message:
|
|
236
237
|
rdoc_options: []
|
|
237
238
|
require_paths:
|