libpng 1.6.58.1-aarch64-linux → 1.6.58.2-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1e1b799c32068955d06d8589295661f3973a74773808f602932527c9c93c4c8
4
- data.tar.gz: 8fd820bcea2f72810060a197a82ad964f4a2d5683bb0358971c77488f303eeb7
3
+ metadata.gz: 75f0cfb37e59edf68ee4debbfacd284af495c705d5944db655eff6ad8b3b39e3
4
+ data.tar.gz: 21aba446ec81467ffc3b0a16405bbf2cc317fe99ad9fb38a508ade23c37943d9
5
5
  SHA512:
6
- metadata.gz: e75aac2a2fcdad2f2a113fd193af5f6db6d31bd0177ec7dc07e470930143a3db24e9c5ea37ca8b1e7534ad9d33fd4b7305604fa7c4d32f828089b98f0a828a32
7
- data.tar.gz: 9da0237ffd5de80720de59250e95669b5acadf1575a915a03c2c0e319052807def68d78fc206f8afc5f7be8d6bbafeac914c93197983a5ef6f70df4749006cba
6
+ metadata.gz: 6b2501953eb4b4911ca2cd7121d870f76e6129fae27872d2fc569189978438b88acc80fcbb9669aca1b26301b8aab80057fb4f8888f42a1435a42c72412cd377
7
+ data.tar.gz: dbb67d49744d157d0b5c8527d677e0183340d875d0dad43701caa72a705a5b9b1415a59e6c85c81ea8ae5b01a915cb36ef2ef172d6392145812ccef14cc5ea9a
data/.rubocop.yml CHANGED
@@ -10,15 +10,15 @@ Gemspec/DevelopmentDependencies:
10
10
  # methods that walk libpng's chunked API; splitting would obscure the
11
11
  # 1-to-1 mapping with the C API.
12
12
  Metrics/AbcSize:
13
- Max: 60
13
+ Max: 70
14
14
  Metrics/ClassLength:
15
15
  Max: 200
16
16
  Metrics/CyclomaticComplexity:
17
17
  Max: 20
18
18
  Metrics/MethodLength:
19
- Max: 50
19
+ Max: 70
20
20
  Metrics/ModuleLength:
21
- Max: 250
21
+ Max: 350
22
22
  Metrics/PerceivedComplexity:
23
23
  Max: 20
24
24
  Metrics/ParameterLists:
data/README.adoc CHANGED
@@ -22,9 +22,33 @@ Or install manually:
22
22
 
23
23
  gem install libpng
24
24
 
25
- The gem downloads a pre-compiled binary for your platform automatically.
26
- No C compiler, libpng development headers, or system packages are needed
27
- at install time.
25
+ RubyGems automatically selects the pre-compiled gem that matches your
26
+ platform. No C compiler, libpng development headers, or system packages
27
+ are required at install time when a binary gem is available. The
28
+ platform-agnostic `ruby` gem is the fallback: it downloads the libpng
29
+ source tarball at install time and compiles it via CMake (requires
30
+ `cmake`, `ninja`, and zlib headers).
31
+
32
+ == Supported platforms
33
+
34
+ The following pre-compiled platform gems are published for each release
35
+ (see the link:https://rubygems.org/gems/libpng/versions[RubyGems versions page]
36
+ for the current set):
37
+
38
+ [cols="1,1,3", options="header"]
39
+ |===
40
+ | Gem platform | Target | Build host
41
+ | `ruby` (source) | Any platform (compiles on install) | n/a
42
+ | `x86_64-linux` | x86_64 Linux (glibc) | `ubuntu-latest`
43
+ | `x86_64-linux-musl` | x86_64 Linux (musl, e.g. Alpine) | `ruby:<ver>-alpine` on x86_64
44
+ | `aarch64-linux` | ARM64 Linux (glibc) | `ubuntu-24.04-arm` (native)
45
+ | `aarch64-linux-musl` | ARM64 Linux (musl) | `ruby:<ver>-alpine` on arm64
46
+ | `x64-mingw32` | x64 Windows, RubyInstaller < 3.0 (MSVCRT) | `windows-latest`
47
+ | `x64-mingw-ucrt` | x64 Windows, RubyInstaller >= 3.0 (UCRT) | `windows-latest`
48
+ | `aarch64-mingw-ucrt` | ARM64 Windows (Ruby >= 3.4) | `windows-11-arm` (native)
49
+ | `x86_64-darwin` | Intel macOS | `macos-15-intel`
50
+ | `arm64-darwin` | Apple Silicon macOS | `macos-latest`
51
+ |===
28
52
 
29
53
  == Usage
30
54
 
@@ -52,12 +76,57 @@ at install time.
52
76
 
53
77
  Libpng.encode(width, height, pixels,
54
78
  pixel_format: "RGBA",
55
- convert_to_8bit: false)
79
+ convert_to_8bit: false,
80
+ strip_colorspace: true)
56
81
 
57
- `convert_to_8bit: true` causes libpng to convert 16-bit input to 8-bit
82
+ `convert_to_8bit: true`:: causes libpng to convert 16-bit input to 8-bit
58
83
  on write (input is still passed as a packed byte buffer; use this if you
59
84
  have packed 16-bit-per-channel data).
60
85
 
86
+ `strip_colorspace: true`:: (default) walks the PNG chunk list after
87
+ encode and keeps only `IHDR`, `IDAT`, and `IEND`, dropping the sRGB/gAMA
88
+ chunks libpng's simplified API emits by default. This matches the
89
+ "classic" libpng write path (e.g. libemf2svg) and produces byte-identical
90
+ output. Set to `false` to keep the ancillary color chunks.
91
+
92
+ === Standard API (encode_standard)
93
+
94
+ For parity with libpng's classic write path -- the same code path used
95
+ by `libemf2svg`'s `rgb2png` -- use `encode_standard` instead of
96
+ `encode`. It calls `png_create_write_struct` + `png_set_IHDR` +
97
+ `png_set_rows` + `png_write_png(PNG_TRANSFORM_IDENTITY)` directly, with
98
+ filter and zlib-compression control exposed:
99
+
100
+ Libpng.encode_standard(width, height, pixels,
101
+ pixel_format: "RGBA",
102
+ filter: :default,
103
+ compression_level: 6)
104
+
105
+ `pixel_format`:: `GRAY`, `GA`, `RGB`, or `RGBA` only. The byte-order
106
+ variants (`BGR`, `ARGB`, `BGRA`, `ABGR`) are simplified-API only --
107
+ the standard API always emits host-order.
108
+
109
+ `filter`:: One of `:default` (adaptive -- libpng picks the best filter
110
+ per row, the libemf2svg default), `:adaptive` (same), `:none`, `:sub`,
111
+ `:up`, `:avg`, `:paeth`, or `:all`.
112
+
113
+ `compression_level`:: zlib level 0-9. Default 6 (Z_DEFAULT_COMPRESSION,
114
+ matching libemf2svg).
115
+
116
+ Output is written directly into a Ruby String via `png_set_write_fn` --
117
+ no `Tempfile`, no disk I/O. The FFI write callback is held on a local
118
+ Array so it survives the libpng calls.
119
+
120
+ Differences from `encode`:
121
+ - Emits only `IHDR` / `IDAT` / `IEND` (no post-hoc chunk stripping
122
+ needed).
123
+ - Standard API only -- no `convert_to_8bit` option.
124
+ - Errors are raised via a `png_set_error_fn` callback (set on
125
+ `png_create_write_struct`). libpng expects error callbacks to
126
+ longjmp; we rb_raise instead, which unwinds the Ruby stack. The
127
+ `ensure` block calls `png_destroy_write_struct` to release the C
128
+ state.
129
+
61
130
  == Ractor safety
62
131
 
63
132
  `Libpng.encode` and `Libpng.decode` are Ractor-safe. Every call
@@ -65,25 +134,26 @@ allocates and frees its own libpng `png_image`; no shared mutable state
65
134
  exists on the Ruby side. Calls from multiple Ractors run concurrently
66
135
  without locking.
67
136
 
68
- Example:
137
+ Example (Ruby 3.x uses `Ractor#take`; Ruby 4.0+ uses `Ractor#value`):
69
138
 
70
139
  r = Ractor.new do
71
140
  Libpng.encode(2, 2, "\xFF" * 16, pixel_format: "RGBA")
72
141
  end
73
- r.take # => PNG binary
142
+ r.take # Ruby 3.x
143
+ r.value # Ruby 4.0+ (Ractor#take was removed in 4.0)
74
144
 
75
145
  == Versioning
76
146
 
77
147
  This gem follows a `{LIBPNG_VERSION}.{ITERATION}` scheme:
78
148
 
79
149
  - `LIBPNG_VERSION` is the upstream libpng release the gem is built
80
- against (currently 1.6.48).
150
+ against (currently `1.6.58`).
81
151
  - `ITERATION` is a counter that bumps on Ruby-side changes (recipe bug
82
152
  fixes, CI tweaks, doc updates). It resets to 0 each time
83
153
  `LIBPNG_VERSION` bumps.
84
154
 
85
- For example, `1.6.48.0` is the first release against libpng 1.6.48,
86
- `1.6.48.1` is a Ruby-side fix, and `1.6.49.0` would be a release against
155
+ For example, `1.6.58.0` is the first release against libpng 1.6.58,
156
+ `1.6.58.1` is a Ruby-side fix, and `1.6.59.0` would be a release against
87
157
  the next upstream libpng.
88
158
 
89
159
  == How it works
@@ -91,15 +161,54 @@ the next upstream libpng.
91
161
  The gem has three layers:
92
162
 
93
163
  1. `lib/libpng.rb` -- Ruby FFI wrapper. Loads `libpng16.{so,dylib,dll}`
94
- from the gem's `lib/libpng/` directory at runtime.
95
- 2. `lib/libpng/recipe.rb` -- a MiniPortileCMake recipe that downloads
96
- the libpng source tarball and runs CMake to produce the shared
97
- library. This is invoked by `ext/extconf.rb` when the gem is installed
98
- from source.
99
- 3. `Rakefile` defines `gem:native:<platform>` tasks that pre-compile
100
- the gem for each target platform. The pre-compiled gems bundle the
101
- `.so`/`.dylib`/`.dll` and disable `extconf.rb`, so installation
102
- requires no C compiler.
164
+ from the gem's `lib/libpng/` directory at runtime and exposes
165
+ `Libpng.encode` / `Libpng.decode` against libpng's "simplified"
166
+ high-level C API (`png_image_*`). The wrapper manually lays out the
167
+ `png_image` struct via explicit byte offsets into an
168
+ `FFI::MemoryPointer` rather than `FFI::Struct`, because `FFI::Struct`
169
+ carries class-level state that is not shareable across non-main
170
+ Ractors.
171
+
172
+ 2. `lib/libpng/recipe.rb` -- a `MiniPortileCMake` recipe that downloads
173
+ the libpng source tarball pinned by `LIBPNG_URL` / `LIBPNG_SHA256`,
174
+ runs CMake with `PNG_SHARED=ON PNG_STATIC=OFF PNG_TESTS=OFF`, and
175
+ copies the resulting shared lib into `lib/libpng/`. Invoked only when
176
+ installing the **source** (`ruby` platform) gem.
177
+
178
+ 3. `ext/extconf.rb` -- gem extension entry point. Calls `Recipe#cook_if_not`,
179
+ which is a no-op once the per-platform checkpoint file
180
+ (`ports/.../<name>-<ver>-<platform>.installed`) exists. After cooking,
181
+ emits a dummy `Makefile` via `mkmf` so RubyGems is satisfied (no Ruby
182
+ C extension is compiled). The pre-compiled platform gems unset
183
+ `spec.extensions`, so this never runs for them.
184
+
185
+ === Pre-compiled platform gems
186
+
187
+ `Rakefile` defines `gem:native:<platform>` tasks for each target. Each
188
+ task clones the gemspec, sets `spec.platform`, adds
189
+ `lib/libpng/*.{dll,so,dylib}` to `spec.files`, removes the
190
+ `mini_portile2` dependency (no longer needed at install time), and
191
+ unsets `spec.extensions` -- the resulting gem installs with no compiler.
192
+
193
+ The release workflow (`.github/workflows/release.yml`) builds all 10
194
+ platforms in parallel on the appropriate native runner:
195
+
196
+ - x86_64 Linux glibc -- `ubuntu-latest`
197
+ - ARM64 Linux glibc -- `ubuntu-24.04-arm` (native)
198
+ - x86_64 Linux musl -- `ruby:<ver>-alpine` via `docker run` on `ubuntu-latest`
199
+ - ARM64 Linux musl -- `ruby:<ver>-alpine` via `docker run` on `ubuntu-24.04-arm`
200
+ - x64 Windows (both MSVCRT and UCRT) -- `windows-latest` with `step-security/msvc-dev-cmd`
201
+ - ARM64 Windows -- `windows-11-arm` (native) with `arch: arm64`
202
+ - Intel macOS -- `macos-15-intel`
203
+ - Apple Silicon macOS -- `macos-latest`
204
+
205
+ Linux glibc and macOS builds run natively on the matching runner. Linux
206
+ musl builds run inside `ruby:<ver>-alpine` containers via `docker run`
207
+ rather than the workflow `container:` field, because Actions' JS runtime
208
+ has no arm64-musl build and therefore cannot run Alpine containers on
209
+ arm64 runners. Windows builds use the Visual Studio toolchain via
210
+ `step-security/msvc-dev-cmd` (a maintained drop-in for the deleted
211
+ `ilammy/msvc-dev-tools`).
103
212
 
104
213
  == License
105
214
 
@@ -11,6 +11,6 @@ module Libpng
11
11
  # new libpng release. The iteration resets to 0 each time
12
12
  # LIBPNG_VERSION bumps.
13
13
  LIBPNG_VERSION = '1.6.58'
14
- LIBPNG_RUBY_ITERATION = 1
14
+ LIBPNG_RUBY_ITERATION = 2
15
15
  VERSION = "#{LIBPNG_VERSION}.#{LIBPNG_RUBY_ITERATION}"
16
16
  end
data/lib/libpng.rb CHANGED
@@ -45,6 +45,20 @@ module Libpng
45
45
  %i[pointer pointer pointer int pointer int pointer], :int
46
46
  attach_function :png_image_free, [:pointer], :void
47
47
 
48
+ # libpng standard (non-simplified) write API. Used by encode_standard.
49
+ attach_function :png_create_write_struct,
50
+ %i[string pointer pointer pointer], :pointer
51
+ attach_function :png_create_info_struct, [:pointer], :pointer
52
+ attach_function :png_destroy_write_struct, %i[pointer pointer], :void
53
+ attach_function :png_set_IHDR,
54
+ %i[pointer pointer uint32 uint32 int int int int int], :void
55
+ attach_function :png_set_rows, %i[pointer pointer pointer], :void
56
+ attach_function :png_set_filter, %i[pointer int int], :void
57
+ attach_function :png_set_compression_level, %i[pointer int], :void
58
+ attach_function :png_set_write_fn,
59
+ %i[pointer pointer pointer pointer], :void
60
+ attach_function :png_write_png, %i[pointer pointer int pointer], :void
61
+
48
62
  # PNG_IMAGE_FORMAT_* bit flags and named formats from png.h.
49
63
  FORMAT_FLAG_ALPHA = 0x01
50
64
  FORMAT_FLAG_COLOR = 0x02
@@ -77,6 +91,64 @@ module Libpng
77
91
  'ABGR' => FORMAT_ABGR
78
92
  }.freeze
79
93
 
94
+ # PNG_COLOR_MASK_* and PNG_COLOR_TYPE_* (png.h).
95
+ COLOR_MASK_PALETTE = 0x01
96
+ COLOR_MASK_COLOR = 0x02
97
+ COLOR_MASK_ALPHA = 0x04
98
+
99
+ COLOR_TYPE_GRAY = 0
100
+ COLOR_TYPE_PALETTE = COLOR_MASK_COLOR | COLOR_MASK_PALETTE
101
+ COLOR_TYPE_RGB = COLOR_MASK_COLOR
102
+ COLOR_TYPE_RGB_ALPHA = COLOR_MASK_COLOR | COLOR_MASK_ALPHA
103
+ COLOR_TYPE_GRAY_ALPHA = COLOR_MASK_ALPHA
104
+
105
+ # Map our FORMAT_* to PNG_COLOR_TYPE_*. encode_standard doesn't support
106
+ # the BGR/ARGB/BGRA/ABGR byte-order variants because the standard API
107
+ # encodes host-order; callers wanting those formats should use the
108
+ # simplified encode path or pre-swap bytes.
109
+ COLOR_TYPE_BY_FORMAT = {
110
+ FORMAT_GRAY => COLOR_TYPE_GRAY,
111
+ FORMAT_GA => COLOR_TYPE_GRAY_ALPHA,
112
+ FORMAT_AG => COLOR_TYPE_GRAY_ALPHA,
113
+ FORMAT_RGB => COLOR_TYPE_RGB,
114
+ FORMAT_RGBA => COLOR_TYPE_RGB_ALPHA
115
+ }.freeze
116
+
117
+ # png_set_IHDR pass-through constants (png.h).
118
+ INTERLACE_NONE = 0
119
+ INTERLACE_ADAM7 = 1
120
+ COMPRESSION_TYPE_DEFAULT = 0
121
+ FILTER_TYPE_DEFAULT = 0
122
+ TRANSFORM_IDENTITY = 0x0000
123
+
124
+ # png_set_filter bitmask (PNG_FILTER_*). :default lets libpng use
125
+ # adaptive filtering across all filter types -- this is what
126
+ # libemf2svg/rgb2png effectively does via PNG_FILTER_TYPE_DEFAULT in
127
+ # the IHDR.
128
+ FILTER_HEURISTIC_DEFAULT = 0
129
+ FILTER_NONE = 0x08
130
+ FILTER_SUB = 0x10
131
+ FILTER_UP = 0x20
132
+ FILTER_AVG = 0x40
133
+ FILTER_PAETH = 0x80
134
+ FILTER_ALL = FILTER_NONE | FILTER_SUB | FILTER_UP | FILTER_AVG | FILTER_PAETH
135
+
136
+ FILTER_MASK_BY_NAME = {
137
+ default: nil, # don't call png_set_filter at all
138
+ adaptive: FILTER_ALL, # call with all filters allowed (same as default)
139
+ none: FILTER_NONE,
140
+ sub: FILTER_SUB,
141
+ up: FILTER_UP,
142
+ avg: FILTER_AVG,
143
+ paeth: FILTER_PAETH,
144
+ all: FILTER_ALL
145
+ }.freeze
146
+
147
+ # PNG_LIBPNG_VER_STRING. Used as the user_png_ver arg to
148
+ # png_create_write_struct. Must match the libpng16.{so,dylib,dll} we
149
+ # ship -- if these ever drift, png_create_write_struct aborts.
150
+ LIBPNG_VER_STRING_C = Libpng::LIBPNG_VERSION.dup.freeze
151
+
80
152
  # png_image::version value libpng checks for. Defined in png.h as
81
153
  # PNG_IMAGE_VERSION == 1.
82
154
  PNG_IMAGE_VERSION = 1
@@ -192,6 +264,111 @@ module Libpng
192
264
  end
193
265
  end
194
266
 
267
+ # Encode raw pixels via libpng's standard write API
268
+ # (png_create_write_struct -> png_set_IHDR -> png_set_rows ->
269
+ # png_write_png(PNG_TRANSFORM_IDENTITY)). This matches the byte
270
+ # output of the "classic" libpng write path used by libemf2svg's
271
+ # rgb2png, and avoids the sRGB/gAMA chunks the simplified API
272
+ # injects by default.
273
+ #
274
+ # +width+, +height+ image dimensions in pixels
275
+ # +pixels+ String of raw pixel bytes (row-major, top-down)
276
+ # +pixel_format+ "RGB", "RGBA", "GRAY", "GA" (default: "RGBA")
277
+ # +filter+ :default (adaptive), :none, :sub, :up, :avg,
278
+ # :paeth, :all, :adaptive (default: :default)
279
+ # +compression_level+ zlib level 0-9 (default: 6 = Z_DEFAULT_COMPRESSION)
280
+ #
281
+ # Output is accumulated in a Ruby String via png_set_write_fn --
282
+ # no Tempfile, no disk I/O. The FFI write callback is held on a
283
+ # local Array so it isn't GC'd mid-call.
284
+ #
285
+ # Errors are raised via a png_set_error_fn callback (set on
286
+ # png_create_write_struct). libpng expects error callbacks to
287
+ # longjmp; rb_raise from the FFI callback unwinds the Ruby stack
288
+ # instead, which works for our usage but means the png_struct is
289
+ # not cleanly torn down inside libpng. The ensure block calls
290
+ # png_destroy_write_struct to release the C state.
291
+ #
292
+ # Ractor-safe: all state is per-call. FFI callbacks are not
293
+ # shareable across Ractors, but they're locals and stay scoped
294
+ # to one Ractor.
295
+ def encode_standard(width, height, pixels, pixel_format: 'RGBA',
296
+ filter: :default, compression_level: 6)
297
+ raise Error, 'width must be positive' unless width.positive?
298
+ raise Error, 'height must be positive' unless height.positive?
299
+
300
+ fmt = FORMAT_BY_NAME[pixel_format.to_s.upcase] ||
301
+ raise(Error, "unknown pixel_format #{pixel_format.inspect}")
302
+ color_type = COLOR_TYPE_BY_FORMAT[fmt] ||
303
+ raise(Error, "encode_standard does not support #{pixel_format} " \
304
+ '(use GRAY, GA, RGB, or RGBA; byte-order variants ' \
305
+ 'like BGRA/ARGB/ABGR are simplified-API only)')
306
+
307
+ bytes_per_pixel = bytes_per_pixel_for_format(fmt)
308
+ stride = width * bytes_per_pixel
309
+ expected = stride * height
310
+ raise Error, "pixels too short: expected #{expected}, got #{pixels.bytesize}" if pixels.bytesize < expected
311
+
312
+ filter_sym = filter.to_sym
313
+ unless FILTER_MASK_BY_NAME.key?(filter_sym)
314
+ raise Error, "unknown filter #{filter.inspect} " \
315
+ '(expected :default, :adaptive, :none, :sub, :up, :avg, :paeth, or :all)'
316
+ end
317
+ filter_mask = FILTER_MASK_BY_NAME[filter_sym]
318
+ raise Error, 'compression_level must be 0..9' unless (0..9).cover?(compression_level)
319
+
320
+ output = String.new.force_encoding('ASCII-8BIT')
321
+
322
+ # FFI::Function objects need a stable reference for the duration of
323
+ # the libpng calls -- otherwise they can be GC'd before libpng
324
+ # invokes them.
325
+ callbacks = []
326
+ write_cb = FFI::Function.new(:void, %i[pointer pointer size_t]) do |_, data, len|
327
+ output << data.read_bytes(len)
328
+ end
329
+ error_cb = FFI::Function.new(:void, %i[pointer string]) do |_, msg|
330
+ raise Error, "libpng: #{msg}"
331
+ end
332
+ callbacks << write_cb << error_cb
333
+
334
+ png_ptr = FFI::Pointer.new(0)
335
+ info_ptr = FFI::Pointer.new(0)
336
+ begin
337
+ png_ptr = png_create_write_struct(LIBPNG_VER_STRING_C, nil, error_cb, nil)
338
+ raise Error, 'png_create_write_struct returned NULL' if png_ptr.null?
339
+
340
+ info_ptr = png_create_info_struct(png_ptr)
341
+ raise Error, 'png_create_info_struct returned NULL' if info_ptr.null?
342
+
343
+ png_set_compression_level(png_ptr, compression_level)
344
+ png_set_write_fn(png_ptr, nil, write_cb, nil)
345
+ png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type,
346
+ INTERLACE_NONE, COMPRESSION_TYPE_DEFAULT, FILTER_TYPE_DEFAULT)
347
+ png_set_filter(png_ptr, FILTER_HEURISTIC_DEFAULT, filter_mask) if filter_mask
348
+
349
+ FFI::MemoryPointer.new(:uint8, pixels.bytesize) do |px|
350
+ px.write_bytes(pixels)
351
+ FFI::MemoryPointer.new(:pointer, height) do |rows|
352
+ height.times { |y| rows.put_pointer(y * FFI.type_size(:pointer), px + (y * stride)) }
353
+ png_set_rows(png_ptr, info_ptr, rows)
354
+ png_write_png(png_ptr, info_ptr, TRANSFORM_IDENTITY, nil)
355
+ end
356
+ end
357
+
358
+ output
359
+ ensure
360
+ unless png_ptr.null?
361
+ FFI::MemoryPointer.new(:pointer) do |pp|
362
+ pp.write_pointer(png_ptr)
363
+ FFI::MemoryPointer.new(:pointer) do |ip|
364
+ ip.write_pointer(info_ptr)
365
+ png_destroy_write_struct(pp, ip)
366
+ end
367
+ end
368
+ end
369
+ end
370
+ end
371
+
195
372
  private
196
373
 
197
374
  # Lower-level encode that produces the raw libpng output (with sRGB
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libpng
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.58.1
4
+ version: 1.6.58.2
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-25 00:00:00.000000000 Z
11
+ date: 2026-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi