png_conform 0.1.4 → 0.1.5

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +22 -0
  3. data/Gemfile +4 -0
  4. data/README.adoc +7 -0
  5. data/Rakefile +8 -1
  6. data/TODO.structured-diagnostics/00-overview.md +98 -0
  7. data/TODO.structured-diagnostics/01-shared-contract.md +36 -0
  8. data/TODO.structured-diagnostics/02-requirement-catalog.md +37 -0
  9. data/TODO.structured-diagnostics/03a-png-apng-emitters.md +45 -0
  10. data/TODO.structured-diagnostics/03b-mng-jng-emitters.md +34 -0
  11. data/TODO.structured-diagnostics/03c-format-aware-orchestration.md +38 -0
  12. data/TODO.structured-diagnostics/04-report-migration.md +40 -0
  13. data/TODO.structured-diagnostics/05-corpus-goldens.md +42 -0
  14. data/TODO.structured-diagnostics/90-progress.md +22 -0
  15. data/config/diagnostics.yml +2906 -0
  16. data/docs/ARCHITECTURE.adoc +13 -4
  17. data/docs/CLI_OPTIONS.adoc +126 -0
  18. data/lib/png_conform/bindata/chunk_structure.rb +7 -0
  19. data/lib/png_conform/diagnostics/builder.rb +52 -0
  20. data/lib/png_conform/diagnostics/catalog.rb +242 -0
  21. data/lib/png_conform/diagnostics/golden_generator.rb +92 -0
  22. data/lib/png_conform/diagnostics/location.rb +45 -0
  23. data/lib/png_conform/models/file_analysis.rb +2 -0
  24. data/lib/png_conform/models/validation_error.rb +96 -1
  25. data/lib/png_conform/models/validation_result.rb +19 -1
  26. data/lib/png_conform/readers/chunk_framing.rb +79 -0
  27. data/lib/png_conform/readers/format_dispatch.rb +49 -0
  28. data/lib/png_conform/readers/full_load_reader.rb +51 -1
  29. data/lib/png_conform/readers/streaming_reader.rb +25 -5
  30. data/lib/png_conform/reporters/summary_reporter.rb +1 -1
  31. data/lib/png_conform/reporters/verbose_reporter.rb +3 -1
  32. data/lib/png_conform/services/chunk_processor.rb +10 -10
  33. data/lib/png_conform/services/profile_manager.rb +77 -28
  34. data/lib/png_conform/services/result_builder.rb +8 -13
  35. data/lib/png_conform/services/validation_orchestrator.rb +175 -49
  36. data/lib/png_conform/validators/ancillary/bkgd_validator.rb +12 -12
  37. data/lib/png_conform/validators/ancillary/chrm_validator.rb +10 -10
  38. data/lib/png_conform/validators/ancillary/cicp_validator.rb +15 -9
  39. data/lib/png_conform/validators/ancillary/gama_validator.rb +10 -10
  40. data/lib/png_conform/validators/ancillary/hist_validator.rb +17 -17
  41. data/lib/png_conform/validators/ancillary/iccp_validator.rb +27 -27
  42. data/lib/png_conform/validators/ancillary/idot_validator.rb +5 -5
  43. data/lib/png_conform/validators/ancillary/itxt_validator.rb +24 -24
  44. data/lib/png_conform/validators/ancillary/mdcv_validator.rb +15 -7
  45. data/lib/png_conform/validators/ancillary/offs_validator.rb +10 -10
  46. data/lib/png_conform/validators/ancillary/pcal_validator.rb +28 -28
  47. data/lib/png_conform/validators/ancillary/phys_validator.rb +8 -8
  48. data/lib/png_conform/validators/ancillary/sbit_validator.rb +13 -13
  49. data/lib/png_conform/validators/ancillary/scal_validator.rb +13 -13
  50. data/lib/png_conform/validators/ancillary/splt_validator.rb +21 -21
  51. data/lib/png_conform/validators/ancillary/srgb_validator.rb +9 -9
  52. data/lib/png_conform/validators/ancillary/ster_validator.rb +9 -9
  53. data/lib/png_conform/validators/ancillary/text_validator.rb +12 -12
  54. data/lib/png_conform/validators/ancillary/time_validator.rb +11 -11
  55. data/lib/png_conform/validators/ancillary/trns_validator.rb +14 -14
  56. data/lib/png_conform/validators/ancillary/ztxt_validator.rb +16 -16
  57. data/lib/png_conform/validators/apng/actl_validator.rb +5 -5
  58. data/lib/png_conform/validators/apng/fctl_validator.rb +13 -11
  59. data/lib/png_conform/validators/apng/fdat_validator.rb +9 -9
  60. data/lib/png_conform/validators/base_validator.rb +71 -38
  61. data/lib/png_conform/validators/critical/idat_validator.rb +7 -4
  62. data/lib/png_conform/validators/critical/iend_validator.rb +8 -5
  63. data/lib/png_conform/validators/critical/ihdr_validator.rb +16 -16
  64. data/lib/png_conform/validators/critical/plte_validator.rb +10 -10
  65. data/lib/png_conform/validators/jng/jdat_validator.rb +5 -5
  66. data/lib/png_conform/validators/jng/jhdr_validator.rb +10 -10
  67. data/lib/png_conform/validators/jng/jsep_validator.rb +7 -7
  68. data/lib/png_conform/validators/mng/back_validator.rb +7 -13
  69. data/lib/png_conform/validators/mng/clip_validator.rb +5 -7
  70. data/lib/png_conform/validators/mng/clon_validator.rb +4 -6
  71. data/lib/png_conform/validators/mng/defi_validator.rb +9 -15
  72. data/lib/png_conform/validators/mng/dhdr_validator.rb +11 -17
  73. data/lib/png_conform/validators/mng/disc_validator.rb +5 -7
  74. data/lib/png_conform/validators/mng/endl_validator.rb +8 -10
  75. data/lib/png_conform/validators/mng/fram_validator.rb +5 -7
  76. data/lib/png_conform/validators/mng/loop_validator.rb +5 -9
  77. data/lib/png_conform/validators/mng/mend_validator.rb +3 -3
  78. data/lib/png_conform/validators/mng/mhdr_validator.rb +4 -4
  79. data/lib/png_conform/validators/mng/move_validator.rb +5 -7
  80. data/lib/png_conform/validators/mng/save_validator.rb +4 -4
  81. data/lib/png_conform/validators/mng/seek_validator.rb +5 -5
  82. data/lib/png_conform/validators/mng/show_validator.rb +4 -6
  83. data/lib/png_conform/validators/mng/term_validator.rb +8 -14
  84. data/lib/png_conform/version.rb +1 -1
  85. data/lib/png_conform.rb +6 -0
  86. data/script/generate_mng_jng_fixtures +90 -0
  87. data/script/regenerate_diagnostic_goldens +9 -0
  88. metadata +36 -5
  89. data/png_conform.gemspec +0 -45
@@ -0,0 +1,2906 @@
1
+ # PNG Conform diagnostic requirement catalog.
2
+ #
3
+ # One stable ID per violated requirement (or informational finding) across
4
+ # PNG, APNG, MNG and JNG. Loaded and validated by
5
+ # PngConform::Diagnostics::Catalog; coverage of every emitter is proven by
6
+ # spec/png_conform/diagnostics/catalog_spec.rb.
7
+ #
8
+ # requirements: conformance findings; each carries a specification citation.
9
+ # informational: non-conformance messages; deliberately no citation.
10
+ # emitters: the call sites (file relative to lib/png_conform, normalized
11
+ # call text, optional site count) that report the finding.
12
+ # abstract: shared BaseValidator helper findings; never bound to a
13
+ # validator call site (each call site has its own ID).
14
+ # excluded_sources: sources inventoried but deliberately not cataloged.
15
+ schema_version: 1
16
+ specifications:
17
+ iso15948:
18
+ name: "ISO/IEC 15948 Portable Network Graphics (PNG): Functional specification"
19
+ version: "2004 (Second Edition; technically identical to W3C REC-PNG-20031110)"
20
+ url: "https://www.w3.org/TR/2003/REC-PNG-20031110/"
21
+ png3:
22
+ name: "Portable Network Graphics (PNG) Specification (Third Edition)"
23
+ version: "W3C Recommendation 2025-06-24"
24
+ url: "https://www.w3.org/TR/png-3/"
25
+ pngext:
26
+ name: "Extensions to the PNG 1.2 Specification"
27
+ version: "1.5.0"
28
+ url: "https://ftp-osl.osuosl.org/pub/libpng/documents/pngext-1.5.0.html"
29
+ apng:
30
+ name: "APNG Specification"
31
+ version: "1.0 (MozillaWiki)"
32
+ url: "https://wiki.mozilla.org/APNG_Specification"
33
+ mng:
34
+ name: "MNG (Multiple-image Network Graphics) Format"
35
+ version: "1.0 (2001-01-31)"
36
+ url: "http://www.libpng.org/pub/mng/spec/"
37
+ jng:
38
+ name: "JNG (JPEG Network Graphics) Format"
39
+ version: "1.0"
40
+ url: "http://www.libpng.org/pub/mng/spec/jng.html"
41
+ apple_idot:
42
+ name: "Apple iDOT chunk (unpublished vendor extension; no public specification)"
43
+ version: "n/a"
44
+ url: null
45
+ profile:
46
+ name: "png_conform validation profiles (config/validation_profiles.yml)"
47
+ version: "1"
48
+ url: null
49
+ requirements:
50
+ all.chunk.length-exceeds-data:
51
+ format: all
52
+ kind: length
53
+ severity: error
54
+ citation: {specification: iso15948, section: "5.3", title: "Chunk layout"}
55
+ emitters:
56
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"all.chunk.length-exceeds-data\", \"Chunk length #{error.declared_length} exceeds the #{error.available - Readers::ChunkFraming::CRC_BYTES} data bytes remaining\", expected: \"0-#{error.available - Readers::ChunkFraming::CRC_BYTES}\", **detail)"}
57
+ all.chunk.length-exceeds-limit:
58
+ format: all
59
+ kind: length
60
+ severity: error
61
+ citation: {specification: iso15948, section: "5.3", title: "Chunk layout"}
62
+ emitters:
63
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"all.chunk.length-exceeds-limit\", \"Chunk length #{error.declared_length} exceeds the maximum #{Readers::ChunkFraming::MAX_LENGTH}\", expected: \"0-#{Readers::ChunkFraming::MAX_LENGTH}\", **detail)"}
64
+ all.helper.crc:
65
+ format: all
66
+ kind: integrity
67
+ severity: error
68
+ abstract: true
69
+ emitters:
70
+ - {file: "validators/base_validator.rb", call: "add_error(id, \"CRC error in #{chunk.chunk_type} chunk\", field: \"crc\")"}
71
+ all.helper.enum:
72
+ format: all
73
+ kind: value
74
+ severity: error
75
+ abstract: true
76
+ emitters:
77
+ - {file: "validators/base_validator.rb", call: "add_error(id, \"invalid #{name} (#{value}, must be one of #{valid.join(', ')})\", field: name, expected: valid.join(\", \"), actual: value)"}
78
+ all.helper.length:
79
+ format: all
80
+ kind: length
81
+ severity: error
82
+ abstract: true
83
+ emitters:
84
+ - {file: "validators/base_validator.rb", call: "add_error(id, \"invalid #{chunk.chunk_type} length (#{actual}, should be #{expected})\", field: \"length\", expected: expected, actual: actual)"}
85
+ all.helper.range:
86
+ format: all
87
+ kind: value
88
+ severity: error
89
+ abstract: true
90
+ emitters:
91
+ - {file: "validators/base_validator.rb", call: "add_error(id, \"invalid #{name} (#{value}, must be #{min}-#{max})\", field: name, expected: \"#{min}-#{max}\", actual: value)"}
92
+ all.signature.unknown:
93
+ format: all
94
+ kind: presence
95
+ severity: error
96
+ citation: {specification: iso15948, section: "5.2", title: "PNG signature"}
97
+ emitters:
98
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"all.signature.unknown\", \"Unrecognized file signature (not PNG, MNG or JNG)\", chunk_type: \"SIGNATURE\", offset: 0, field: \"signature\", actual: sig.to_s.bytes.map { |b| format(\"%02x\", b) }.join(\" \") )"}
99
+ apng.acTL.before-fctl:
100
+ format: apng
101
+ kind: ordering
102
+ severity: error
103
+ citation: {specification: apng, section: "2.2", title: "acTL: The Animation Control Chunk"}
104
+ emitters:
105
+ - {file: "validators/apng/actl_validator.rb", call: "add_error(\"apng.acTL.before-fctl\", \"acTL must appear before first fcTL\")"}
106
+ apng.acTL.before-idat:
107
+ format: apng
108
+ kind: ordering
109
+ severity: error
110
+ citation: {specification: apng, section: "2.2", title: "acTL: The Animation Control Chunk"}
111
+ emitters:
112
+ - {file: "validators/apng/actl_validator.rb", call: "add_error(\"apng.acTL.before-idat\", \"acTL must appear before IDAT\")"}
113
+ apng.acTL.crc:
114
+ format: apng
115
+ kind: integrity
116
+ severity: error
117
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
118
+ emitters:
119
+ - {file: "validators/apng/actl_validator.rb", call: "check_crc(id: \"apng.acTL.crc\")"}
120
+ apng.acTL.length:
121
+ format: apng
122
+ kind: length
123
+ severity: error
124
+ citation: {specification: apng, section: "2.2", title: "acTL: The Animation Control Chunk"}
125
+ emitters:
126
+ - {file: "validators/apng/actl_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"apng.acTL.length\")"}
127
+ apng.acTL.num-frames-zero:
128
+ format: apng
129
+ kind: value
130
+ severity: error
131
+ citation: {specification: apng, section: "2.2", title: "acTL: The Animation Control Chunk"}
132
+ emitters:
133
+ - {file: "validators/apng/actl_validator.rb", call: "add_error(\"apng.acTL.num-frames-zero\", \"acTL num_frames must be > 0\")"}
134
+ apng.fcTL.blend-op:
135
+ format: apng
136
+ kind: value
137
+ severity: error
138
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
139
+ emitters:
140
+ - {file: "validators/apng/fctl_validator.rb", call: "check_enum(blend_op, [BLEND_OP_SOURCE, BLEND_OP_OVER], \"blend_op\", id: \"apng.fcTL.blend-op\")"}
141
+ apng.fcTL.crc:
142
+ format: apng
143
+ kind: integrity
144
+ severity: error
145
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
146
+ emitters:
147
+ - {file: "validators/apng/fctl_validator.rb", call: "check_crc(id: \"apng.fcTL.crc\")"}
148
+ apng.fcTL.dimensions-zero:
149
+ format: apng
150
+ kind: value
151
+ severity: error
152
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
153
+ emitters:
154
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.dimensions-zero\", \"fcTL width and height must be > 0\")"}
155
+ apng.fcTL.dispose-op:
156
+ format: apng
157
+ kind: value
158
+ severity: error
159
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
160
+ emitters:
161
+ - {file: "validators/apng/fctl_validator.rb", call: "check_enum(dispose_op, [DISPOSE_OP_NONE, DISPOSE_OP_BACKGROUND, DISPOSE_OP_PREVIOUS], \"dispose_op\", id: \"apng.fcTL.dispose-op\")"}
162
+ apng.fcTL.exceeds-ihdr:
163
+ format: apng
164
+ kind: consistency
165
+ severity: error
166
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
167
+ emitters:
168
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.exceeds-ihdr\", \"fcTL frame dimensions exceed IHDR dimensions\")"}
169
+ apng.fcTL.extends-ihdr-height:
170
+ format: apng
171
+ kind: consistency
172
+ severity: error
173
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
174
+ emitters:
175
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.extends-ihdr-height\", \"fcTL frame extends beyond IHDR height\")"}
176
+ apng.fcTL.extends-ihdr-width:
177
+ format: apng
178
+ kind: consistency
179
+ severity: error
180
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
181
+ emitters:
182
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.extends-ihdr-width\", \"fcTL frame extends beyond IHDR width\")"}
183
+ apng.fcTL.length:
184
+ format: apng
185
+ kind: length
186
+ severity: error
187
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
188
+ emitters:
189
+ - {file: "validators/apng/fctl_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"apng.fcTL.length\")"}
190
+ apng.fcTL.requires-actl:
191
+ format: apng
192
+ kind: presence
193
+ severity: error
194
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
195
+ emitters:
196
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.requires-actl\", \"fcTL requires acTL chunk\")"}
197
+ apng.fcTL.sequence-number:
198
+ format: apng
199
+ kind: ordering
200
+ severity: error
201
+ citation: {specification: apng, section: "2.3", title: "fcTL: The Frame Control Chunk"}
202
+ emitters:
203
+ - {file: "validators/apng/fctl_validator.rb", call: "add_error(\"apng.fcTL.sequence-number\", \"fcTL sequence number mismatch (expected #{expected_sequence}, got #{sequence_number})\")"}
204
+ apng.fdAT.after-fctl:
205
+ format: apng
206
+ kind: ordering
207
+ severity: error
208
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
209
+ emitters:
210
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.after-fctl\", \"fdAT must follow fcTL chunk\")"}
211
+ apng.fdAT.crc:
212
+ format: apng
213
+ kind: integrity
214
+ severity: error
215
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
216
+ emitters:
217
+ - {file: "validators/apng/fdat_validator.rb", call: "check_crc(id: \"apng.fdAT.crc\")"}
218
+ apng.fdAT.frame-data-empty:
219
+ format: apng
220
+ kind: length
221
+ severity: error
222
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
223
+ emitters:
224
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.frame-data-empty\", \"fdAT has no frame data\")"}
225
+ apng.fdAT.min-length:
226
+ format: apng
227
+ kind: length
228
+ severity: error
229
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
230
+ emitters:
231
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.min-length\", \"fdAT chunk too short (#{actual} bytes, minimum #{MIN_LENGTH})\")"}
232
+ apng.fdAT.requires-actl:
233
+ format: apng
234
+ kind: presence
235
+ severity: error
236
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
237
+ emitters:
238
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.requires-actl\", \"fdAT requires acTL chunk\")"}
239
+ apng.fdAT.requires-fctl:
240
+ format: apng
241
+ kind: presence
242
+ severity: error
243
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
244
+ emitters:
245
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.requires-fctl\", \"fdAT chunk requires fcTL chunk\")"}
246
+ apng.fdAT.sequence-number:
247
+ format: apng
248
+ kind: ordering
249
+ severity: error
250
+ citation: {specification: apng, section: "2.4", title: "fdAT: The Frame Data Chunk"}
251
+ emitters:
252
+ - {file: "validators/apng/fdat_validator.rb", call: "add_error(\"apng.fdAT.sequence-number\", \"fdAT sequence number mismatch (expected #{expected_sequence}, got #{sequence_number})\")"}
253
+ jng.IEND.last-chunk:
254
+ format: jng
255
+ kind: ordering
256
+ severity: error
257
+ citation: {specification: jng, section: "1.1.6", title: "IEND End of JNG datastream"}
258
+ emitters:
259
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"jng.IEND.last-chunk\", \"IEND must be the last chunk\", **located(\"IEND\", index) )"}
260
+ jng.IEND.missing:
261
+ format: jng
262
+ kind: presence
263
+ severity: error
264
+ citation: {specification: jng, section: "1.1.6", title: "IEND End of JNG datastream"}
265
+ emitters:
266
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"jng.IEND.missing\", \"Missing IEND chunk (must be last)\", chunk_type: \"IEND\" )"}
267
+ jng.JDAT.after-jhdr:
268
+ format: jng
269
+ kind: ordering
270
+ severity: error
271
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
272
+ emitters:
273
+ - {file: "validators/jng/jdat_validator.rb", call: "add_error(\"jng.JDAT.after-jhdr\", \"JDAT must appear after JHDR\")"}
274
+ jng.JDAT.before-iend:
275
+ format: jng
276
+ kind: ordering
277
+ severity: error
278
+ citation: {specification: jng, section: "1.1.6", title: "IEND End of JNG datastream"}
279
+ emitters:
280
+ - {file: "validators/jng/jdat_validator.rb", call: "add_error(\"jng.JDAT.before-iend\", \"JDAT must appear before IEND\")"}
281
+ jng.JDAT.crc:
282
+ format: jng
283
+ kind: integrity
284
+ severity: error
285
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
286
+ emitters:
287
+ - {file: "validators/jng/jdat_validator.rb", call: "check_crc(id: \"jng.JDAT.crc\")"}
288
+ jng.JDAT.min-length:
289
+ format: jng
290
+ kind: length
291
+ severity: error
292
+ citation: {specification: jng, section: "1.1.2", title: "JDAT JNG image data"}
293
+ emitters:
294
+ - {file: "validators/jng/jdat_validator.rb", call: "add_error(\"jng.JDAT.min-length\", \"JDAT chunk too short (#{data.length} bytes, minimum 1)\", field: \"length\", expected: \">= 1\", actual: data.length)"}
295
+ jng.JDAT.missing:
296
+ format: jng
297
+ kind: presence
298
+ severity: error
299
+ citation: {specification: jng, section: "1.1.2", title: "JDAT JNG image data"}
300
+ emitters:
301
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"jng.JDAT.missing\", \"Missing JDAT chunk (at least one required)\", chunk_type: \"JDAT\" )"}
302
+ jng.JHDR.color-type:
303
+ format: jng
304
+ kind: value
305
+ severity: error
306
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
307
+ emitters:
308
+ - {file: "validators/jng/jhdr_validator.rb", call: "check_enum(color_type, VALID_COLOR_TYPES, \"color type\", id: \"jng.JHDR.color-type\")"}
309
+ jng.JHDR.crc:
310
+ format: jng
311
+ kind: integrity
312
+ severity: error
313
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
314
+ emitters:
315
+ - {file: "validators/jng/jhdr_validator.rb", call: "check_crc(id: \"jng.JHDR.crc\")"}
316
+ jng.JHDR.first-chunk:
317
+ format: jng
318
+ kind: ordering
319
+ severity: error
320
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
321
+ emitters:
322
+ - {file: "validators/jng/jhdr_validator.rb", call: "add_error(\"jng.JHDR.first-chunk\", \"JHDR must be the first chunk in JNG datastream\")"}
323
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"jng.JHDR.first-chunk\", \"JHDR must be the first chunk in JNG datastream\", **located(\"JHDR\", index))"}
324
+ jng.JHDR.height-zero:
325
+ format: jng
326
+ kind: value
327
+ severity: error
328
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
329
+ emitters:
330
+ - {file: "validators/jng/jhdr_validator.rb", call: "add_error(\"jng.JHDR.height-zero\", \"invalid image height (0)\", field: \"height\", expected: \">0\", actual: 0)"}
331
+ jng.JHDR.image-compression-method:
332
+ format: jng
333
+ kind: value
334
+ severity: error
335
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
336
+ emitters:
337
+ - {file: "validators/jng/jhdr_validator.rb", call: "add_error(\"jng.JHDR.image-compression-method\", \"invalid image compression method (#{image_compression}, must be 8)\", field: \"image_compression_method\", expected: 8, actual: image_compression)"}
338
+ jng.JHDR.image-sample-depth:
339
+ format: jng
340
+ kind: value
341
+ severity: error
342
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
343
+ emitters:
344
+ - {file: "validators/jng/jhdr_validator.rb", call: "check_enum(image_sample_depth, VALID_SAMPLE_DEPTHS, \"image sample depth\", id: \"jng.JHDR.image-sample-depth\")"}
345
+ jng.JHDR.interlace-method:
346
+ format: jng
347
+ kind: value
348
+ severity: error
349
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
350
+ emitters:
351
+ - {file: "validators/jng/jhdr_validator.rb", call: "add_error(\"jng.JHDR.interlace-method\", \"invalid interlace method (#{interlace}, must be 0)\", field: \"interlace_method\", expected: 0, actual: interlace)"}
352
+ jng.JHDR.length:
353
+ format: jng
354
+ kind: length
355
+ severity: error
356
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
357
+ emitters:
358
+ - {file: "validators/jng/jhdr_validator.rb", call: "check_length(16, id: \"jng.JHDR.length\")"}
359
+ jng.JHDR.missing:
360
+ format: jng
361
+ kind: presence
362
+ severity: error
363
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
364
+ emitters:
365
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"jng.JHDR.missing\", \"Missing JHDR chunk (must be first)\", chunk_type: \"JHDR\" )"}
366
+ jng.JHDR.width-zero:
367
+ format: jng
368
+ kind: value
369
+ severity: error
370
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
371
+ emitters:
372
+ - {file: "validators/jng/jhdr_validator.rb", call: "add_error(\"jng.JHDR.width-zero\", \"invalid image width (0)\", field: \"width\", expected: \">0\", actual: 0)"}
373
+ jng.JSEP.after-jdat:
374
+ format: jng
375
+ kind: ordering
376
+ severity: warning
377
+ citation: {specification: jng, section: "1.1.5", title: "JSEP 8-bit/12-bit image separator"}
378
+ emitters:
379
+ - {file: "validators/jng/jsep_validator.rb", call: "add_warning(\"jng.JSEP.after-jdat\", \"JSEP should appear after 8-bit JDAT chunks\")"}
380
+ jng.JSEP.after-jhdr:
381
+ format: jng
382
+ kind: ordering
383
+ severity: error
384
+ citation: {specification: jng, section: "1.1.1", title: "JHDR JNG header"}
385
+ emitters:
386
+ - {file: "validators/jng/jsep_validator.rb", call: "add_error(\"jng.JSEP.after-jhdr\", \"JSEP must appear after JHDR\")"}
387
+ jng.JSEP.before-iend:
388
+ format: jng
389
+ kind: ordering
390
+ severity: error
391
+ citation: {specification: jng, section: "1.1.6", title: "IEND End of JNG datastream"}
392
+ emitters:
393
+ - {file: "validators/jng/jsep_validator.rb", call: "add_error(\"jng.JSEP.before-iend\", \"JSEP must appear before IEND\")"}
394
+ jng.JSEP.crc:
395
+ format: jng
396
+ kind: integrity
397
+ severity: error
398
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
399
+ emitters:
400
+ - {file: "validators/jng/jsep_validator.rb", call: "check_crc(id: \"jng.JSEP.crc\")"}
401
+ jng.JSEP.length:
402
+ format: jng
403
+ kind: length
404
+ severity: error
405
+ citation: {specification: jng, section: "1.1.5", title: "JSEP 8-bit/12-bit image separator"}
406
+ emitters:
407
+ - {file: "validators/jng/jsep_validator.rb", call: "check_length(0, id: \"jng.JSEP.length\")"}
408
+ jng.JSEP.sample-depth:
409
+ format: jng
410
+ kind: consistency
411
+ severity: error
412
+ citation: {specification: jng, section: "1.1.5", title: "JSEP 8-bit/12-bit image separator"}
413
+ emitters:
414
+ - {file: "validators/jng/jsep_validator.rb", call: "add_error(\"jng.JSEP.sample-depth\", \"JSEP is only valid with 12-bit sample depth, got #{sample_depth}-bit\", field: \"sample_depth\", expected: 12, actual: sample_depth)"}
415
+ mng.BACK.after-mhdr:
416
+ format: mng
417
+ kind: ordering
418
+ severity: error
419
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
420
+ emitters:
421
+ - {file: "validators/mng/back_validator.rb", call: "add_error(\"mng.BACK.after-mhdr\", \"BACK must appear after MHDR\")"}
422
+ mng.BACK.before-mend:
423
+ format: mng
424
+ kind: ordering
425
+ severity: error
426
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
427
+ emitters:
428
+ - {file: "validators/mng/back_validator.rb", call: "add_error(\"mng.BACK.before-mend\", \"BACK must appear before MEND\")"}
429
+ mng.BACK.crc:
430
+ format: mng
431
+ kind: integrity
432
+ severity: error
433
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
434
+ emitters:
435
+ - {file: "validators/mng/back_validator.rb", call: "check_crc(id: \"mng.BACK.crc\")"}
436
+ mng.BACK.length:
437
+ format: mng
438
+ kind: length
439
+ severity: error
440
+ citation: {specification: mng, section: "4.3.1", title: "BACK Background"}
441
+ emitters:
442
+ - {file: "validators/mng/back_validator.rb", call: "add_error(\"mng.BACK.length\", \"BACK chunk must be 6, 7, or 10 bytes, got #{data.length}\", field: \"length\", expected: \"6, 7, or 10\", actual: data.length)"}
443
+ mng.BACK.mandatory-flag:
444
+ format: mng
445
+ kind: value
446
+ severity: error
447
+ citation: {specification: mng, section: "4.3.1", title: "BACK Background"}
448
+ emitters:
449
+ - {file: "validators/mng/back_validator.rb", call: "add_error(\"mng.BACK.mandatory-flag\", \"BACK mandatory flag must be 0 or 1, got #{mandatory}\", field: \"mandatory_flag\", expected: \"0 or 1\", actual: mandatory)"}
450
+ mng.BACK.tile-mode:
451
+ format: mng
452
+ kind: value
453
+ severity: error
454
+ citation: {specification: mng, section: "4.3.1", title: "BACK Background"}
455
+ emitters:
456
+ - {file: "validators/mng/back_validator.rb", call: "add_error(\"mng.BACK.tile-mode\", \"BACK tile mode must be 0-3, got #{tile_mode}\", field: \"tile_mode\", expected: \"0-3\", actual: tile_mode)"}
457
+ mng.CLIP.after-mhdr:
458
+ format: mng
459
+ kind: ordering
460
+ severity: error
461
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
462
+ emitters:
463
+ - {file: "validators/mng/clip_validator.rb", call: "add_error(\"mng.CLIP.after-mhdr\", \"CLIP must appear after MHDR\")"}
464
+ mng.CLIP.before-mend:
465
+ format: mng
466
+ kind: ordering
467
+ severity: error
468
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
469
+ emitters:
470
+ - {file: "validators/mng/clip_validator.rb", call: "add_error(\"mng.CLIP.before-mend\", \"CLIP must appear before MEND\")"}
471
+ mng.CLIP.crc:
472
+ format: mng
473
+ kind: integrity
474
+ severity: error
475
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
476
+ emitters:
477
+ - {file: "validators/mng/clip_validator.rb", call: "check_crc(id: \"mng.CLIP.crc\")"}
478
+ mng.CLIP.length:
479
+ format: mng
480
+ kind: length
481
+ severity: error
482
+ citation: {specification: mng, section: "4.3.4", title: "CLIP Object clipping boundaries"}
483
+ emitters:
484
+ - {file: "validators/mng/clip_validator.rb", call: "add_error(\"mng.CLIP.length\", \"CLIP chunk must be #{EXPECTED_LENGTH} bytes, got #{data.length}\", field: \"length\", expected: EXPECTED_LENGTH, actual: data.length)"}
485
+ mng.CLON.after-mhdr:
486
+ format: mng
487
+ kind: ordering
488
+ severity: error
489
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
490
+ emitters:
491
+ - {file: "validators/mng/clon_validator.rb", call: "add_error(\"mng.CLON.after-mhdr\", \"CLON must appear after MHDR\")"}
492
+ mng.CLON.before-mend:
493
+ format: mng
494
+ kind: ordering
495
+ severity: error
496
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
497
+ emitters:
498
+ - {file: "validators/mng/clon_validator.rb", call: "add_error(\"mng.CLON.before-mend\", \"CLON must appear before MEND\")"}
499
+ mng.CLON.crc:
500
+ format: mng
501
+ kind: integrity
502
+ severity: error
503
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
504
+ emitters:
505
+ - {file: "validators/mng/clon_validator.rb", call: "check_crc(id: \"mng.CLON.crc\")"}
506
+ mng.CLON.length:
507
+ format: mng
508
+ kind: length
509
+ severity: error
510
+ citation: {specification: mng, section: "4.2.6", title: "CLON Clone an object"}
511
+ emitters:
512
+ - {file: "validators/mng/clon_validator.rb", call: "add_error(\"mng.CLON.length\", \"CLON chunk must be 4 or 16 bytes, got #{data.length}\", field: \"length\", expected: \"4 or 16\", actual: data.length)"}
513
+ mng.DEFI.after-mhdr:
514
+ format: mng
515
+ kind: ordering
516
+ severity: error
517
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
518
+ emitters:
519
+ - {file: "validators/mng/defi_validator.rb", call: "add_error(\"mng.DEFI.after-mhdr\", \"DEFI must appear after MHDR\")"}
520
+ mng.DEFI.before-mend:
521
+ format: mng
522
+ kind: ordering
523
+ severity: error
524
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
525
+ emitters:
526
+ - {file: "validators/mng/defi_validator.rb", call: "add_error(\"mng.DEFI.before-mend\", \"DEFI must appear before MEND\")"}
527
+ mng.DEFI.clip-horizontal-order:
528
+ format: mng
529
+ kind: value
530
+ severity: error
531
+ citation: {specification: mng, section: "4.2.1", title: "DEFI Define an object"}
532
+ emitters:
533
+ - {file: "validators/mng/defi_validator.rb", call: "add_error(\"mng.DEFI.clip-horizontal-order\", \"DEFI left clipping (#{left}) must not exceed right clipping (#{right})\", field: \"left_clipping\", expected: \"<= #{right}\", actual: left)"}
534
+ mng.DEFI.clip-vertical-order:
535
+ format: mng
536
+ kind: value
537
+ severity: error
538
+ citation: {specification: mng, section: "4.2.1", title: "DEFI Define an object"}
539
+ emitters:
540
+ - {file: "validators/mng/defi_validator.rb", call: "add_error(\"mng.DEFI.clip-vertical-order\", \"DEFI top clipping (#{top}) must not exceed bottom clipping (#{bottom})\", field: \"top_clipping\", expected: \"<= #{bottom}\", actual: top)"}
541
+ mng.DEFI.crc:
542
+ format: mng
543
+ kind: integrity
544
+ severity: error
545
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
546
+ emitters:
547
+ - {file: "validators/mng/defi_validator.rb", call: "check_crc(id: \"mng.DEFI.crc\")"}
548
+ mng.DEFI.length:
549
+ format: mng
550
+ kind: length
551
+ severity: error
552
+ citation: {specification: mng, section: "4.2.1", title: "DEFI Define an object"}
553
+ emitters:
554
+ - {file: "validators/mng/defi_validator.rb", call: "add_error(\"mng.DEFI.length\", \"DEFI chunk must be 2, 3, 4, 12, or 28 bytes, got #{data.length}\", field: \"length\", expected: \"2, 3, 4, 12, or 28\", actual: data.length)"}
555
+ mng.DHDR.after-mhdr:
556
+ format: mng
557
+ kind: ordering
558
+ severity: error
559
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
560
+ emitters:
561
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.after-mhdr\", \"DHDR must appear after MHDR\")"}
562
+ mng.DHDR.before-mend:
563
+ format: mng
564
+ kind: ordering
565
+ severity: error
566
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
567
+ emitters:
568
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.before-mend\", \"DHDR must appear before MEND\")"}
569
+ mng.DHDR.block-height-zero:
570
+ format: mng
571
+ kind: value
572
+ severity: error
573
+ citation: {specification: mng, section: "4.2.7", title: "DHDR, Delta-PNG chunks, IEND"}
574
+ emitters:
575
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.block-height-zero\", \"DHDR block height must be greater than 0\", field: \"block_height\", expected: \">0\", actual: 0)"}
576
+ mng.DHDR.block-width-zero:
577
+ format: mng
578
+ kind: value
579
+ severity: error
580
+ citation: {specification: mng, section: "4.2.7", title: "DHDR, Delta-PNG chunks, IEND"}
581
+ emitters:
582
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.block-width-zero\", \"DHDR block width must be greater than 0\", field: \"block_width\", expected: \">0\", actual: 0)"}
583
+ mng.DHDR.crc:
584
+ format: mng
585
+ kind: integrity
586
+ severity: error
587
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
588
+ emitters:
589
+ - {file: "validators/mng/dhdr_validator.rb", call: "check_crc(id: \"mng.DHDR.crc\")"}
590
+ mng.DHDR.delta-type:
591
+ format: mng
592
+ kind: value
593
+ severity: error
594
+ citation: {specification: mng, section: "4.2.7", title: "DHDR, Delta-PNG chunks, IEND"}
595
+ emitters:
596
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.delta-type\", \"Invalid DHDR delta type: #{delta_type} (must be 0-7)\", field: \"delta_type\", expected: \"0-7\", actual: delta_type)"}
597
+ mng.DHDR.image-type:
598
+ format: mng
599
+ kind: value
600
+ severity: error
601
+ citation: {specification: mng, section: "4.2.7", title: "DHDR, Delta-PNG chunks, IEND"}
602
+ emitters:
603
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.image-type\", \"Invalid DHDR image type: #{image_type} (must be 0, 2, or 4)\", field: \"image_type\", expected: \"0, 2, or 4\", actual: image_type)"}
604
+ mng.DHDR.length:
605
+ format: mng
606
+ kind: length
607
+ severity: error
608
+ citation: {specification: mng, section: "4.2.7", title: "DHDR, Delta-PNG chunks, IEND"}
609
+ emitters:
610
+ - {file: "validators/mng/dhdr_validator.rb", call: "add_error(\"mng.DHDR.length\", \"DHDR chunk must be 4, 12, or 20 bytes, got #{data.length}\", field: \"length\", expected: \"4, 12, or 20\", actual: data.length)"}
611
+ mng.DISC.after-mhdr:
612
+ format: mng
613
+ kind: ordering
614
+ severity: error
615
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
616
+ emitters:
617
+ - {file: "validators/mng/disc_validator.rb", call: "add_error(\"mng.DISC.after-mhdr\", \"DISC must appear after MHDR\")"}
618
+ mng.DISC.before-mend:
619
+ format: mng
620
+ kind: ordering
621
+ severity: error
622
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
623
+ emitters:
624
+ - {file: "validators/mng/disc_validator.rb", call: "add_error(\"mng.DISC.before-mend\", \"DISC must appear before MEND\")"}
625
+ mng.DISC.crc:
626
+ format: mng
627
+ kind: integrity
628
+ severity: error
629
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
630
+ emitters:
631
+ - {file: "validators/mng/disc_validator.rb", call: "check_crc(id: \"mng.DISC.crc\")"}
632
+ mng.DISC.length-multiple-of-2:
633
+ format: mng
634
+ kind: length
635
+ severity: error
636
+ citation: {specification: mng, section: "4.2.10", title: "DISC Discard objects"}
637
+ emitters:
638
+ - {file: "validators/mng/disc_validator.rb", call: "add_error(\"mng.DISC.length-multiple-of-2\", \"DISC chunk length must be a multiple of 2, got #{data.length}\", field: \"length\", expected: \"multiple of 2\", actual: data.length)"}
639
+ mng.ENDL.after-loop:
640
+ format: mng
641
+ kind: ordering
642
+ severity: error
643
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
644
+ emitters:
645
+ - {file: "validators/mng/endl_validator.rb", call: "add_error(\"mng.ENDL.after-loop\", \"ENDL must appear after LOOP\")"}
646
+ mng.ENDL.after-mhdr:
647
+ format: mng
648
+ kind: ordering
649
+ severity: error
650
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
651
+ emitters:
652
+ - {file: "validators/mng/endl_validator.rb", call: "add_error(\"mng.ENDL.after-mhdr\", \"ENDL must appear after MHDR\")"}
653
+ mng.ENDL.before-mend:
654
+ format: mng
655
+ kind: ordering
656
+ severity: error
657
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
658
+ emitters:
659
+ - {file: "validators/mng/endl_validator.rb", call: "add_error(\"mng.ENDL.before-mend\", \"ENDL must appear before MEND\")"}
660
+ mng.ENDL.crc:
661
+ format: mng
662
+ kind: integrity
663
+ severity: error
664
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
665
+ emitters:
666
+ - {file: "validators/mng/endl_validator.rb", call: "check_crc(id: \"mng.ENDL.crc\")"}
667
+ mng.ENDL.length:
668
+ format: mng
669
+ kind: length
670
+ severity: error
671
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
672
+ emitters:
673
+ - {file: "validators/mng/endl_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"mng.ENDL.length\")"}
674
+ mng.ENDL.nesting-level:
675
+ format: mng
676
+ kind: consistency
677
+ severity: error
678
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
679
+ emitters:
680
+ - {file: "validators/mng/endl_validator.rb", call: "add_error(\"mng.ENDL.nesting-level\", \"ENDL nesting level (#{nesting_level}) does not match LOOP nesting level (#{loop_stack.last})\", field: \"nesting_level\", expected: loop_stack.last, actual: nesting_level)"}
681
+ mng.ENDL.requires-loop:
682
+ format: mng
683
+ kind: presence
684
+ severity: error
685
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
686
+ emitters:
687
+ - {file: "validators/mng/endl_validator.rb", call: "add_error(\"mng.ENDL.requires-loop\", \"ENDL without corresponding LOOP\")"}
688
+ mng.FRAM.after-mhdr:
689
+ format: mng
690
+ kind: ordering
691
+ severity: error
692
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
693
+ emitters:
694
+ - {file: "validators/mng/fram_validator.rb", call: "add_error(\"mng.FRAM.after-mhdr\", \"FRAM must appear after MHDR\")"}
695
+ mng.FRAM.before-mend:
696
+ format: mng
697
+ kind: ordering
698
+ severity: error
699
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
700
+ emitters:
701
+ - {file: "validators/mng/fram_validator.rb", call: "add_error(\"mng.FRAM.before-mend\", \"FRAM must appear before MEND\")"}
702
+ mng.FRAM.crc:
703
+ format: mng
704
+ kind: integrity
705
+ severity: error
706
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
707
+ emitters:
708
+ - {file: "validators/mng/fram_validator.rb", call: "check_crc(id: \"mng.FRAM.crc\")"}
709
+ mng.FRAM.framing-mode:
710
+ format: mng
711
+ kind: value
712
+ severity: error
713
+ citation: {specification: mng, section: "4.3.2", title: "FRAM Frame definitions"}
714
+ emitters:
715
+ - {file: "validators/mng/fram_validator.rb", call: "add_error(\"mng.FRAM.framing-mode\", \"Invalid FRAM framing mode: #{framing_mode} (must be 0-4)\", field: \"framing_mode\", expected: \"0-4\", actual: framing_mode)"}
716
+ mng.FRAM.subframe-name-length:
717
+ format: mng
718
+ kind: length
719
+ severity: error
720
+ citation: {specification: mng, section: "4.3.2", title: "FRAM Frame definitions"}
721
+ emitters:
722
+ - {file: "validators/mng/fram_validator.rb", call: "add_error(\"mng.FRAM.subframe-name-length\", \"FRAM subframe name extends beyond chunk\")"}
723
+ mng.LOOP.after-mhdr:
724
+ format: mng
725
+ kind: ordering
726
+ severity: error
727
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
728
+ emitters:
729
+ - {file: "validators/mng/loop_validator.rb", call: "add_error(\"mng.LOOP.after-mhdr\", \"LOOP must appear after MHDR\")"}
730
+ mng.LOOP.before-mend:
731
+ format: mng
732
+ kind: ordering
733
+ severity: error
734
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
735
+ emitters:
736
+ - {file: "validators/mng/loop_validator.rb", call: "add_error(\"mng.LOOP.before-mend\", \"LOOP must appear before MEND\")"}
737
+ mng.LOOP.crc:
738
+ format: mng
739
+ kind: integrity
740
+ severity: error
741
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
742
+ emitters:
743
+ - {file: "validators/mng/loop_validator.rb", call: "check_crc(id: \"mng.LOOP.crc\")"}
744
+ mng.LOOP.length:
745
+ format: mng
746
+ kind: length
747
+ severity: error
748
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
749
+ emitters:
750
+ - {file: "validators/mng/loop_validator.rb", call: "add_error(\"mng.LOOP.length\", \"LOOP chunk must be 5 or 6 bytes, got #{data.length}\", field: \"length\", expected: \"5 or 6\", actual: data.length)"}
751
+ mng.LOOP.termination-condition:
752
+ format: mng
753
+ kind: value
754
+ severity: error
755
+ citation: {specification: mng, section: "4.1.3", title: "LOOP, ENDL Define a loop"}
756
+ emitters:
757
+ - {file: "validators/mng/loop_validator.rb", call: "add_error(\"mng.LOOP.termination-condition\", \"LOOP termination condition must be 0-3, got #{termination}\", field: \"termination_condition\", expected: \"0-3\", actual: termination)"}
758
+ mng.MEND.crc:
759
+ format: mng
760
+ kind: integrity
761
+ severity: error
762
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
763
+ emitters:
764
+ - {file: "validators/mng/mend_validator.rb", call: "check_crc(id: \"mng.MEND.crc\")"}
765
+ mng.MEND.last-chunk:
766
+ format: mng
767
+ kind: ordering
768
+ severity: error
769
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
770
+ emitters:
771
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"mng.MEND.last-chunk\", \"MEND must be the last chunk\", **located(\"MEND\", index) )"}
772
+ mng.MEND.length:
773
+ format: mng
774
+ kind: length
775
+ severity: error
776
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
777
+ emitters:
778
+ - {file: "validators/mng/mend_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"mng.MEND.length\")"}
779
+ mng.MEND.missing:
780
+ format: mng
781
+ kind: presence
782
+ severity: error
783
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
784
+ emitters:
785
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"mng.MEND.missing\", \"Missing MEND chunk (must be last)\", chunk_type: \"MEND\" )"}
786
+ mng.MEND.requires-mhdr:
787
+ format: mng
788
+ kind: presence
789
+ severity: error
790
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
791
+ emitters:
792
+ - {file: "validators/mng/mend_validator.rb", call: "add_error(\"mng.MEND.requires-mhdr\", \"MEND requires MHDR chunk\")"}
793
+ mng.MHDR.crc:
794
+ format: mng
795
+ kind: integrity
796
+ severity: error
797
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
798
+ emitters:
799
+ - {file: "validators/mng/mhdr_validator.rb", call: "check_crc(id: \"mng.MHDR.crc\")"}
800
+ mng.MHDR.first-chunk:
801
+ format: mng
802
+ kind: ordering
803
+ severity: error
804
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
805
+ emitters:
806
+ - {file: "validators/mng/mhdr_validator.rb", call: "add_error(\"mng.MHDR.first-chunk\", \"MHDR must be the first chunk in MNG file\")"}
807
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"mng.MHDR.first-chunk\", \"MHDR must be the first chunk in MNG file\", **located(\"MHDR\", index) )"}
808
+ mng.MHDR.frame-dimensions-zero:
809
+ format: mng
810
+ kind: value
811
+ severity: error
812
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
813
+ emitters:
814
+ - {file: "validators/mng/mhdr_validator.rb", call: "add_error(\"mng.MHDR.frame-dimensions-zero\", \"MHDR frame dimensions must be > 0\")"}
815
+ mng.MHDR.length:
816
+ format: mng
817
+ kind: length
818
+ severity: error
819
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
820
+ emitters:
821
+ - {file: "validators/mng/mhdr_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"mng.MHDR.length\")"}
822
+ mng.MHDR.missing:
823
+ format: mng
824
+ kind: presence
825
+ severity: error
826
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
827
+ emitters:
828
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"mng.MHDR.missing\", \"Missing MHDR chunk (must be first)\", chunk_type: \"MHDR\" )"}
829
+ mng.MOVE.after-mhdr:
830
+ format: mng
831
+ kind: ordering
832
+ severity: error
833
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
834
+ emitters:
835
+ - {file: "validators/mng/move_validator.rb", call: "add_error(\"mng.MOVE.after-mhdr\", \"MOVE must appear after MHDR\")"}
836
+ mng.MOVE.before-mend:
837
+ format: mng
838
+ kind: ordering
839
+ severity: error
840
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
841
+ emitters:
842
+ - {file: "validators/mng/move_validator.rb", call: "add_error(\"mng.MOVE.before-mend\", \"MOVE must appear before MEND\")"}
843
+ mng.MOVE.crc:
844
+ format: mng
845
+ kind: integrity
846
+ severity: error
847
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
848
+ emitters:
849
+ - {file: "validators/mng/move_validator.rb", call: "check_crc(id: \"mng.MOVE.crc\")"}
850
+ mng.MOVE.length:
851
+ format: mng
852
+ kind: length
853
+ severity: error
854
+ citation: {specification: mng, section: "4.3.3", title: "MOVE New image location"}
855
+ emitters:
856
+ - {file: "validators/mng/move_validator.rb", call: "add_error(\"mng.MOVE.length\", \"MOVE chunk must be #{EXPECTED_LENGTH} bytes, got #{data.length}\", field: \"length\", expected: EXPECTED_LENGTH, actual: data.length)"}
857
+ mng.SAVE.after-mhdr:
858
+ format: mng
859
+ kind: ordering
860
+ severity: error
861
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
862
+ emitters:
863
+ - {file: "validators/mng/save_validator.rb", call: "add_error(\"mng.SAVE.after-mhdr\", \"SAVE must appear after MHDR\")"}
864
+ mng.SAVE.before-mend:
865
+ format: mng
866
+ kind: ordering
867
+ severity: error
868
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
869
+ emitters:
870
+ - {file: "validators/mng/save_validator.rb", call: "add_error(\"mng.SAVE.before-mend\", \"SAVE must appear before MEND\")"}
871
+ mng.SAVE.crc:
872
+ format: mng
873
+ kind: integrity
874
+ severity: error
875
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
876
+ emitters:
877
+ - {file: "validators/mng/save_validator.rb", call: "check_crc(id: \"mng.SAVE.crc\")"}
878
+ mng.SAVE.length:
879
+ format: mng
880
+ kind: length
881
+ severity: error
882
+ citation: {specification: mng, section: "4.4.1", title: "SAVE Save information"}
883
+ emitters:
884
+ - {file: "validators/mng/save_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"mng.SAVE.length\")"}
885
+ mng.SEEK.after-mhdr:
886
+ format: mng
887
+ kind: ordering
888
+ severity: error
889
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
890
+ emitters:
891
+ - {file: "validators/mng/seek_validator.rb", call: "add_error(\"mng.SEEK.after-mhdr\", \"SEEK must appear after MHDR\")"}
892
+ mng.SEEK.before-mend:
893
+ format: mng
894
+ kind: ordering
895
+ severity: error
896
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
897
+ emitters:
898
+ - {file: "validators/mng/seek_validator.rb", call: "add_error(\"mng.SEEK.before-mend\", \"SEEK must appear before MEND\")"}
899
+ mng.SEEK.crc:
900
+ format: mng
901
+ kind: integrity
902
+ severity: error
903
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
904
+ emitters:
905
+ - {file: "validators/mng/seek_validator.rb", call: "check_crc(id: \"mng.SEEK.crc\")"}
906
+ mng.SEEK.length:
907
+ format: mng
908
+ kind: length
909
+ severity: error
910
+ citation: {specification: mng, section: "4.4.2", title: "SEEK Seek point"}
911
+ emitters:
912
+ - {file: "validators/mng/seek_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"mng.SEEK.length\")"}
913
+ mng.SEEK.requires-save:
914
+ format: mng
915
+ kind: presence
916
+ severity: warning
917
+ citation: {specification: mng, section: "4.4.2", title: "SEEK Seek point"}
918
+ emitters:
919
+ - {file: "validators/mng/seek_validator.rb", call: "add_warning(\"mng.SEEK.requires-save\", \"SEEK without corresponding SAVE\")"}
920
+ mng.SHOW.after-mhdr:
921
+ format: mng
922
+ kind: ordering
923
+ severity: error
924
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
925
+ emitters:
926
+ - {file: "validators/mng/show_validator.rb", call: "add_error(\"mng.SHOW.after-mhdr\", \"SHOW must appear after MHDR\")"}
927
+ mng.SHOW.before-mend:
928
+ format: mng
929
+ kind: ordering
930
+ severity: error
931
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
932
+ emitters:
933
+ - {file: "validators/mng/show_validator.rb", call: "add_error(\"mng.SHOW.before-mend\", \"SHOW must appear before MEND\")"}
934
+ mng.SHOW.crc:
935
+ format: mng
936
+ kind: integrity
937
+ severity: error
938
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
939
+ emitters:
940
+ - {file: "validators/mng/show_validator.rb", call: "check_crc(id: \"mng.SHOW.crc\")"}
941
+ mng.SHOW.length:
942
+ format: mng
943
+ kind: length
944
+ severity: error
945
+ citation: {specification: mng, section: "4.3.5", title: "SHOW Show images"}
946
+ emitters:
947
+ - {file: "validators/mng/show_validator.rb", call: "add_error(\"mng.SHOW.length\", \"SHOW chunk must be 0 or 2 bytes, got #{data.length}\", field: \"length\", expected: \"0 or 2\", actual: data.length)"}
948
+ mng.TERM.action-after-iterations:
949
+ format: mng
950
+ kind: value
951
+ severity: error
952
+ citation: {specification: mng, section: "4.2.11", title: "TERM Termination action"}
953
+ emitters:
954
+ - {file: "validators/mng/term_validator.rb", call: "add_error(\"mng.TERM.action-after-iterations\", \"Invalid TERM action after iterations: #{after_iterations} (must be 0-2)\", field: \"action_after_iterations\", expected: \"0-2\", actual: after_iterations)"}
955
+ mng.TERM.after-mhdr:
956
+ format: mng
957
+ kind: ordering
958
+ severity: error
959
+ citation: {specification: mng, section: "4.1.1", title: "MHDR MNG datastream header"}
960
+ emitters:
961
+ - {file: "validators/mng/term_validator.rb", call: "add_error(\"mng.TERM.after-mhdr\", \"TERM must appear after MHDR\")"}
962
+ mng.TERM.before-mend:
963
+ format: mng
964
+ kind: ordering
965
+ severity: error
966
+ citation: {specification: mng, section: "4.1.2", title: "MEND End of MNG datastream"}
967
+ emitters:
968
+ - {file: "validators/mng/term_validator.rb", call: "add_error(\"mng.TERM.before-mend\", \"TERM must appear before MEND\")"}
969
+ mng.TERM.crc:
970
+ format: mng
971
+ kind: integrity
972
+ severity: error
973
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
974
+ emitters:
975
+ - {file: "validators/mng/term_validator.rb", call: "check_crc(id: \"mng.TERM.crc\")"}
976
+ mng.TERM.length:
977
+ format: mng
978
+ kind: length
979
+ severity: error
980
+ citation: {specification: mng, section: "4.2.11", title: "TERM Termination action"}
981
+ emitters:
982
+ - {file: "validators/mng/term_validator.rb", call: "add_error(\"mng.TERM.length\", \"TERM chunk must be 1 or 10 bytes, got #{data.length}\", field: \"length\", expected: \"1 or 10\", actual: data.length)"}
983
+ mng.TERM.termination-action:
984
+ format: mng
985
+ kind: value
986
+ severity: error
987
+ citation: {specification: mng, section: "4.2.11", title: "TERM Termination action"}
988
+ emitters:
989
+ - {file: "validators/mng/term_validator.rb", call: "add_error(\"mng.TERM.termination-action\", \"Invalid TERM termination action: #{termination_action} (must be 0-3)\", field: \"termination_action\", expected: \"0-3\", actual: termination_action)"}
990
+ png.IDAT.after-ihdr:
991
+ format: png
992
+ kind: ordering
993
+ severity: error
994
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
995
+ emitters:
996
+ - {file: "validators/critical/idat_validator.rb", call: "add_error(\"png.IDAT.after-ihdr\", \"IDAT chunk before IHDR\")"}
997
+ png.IDAT.after-plte:
998
+ format: png
999
+ kind: ordering
1000
+ severity: error
1001
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1002
+ emitters:
1003
+ - {file: "validators/critical/idat_validator.rb", call: "add_error(\"png.IDAT.after-plte\", \"IDAT chunk before PLTE for indexed-color image\")"}
1004
+ png.IDAT.crc:
1005
+ format: png
1006
+ kind: integrity
1007
+ severity: error
1008
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1009
+ emitters:
1010
+ - {file: "validators/critical/idat_validator.rb", call: "check_crc(id: \"png.IDAT.crc\")"}
1011
+ png.IDAT.empty:
1012
+ format: png
1013
+ kind: length
1014
+ severity: error
1015
+ citation: {specification: iso15948, section: "11.2.4", title: "IDAT Image data"}
1016
+ emitters:
1017
+ - {file: "validators/critical/idat_validator.rb", call: "add_error(\"png.IDAT.empty\", \"IDAT chunk is empty\")"}
1018
+ png.IDAT.missing:
1019
+ format: png
1020
+ kind: presence
1021
+ severity: error
1022
+ citation: {specification: iso15948, section: "11.2.1", title: "General"}
1023
+ emitters:
1024
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"png.IDAT.missing\", \"Missing IDAT chunk (at least one required)\", chunk_type: \"IDAT\" )"}
1025
+ png.IEND.after-idat:
1026
+ format: png
1027
+ kind: ordering
1028
+ severity: error
1029
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1030
+ emitters:
1031
+ - {file: "validators/critical/iend_validator.rb", call: "add_error(\"png.IEND.after-idat\", \"IEND chunk before IDAT\")"}
1032
+ png.IEND.after-ihdr:
1033
+ format: png
1034
+ kind: ordering
1035
+ severity: error
1036
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1037
+ emitters:
1038
+ - {file: "validators/critical/iend_validator.rb", call: "add_error(\"png.IEND.after-ihdr\", \"IEND chunk before IHDR\")"}
1039
+ png.IEND.crc:
1040
+ format: png
1041
+ kind: integrity
1042
+ severity: error
1043
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1044
+ emitters:
1045
+ - {file: "validators/critical/iend_validator.rb", call: "check_crc(id: \"png.IEND.crc\")"}
1046
+ png.IEND.last-chunk:
1047
+ format: png
1048
+ kind: ordering
1049
+ severity: error
1050
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1051
+ emitters:
1052
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"png.IEND.last-chunk\", \"IEND must be the last chunk\", **located(\"IEND\", index) )"}
1053
+ png.IEND.length:
1054
+ format: png
1055
+ kind: length
1056
+ severity: error
1057
+ citation: {specification: iso15948, section: "11.2.5", title: "IEND Image trailer"}
1058
+ emitters:
1059
+ - {file: "validators/critical/iend_validator.rb", call: "add_error(\"png.IEND.length\", \"invalid IEND chunk length (#{chunk.chunk_data.length}, should be 0)\")"}
1060
+ png.IEND.missing:
1061
+ format: png
1062
+ kind: presence
1063
+ severity: error
1064
+ citation: {specification: iso15948, section: "11.2.1", title: "General"}
1065
+ emitters:
1066
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"png.IEND.missing\", \"Missing IEND chunk (must be last)\", chunk_type: \"IEND\" )"}
1067
+ png.IHDR.bit-depth:
1068
+ format: png
1069
+ kind: value
1070
+ severity: error
1071
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1072
+ emitters:
1073
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_error(\"png.IHDR.bit-depth\", \"invalid bit depth (#{bit_depth}) for #{COLOR_TYPES[color_type]} (must be one of #{valid_depths.join(', ')})\")"}
1074
+ png.IHDR.color-type:
1075
+ format: png
1076
+ kind: value
1077
+ severity: error
1078
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1079
+ emitters:
1080
+ - {file: "validators/critical/ihdr_validator.rb", call: "check_enum(color_type, COLOR_TYPES.keys, \"color type\", id: \"png.IHDR.color-type\")"}
1081
+ png.IHDR.compression-method:
1082
+ format: png
1083
+ kind: value
1084
+ severity: error
1085
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1086
+ emitters:
1087
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_error(\"png.IHDR.compression-method\", \"invalid compression method (#{compression}, must be 0)\")"}
1088
+ png.IHDR.crc:
1089
+ format: png
1090
+ kind: integrity
1091
+ severity: error
1092
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1093
+ emitters:
1094
+ - {file: "validators/critical/ihdr_validator.rb", call: "check_crc(id: \"png.IHDR.crc\")"}
1095
+ png.IHDR.filter-method:
1096
+ format: png
1097
+ kind: value
1098
+ severity: error
1099
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1100
+ emitters:
1101
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_error(\"png.IHDR.filter-method\", \"invalid filter method (#{filter}, must be 0)\")"}
1102
+ png.IHDR.first-chunk:
1103
+ format: png
1104
+ kind: ordering
1105
+ severity: error
1106
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1107
+ emitters:
1108
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"png.IHDR.first-chunk\", \"IHDR must be the first chunk\", **located(\"IHDR\", index) )"}
1109
+ png.IHDR.height-recommended-max:
1110
+ format: png
1111
+ kind: value
1112
+ severity: warning
1113
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1114
+ emitters:
1115
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_warning(\"png.IHDR.height-recommended-max\", \"image height (#{height}) exceeds maximum recommended value\")"}
1116
+ png.IHDR.height-zero:
1117
+ format: png
1118
+ kind: value
1119
+ severity: error
1120
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1121
+ emitters:
1122
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_error(\"png.IHDR.height-zero\", \"invalid image height (0)\")"}
1123
+ png.IHDR.interlace-method:
1124
+ format: png
1125
+ kind: value
1126
+ severity: error
1127
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1128
+ emitters:
1129
+ - {file: "validators/critical/ihdr_validator.rb", call: "check_enum(interlace, [0, 1], \"interlace method\", id: \"png.IHDR.interlace-method\")"}
1130
+ png.IHDR.length:
1131
+ format: png
1132
+ kind: length
1133
+ severity: error
1134
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1135
+ emitters:
1136
+ - {file: "validators/critical/ihdr_validator.rb", call: "check_length(13, id: \"png.IHDR.length\")"}
1137
+ png.IHDR.missing:
1138
+ format: png
1139
+ kind: presence
1140
+ severity: error
1141
+ citation: {specification: iso15948, section: "11.2.1", title: "General"}
1142
+ emitters:
1143
+ - {file: "services/validation_orchestrator.rb", call: "add_diagnostic(\"png.IHDR.missing\", \"Missing IHDR chunk (must be first)\", chunk_type: \"IHDR\" )"}
1144
+ png.IHDR.width-recommended-max:
1145
+ format: png
1146
+ kind: value
1147
+ severity: warning
1148
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1149
+ emitters:
1150
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_warning(\"png.IHDR.width-recommended-max\", \"image width (#{width}) exceeds maximum recommended value\")"}
1151
+ png.IHDR.width-zero:
1152
+ format: png
1153
+ kind: value
1154
+ severity: error
1155
+ citation: {specification: iso15948, section: "11.2.2", title: "IHDR Image header"}
1156
+ emitters:
1157
+ - {file: "validators/critical/ihdr_validator.rb", call: "add_error(\"png.IHDR.width-zero\", \"invalid image width (0)\")"}
1158
+ png.PLTE.color-type-grayscale:
1159
+ format: png
1160
+ kind: consistency
1161
+ severity: error
1162
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1163
+ emitters:
1164
+ - {file: "validators/critical/plte_validator.rb", call: "add_error(\"png.PLTE.color-type-grayscale\", \"PLTE chunk not allowed for grayscale images\")"}
1165
+ png.PLTE.color-type-unknown:
1166
+ format: png
1167
+ kind: consistency
1168
+ severity: warning
1169
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1170
+ emitters:
1171
+ - {file: "validators/critical/plte_validator.rb", call: "add_warning(\"png.PLTE.color-type-unknown\", \"PLTE chunk present but color type unknown\")"}
1172
+ png.PLTE.crc:
1173
+ format: png
1174
+ kind: integrity
1175
+ severity: error
1176
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1177
+ emitters:
1178
+ - {file: "validators/critical/plte_validator.rb", call: "check_crc(id: \"png.PLTE.crc\")"}
1179
+ png.PLTE.entries-max:
1180
+ format: png
1181
+ kind: value
1182
+ severity: error
1183
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1184
+ emitters:
1185
+ - {file: "validators/critical/plte_validator.rb", call: "add_error(\"png.PLTE.entries-max\", \"invalid PLTE chunk (#{entries} entries, maximum is #{MAX_ENTRIES})\")"}
1186
+ png.PLTE.entries-none:
1187
+ format: png
1188
+ kind: value
1189
+ severity: error
1190
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1191
+ emitters:
1192
+ - {file: "validators/critical/plte_validator.rb", call: "add_error(\"png.PLTE.entries-none\", \"invalid PLTE chunk (no entries)\")"}
1193
+ png.PLTE.entries-vs-bit-depth:
1194
+ format: png
1195
+ kind: consistency
1196
+ severity: error
1197
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1198
+ emitters:
1199
+ - {file: "validators/critical/plte_validator.rb", call: "add_error(\"png.PLTE.entries-vs-bit-depth\", \"PLTE chunk has #{entries} entries but bit depth #{bit_depth} allows maximum of #{max_entries}\")"}
1200
+ png.PLTE.length-multiple-of-3:
1201
+ format: png
1202
+ kind: length
1203
+ severity: error
1204
+ citation: {specification: iso15948, section: "11.2.3", title: "PLTE Palette"}
1205
+ emitters:
1206
+ - {file: "validators/critical/plte_validator.rb", call: "add_error(\"png.PLTE.length-multiple-of-3\", \"invalid PLTE length (#{length}, must be divisible by 3)\")"}
1207
+ png.bKGD.after-plte:
1208
+ format: png
1209
+ kind: ordering
1210
+ severity: error
1211
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1212
+ emitters:
1213
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_error(\"png.bKGD.after-plte\", \"bKGD chunk before PLTE for indexed-color image\")"}
1214
+ png.bKGD.before-idat:
1215
+ format: png
1216
+ kind: ordering
1217
+ severity: error
1218
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1219
+ emitters:
1220
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_error(\"png.bKGD.before-idat\", \"bKGD chunk after IDAT (must be before)\")"}
1221
+ png.bKGD.crc:
1222
+ format: png
1223
+ kind: integrity
1224
+ severity: error
1225
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1226
+ emitters:
1227
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "check_crc(id: \"png.bKGD.crc\")"}
1228
+ png.bKGD.length:
1229
+ format: png
1230
+ kind: length
1231
+ severity: error
1232
+ citation: {specification: iso15948, section: "11.3.5.1", title: "bKGD Background colour"}
1233
+ emitters:
1234
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "check_length(2, id: \"png.bKGD.length\")"}
1235
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "check_length(6, id: \"png.bKGD.length\")"}
1236
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "check_length(1, id: \"png.bKGD.length\")"}
1237
+ png.bKGD.palette-index:
1238
+ format: png
1239
+ kind: value
1240
+ severity: error
1241
+ citation: {specification: iso15948, section: "11.3.5.1", title: "bKGD Background colour"}
1242
+ emitters:
1243
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_error(\"png.bKGD.palette-index\", \"bKGD palette index (#{index}) exceeds palette size (#{palette_entries})\")"}
1244
+ png.bKGD.single-instance:
1245
+ format: png
1246
+ kind: multiplicity
1247
+ severity: error
1248
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1249
+ emitters:
1250
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_error(\"png.bKGD.single-instance\", \"duplicate bKGD chunk\")"}
1251
+ png.cHRM.before-idat:
1252
+ format: png
1253
+ kind: ordering
1254
+ severity: error
1255
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1256
+ emitters:
1257
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_error(\"png.cHRM.before-idat\", \"cHRM chunk after IDAT (must be before)\")"}
1258
+ png.cHRM.before-plte:
1259
+ format: png
1260
+ kind: ordering
1261
+ severity: warning
1262
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1263
+ emitters:
1264
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_warning(\"png.cHRM.before-plte\", \"cHRM chunk after PLTE (should be before)\")"}
1265
+ png.cHRM.chromaticity-range:
1266
+ format: png
1267
+ kind: value
1268
+ severity: warning
1269
+ citation: {specification: iso15948, section: "11.3.3.1", title: "cHRM Primary chromaticities and white point"}
1270
+ emitters:
1271
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_warning(\"png.cHRM.chromaticity-range\", \"#{name} chromaticity (#{value / 100_000.0}) exceeds typical range (0.0-1.0)\")"}
1272
+ png.cHRM.crc:
1273
+ format: png
1274
+ kind: integrity
1275
+ severity: error
1276
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1277
+ emitters:
1278
+ - {file: "validators/ancillary/chrm_validator.rb", call: "check_crc(id: \"png.cHRM.crc\")"}
1279
+ png.cHRM.length:
1280
+ format: png
1281
+ kind: length
1282
+ severity: error
1283
+ citation: {specification: iso15948, section: "11.3.3.1", title: "cHRM Primary chromaticities and white point"}
1284
+ emitters:
1285
+ - {file: "validators/ancillary/chrm_validator.rb", call: "check_length(32, id: \"png.cHRM.length\")"}
1286
+ png.cHRM.single-instance:
1287
+ format: png
1288
+ kind: multiplicity
1289
+ severity: error
1290
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1291
+ emitters:
1292
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_error(\"png.cHRM.single-instance\", \"duplicate cHRM chunk\")"}
1293
+ png.cHRM.srgb-consistency:
1294
+ format: png
1295
+ kind: consistency
1296
+ severity: warning
1297
+ citation: {specification: iso15948, section: "11.3.3.1", title: "cHRM Primary chromaticities and white point"}
1298
+ emitters:
1299
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_warning(\"png.cHRM.srgb-consistency\", \"cHRM values don't match sRGB: #{mismatches.join(', ')}\")"}
1300
+ png.cICP.before-idat:
1301
+ format: png
1302
+ kind: ordering
1303
+ severity: error
1304
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1305
+ emitters:
1306
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.before-idat\", \"cICP must appear before IDAT\")"}
1307
+ png.cICP.before-plte:
1308
+ format: png
1309
+ kind: ordering
1310
+ severity: error
1311
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1312
+ emitters:
1313
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.before-plte\", \"cICP must appear before PLTE\")"}
1314
+ png.cICP.coexist-iccp:
1315
+ format: png
1316
+ kind: consistency
1317
+ severity: warning
1318
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1319
+ emitters:
1320
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_warning(\"png.cICP.coexist-iccp\", \"cICP should not coexist with iCCP (both specify color space information)\")"}
1321
+ png.cICP.coexist-srgb:
1322
+ format: png
1323
+ kind: consistency
1324
+ severity: warning
1325
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1326
+ emitters:
1327
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_warning(\"png.cICP.coexist-srgb\", \"cICP should not coexist with sRGB (both specify color space information)\")"}
1328
+ png.cICP.color-primaries:
1329
+ format: png
1330
+ kind: value
1331
+ severity: error
1332
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1333
+ emitters:
1334
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.color-primaries\", \"invalid color primaries: #{value} (valid: #{VALID_COLOR_PRIMARIES.join(', ')})\")"}
1335
+ png.cICP.color-primaries-reserved:
1336
+ format: png
1337
+ kind: value
1338
+ severity: warning
1339
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1340
+ emitters:
1341
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_warning(\"png.cICP.color-primaries-reserved\", \"color primaries = 0 (reserved)\")"}
1342
+ png.cICP.full-range-flag:
1343
+ format: png
1344
+ kind: value
1345
+ severity: error
1346
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1347
+ emitters:
1348
+ - {file: "validators/ancillary/cicp_validator.rb", call: "check_enum(value, [0, 1], \"video full range flag\", id: \"png.cICP.full-range-flag\")"}
1349
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.full-range-flag\", \"invalid video full range flag: #{value} (must be 0 or 1)\")"}
1350
+ png.cICP.length:
1351
+ format: png
1352
+ kind: length
1353
+ severity: error
1354
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1355
+ emitters:
1356
+ - {file: "validators/ancillary/cicp_validator.rb", call: "check_length(4, id: \"png.cICP.length\")"}
1357
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.length\", \"invalid chunk length: #{chunk.chunk_data.bytesize} bytes\")"}
1358
+ png.cICP.matrix-coefficients:
1359
+ format: png
1360
+ kind: value
1361
+ severity: error
1362
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1363
+ emitters:
1364
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.matrix-coefficients\", \"invalid matrix coefficients: #{value} (valid: #{VALID_MATRIX_COEFFICIENTS.join(', ')})\")"}
1365
+ png.cICP.single-instance:
1366
+ format: png
1367
+ kind: multiplicity
1368
+ severity: error
1369
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1370
+ emitters:
1371
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.single-instance\", \"multiple cICP chunks not allowed\")"}
1372
+ png.cICP.transfer-function:
1373
+ format: png
1374
+ kind: value
1375
+ severity: error
1376
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1377
+ emitters:
1378
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_error(\"png.cICP.transfer-function\", \"invalid transfer function: #{value} (valid: #{VALID_TRANSFER_FUNCTIONS.join(', ')})\")"}
1379
+ png.cICP.transfer-function-reserved:
1380
+ format: png
1381
+ kind: value
1382
+ severity: warning
1383
+ citation: {specification: png3, section: "11.3.2.6", title: "cICP Coding-independent code points for video signal type identification"}
1384
+ emitters:
1385
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_warning(\"png.cICP.transfer-function-reserved\", \"transfer function = 0 (reserved)\")"}
1386
+ png.chunk.unknown-critical:
1387
+ format: png
1388
+ kind: presence
1389
+ severity: error
1390
+ citation: {specification: iso15948, section: "13.2", title: "Error handling"}
1391
+ emitters:
1392
+ - {file: "services/chunk_processor.rb", call: "add_diagnostic(\"png.chunk.unknown-critical\", \"Unknown critical chunk type: #{chunk_type}\", chunk_type: chunk_type, offset: chunk.abs_offset, field: \"chunk type\", actual: chunk_type )"}
1393
+ png.gAMA.before-idat:
1394
+ format: png
1395
+ kind: ordering
1396
+ severity: error
1397
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1398
+ emitters:
1399
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_error(\"png.gAMA.before-idat\", \"gAMA chunk after IDAT (must be before)\")"}
1400
+ png.gAMA.before-plte:
1401
+ format: png
1402
+ kind: ordering
1403
+ severity: error
1404
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1405
+ emitters:
1406
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_error(\"png.gAMA.before-plte\", \"gAMA chunk after PLTE (should be before)\")"}
1407
+ png.gAMA.crc:
1408
+ format: png
1409
+ kind: integrity
1410
+ severity: error
1411
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1412
+ emitters:
1413
+ - {file: "validators/ancillary/gama_validator.rb", call: "check_crc(id: \"png.gAMA.crc\")"}
1414
+ png.gAMA.length:
1415
+ format: png
1416
+ kind: length
1417
+ severity: error
1418
+ citation: {specification: iso15948, section: "11.3.3.2", title: "gAMA Image gamma"}
1419
+ emitters:
1420
+ - {file: "validators/ancillary/gama_validator.rb", call: "check_length(4, id: \"png.gAMA.length\")"}
1421
+ png.gAMA.single-instance:
1422
+ format: png
1423
+ kind: multiplicity
1424
+ severity: error
1425
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1426
+ emitters:
1427
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_error(\"png.gAMA.single-instance\", \"duplicate gAMA chunk\")"}
1428
+ png.gAMA.srgb-consistency:
1429
+ format: png
1430
+ kind: consistency
1431
+ severity: warning
1432
+ citation: {specification: iso15948, section: "11.3.3.2", title: "gAMA Image gamma"}
1433
+ emitters:
1434
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_warning(\"png.gAMA.srgb-consistency\", \"gAMA value #{gamma} with sRGB present (should be #{GAMMA_2_2} for gamma 2.2)\")"}
1435
+ png.gAMA.value-zero:
1436
+ format: png
1437
+ kind: value
1438
+ severity: error
1439
+ citation: {specification: iso15948, section: "11.3.3.2", title: "gAMA Image gamma"}
1440
+ emitters:
1441
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_error(\"png.gAMA.value-zero\", \"invalid gAMA value (0)\")"}
1442
+ png.hIST.after-ihdr:
1443
+ format: png
1444
+ kind: ordering
1445
+ severity: error
1446
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1447
+ emitters:
1448
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.after-ihdr\", \"hIST chunk before IHDR\")"}
1449
+ png.hIST.after-plte:
1450
+ format: png
1451
+ kind: ordering
1452
+ severity: error
1453
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1454
+ emitters:
1455
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.after-plte\", \"hIST chunk without preceding PLTE chunk\")"}
1456
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.after-plte\", \"hIST chunk before PLTE chunk\")"}
1457
+ png.hIST.before-idat:
1458
+ format: png
1459
+ kind: ordering
1460
+ severity: error
1461
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1462
+ emitters:
1463
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.before-idat\", \"hIST chunk after IDAT chunk\")"}
1464
+ png.hIST.color-type-indexed:
1465
+ format: png
1466
+ kind: consistency
1467
+ severity: error
1468
+ citation: {specification: iso15948, section: "11.3.5.2", title: "hIST Image histogram"}
1469
+ emitters:
1470
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.color-type-indexed\", \"hIST chunk invalid for color type #{color_type} (only valid for indexed color)\")"}
1471
+ png.hIST.crc:
1472
+ format: png
1473
+ kind: integrity
1474
+ severity: error
1475
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1476
+ emitters:
1477
+ - {file: "validators/ancillary/hist_validator.rb", call: "check_crc(id: \"png.hIST.crc\")"}
1478
+ png.hIST.length:
1479
+ format: png
1480
+ kind: length
1481
+ severity: error
1482
+ citation: {specification: iso15948, section: "11.3.5.2", title: "hIST Image histogram"}
1483
+ emitters:
1484
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.length\", \"hIST chunk wrong length (#{actual_length} bytes, expected #{expected_length} for #{palette_entries} palette entries)\")"}
1485
+ png.hIST.single-instance:
1486
+ format: png
1487
+ kind: multiplicity
1488
+ severity: error
1489
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1490
+ emitters:
1491
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_error(\"png.hIST.single-instance\", \"Multiple hIST chunks (only one allowed)\")"}
1492
+ png.iCCP.before-idat:
1493
+ format: png
1494
+ kind: ordering
1495
+ severity: error
1496
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1497
+ emitters:
1498
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.before-idat\", \"iCCP chunk after IDAT chunk\")"}
1499
+ png.iCCP.before-plte:
1500
+ format: png
1501
+ kind: ordering
1502
+ severity: error
1503
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1504
+ emitters:
1505
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.before-plte\", \"iCCP chunk after PLTE chunk\")"}
1506
+ png.iCCP.coexist-srgb:
1507
+ format: png
1508
+ kind: consistency
1509
+ severity: warning
1510
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1511
+ emitters:
1512
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_warning(\"png.iCCP.coexist-srgb\", \"iCCP chunk present with sRGB chunk (iCCP takes precedence)\")"}
1513
+ png.iCCP.compression-method:
1514
+ format: png
1515
+ kind: value
1516
+ severity: error
1517
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1518
+ emitters:
1519
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.compression-method\", \"iCCP invalid compression method (#{compression_method}, must be 0)\")"}
1520
+ png.iCCP.crc:
1521
+ format: png
1522
+ kind: integrity
1523
+ severity: error
1524
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1525
+ emitters:
1526
+ - {file: "validators/ancillary/iccp_validator.rb", call: "check_crc(id: \"png.iCCP.crc\")"}
1527
+ png.iCCP.decompress:
1528
+ format: png
1529
+ kind: encoding
1530
+ severity: error
1531
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1532
+ emitters:
1533
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.decompress\", \"iCCP decompression failed: #{e.message}\")"}
1534
+ png.iCCP.min-length:
1535
+ format: png
1536
+ kind: length
1537
+ severity: error
1538
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1539
+ emitters:
1540
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.min-length\", \"iCCP chunk too short (minimum 3 bytes)\")"}
1541
+ png.iCCP.name-consecutive-spaces:
1542
+ format: png
1543
+ kind: encoding
1544
+ severity: error
1545
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1546
+ emitters:
1547
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-consecutive-spaces\", \"iCCP profile name has consecutive spaces\")"}
1548
+ png.iCCP.name-empty:
1549
+ format: png
1550
+ kind: encoding
1551
+ severity: error
1552
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1553
+ emitters:
1554
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-empty\", \"iCCP chunk has empty profile name\")"}
1555
+ png.iCCP.name-leading-space:
1556
+ format: png
1557
+ kind: encoding
1558
+ severity: error
1559
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1560
+ emitters:
1561
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-leading-space\", \"iCCP profile name has leading space\")"}
1562
+ png.iCCP.name-printable:
1563
+ format: png
1564
+ kind: encoding
1565
+ severity: error
1566
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1567
+ emitters:
1568
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-printable\", \"iCCP profile name contains non-printable character (0x#{byte.to_s(16)})\")"}
1569
+ png.iCCP.name-too-long:
1570
+ format: png
1571
+ kind: encoding
1572
+ severity: error
1573
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1574
+ emitters:
1575
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-too-long\", \"iCCP profile name too long (#{profile_name.length}, max #{MAX_PROFILE_NAME_LENGTH})\")"}
1576
+ png.iCCP.name-trailing-space:
1577
+ format: png
1578
+ kind: encoding
1579
+ severity: error
1580
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1581
+ emitters:
1582
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.name-trailing-space\", \"iCCP profile name has trailing space\")"}
1583
+ png.iCCP.null-separator:
1584
+ format: png
1585
+ kind: encoding
1586
+ severity: error
1587
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1588
+ emitters:
1589
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.null-separator\", \"iCCP chunk missing null separator\")"}
1590
+ png.iCCP.profile-min-length:
1591
+ format: png
1592
+ kind: length
1593
+ severity: error
1594
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1595
+ emitters:
1596
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.profile-min-length\", \"iCCP decompressed profile too short (#{decompressed.length} bytes, minimum 128)\")"}
1597
+ png.iCCP.profile-signature:
1598
+ format: png
1599
+ kind: value
1600
+ severity: warning
1601
+ citation: {specification: iso15948, section: "11.3.3.3", title: "iCCP Embedded ICC profile"}
1602
+ emitters:
1603
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_warning(\"png.iCCP.profile-signature\", \"iCCP profile signature mismatch (expected 'acsp', got '#{signature}')\")"}
1604
+ png.iCCP.single-instance:
1605
+ format: png
1606
+ kind: multiplicity
1607
+ severity: error
1608
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1609
+ emitters:
1610
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_error(\"png.iCCP.single-instance\", \"Multiple iCCP chunks (only one allowed)\")"}
1611
+ png.iDOT.before-idat:
1612
+ format: png
1613
+ kind: ordering
1614
+ severity: error
1615
+ citation: {specification: apple_idot, section: "n/a", title: "iDOT (unpublished vendor chunk)"}
1616
+ emitters:
1617
+ - {file: "validators/ancillary/idot_validator.rb", call: "add_error(\"png.iDOT.before-idat\", \"iDOT chunk after IDAT (must be before)\")"}
1618
+ png.iDOT.crc:
1619
+ format: png
1620
+ kind: integrity
1621
+ severity: error
1622
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1623
+ emitters:
1624
+ - {file: "validators/ancillary/idot_validator.rb", call: "check_crc(id: \"png.iDOT.crc\")"}
1625
+ png.iDOT.length:
1626
+ format: png
1627
+ kind: length
1628
+ severity: error
1629
+ citation: {specification: apple_idot, section: "n/a", title: "iDOT (unpublished vendor chunk)"}
1630
+ emitters:
1631
+ - {file: "validators/ancillary/idot_validator.rb", call: "check_length(EXPECTED_LENGTH, id: \"png.iDOT.length\")"}
1632
+ png.iDOT.single-instance:
1633
+ format: png
1634
+ kind: multiplicity
1635
+ severity: error
1636
+ citation: {specification: apple_idot, section: "n/a", title: "iDOT (unpublished vendor chunk)"}
1637
+ emitters:
1638
+ - {file: "validators/ancillary/idot_validator.rb", call: "add_error(\"png.iDOT.single-instance\", \"duplicate iDOT chunk (only one allowed)\")"}
1639
+ png.iTXt.compression-flag:
1640
+ format: png
1641
+ kind: value
1642
+ severity: error
1643
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1644
+ emitters:
1645
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.compression-flag\", \"iTXt invalid compression flag (#{compression_flag}, must be 0 or 1)\")"}
1646
+ png.iTXt.compression-method:
1647
+ format: png
1648
+ kind: value
1649
+ severity: error
1650
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1651
+ emitters:
1652
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.compression-method\", \"iTXt invalid compression method (#{compression_method}, must be 0 when compressed)\")"}
1653
+ png.iTXt.crc:
1654
+ format: png
1655
+ kind: integrity
1656
+ severity: error
1657
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1658
+ emitters:
1659
+ - {file: "validators/ancillary/itxt_validator.rb", call: "check_crc(id: \"png.iTXt.crc\")"}
1660
+ png.iTXt.decompress:
1661
+ format: png
1662
+ kind: encoding
1663
+ severity: error
1664
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1665
+ emitters:
1666
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.decompress\", \"iTXt decompression failed: #{e.message}\")"}
1667
+ png.iTXt.decompressed-text-utf8:
1668
+ format: png
1669
+ kind: encoding
1670
+ severity: error
1671
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1672
+ emitters:
1673
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.decompressed-text-utf8\", \"iTXt decompressed text is not valid UTF-8\")"}
1674
+ png.iTXt.language-tag-ascii:
1675
+ format: png
1676
+ kind: encoding
1677
+ severity: error
1678
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1679
+ emitters:
1680
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.language-tag-ascii\", \"iTXt language tag contains non-ASCII character (0x#{byte.to_s(16)})\")"}
1681
+ png.iTXt.min-length:
1682
+ format: png
1683
+ kind: length
1684
+ severity: error
1685
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1686
+ emitters:
1687
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.min-length\", \"iTXt chunk too short (minimum 5 bytes)\")"}
1688
+ png.iTXt.name-consecutive-spaces:
1689
+ format: png
1690
+ kind: encoding
1691
+ severity: error
1692
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1693
+ emitters:
1694
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-consecutive-spaces\", \"iTXt keyword has consecutive spaces\")"}
1695
+ png.iTXt.name-empty:
1696
+ format: png
1697
+ kind: encoding
1698
+ severity: error
1699
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1700
+ emitters:
1701
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-empty\", \"iTXt chunk has empty keyword\")"}
1702
+ png.iTXt.name-leading-space:
1703
+ format: png
1704
+ kind: encoding
1705
+ severity: error
1706
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1707
+ emitters:
1708
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-leading-space\", \"iTXt keyword has leading space\")"}
1709
+ png.iTXt.name-printable:
1710
+ format: png
1711
+ kind: encoding
1712
+ severity: error
1713
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1714
+ emitters:
1715
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-printable\", \"iTXt keyword contains non-printable character (0x#{byte.to_s(16)})\")"}
1716
+ png.iTXt.name-too-long:
1717
+ format: png
1718
+ kind: encoding
1719
+ severity: error
1720
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1721
+ emitters:
1722
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-too-long\", \"iTXt keyword too long (#{keyword.length}, max #{MAX_KEYWORD_LENGTH})\")"}
1723
+ png.iTXt.name-trailing-space:
1724
+ format: png
1725
+ kind: encoding
1726
+ severity: error
1727
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
1728
+ emitters:
1729
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.name-trailing-space\", \"iTXt keyword has trailing space\")"}
1730
+ png.iTXt.null-separators:
1731
+ format: png
1732
+ kind: encoding
1733
+ severity: error
1734
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1735
+ emitters:
1736
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.null-separators\", \"iTXt chunk missing null separators (found #{nulls.length}, need 3)\")"}
1737
+ png.iTXt.text-utf8:
1738
+ format: png
1739
+ kind: encoding
1740
+ severity: error
1741
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1742
+ emitters:
1743
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.text-utf8\", \"iTXt text is not valid UTF-8\")"}
1744
+ png.iTXt.translated-keyword-utf8:
1745
+ format: png
1746
+ kind: encoding
1747
+ severity: error
1748
+ citation: {specification: iso15948, section: "11.3.4.5", title: "iTXt International textual data"}
1749
+ emitters:
1750
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_error(\"png.iTXt.translated-keyword-utf8\", \"iTXt translated keyword is not valid UTF-8\")"}
1751
+ png.mDCv.before-idat:
1752
+ format: png
1753
+ kind: ordering
1754
+ severity: error
1755
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1756
+ emitters:
1757
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.before-idat\", \"mDCv must appear before IDAT\")"}
1758
+ png.mDCv.before-plte:
1759
+ format: png
1760
+ kind: ordering
1761
+ severity: error
1762
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1763
+ emitters:
1764
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.before-plte\", \"mDCv must appear before PLTE\")"}
1765
+ png.mDCv.coordinate-range:
1766
+ format: png
1767
+ kind: value
1768
+ severity: error
1769
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1770
+ emitters:
1771
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "check_range(value, 0, MAX_COORDINATE, name, id: \"png.mDCv.coordinate-range\")"}
1772
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.coordinate-range\", \"#{name} out of range: #{value} (must be 0-#{MAX_COORDINATE})\")"}
1773
+ png.mDCv.length:
1774
+ format: png
1775
+ kind: length
1776
+ severity: error
1777
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1778
+ emitters:
1779
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "check_length(24, id: \"png.mDCv.length\")"}
1780
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.length\", \"invalid chunk length: #{chunk.chunk_data.bytesize} bytes\")"}
1781
+ png.mDCv.luminance-order:
1782
+ format: png
1783
+ kind: value
1784
+ severity: error
1785
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1786
+ emitters:
1787
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.luminance-order\", \"maximum luminance (#{format_luminance(max_lum)}) must be > minimum luminance (#{format_luminance(min_lum)})\")"}
1788
+ png.mDCv.max-luminance-high:
1789
+ format: png
1790
+ kind: value
1791
+ severity: warning
1792
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1793
+ emitters:
1794
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_warning(\"png.mDCv.max-luminance-high\", \"maximum luminance very high: #{format_luminance(max_lum)} (> 10,000 cd/m²)\")"}
1795
+ png.mDCv.max-luminance-zero:
1796
+ format: png
1797
+ kind: value
1798
+ severity: warning
1799
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1800
+ emitters:
1801
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_warning(\"png.mDCv.max-luminance-zero\", \"maximum luminance is 0 cd/m²\")"}
1802
+ png.mDCv.primary-sum:
1803
+ format: png
1804
+ kind: value
1805
+ severity: warning
1806
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1807
+ emitters:
1808
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_warning(\"png.mDCv.primary-sum\", \"#{color} primary coordinates sum > 1.0 (x=#{format_coordinate(x_value)}, y=#{format_coordinate(y_value)})\")"}
1809
+ png.mDCv.single-instance:
1810
+ format: png
1811
+ kind: multiplicity
1812
+ severity: error
1813
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1814
+ emitters:
1815
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_error(\"png.mDCv.single-instance\", \"duplicate mDCV chunk (only one allowed)\")"}
1816
+ png.mDCv.white-point-sum:
1817
+ format: png
1818
+ kind: value
1819
+ severity: warning
1820
+ citation: {specification: png3, section: "11.3.2.7", title: "mDCV Mastering Display Color Volume"}
1821
+ emitters:
1822
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_warning(\"png.mDCv.white-point-sum\", \"white point coordinates sum > 1.0 (x=#{format_coordinate(x_value)}, y=#{format_coordinate(y_value)})\")"}
1823
+ png.oFFs.before-idat:
1824
+ format: png
1825
+ kind: ordering
1826
+ severity: error
1827
+ citation: {specification: pngext, section: "3.1", title: "oFFs Image offset"}
1828
+ emitters:
1829
+ - {file: "validators/ancillary/offs_validator.rb", call: "add_error(\"png.oFFs.before-idat\", \"oFFs chunk after IDAT chunk\")"}
1830
+ png.oFFs.crc:
1831
+ format: png
1832
+ kind: integrity
1833
+ severity: error
1834
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1835
+ emitters:
1836
+ - {file: "validators/ancillary/offs_validator.rb", call: "check_crc(id: \"png.oFFs.crc\")"}
1837
+ png.oFFs.length:
1838
+ format: png
1839
+ kind: length
1840
+ severity: error
1841
+ citation: {specification: pngext, section: "3.1", title: "oFFs Image offset"}
1842
+ emitters:
1843
+ - {file: "validators/ancillary/offs_validator.rb", call: "add_error(\"png.oFFs.length\", \"oFFs chunk wrong length (#{actual_length} bytes, expected #{EXPECTED_LENGTH})\")"}
1844
+ png.oFFs.single-instance:
1845
+ format: png
1846
+ kind: multiplicity
1847
+ severity: error
1848
+ citation: {specification: pngext, section: "3.1", title: "oFFs Image offset"}
1849
+ emitters:
1850
+ - {file: "validators/ancillary/offs_validator.rb", call: "add_error(\"png.oFFs.single-instance\", \"Multiple oFFs chunks (only one allowed)\")"}
1851
+ png.oFFs.unit:
1852
+ format: png
1853
+ kind: value
1854
+ severity: error
1855
+ citation: {specification: pngext, section: "3.1", title: "oFFs Image offset"}
1856
+ emitters:
1857
+ - {file: "validators/ancillary/offs_validator.rb", call: "add_error(\"png.oFFs.unit\", \"oFFs invalid unit specifier (#{unit}, must be 0 or 1)\")"}
1858
+ png.pCAL.before-idat:
1859
+ format: png
1860
+ kind: ordering
1861
+ severity: error
1862
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1863
+ emitters:
1864
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.before-idat\", \"pCAL chunk after IDAT chunk\")"}
1865
+ png.pCAL.crc:
1866
+ format: png
1867
+ kind: integrity
1868
+ severity: error
1869
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1870
+ emitters:
1871
+ - {file: "validators/ancillary/pcal_validator.rb", call: "check_crc(id: \"png.pCAL.crc\")"}
1872
+ png.pCAL.equation-type:
1873
+ format: png
1874
+ kind: value
1875
+ severity: error
1876
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1877
+ emitters:
1878
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.equation-type\", \"pCAL invalid equation type (#{equation_type}, must be 0-3)\")"}
1879
+ png.pCAL.min-length:
1880
+ format: png
1881
+ kind: length
1882
+ severity: error
1883
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1884
+ emitters:
1885
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.min-length\", \"pCAL chunk too short (minimum 12 bytes)\")"}
1886
+ png.pCAL.name-consecutive-spaces:
1887
+ format: png
1888
+ kind: encoding
1889
+ severity: error
1890
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1891
+ emitters:
1892
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-consecutive-spaces\", \"pCAL calibration name has consecutive spaces\")"}
1893
+ png.pCAL.name-empty:
1894
+ format: png
1895
+ kind: encoding
1896
+ severity: error
1897
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1898
+ emitters:
1899
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-empty\", \"pCAL chunk has empty calibration name\")"}
1900
+ png.pCAL.name-leading-space:
1901
+ format: png
1902
+ kind: encoding
1903
+ severity: error
1904
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1905
+ emitters:
1906
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-leading-space\", \"pCAL calibration name has leading space\")"}
1907
+ png.pCAL.name-printable:
1908
+ format: png
1909
+ kind: encoding
1910
+ severity: error
1911
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1912
+ emitters:
1913
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-printable\", \"pCAL calibration name contains non-printable character (0x#{byte.to_s(16)})\")"}
1914
+ png.pCAL.name-too-long:
1915
+ format: png
1916
+ kind: encoding
1917
+ severity: error
1918
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1919
+ emitters:
1920
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-too-long\", \"pCAL calibration name too long (#{cal_name.length}, max #{MAX_CALIBRATION_NAME_LENGTH})\")"}
1921
+ png.pCAL.name-trailing-space:
1922
+ format: png
1923
+ kind: encoding
1924
+ severity: error
1925
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1926
+ emitters:
1927
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.name-trailing-space\", \"pCAL calibration name has trailing space\")"}
1928
+ png.pCAL.null-separator:
1929
+ format: png
1930
+ kind: encoding
1931
+ severity: error
1932
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1933
+ emitters:
1934
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.null-separator\", \"pCAL chunk missing null separator\")"}
1935
+ png.pCAL.parameter-count:
1936
+ format: png
1937
+ kind: consistency
1938
+ severity: error
1939
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1940
+ emitters:
1941
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.parameter-count\", \"pCAL found #{params_found} parameters, expected #{num_params}\")"}
1942
+ png.pCAL.parameter-count-mismatch:
1943
+ format: png
1944
+ kind: consistency
1945
+ severity: error
1946
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1947
+ emitters:
1948
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.parameter-count-mismatch\", \"pCAL parameter count mismatch (#{num_params}, expected #{expected_params} for equation type #{equation_type})\")"}
1949
+ png.pCAL.parameter-format:
1950
+ format: png
1951
+ kind: encoding
1952
+ severity: error
1953
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1954
+ emitters:
1955
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.parameter-format\", \"pCAL invalid parameter #{params_found + 1} format: '#{param_str}'\")"}
1956
+ png.pCAL.parameter-terminator:
1957
+ format: png
1958
+ kind: encoding
1959
+ severity: error
1960
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1961
+ emitters:
1962
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.parameter-terminator\", \"pCAL missing parameter #{params_found + 1} null terminator\")"}
1963
+ png.pCAL.single-instance:
1964
+ format: png
1965
+ kind: multiplicity
1966
+ severity: error
1967
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1968
+ emitters:
1969
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.single-instance\", \"duplicate pCAL chunk (only one allowed)\")"}
1970
+ png.pCAL.unit-terminator:
1971
+ format: png
1972
+ kind: encoding
1973
+ severity: error
1974
+ citation: {specification: pngext, section: "3.2", title: "pCAL Calibration of pixel values"}
1975
+ emitters:
1976
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_error(\"png.pCAL.unit-terminator\", \"pCAL missing unit name null terminator\")"}
1977
+ png.pHYs.before-idat:
1978
+ format: png
1979
+ kind: ordering
1980
+ severity: error
1981
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
1982
+ emitters:
1983
+ - {file: "validators/ancillary/phys_validator.rb", call: "add_error(\"png.pHYs.before-idat\", \"pHYs chunk after IDAT (must be before)\")"}
1984
+ png.pHYs.crc:
1985
+ format: png
1986
+ kind: integrity
1987
+ severity: error
1988
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
1989
+ emitters:
1990
+ - {file: "validators/ancillary/phys_validator.rb", call: "check_crc(id: \"png.pHYs.crc\")"}
1991
+ png.pHYs.length:
1992
+ format: png
1993
+ kind: length
1994
+ severity: error
1995
+ citation: {specification: iso15948, section: "11.3.5.3", title: "pHYs Physical pixel dimensions"}
1996
+ emitters:
1997
+ - {file: "validators/ancillary/phys_validator.rb", call: "check_length(9, id: \"png.pHYs.length\")"}
1998
+ png.pHYs.single-instance:
1999
+ format: png
2000
+ kind: multiplicity
2001
+ severity: error
2002
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2003
+ emitters:
2004
+ - {file: "validators/ancillary/phys_validator.rb", call: "add_error(\"png.pHYs.single-instance\", \"duplicate pHYs chunk\")"}
2005
+ png.pHYs.unit-specifier:
2006
+ format: png
2007
+ kind: value
2008
+ severity: error
2009
+ citation: {specification: iso15948, section: "11.3.5.3", title: "pHYs Physical pixel dimensions"}
2010
+ emitters:
2011
+ - {file: "validators/ancillary/phys_validator.rb", call: "check_enum(unit, [UNIT_UNKNOWN, UNIT_METER], \"unit specifier\", id: \"png.pHYs.unit-specifier\")"}
2012
+ png.sBIT.before-idat:
2013
+ format: png
2014
+ kind: ordering
2015
+ severity: error
2016
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2017
+ emitters:
2018
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_error(\"png.sBIT.before-idat\", \"sBIT chunk after IDAT (must be before)\")"}
2019
+ png.sBIT.before-plte:
2020
+ format: png
2021
+ kind: ordering
2022
+ severity: warning
2023
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2024
+ emitters:
2025
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_warning(\"png.sBIT.before-plte\", \"sBIT chunk after PLTE (should be before)\")"}
2026
+ png.sBIT.bits-exceed-depth:
2027
+ format: png
2028
+ kind: value
2029
+ severity: error
2030
+ citation: {specification: iso15948, section: "11.3.3.4", title: "sBIT Significant bits"}
2031
+ emitters:
2032
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_error(\"png.sBIT.bits-exceed-depth\", \"#{name} significant bits (#{value}) exceeds sample depth (#{max_depth})\")"}
2033
+ png.sBIT.bits-zero:
2034
+ format: png
2035
+ kind: value
2036
+ severity: error
2037
+ citation: {specification: iso15948, section: "11.3.3.4", title: "sBIT Significant bits"}
2038
+ emitters:
2039
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_error(\"png.sBIT.bits-zero\", \"#{name} significant bits cannot be 0\")"}
2040
+ png.sBIT.crc:
2041
+ format: png
2042
+ kind: integrity
2043
+ severity: error
2044
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2045
+ emitters:
2046
+ - {file: "validators/ancillary/sbit_validator.rb", call: "check_crc(id: \"png.sBIT.crc\")"}
2047
+ png.sBIT.length:
2048
+ format: png
2049
+ kind: length
2050
+ severity: error
2051
+ citation: {specification: iso15948, section: "11.3.3.4", title: "sBIT Significant bits"}
2052
+ emitters:
2053
+ - {file: "validators/ancillary/sbit_validator.rb", call: "check_length(expected_length, id: \"png.sBIT.length\")"}
2054
+ png.sBIT.single-instance:
2055
+ format: png
2056
+ kind: multiplicity
2057
+ severity: error
2058
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2059
+ emitters:
2060
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_error(\"png.sBIT.single-instance\", \"duplicate sBIT chunk\")"}
2061
+ png.sCAL.before-idat:
2062
+ format: png
2063
+ kind: ordering
2064
+ severity: error
2065
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2066
+ emitters:
2067
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.before-idat\", \"sCAL chunk after IDAT chunk\")"}
2068
+ png.sCAL.crc:
2069
+ format: png
2070
+ kind: integrity
2071
+ severity: error
2072
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2073
+ emitters:
2074
+ - {file: "validators/ancillary/scal_validator.rb", call: "check_crc(id: \"png.sCAL.crc\")"}
2075
+ png.sCAL.height-format:
2076
+ format: png
2077
+ kind: encoding
2078
+ severity: error
2079
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2080
+ emitters:
2081
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.height-format\", \"sCAL invalid height format: '#{height_str}'\")"}
2082
+ png.sCAL.height-positive:
2083
+ format: png
2084
+ kind: value
2085
+ severity: error
2086
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2087
+ emitters:
2088
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.height-positive\", \"sCAL height must be positive (got #{height})\")"}
2089
+ png.sCAL.min-length:
2090
+ format: png
2091
+ kind: length
2092
+ severity: error
2093
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2094
+ emitters:
2095
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.min-length\", \"sCAL chunk too short (minimum 5 bytes)\")"}
2096
+ png.sCAL.null-separators:
2097
+ format: png
2098
+ kind: encoding
2099
+ severity: error
2100
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2101
+ emitters:
2102
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.null-separators\", \"sCAL chunk missing null separators (found #{nulls.length}, need 2)\")"}
2103
+ png.sCAL.single-instance:
2104
+ format: png
2105
+ kind: multiplicity
2106
+ severity: error
2107
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2108
+ emitters:
2109
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.single-instance\", \"duplicate sCAL chunk (only one allowed)\")"}
2110
+ png.sCAL.unit:
2111
+ format: png
2112
+ kind: value
2113
+ severity: error
2114
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2115
+ emitters:
2116
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.unit\", \"sCAL invalid unit specifier (#{unit}, must be 1 or 2)\")"}
2117
+ png.sCAL.width-format:
2118
+ format: png
2119
+ kind: encoding
2120
+ severity: error
2121
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2122
+ emitters:
2123
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.width-format\", \"sCAL invalid width format: '#{width_str}'\")"}
2124
+ png.sCAL.width-positive:
2125
+ format: png
2126
+ kind: value
2127
+ severity: error
2128
+ citation: {specification: pngext, section: "3.3", title: "sCAL Physical scale of image subject"}
2129
+ emitters:
2130
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_error(\"png.sCAL.width-positive\", \"sCAL width must be positive (got #{width})\")"}
2131
+ png.sPLT.before-idat:
2132
+ format: png
2133
+ kind: ordering
2134
+ severity: error
2135
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2136
+ emitters:
2137
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.before-idat\", \"sPLT chunk after IDAT chunk\")"}
2138
+ png.sPLT.crc:
2139
+ format: png
2140
+ kind: integrity
2141
+ severity: error
2142
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2143
+ emitters:
2144
+ - {file: "validators/ancillary/splt_validator.rb", call: "check_crc(id: \"png.sPLT.crc\")"}
2145
+ png.sPLT.entries-length:
2146
+ format: png
2147
+ kind: length
2148
+ severity: error
2149
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2150
+ emitters:
2151
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.entries-length\", \"sPLT entries data length (#{entries_data.length}) not a multiple of entry size (#{entry_size})\")"}
2152
+ png.sPLT.entries-none:
2153
+ format: png
2154
+ kind: value
2155
+ severity: error
2156
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2157
+ emitters:
2158
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.entries-none\", \"sPLT chunk has no palette entries\")"}
2159
+ png.sPLT.min-length:
2160
+ format: png
2161
+ kind: length
2162
+ severity: error
2163
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2164
+ emitters:
2165
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.min-length\", \"sPLT chunk too short (minimum 3 bytes)\")"}
2166
+ png.sPLT.name-consecutive-spaces:
2167
+ format: png
2168
+ kind: encoding
2169
+ severity: error
2170
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2171
+ emitters:
2172
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-consecutive-spaces\", \"sPLT palette name has consecutive spaces\")"}
2173
+ png.sPLT.name-empty:
2174
+ format: png
2175
+ kind: encoding
2176
+ severity: error
2177
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2178
+ emitters:
2179
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-empty\", \"sPLT chunk has empty palette name\")"}
2180
+ png.sPLT.name-leading-space:
2181
+ format: png
2182
+ kind: encoding
2183
+ severity: error
2184
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2185
+ emitters:
2186
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-leading-space\", \"sPLT palette name has leading space\")"}
2187
+ png.sPLT.name-printable:
2188
+ format: png
2189
+ kind: encoding
2190
+ severity: error
2191
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2192
+ emitters:
2193
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-printable\", \"sPLT palette name contains non-printable character (0x#{byte.to_s(16)})\")"}
2194
+ png.sPLT.name-too-long:
2195
+ format: png
2196
+ kind: encoding
2197
+ severity: error
2198
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2199
+ emitters:
2200
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-too-long\", \"sPLT palette name too long (#{palette_name.length}, max #{MAX_PALETTE_NAME_LENGTH})\")"}
2201
+ png.sPLT.name-trailing-space:
2202
+ format: png
2203
+ kind: encoding
2204
+ severity: error
2205
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2206
+ emitters:
2207
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.name-trailing-space\", \"sPLT palette name has trailing space\")"}
2208
+ png.sPLT.null-separator:
2209
+ format: png
2210
+ kind: encoding
2211
+ severity: error
2212
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2213
+ emitters:
2214
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.null-separator\", \"sPLT chunk missing null separator\")"}
2215
+ png.sPLT.sample-depth:
2216
+ format: png
2217
+ kind: value
2218
+ severity: error
2219
+ citation: {specification: iso15948, section: "11.3.5.4", title: "sPLT Suggested palette"}
2220
+ emitters:
2221
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_error(\"png.sPLT.sample-depth\", \"sPLT invalid sample depth (#{sample_depth}, must be 8 or 16)\")"}
2222
+ png.sRGB.before-idat:
2223
+ format: png
2224
+ kind: ordering
2225
+ severity: error
2226
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2227
+ emitters:
2228
+ - {file: "validators/ancillary/srgb_validator.rb", call: "add_error(\"png.sRGB.before-idat\", \"sRGB chunk after IDAT (must be before)\")"}
2229
+ png.sRGB.before-plte:
2230
+ format: png
2231
+ kind: ordering
2232
+ severity: warning
2233
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2234
+ emitters:
2235
+ - {file: "validators/ancillary/srgb_validator.rb", call: "add_warning(\"png.sRGB.before-plte\", \"sRGB chunk after PLTE (should be before)\")"}
2236
+ png.sRGB.crc:
2237
+ format: png
2238
+ kind: integrity
2239
+ severity: error
2240
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2241
+ emitters:
2242
+ - {file: "validators/ancillary/srgb_validator.rb", call: "check_crc(id: \"png.sRGB.crc\")"}
2243
+ png.sRGB.gama-consistency:
2244
+ format: png
2245
+ kind: consistency
2246
+ severity: warning
2247
+ citation: {specification: iso15948, section: "11.3.3.5", title: "sRGB Standard RGB colour space"}
2248
+ emitters:
2249
+ - {file: "validators/ancillary/srgb_validator.rb", call: "add_warning(\"png.sRGB.gama-consistency\", \"sRGB chunk present but gAMA is #{actual_gamma} (should be 2.2 for sRGB)\")"}
2250
+ png.sRGB.length:
2251
+ format: png
2252
+ kind: length
2253
+ severity: error
2254
+ citation: {specification: iso15948, section: "11.3.3.5", title: "sRGB Standard RGB colour space"}
2255
+ emitters:
2256
+ - {file: "validators/ancillary/srgb_validator.rb", call: "check_length(1, id: \"png.sRGB.length\")"}
2257
+ png.sRGB.rendering-intent:
2258
+ format: png
2259
+ kind: value
2260
+ severity: error
2261
+ citation: {specification: iso15948, section: "11.3.3.5", title: "sRGB Standard RGB colour space"}
2262
+ emitters:
2263
+ - {file: "validators/ancillary/srgb_validator.rb", call: "check_enum(intent, INTENT_NAMES.keys, \"rendering intent\", id: \"png.sRGB.rendering-intent\")"}
2264
+ png.sRGB.single-instance:
2265
+ format: png
2266
+ kind: multiplicity
2267
+ severity: error
2268
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2269
+ emitters:
2270
+ - {file: "validators/ancillary/srgb_validator.rb", call: "add_error(\"png.sRGB.single-instance\", \"duplicate sRGB chunk\")"}
2271
+ png.sTER.before-idat:
2272
+ format: png
2273
+ kind: ordering
2274
+ severity: error
2275
+ citation: {specification: pngext, section: "3.6", title: "sTER Indicator of Stereo Image"}
2276
+ emitters:
2277
+ - {file: "validators/ancillary/ster_validator.rb", call: "add_error(\"png.sTER.before-idat\", \"sTER chunk after IDAT chunk\")"}
2278
+ png.sTER.crc:
2279
+ format: png
2280
+ kind: integrity
2281
+ severity: error
2282
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2283
+ emitters:
2284
+ - {file: "validators/ancillary/ster_validator.rb", call: "check_crc(id: \"png.sTER.crc\")"}
2285
+ png.sTER.length:
2286
+ format: png
2287
+ kind: length
2288
+ severity: error
2289
+ citation: {specification: pngext, section: "3.6", title: "sTER Indicator of Stereo Image"}
2290
+ emitters:
2291
+ - {file: "validators/ancillary/ster_validator.rb", call: "add_error(\"png.sTER.length\", \"sTER chunk wrong length (#{actual_length} byte(s), expected #{EXPECTED_LENGTH})\")"}
2292
+ png.sTER.mode:
2293
+ format: png
2294
+ kind: value
2295
+ severity: error
2296
+ citation: {specification: pngext, section: "3.6", title: "sTER Indicator of Stereo Image"}
2297
+ emitters:
2298
+ - {file: "validators/ancillary/ster_validator.rb", call: "add_error(\"png.sTER.mode\", \"sTER invalid mode (#{mode}, must be 0 or 1)\")"}
2299
+ png.sTER.single-instance:
2300
+ format: png
2301
+ kind: multiplicity
2302
+ severity: error
2303
+ citation: {specification: pngext, section: "3.6", title: "sTER Indicator of Stereo Image"}
2304
+ emitters:
2305
+ - {file: "validators/ancillary/ster_validator.rb", call: "add_error(\"png.sTER.single-instance\", \"Multiple sTER chunks (only one allowed)\")"}
2306
+ png.tEXt.crc:
2307
+ format: png
2308
+ kind: integrity
2309
+ severity: error
2310
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2311
+ emitters:
2312
+ - {file: "validators/ancillary/text_validator.rb", call: "check_crc(id: \"png.tEXt.crc\")"}
2313
+ png.tEXt.min-length:
2314
+ format: png
2315
+ kind: length
2316
+ severity: error
2317
+ citation: {specification: iso15948, section: "11.3.4.3", title: "tEXt Textual data"}
2318
+ emitters:
2319
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.min-length\", \"tEXt chunk too short (minimum 2 bytes)\")"}
2320
+ png.tEXt.name-consecutive-spaces:
2321
+ format: png
2322
+ kind: encoding
2323
+ severity: error
2324
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2325
+ emitters:
2326
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-consecutive-spaces\", \"tEXt keyword has consecutive spaces\")"}
2327
+ png.tEXt.name-empty:
2328
+ format: png
2329
+ kind: encoding
2330
+ severity: error
2331
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2332
+ emitters:
2333
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-empty\", \"tEXt chunk has empty keyword\")"}
2334
+ png.tEXt.name-leading-space:
2335
+ format: png
2336
+ kind: encoding
2337
+ severity: error
2338
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2339
+ emitters:
2340
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-leading-space\", \"tEXt keyword has leading space\")"}
2341
+ png.tEXt.name-printable:
2342
+ format: png
2343
+ kind: encoding
2344
+ severity: error
2345
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2346
+ emitters:
2347
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-printable\", \"tEXt keyword contains non-printable character (0x#{byte.to_s(16)})\")"}
2348
+ png.tEXt.name-too-long:
2349
+ format: png
2350
+ kind: encoding
2351
+ severity: error
2352
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2353
+ emitters:
2354
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-too-long\", \"tEXt keyword too long (#{keyword.length}, max #{MAX_KEYWORD_LENGTH})\")"}
2355
+ png.tEXt.name-trailing-space:
2356
+ format: png
2357
+ kind: encoding
2358
+ severity: error
2359
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2360
+ emitters:
2361
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.name-trailing-space\", \"tEXt keyword has trailing space\")"}
2362
+ png.tEXt.null-separator:
2363
+ format: png
2364
+ kind: encoding
2365
+ severity: error
2366
+ citation: {specification: iso15948, section: "11.3.4.3", title: "tEXt Textual data"}
2367
+ emitters:
2368
+ - {file: "validators/ancillary/text_validator.rb", call: "add_error(\"png.tEXt.null-separator\", \"tEXt chunk missing null separator\")"}
2369
+ png.tIME.crc:
2370
+ format: png
2371
+ kind: integrity
2372
+ severity: error
2373
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2374
+ emitters:
2375
+ - {file: "validators/ancillary/time_validator.rb", call: "check_crc(id: \"png.tIME.crc\")"}
2376
+ png.tIME.day:
2377
+ format: png
2378
+ kind: value
2379
+ severity: error
2380
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2381
+ emitters:
2382
+ - {file: "validators/ancillary/time_validator.rb", call: "check_range(day, 1, 31, \"day\", id: \"png.tIME.day\")"}
2383
+ png.tIME.day-of-month:
2384
+ format: png
2385
+ kind: value
2386
+ severity: error
2387
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2388
+ emitters:
2389
+ - {file: "validators/ancillary/time_validator.rb", call: "add_error(\"png.tIME.day-of-month\", \"invalid day (#{day}) for month #{month}\")"}
2390
+ png.tIME.hour:
2391
+ format: png
2392
+ kind: value
2393
+ severity: error
2394
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2395
+ emitters:
2396
+ - {file: "validators/ancillary/time_validator.rb", call: "check_range(hour, 0, 23, \"hour\", id: \"png.tIME.hour\")"}
2397
+ png.tIME.length:
2398
+ format: png
2399
+ kind: length
2400
+ severity: error
2401
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2402
+ emitters:
2403
+ - {file: "validators/ancillary/time_validator.rb", call: "check_length(7, id: \"png.tIME.length\")"}
2404
+ png.tIME.minute:
2405
+ format: png
2406
+ kind: value
2407
+ severity: error
2408
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2409
+ emitters:
2410
+ - {file: "validators/ancillary/time_validator.rb", call: "check_range(minute, 0, 59, \"minute\", id: \"png.tIME.minute\")"}
2411
+ png.tIME.month:
2412
+ format: png
2413
+ kind: value
2414
+ severity: error
2415
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2416
+ emitters:
2417
+ - {file: "validators/ancillary/time_validator.rb", call: "check_range(month, 1, 12, \"month\", id: \"png.tIME.month\")"}
2418
+ png.tIME.second:
2419
+ format: png
2420
+ kind: value
2421
+ severity: error
2422
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2423
+ emitters:
2424
+ - {file: "validators/ancillary/time_validator.rb", call: "check_range(second, 0, 60, \"second\", id: \"png.tIME.second\")"}
2425
+ png.tIME.single-instance:
2426
+ format: png
2427
+ kind: multiplicity
2428
+ severity: error
2429
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2430
+ emitters:
2431
+ - {file: "validators/ancillary/time_validator.rb", call: "add_error(\"png.tIME.single-instance\", \"duplicate tIME chunk\")"}
2432
+ png.tIME.year:
2433
+ format: png
2434
+ kind: value
2435
+ severity: error
2436
+ citation: {specification: iso15948, section: "11.3.6.1", title: "tIME Image last-modification time"}
2437
+ emitters:
2438
+ - {file: "validators/ancillary/time_validator.rb", call: "add_error(\"png.tIME.year\", \"invalid tIME year (before PNG existed!) (#{year})\")"}
2439
+ png.tRNS.after-plte:
2440
+ format: png
2441
+ kind: ordering
2442
+ severity: error
2443
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2444
+ emitters:
2445
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.after-plte\", \"tRNS chunk before PLTE for indexed-color image\")"}
2446
+ png.tRNS.before-idat:
2447
+ format: png
2448
+ kind: ordering
2449
+ severity: error
2450
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2451
+ emitters:
2452
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.before-idat\", \"tRNS chunk after IDAT (must be before)\")"}
2453
+ png.tRNS.color-type-alpha:
2454
+ format: png
2455
+ kind: consistency
2456
+ severity: error
2457
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2458
+ emitters:
2459
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.color-type-alpha\", \"tRNS chunk not allowed for color type with alpha channel\")"}
2460
+ png.tRNS.color-type-unknown:
2461
+ format: png
2462
+ kind: consistency
2463
+ severity: warning
2464
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2465
+ emitters:
2466
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_warning(\"png.tRNS.color-type-unknown\", \"tRNS chunk present but color type unknown\")"}
2467
+ png.tRNS.crc:
2468
+ format: png
2469
+ kind: integrity
2470
+ severity: error
2471
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2472
+ emitters:
2473
+ - {file: "validators/ancillary/trns_validator.rb", call: "check_crc(id: \"png.tRNS.crc\")"}
2474
+ png.tRNS.entries-exceed-palette:
2475
+ format: png
2476
+ kind: consistency
2477
+ severity: error
2478
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2479
+ emitters:
2480
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.entries-exceed-palette\", \"tRNS has more entries than palette (#{length} > #{palette_entries})\")"}
2481
+ png.tRNS.indexed-length:
2482
+ format: png
2483
+ kind: length
2484
+ severity: error
2485
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2486
+ emitters:
2487
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.indexed-length\", \"invalid tRNS length for indexed-color (#{length}, must be 1-256)\")"}
2488
+ png.tRNS.indexed-needs-plte:
2489
+ format: png
2490
+ kind: consistency
2491
+ severity: error
2492
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2493
+ emitters:
2494
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.indexed-needs-plte\", \"tRNS chunk for indexed-color without PLTE chunk\")"}
2495
+ png.tRNS.length:
2496
+ format: png
2497
+ kind: length
2498
+ severity: error
2499
+ citation: {specification: iso15948, section: "11.3.2.1", title: "tRNS Transparency"}
2500
+ emitters:
2501
+ - {file: "validators/ancillary/trns_validator.rb", call: "check_length(2, id: \"png.tRNS.length\")"}
2502
+ - {file: "validators/ancillary/trns_validator.rb", call: "check_length(6, id: \"png.tRNS.length\")"}
2503
+ png.tRNS.single-instance:
2504
+ format: png
2505
+ kind: multiplicity
2506
+ severity: error
2507
+ citation: {specification: iso15948, section: "5.6", title: "Chunk ordering"}
2508
+ emitters:
2509
+ - {file: "validators/ancillary/trns_validator.rb", call: "add_error(\"png.tRNS.single-instance\", \"duplicate tRNS chunk\")"}
2510
+ png.zTXt.compression-method:
2511
+ format: png
2512
+ kind: value
2513
+ severity: error
2514
+ citation: {specification: iso15948, section: "11.3.4.4", title: "zTXt Compressed textual data"}
2515
+ emitters:
2516
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.compression-method\", \"zTXt invalid compression method (#{compression_method}, must be 0)\")"}
2517
+ png.zTXt.crc:
2518
+ format: png
2519
+ kind: integrity
2520
+ severity: error
2521
+ citation: {specification: iso15948, section: "5.5", title: "Cyclic Redundancy Code algorithm"}
2522
+ emitters:
2523
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "check_crc(id: \"png.zTXt.crc\")"}
2524
+ png.zTXt.decompress:
2525
+ format: png
2526
+ kind: encoding
2527
+ severity: error
2528
+ citation: {specification: iso15948, section: "11.3.4.4", title: "zTXt Compressed textual data"}
2529
+ emitters:
2530
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.decompress\", \"zTXt decompression failed: #{e.message}\")"}
2531
+ png.zTXt.min-length:
2532
+ format: png
2533
+ kind: length
2534
+ severity: error
2535
+ citation: {specification: iso15948, section: "11.3.4.4", title: "zTXt Compressed textual data"}
2536
+ emitters:
2537
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.min-length\", \"zTXt chunk too short (minimum 3 bytes)\")"}
2538
+ png.zTXt.name-consecutive-spaces:
2539
+ format: png
2540
+ kind: encoding
2541
+ severity: error
2542
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2543
+ emitters:
2544
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-consecutive-spaces\", \"zTXt keyword has consecutive spaces\")"}
2545
+ png.zTXt.name-empty:
2546
+ format: png
2547
+ kind: encoding
2548
+ severity: error
2549
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2550
+ emitters:
2551
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-empty\", \"zTXt chunk has empty keyword\")"}
2552
+ png.zTXt.name-leading-space:
2553
+ format: png
2554
+ kind: encoding
2555
+ severity: error
2556
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2557
+ emitters:
2558
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-leading-space\", \"zTXt keyword has leading space\")"}
2559
+ png.zTXt.name-printable:
2560
+ format: png
2561
+ kind: encoding
2562
+ severity: error
2563
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2564
+ emitters:
2565
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-printable\", \"zTXt keyword contains non-printable character (0x#{byte.to_s(16)})\")"}
2566
+ png.zTXt.name-too-long:
2567
+ format: png
2568
+ kind: encoding
2569
+ severity: error
2570
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2571
+ emitters:
2572
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-too-long\", \"zTXt keyword too long (#{keyword.length}, max #{MAX_KEYWORD_LENGTH})\")"}
2573
+ png.zTXt.name-trailing-space:
2574
+ format: png
2575
+ kind: encoding
2576
+ severity: error
2577
+ citation: {specification: iso15948, section: "11.3.4.2", title: "Keywords and text strings"}
2578
+ emitters:
2579
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.name-trailing-space\", \"zTXt keyword has trailing space\")"}
2580
+ png.zTXt.null-separator:
2581
+ format: png
2582
+ kind: encoding
2583
+ severity: error
2584
+ citation: {specification: iso15948, section: "11.3.4.4", title: "zTXt Compressed textual data"}
2585
+ emitters:
2586
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_error(\"png.zTXt.null-separator\", \"zTXt chunk missing null separator\")"}
2587
+ profile.chunk.prohibited:
2588
+ format: png
2589
+ kind: policy
2590
+ severity: error
2591
+ citation: {specification: profile, section: "prohibited_chunks", title: "Prohibited chunks"}
2592
+ emitters:
2593
+ - {file: "services/profile_manager.rb", call: "error_result(\"profile.chunk.prohibited\", \"#{chunk_type} chunk prohibited in #{profile[:name]} profile\", **context)"}
2594
+ profile.chunk.undefined:
2595
+ format: png
2596
+ kind: policy
2597
+ severity: warning
2598
+ citation: {specification: profile, section: "required_chunks / optional_chunks", title: "Chunks undefined by the profile"}
2599
+ emitters:
2600
+ - {file: "services/profile_manager.rb", call: "warning_result(\"profile.chunk.undefined\", \"#{chunk_type} chunk not defined in #{profile[:name]} profile\", **context)"}
2601
+ profile.chunk.unknown-profile:
2602
+ format: png
2603
+ kind: policy
2604
+ severity: error
2605
+ citation: {specification: profile, section: "unknown-profile", title: "Profile lookup"}
2606
+ emitters:
2607
+ - {file: "services/profile_manager.rb", call: "error_result(\"profile.chunk.unknown-profile\", \"Unknown profile: #{profile_name}\", chunk_type: chunk_type, profile: profile_name )"}
2608
+ profile.file.prohibited-present:
2609
+ format: png
2610
+ kind: policy
2611
+ severity: error
2612
+ citation: {specification: profile, section: "prohibited_chunks", title: "Prohibited chunks"}
2613
+ emitters:
2614
+ - {file: "services/profile_manager.rb", call: "profile_diagnostic(\"profile.file.prohibited-present\", \"Prohibited chunk present: #{chunk_type}\", chunk_type: chunk_type, profile: profile_name, label: profile[:name] )"}
2615
+ profile.file.required-missing:
2616
+ format: png
2617
+ kind: policy
2618
+ severity: error
2619
+ citation: {specification: profile, section: "required_chunks", title: "Required chunks"}
2620
+ emitters:
2621
+ - {file: "services/profile_manager.rb", call: "profile_diagnostic(\"profile.file.required-missing\", \"Missing required chunk: #{chunk_type}\", chunk_type: chunk_type, profile: profile_name, label: profile[:name] )"}
2622
+ informational:
2623
+ info.png.PLTE.palette-present:
2624
+ format: png
2625
+ kind: information
2626
+ severity: info
2627
+ emitters:
2628
+ - {file: "validators/critical/plte_validator.rb", call: "add_info(\"info.png.PLTE.palette-present\", \"PLTE chunk present (suggested palette)\")"}
2629
+ info.png.bKGD.gray:
2630
+ format: png
2631
+ kind: information
2632
+ severity: info
2633
+ emitters:
2634
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_info(\"info.png.bKGD.gray\", \"bKGD: gray = #{gray}\")"}
2635
+ info.png.bKGD.palette-index:
2636
+ format: png
2637
+ kind: information
2638
+ severity: info
2639
+ emitters:
2640
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_info(\"info.png.bKGD.palette-index\", \"bKGD: palette index = #{index}\")"}
2641
+ info.png.bKGD.rgb:
2642
+ format: png
2643
+ kind: information
2644
+ severity: info
2645
+ emitters:
2646
+ - {file: "validators/ancillary/bkgd_validator.rb", call: "add_info(\"info.png.bKGD.rgb\", \"bKGD: RGB = (#{r}, #{g}, #{b})\")"}
2647
+ info.png.cHRM.white-point:
2648
+ format: png
2649
+ kind: information
2650
+ severity: info
2651
+ emitters:
2652
+ - {file: "validators/ancillary/chrm_validator.rb", call: "add_info(\"info.png.cHRM.white-point\", \"cHRM: white=(#{format('%.4f', white_x / 100_000.0)}, #{format('%.4f', white_y / 100_000.0)})\")"}
2653
+ info.png.cICP.matrix-coefficients-rgb-recommendation:
2654
+ format: png
2655
+ kind: information
2656
+ severity: info
2657
+ emitters:
2658
+ - {file: "validators/ancillary/cicp_validator.rb", call: "add_info(\"info.png.cICP.matrix-coefficients-rgb-recommendation\", \"matrix coefficients = 0 (identity) is recommended for RGB\")"}
2659
+ info.png.chunk.unknown-ancillary:
2660
+ format: png
2661
+ kind: information
2662
+ severity: info
2663
+ emitters:
2664
+ - {file: "services/chunk_processor.rb", call: "add_diagnostic(\"info.png.chunk.unknown-ancillary\", \"Unknown ancillary chunk type: #{chunk_type} (ignored)\", chunk_type: chunk_type, offset: chunk.abs_offset, field: \"chunk type\", actual: chunk_type )"}
2665
+ info.png.gAMA.gamma-linear:
2666
+ format: png
2667
+ kind: information
2668
+ severity: info
2669
+ emitters:
2670
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_info(\"info.png.gAMA.gamma-linear\", \"gAMA: 1.0 (linear)\")"}
2671
+ info.png.gAMA.gamma-standard:
2672
+ format: png
2673
+ kind: information
2674
+ severity: info
2675
+ emitters:
2676
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_info(\"info.png.gAMA.gamma-standard\", \"gAMA: 2.2 (standard display gamma)\")"}
2677
+ info.png.gAMA.gamma-value:
2678
+ format: png
2679
+ kind: information
2680
+ severity: info
2681
+ emitters:
2682
+ - {file: "validators/ancillary/gama_validator.rb", call: "add_info(\"info.png.gAMA.gamma-value\", \"gAMA: #{format('%.5f', actual_gamma)}\")"}
2683
+ info.png.hIST.all-zero:
2684
+ format: png
2685
+ kind: information
2686
+ severity: info
2687
+ emitters:
2688
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_info(\"info.png.hIST.all-zero\", \"hIST: #{palette_entries} entries (all zero)\")"}
2689
+ info.png.hIST.usage-summary:
2690
+ format: png
2691
+ kind: information
2692
+ severity: info
2693
+ emitters:
2694
+ - {file: "validators/ancillary/hist_validator.rb", call: "add_info(\"info.png.hIST.usage-summary\", \"hIST: #{palette_entries} palette entries, most used: index #{max_idx} (#{max_freq}), least used: index #{min_idx} (#{min_freq})\")"}
2695
+ info.png.iCCP.profile-summary:
2696
+ format: png
2697
+ kind: information
2698
+ severity: info
2699
+ emitters:
2700
+ - {file: "validators/ancillary/iccp_validator.rb", call: "add_info(\"info.png.iCCP.profile-summary\", \"iCCP: \\\"#{profile_name}\\\" (#{decompressed.length} bytes, compressed from #{compressed_data.length} bytes, ratio #{compression_ratio}:1)\")"}
2701
+ info.png.iDOT.apple-display-optimization:
2702
+ format: png
2703
+ kind: information
2704
+ severity: info
2705
+ emitters:
2706
+ - {file: "validators/ancillary/idot_validator.rb", call: "add_info(\"info.png.iDOT.apple-display-optimization\", \"iDOT: Apple display optimization (#{idot_data.detailed_info})\")"}
2707
+ info.png.iTXt.text-content:
2708
+ format: png
2709
+ kind: information
2710
+ severity: info
2711
+ emitters:
2712
+ - {file: "validators/ancillary/itxt_validator.rb", call: "add_info(\"info.png.iTXt.text-content\", \"iTXt: #{keyword}#{lang_info}#{trans_info} = \\\"#{text_preview}\\\"#{comp_info}\")"}
2713
+ info.png.mDCv.luminance-range:
2714
+ format: png
2715
+ kind: information
2716
+ severity: info
2717
+ emitters:
2718
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_info(\"info.png.mDCv.luminance-range\", \"luminance range: #{format_luminance(min_lum)} - #{format_luminance(max_lum)} cd/m²\")"}
2719
+ info.png.mDCv.primaries:
2720
+ format: png
2721
+ kind: information
2722
+ severity: info
2723
+ emitters:
2724
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_info(\"info.png.mDCv.primaries\", \"mastering display: R=(#{format_coordinate(red_x)},#{format_coordinate(red_y)}), G=(#{format_coordinate(green_x)},#{format_coordinate(green_y)}), B=(#{format_coordinate(blue_x)},#{format_coordinate(blue_y)})\")"}
2725
+ info.png.mDCv.white-point:
2726
+ format: png
2727
+ kind: information
2728
+ severity: info
2729
+ emitters:
2730
+ - {file: "validators/ancillary/mdcv_validator.rb", call: "add_info(\"info.png.mDCv.white-point\", \"white point: (#{format_coordinate(white_x)},#{format_coordinate(white_y)})\")"}
2731
+ info.png.oFFs.position:
2732
+ format: png
2733
+ kind: information
2734
+ severity: info
2735
+ emitters:
2736
+ - {file: "validators/ancillary/offs_validator.rb", call: "add_info(\"info.png.oFFs.position\", \"oFFs: position (#{x_pos}, #{y_pos}) #{unit_name}\")"}
2737
+ info.png.pCAL.calibration-summary:
2738
+ format: png
2739
+ kind: information
2740
+ severity: info
2741
+ emitters:
2742
+ - {file: "validators/ancillary/pcal_validator.rb", call: "add_info(\"info.png.pCAL.calibration-summary\", \"pCAL: \\\"#{cal_name}\\\" #{eq_type_name} equation, range #{orig_zero}..#{orig_max}, unit \\\"#{unit_name}\\\", params: #{params.join(', ')}\")"}
2743
+ info.png.pHYs.dpi:
2744
+ format: png
2745
+ kind: information
2746
+ severity: info
2747
+ emitters:
2748
+ - {file: "validators/ancillary/phys_validator.rb", call: "add_info(\"info.png.pHYs.dpi\", \"pHYs: #{dpi} DPI\")"}
2749
+ info.png.pHYs.non-square-pixels:
2750
+ format: png
2751
+ kind: information
2752
+ severity: info
2753
+ emitters:
2754
+ - {file: "validators/ancillary/phys_validator.rb", call: "add_info(\"info.png.pHYs.non-square-pixels\", \"pHYs: non-square pixels (aspect ratio #{format('%.3f', aspect)})\")"}
2755
+ info.png.sBIT.bits-gray:
2756
+ format: png
2757
+ kind: information
2758
+ severity: info
2759
+ emitters:
2760
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_info(\"info.png.sBIT.bits-gray\", \"sBIT: gray=#{gray}\")"}
2761
+ info.png.sBIT.bits-gray-alpha:
2762
+ format: png
2763
+ kind: information
2764
+ severity: info
2765
+ emitters:
2766
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_info(\"info.png.sBIT.bits-gray-alpha\", \"sBIT: gray=#{gray}, alpha=#{alpha}\")"}
2767
+ info.png.sBIT.bits-rgb:
2768
+ format: png
2769
+ kind: information
2770
+ severity: info
2771
+ emitters:
2772
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_info(\"info.png.sBIT.bits-rgb\", \"sBIT: R=#{red}, G=#{green}, B=#{blue}\")", sites: 2}
2773
+ info.png.sBIT.bits-rgba:
2774
+ format: png
2775
+ kind: information
2776
+ severity: info
2777
+ emitters:
2778
+ - {file: "validators/ancillary/sbit_validator.rb", call: "add_info(\"info.png.sBIT.bits-rgba\", \"sBIT: R=#{red}, G=#{green}, B=#{blue}, A=#{alpha}\")"}
2779
+ info.png.sCAL.scale:
2780
+ format: png
2781
+ kind: information
2782
+ severity: info
2783
+ emitters:
2784
+ - {file: "validators/ancillary/scal_validator.rb", call: "add_info(\"info.png.sCAL.scale\", \"sCAL: #{width} x #{height} #{unit_name}s per pixel\")"}
2785
+ info.png.sPLT.palette-summary:
2786
+ format: png
2787
+ kind: information
2788
+ severity: info
2789
+ emitters:
2790
+ - {file: "validators/ancillary/splt_validator.rb", call: "add_info(\"info.png.sPLT.palette-summary\", \"sPLT: \\\"#{palette_name}\\\" (#{num_entries} entries, #{sample_depth}-bit, frequency range #{min_freq}-#{max_freq}, total #{total_freq})\")"}
2791
+ info.png.sRGB.rendering-intent:
2792
+ format: png
2793
+ kind: information
2794
+ severity: info
2795
+ emitters:
2796
+ - {file: "validators/ancillary/srgb_validator.rb", call: "add_info(\"info.png.sRGB.rendering-intent\", \"sRGB: #{intent_name} rendering intent\")"}
2797
+ info.png.sTER.mode:
2798
+ format: png
2799
+ kind: information
2800
+ severity: info
2801
+ emitters:
2802
+ - {file: "validators/ancillary/ster_validator.rb", call: "add_info(\"info.png.sTER.mode\", \"sTER: #{mode_name} (mode #{mode})\")"}
2803
+ info.png.tEXt.text-content:
2804
+ format: png
2805
+ kind: information
2806
+ severity: info
2807
+ emitters:
2808
+ - {file: "validators/ancillary/text_validator.rb", call: "add_info(\"info.png.tEXt.text-content\", \"tEXt: #{keyword} = \\\"#{text_preview}\\\"\")"}
2809
+ info.png.tIME.timestamp:
2810
+ format: png
2811
+ kind: information
2812
+ severity: info
2813
+ emitters:
2814
+ - {file: "validators/ancillary/time_validator.rb", call: "add_info(\"info.png.tIME.timestamp\", \"tIME: #{iso_time}\")"}
2815
+ info.png.zTXt.text-content:
2816
+ format: png
2817
+ kind: information
2818
+ severity: info
2819
+ emitters:
2820
+ - {file: "validators/ancillary/ztxt_validator.rb", call: "add_info(\"info.png.zTXt.text-content\", \"zTXt: #{keyword} = \\\"#{text_preview}\\\" (compressed from #{compressed_data.length} bytes)\")"}
2821
+ info.profile.chunk.optional-present:
2822
+ format: png
2823
+ kind: information
2824
+ severity: info
2825
+ emitters:
2826
+ - {file: "services/profile_manager.rb", call: "success_result(\"info.profile.chunk.optional-present\", \"#{chunk_type} chunk optional and present\", **context)"}
2827
+ info.profile.chunk.required-present:
2828
+ format: png
2829
+ kind: information
2830
+ severity: info
2831
+ emitters:
2832
+ - {file: "services/profile_manager.rb", call: "success_result(\"info.profile.chunk.required-present\", \"#{chunk_type} chunk required and present\", **context)"}
2833
+ excluded_sources:
2834
+ pipelines:
2835
+ paths: ["pipelines/"]
2836
+ classification: dormant
2837
+ decision: exclude
2838
+ constants: ["PngConform::Pipelines"]
2839
+ reference_pattern: "Pipelines|ValidationPipeline|pipeline_result"
2840
+ rationale: >-
2841
+ Nothing requires lib/png_conform/pipelines/ and no documented public
2842
+ contract names it. Its sequence and signature stages repeat messages
2843
+ the active ValidationOrchestrator already emits, which are cataloged as
2844
+ all.signature.unknown, png.IHDR.missing, png.IEND.missing and
2845
+ png.IDAT.missing. Wiring or cataloging the stages would duplicate those
2846
+ IDs for unreachable code.
2847
+ evidence:
2848
+ - "No require_relative of pipelines/ in lib/png_conform.rb or any file it loads."
2849
+ - "PngConform::Pipelines is undefined after requiring png_conform and loading all 47 registered validators."
2850
+ - "No reference in spec/, exe/, bin/, examples/, benchmarks/, docs/, README.adoc or Rakefile."
2851
+ zlib_validator:
2852
+ paths: ["services/zlib_validator.rb"]
2853
+ classification: dormant
2854
+ decision: exclude
2855
+ constants: ["PngConform::Services::ZlibValidator"]
2856
+ reference_pattern: "ZlibValidator|zlib_validator"
2857
+ rationale: >-
2858
+ Services::ZlibValidator is never required and has no spec or
2859
+ documentation. The active zlib findings live in the iCCP, zTXt and iTXt
2860
+ validators (png.iCCP.decompress, png.zTXt.decompress,
2861
+ png.iTXt.decompress) and are cataloged there.
2862
+ evidence:
2863
+ - "No require of services/zlib_validator in lib/."
2864
+ - "PngConform::Services::ZlibValidator is undefined after requiring png_conform."
2865
+ - "No reference in spec/, exe/, bin/, examples/, benchmarks/, docs/, README.adoc or Rakefile."
2866
+ streaming_idat_validator:
2867
+ paths: ["validators/streaming_idat_validator.rb"]
2868
+ classification: dormant
2869
+ decision: exclude
2870
+ constants: ["PngConform::Validators::StreamingIdatValidator"]
2871
+ reference_pattern: "StreamingIdatValidator|streaming_idat_validator"
2872
+ rationale: >-
2873
+ StreamingIdatValidator is not in ChunkRegistry::VALIDATOR_PATHS, is never
2874
+ required, and has no spec or documented use. The registered
2875
+ IdatValidator is the active IDAT validator and is cataloged.
2876
+ evidence:
2877
+ - "Absent from ChunkRegistry::VALIDATOR_PATHS (47 entries)."
2878
+ - "PngConform::Validators::StreamingIdatValidator is undefined after requiring png_conform and loading all registered validators."
2879
+ - "No reference in spec/, exe/, bin/, examples/, benchmarks/, docs/, README.adoc or Rakefile."
2880
+ validation_service_helpers:
2881
+ paths: ["services/validation_service.rb"]
2882
+ classification: private-legacy
2883
+ decision: exclude-private-helpers
2884
+ private_helpers: ["add_error", "add_warning", "add_info", "merge_results"]
2885
+ uncalled_helpers: ["merge_results"]
2886
+ rationale: >-
2887
+ ValidationService is a documented public facade (ValidationService
2888
+ .validate_file and #validate, docs/CLI_OPTIONS.adoc), but both delegate
2889
+ to ValidationOrchestrator, whose findings are cataloged. Its private
2890
+ add_error, add_warning, add_info and merge_results helpers are
2891
+ uncalled: merge_results has no caller, and it is the only caller of the
2892
+ other three.
2893
+ evidence:
2894
+ - "validate_file and #validate delegate to ValidationOrchestrator."
2895
+ - "add_error, add_warning, add_info and merge_results are private."
2896
+ - "merge_results is referenced once in lib/, spec/ and docs/: its definition."
2897
+ resolution_analyzer_recommendations:
2898
+ paths: ["analyzers/resolution_analyzer.rb"]
2899
+ classification: advisory-analysis
2900
+ decision: exclude
2901
+ rationale: >-
2902
+ The resolution analyzer returns optimization recommendations (Retina
2903
+ size, missing pHYs, large web image). They are analysis output, not
2904
+ conformance findings, and carry no requirement to cite.
2905
+ evidence:
2906
+ - "Messages are built as recommendation hashes in analyzers/resolution_analyzer.rb, not added to ValidationContext."