png_conform 0.1.2 → 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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +143 -12
  3. data/Gemfile +1 -1
  4. data/benchmarks/lib/benchmark_runner.rb +1 -1
  5. data/benchmarks/lib/metrics_collector.rb +3 -3
  6. data/benchmarks/lib/report_generator.rb +8 -9
  7. data/config/validation_profiles.yml +105 -0
  8. data/lib/png_conform/analyzers/comparison_analyzer.rb +46 -12
  9. data/lib/png_conform/analyzers/metrics_analyzer.rb +6 -9
  10. data/lib/png_conform/analyzers/optimization_analyzer.rb +33 -27
  11. data/lib/png_conform/analyzers/resolution_analyzer.rb +31 -32
  12. data/lib/png_conform/bindata/chunk_structure.rb +1 -1
  13. data/lib/png_conform/cli.rb +12 -7
  14. data/lib/png_conform/commands/check_command.rb +121 -55
  15. data/lib/png_conform/configuration.rb +147 -0
  16. data/lib/png_conform/container.rb +113 -0
  17. data/lib/png_conform/models/chunk_info.rb +1 -1
  18. data/lib/png_conform/models/validation_result.rb +30 -4
  19. data/lib/png_conform/pipelines/pipeline_result.rb +39 -0
  20. data/lib/png_conform/pipelines/stages/analysis_stage.rb +35 -0
  21. data/lib/png_conform/pipelines/stages/base_stage.rb +23 -0
  22. data/lib/png_conform/pipelines/stages/chunk_validation_stage.rb +74 -0
  23. data/lib/png_conform/pipelines/stages/sequence_validation_stage.rb +77 -0
  24. data/lib/png_conform/pipelines/stages/signature_validation_stage.rb +41 -0
  25. data/lib/png_conform/pipelines/validation_pipeline.rb +90 -0
  26. data/lib/png_conform/readers/full_load_reader.rb +13 -4
  27. data/lib/png_conform/readers/streaming_reader.rb +27 -2
  28. data/lib/png_conform/reporters/color_reporter.rb +17 -14
  29. data/lib/png_conform/reporters/visual_elements.rb +22 -16
  30. data/lib/png_conform/services/analysis_manager.rb +120 -0
  31. data/lib/png_conform/services/chunk_processor.rb +195 -0
  32. data/lib/png_conform/services/file_signature.rb +226 -0
  33. data/lib/png_conform/services/file_strategy.rb +78 -0
  34. data/lib/png_conform/services/lru_cache.rb +170 -0
  35. data/lib/png_conform/services/parallel_validator.rb +118 -0
  36. data/lib/png_conform/services/profile_manager.rb +41 -12
  37. data/lib/png_conform/services/result_builder.rb +299 -0
  38. data/lib/png_conform/services/validation_cache.rb +210 -0
  39. data/lib/png_conform/services/validation_orchestrator.rb +188 -0
  40. data/lib/png_conform/services/validation_service.rb +53 -337
  41. data/lib/png_conform/services/validator_pool.rb +142 -0
  42. data/lib/png_conform/services/zlib_validator.rb +2 -2
  43. data/lib/png_conform/utils/colorizer.rb +149 -0
  44. data/lib/png_conform/validators/ancillary/trns_validator.rb +1 -1
  45. data/lib/png_conform/validators/base_validator.rb +1 -1
  46. data/lib/png_conform/validators/chunk_registry.rb +12 -0
  47. data/lib/png_conform/validators/critical/ihdr_validator.rb +2 -2
  48. data/lib/png_conform/validators/streaming_idat_validator.rb +123 -0
  49. data/lib/png_conform/version.rb +1 -1
  50. data/lib/png_conform.rb +38 -0
  51. data/png_conform.gemspec +2 -0
  52. metadata +39 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9838bb140397822f351596fc1ff51179969ba68ac9d4310718a6ddcd549acb67
4
- data.tar.gz: b88887d300166cb6aa8d38db1d277450a9ddec7d3662498b8529ec3d5eb1f168
3
+ metadata.gz: f40907ca0fa307f62da38b9fecdd97fa05e6f9953315d3bc197a6c1385c1c490
4
+ data.tar.gz: 27891ced82861b1ff72ac09ef12fcc6801c1f28b46cb849e1a4d6100a6ad9f6c
5
5
  SHA512:
6
- metadata.gz: ab5ec06d2d129c872e75fe3002129ce258eb6faa80519f147a358be32cad5c16a49e88592226bab55391c274512a17f76679ac51e031dd1e296e949d12d981d2
7
- data.tar.gz: dbc3ceb3ceafc05d1f92e22c6693668249759fc7a1a54b2191854fb944e11c4445171fae162b0b145d7016afe9287afb9f278d6fc7d4e6cb0b71dc2957e56f40
6
+ metadata.gz: f58ca78ca13ca9934b677118c06cd67d362b96af38863b943dc0f60b757d0685435c450261ee1107d4eebbc5aa95e494c877cf6f55faccccb0dc89fdb0dd9bfc
7
+ data.tar.gz: 4479d1b4a79ee5d97fc49c297297f11818443e1f7c29e612131520d7037293951488a8fc8ec6af8772d7b49f833d45973ee21817e4bcaa34f98a4f88117818ff
data/.rubocop_todo.yml CHANGED
@@ -1,18 +1,64 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-11-23 07:50:45 UTC using RuboCop version 1.81.1.
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: 231
9
+ # Offense count: 1
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ Gemspec/RequireMFA:
12
+ Exclude:
13
+ - 'png_conform.gemspec'
14
+
15
+ # Offense count: 1
16
+ # This cop supports safe autocorrection (--autocorrect).
17
+ # Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
18
+ Layout/ExtraSpacing:
19
+ Exclude:
20
+ - 'spec/png_conform/validators/ancillary/bkgd_validator_spec.rb'
21
+
22
+ # Offense count: 1
23
+ # This cop supports safe autocorrection (--autocorrect).
24
+ # Configuration parameters: EnforcedStyle.
25
+ # SupportedStyles: normal, indented_internal_methods
26
+ Layout/IndentationConsistency:
27
+ Exclude:
28
+ - 'png_conform.gemspec'
29
+
30
+ # Offense count: 6
10
31
  # This cop supports safe autocorrection (--autocorrect).
11
- # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
32
+ # Configuration parameters: EnforcedStyle, IndentationWidth.
33
+ # SupportedStyles: aligned, indented
34
+ Layout/LineEndStringConcatenationIndentation:
35
+ Exclude:
36
+ - 'lib/png_conform/analyzers/optimization_analyzer.rb'
37
+
38
+ # Offense count: 263
39
+ # This cop supports safe autocorrection (--autocorrect).
40
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
12
41
  # URISchemes: http, https
13
42
  Layout/LineLength:
14
43
  Enabled: false
15
44
 
45
+ # Offense count: 1
46
+ # This cop supports safe autocorrection (--autocorrect).
47
+ # Configuration parameters: AllowInHeredoc.
48
+ Layout/TrailingWhitespace:
49
+ Exclude:
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'
61
+
16
62
  # Offense count: 1
17
63
  Lint/BinaryOperatorWithIdenticalOperands:
18
64
  Exclude:
@@ -27,7 +73,22 @@ Lint/DuplicateBranch:
27
73
  - 'lib/png_conform/validators/ancillary/sbit_validator.rb'
28
74
  - 'spec/pngsuite/helpers/semantic_validator.rb'
29
75
 
30
- # Offense count: 113
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
+
82
+ # Offense count: 4
83
+ # Configuration parameters: AllowedParentClasses.
84
+ Lint/MissingSuper:
85
+ Exclude:
86
+ - 'lib/png_conform/pipelines/stages/analysis_stage.rb'
87
+ - 'lib/png_conform/pipelines/stages/chunk_validation_stage.rb'
88
+ - 'lib/png_conform/pipelines/stages/sequence_validation_stage.rb'
89
+ - 'lib/png_conform/pipelines/stages/signature_validation_stage.rb'
90
+
91
+ # Offense count: 124
31
92
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
32
93
  Metrics/AbcSize:
33
94
  Enabled: false
@@ -36,14 +97,14 @@ Metrics/AbcSize:
36
97
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
37
98
  # AllowedMethods: refine
38
99
  Metrics/BlockLength:
39
- Max: 54
100
+ Max: 52
40
101
 
41
- # Offense count: 57
102
+ # Offense count: 62
42
103
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
43
104
  Metrics/CyclomaticComplexity:
44
105
  Enabled: false
45
106
 
46
- # Offense count: 171
107
+ # Offense count: 193
47
108
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
48
109
  Metrics/MethodLength:
49
110
  Max: 66
@@ -58,6 +119,13 @@ Metrics/ParameterLists:
58
119
  Metrics/PerceivedComplexity:
59
120
  Enabled: false
60
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
+
61
129
  # Offense count: 1
62
130
  # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
63
131
  # SupportedStyles: snake_case, normalcase, non_integer
@@ -72,6 +140,13 @@ Performance/CollectionLiteralInLoop:
72
140
  Exclude:
73
141
  - 'examples/advanced_usage.rb'
74
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
+
75
150
  # Offense count: 70
76
151
  # Configuration parameters: Prefixes, AllowedPatterns.
77
152
  # Prefixes: when, with, without
@@ -103,25 +178,81 @@ RSpec/MultipleMemoizedHelpers:
103
178
  Max: 6
104
179
 
105
180
  # Offense count: 2
106
- # Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata.
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
107
189
  RSpec/SpecFilePathFormat:
108
190
  Exclude:
109
191
  - 'spec/png_conform/bindata/chunk_structure_spec.rb'
110
192
  - 'spec/png_conform/bindata/png_file_spec.rb'
111
193
 
112
- # Offense count: 45
194
+ # Offense count: 44
113
195
  # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
114
196
  RSpec/VerifiedDoubles:
115
197
  Enabled: false
116
198
 
117
- # Offense count: 41
199
+ # Offense count: 2
200
+ # This cop supports unsafe autocorrection (--autocorrect-all).
201
+ Style/BitwisePredicate:
202
+ Exclude:
203
+ - 'lib/png_conform/bindata/chunk_structure.rb'
204
+ - 'lib/png_conform/services/chunk_processor.rb'
205
+
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
118
219
  # This cop supports safe autocorrection (--autocorrect).
119
220
  # Configuration parameters: MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
120
221
  # SupportedStyles: annotated, template, unannotated
121
222
  Style/FormatStringToken:
122
223
  EnforcedStyle: unannotated
123
224
 
225
+ # Offense count: 4
226
+ # This cop supports unsafe autocorrection (--autocorrect-all).
227
+ Style/MapToSet:
228
+ Exclude:
229
+ - 'lib/png_conform/analyzers/comparison_analyzer.rb'
230
+
124
231
  # Offense count: 1
125
- Style/MissingRespondToMissing:
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
246
+ # This cop supports safe autocorrection (--autocorrect).
247
+ # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
248
+ # SupportedStyles: single_quotes, double_quotes
249
+ Style/StringLiterals:
250
+ Exclude:
251
+ - 'png_conform.gemspec'
252
+
253
+ # Offense count: 2
254
+ # This cop supports safe autocorrection (--autocorrect).
255
+ Style/SuperArguments:
126
256
  Exclude:
127
- - 'lib/png_conform/cli.rb'
257
+ - 'lib/png_conform/models/chunk_info.rb'
258
+ - 'lib/png_conform/models/validation_result.rb'
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in png_conform.gemspec
6
6
  gemspec
7
7
 
8
- gem "openssl"
8
+ gem "openssl", "~> 3.0"
9
9
  gem "rake"
10
10
  gem "rspec"
11
11
  gem "rubocop"
@@ -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.map { |r| r[:execution_time] }.compact
50
- memory_values = tool_runs.map { |r| r[:peak_memory] }.compact
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.map { |tool| calculate_statistics(tool) }.compact,
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 << sprintf("%-15s %12s %12s %12s %8s",
180
- "Tool", "Avg Time", "Files/sec", "Peak Memory", "Winner")
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]
@@ -0,0 +1,105 @@
1
+ # PNG Conform Validation Profiles
2
+ #
3
+ # This file defines validation profiles for PNG files. Each profile specifies
4
+ # which chunks are required, optional, or prohibited.
5
+ #
6
+ # Profile structure:
7
+ # name: Display name
8
+ # description: Human-readable description
9
+ # required_chunks: List of chunk types that MUST be present
10
+ # optional_chunks: List of chunk types that MAY be present (use "*" for all)
11
+ # prohibited_chunks: List of chunk types that MUST NOT be present
12
+ #
13
+
14
+ minimal:
15
+ name: "Minimal validation"
16
+ description: "Only critical chunks required"
17
+ required_chunks:
18
+ - IHDR
19
+ - IDAT
20
+ - IEND
21
+ optional_chunks: "*"
22
+ prohibited_chunks: []
23
+
24
+ web:
25
+ name: "Web-optimized"
26
+ description: "Recommended for web images"
27
+ required_chunks:
28
+ - IHDR
29
+ - IDAT
30
+ - IEND
31
+ - gAMA
32
+ - sRGB
33
+ optional_chunks:
34
+ - tRNS
35
+ - bKGD
36
+ - tEXt
37
+ - iTXt
38
+ - zTXt
39
+ - pHYs
40
+ prohibited_chunks: []
41
+
42
+ print:
43
+ name: "Print-ready"
44
+ description: "For high-quality print output"
45
+ required_chunks:
46
+ - IHDR
47
+ - IDAT
48
+ - IEND
49
+ - pHYs
50
+ optional_chunks:
51
+ - gAMA
52
+ - cHRM
53
+ - sRGB
54
+ - iCCP
55
+ - tRNS
56
+ - bKGD
57
+ prohibited_chunks: []
58
+
59
+ archive:
60
+ name: "Archive quality"
61
+ description: "For long-term image storage"
62
+ required_chunks:
63
+ - IHDR
64
+ - IDAT
65
+ - IEND
66
+ optional_chunks:
67
+ - gAMA
68
+ - cHRM
69
+ - sRGB
70
+ - iCCP
71
+ - tEXt
72
+ - iTXt
73
+ - zTXt
74
+ - tIME
75
+ prohibited_chunks: []
76
+
77
+ strict:
78
+ name: "Strict PNG specification"
79
+ description: "Full compliance with PNG specification"
80
+ required_chunks:
81
+ - IHDR
82
+ - IDAT
83
+ - IEND
84
+ optional_chunks:
85
+ - PLTE
86
+ - gAMA
87
+ - cHRM
88
+ - sRGB
89
+ - iCCP
90
+ - tRNS
91
+ - bKGD
92
+ - hIST
93
+ - tEXt
94
+ - zTXt
95
+ - iTXt
96
+ - pHYs
97
+ - sPLT
98
+ - sBIT
99
+ - oFFs
100
+ - pCAL
101
+ - sCAL
102
+ - tIME
103
+ - cICP
104
+ - mDCv
105
+ prohibited_chunks: []
@@ -1,18 +1,51 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../configuration"
4
+ require_relative "../services/file_signature"
5
+
3
6
  module PngConform
4
7
  module Analyzers
5
8
  # Compares two PNG files and reports differences
6
9
  class ComparisonAnalyzer
7
- # Metadata chunk types
8
- METADATA_CHUNKS = %w[tEXt zTXt iTXt tIME].freeze
9
-
10
- def initialize(result1, result2)
10
+ def initialize(result1, result2, config: Configuration.instance)
11
11
  @result1 = result1
12
12
  @result2 = result2
13
+ @config = config
14
+
15
+ # Fast path: compute signatures for quick equality check
16
+ @sig1 = Services::FileSignature.from_result(result1).compute_signature
17
+ @sig2 = Services::FileSignature.from_result(result2).compute_signature
13
18
  end
14
19
 
15
20
  def analyze
21
+ # Fast return if signatures are identical
22
+ return identical_result if @sig1 == @sig2
23
+
24
+ # Full comparison for different files
25
+ full_comparison
26
+ end
27
+
28
+ private
29
+
30
+ # Return result for identical files
31
+ #
32
+ # @return [Hash] Analysis result for identical files
33
+ def identical_result
34
+ {
35
+ files: {
36
+ file1: @result1.filename,
37
+ file2: @result2.filename,
38
+ identical: true,
39
+ signature: @sig1.short_signature,
40
+ },
41
+ summary: ["Files are binary identical"],
42
+ }
43
+ end
44
+
45
+ # Full comparison for different files
46
+ #
47
+ # @return [Hash] Complete comparison analysis
48
+ def full_comparison
16
49
  {
17
50
  files: file_comparison,
18
51
  image: image_comparison,
@@ -23,8 +56,6 @@ module PngConform
23
56
  }
24
57
  end
25
58
 
26
- private
27
-
28
59
  def file_comparison
29
60
  size1 = @result1.file_size
30
61
  size2 = @result2.file_size
@@ -144,19 +175,19 @@ module PngConform
144
175
  end
145
176
 
146
177
  def new_errors
147
- errors1 = @result1.errors.map(&:message).to_set
148
- errors2 = @result2.errors.map(&:message).to_set
178
+ errors1 = @result1.errors.to_set(&:message)
179
+ errors2 = @result2.errors.to_set(&:message)
149
180
  (errors2 - errors1).to_a
150
181
  end
151
182
 
152
183
  def resolved_errors
153
- errors1 = @result1.errors.map(&:message).to_set
154
- errors2 = @result2.errors.map(&:message).to_set
184
+ errors1 = @result1.errors.to_set(&:message)
185
+ errors2 = @result2.errors.to_set(&:message)
155
186
  (errors1 - errors2).to_a
156
187
  end
157
188
 
158
189
  def compression_improved?
159
- return nil unless @result1.compression_ratio && @result2.compression_ratio
190
+ return false unless @result1.compression_ratio && @result2.compression_ratio
160
191
 
161
192
  @result2.compression_ratio > @result1.compression_ratio
162
193
  end
@@ -166,7 +197,10 @@ module PngConform
166
197
  end
167
198
 
168
199
  def metadata_count(result)
169
- result.chunks.count { |c| METADATA_CHUNKS.include?(c.type) }
200
+ # Use only text and time chunks from metadata (excluding pHYs which is physical)
201
+ result.chunks.count do |c|
202
+ @config.text_chunks.include?(c.type) || c.type == "tIME"
203
+ end
170
204
  end
171
205
 
172
206
  def format_size_change(diff, percent)
@@ -1,17 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../configuration"
4
+
3
5
  module PngConform
4
6
  module Analyzers
5
7
  # Generates comprehensive metrics for CI/CD and automation
6
8
  class MetricsAnalyzer
7
- # Text chunk types
8
- TEXT_CHUNKS = %w[tEXt zTXt iTXt].freeze
9
-
10
- # Metadata chunk types including time
11
- METADATA_CHUNKS = %w[tEXt zTXt iTXt tIME].freeze
12
-
13
- def initialize(result)
9
+ def initialize(result, config: Configuration.instance)
14
10
  @result = result
11
+ @config = config
15
12
  ihdr = result.ihdr_chunk
16
13
  @width = ihdr ? get_width(ihdr) : 0
17
14
  @height = ihdr ? get_height(ihdr) : 0
@@ -149,10 +146,10 @@ module PngConform
149
146
  has_iccp: @result.has_chunk?("iCCP"),
150
147
  has_transparency: @result.has_chunk?("tRNS"),
151
148
  has_metadata: @result.chunks.any? do |c|
152
- TEXT_CHUNKS.include?(c.type)
149
+ @config.text_chunks.include?(c.type)
153
150
  end,
154
151
  metadata_chunks_count: @result.chunks.count do |c|
155
- METADATA_CHUNKS.include?(c.type)
152
+ @config.metadata_chunks.include?(c.type)
156
153
  end,
157
154
  bytes_per_pixel: calculate_bytes_per_pixel,
158
155
  }