Git Product home page Git Product logo

swift-png's Introduction

png
4.4

ci status

swift package index versions swift package index platforms

Swift PNG is a Foundation-less, cross-platform framework for decoding, inspecting, editing, and encoding PNG images. The framework is written in pure Swift, and will compile and provide consistent behavior on all Swift platforms. The library also comes with built-in file system support on linux, macOS, and Windows.

The library is powered by a native Swift DEFLATE implementation, which can be used as a standalone module.

Swift PNG is available under the Apache 2.0 license. The example programs are public domain and can be adapted freely.

Swift PNG’s documentation is available on Swiftinit!

Getting started

To use Swift PNG in a project, add this descriptor to the dependencies list in your Package.swift file:

.package(url: "https://github.com/tayloraswift/swift-png", .from("4.4.0"))

Basic usage

Decode an image:

import PNG
func decode(png path:String) throws
{
    guard
    let image:PNG.Image = try .decompress(path: path)
    else
    {
        // failed to access file from file system
    }

    let rgba:[PNG.RGBA<UInt8>] = image.unpack(as: PNG.RGBA<UInt8>.self),
        size:(x:Int, y:Int)    = image.size
    // ...
}

Encode an image:

func encode(png path:String, size:(x:Int, y:Int), pixels:[PNG.RGBA<UInt8>]) throws
{
    let image:PNG.Image = .init(packing: pixels, size: size,
        layout: .init(format: .rgba8(palette: [], fill: nil)))
    try image.compress(path: path, level: 9)
}

Features

  • Powerful interfaces. Swift PNG’s expressive, strongly-typed APIs make working with PNG images easy for beginners and advanced users alike. If your code compiles, you’re already most of the way there. Power users can take advantage of custom indexing, manual decoding workflows, and user-defined color targets.

  • Superior compression. Swift PNG supports minimum cost path-based DEFLATE optimization, which is why it offers four additional compression levels beyond what libpng supports.

  • Competitive performance. Swift PNG offers competitive performance compared to libpng. On appropriate CPU architectures, the Swift PNG encoder makes use of hardware-accelerated hash tables for even greater performance.

  • Pure Swift, all the way down. Swift PNG is powered by its own, native Swift DEFLATE implementation. It depends only on other Foundation-less, pure-Swift libraries, and therefore does not need to link Foundation. This also means the core components of Swift PNG work on any platform that Swift itself works on, and that Swift PNG’s performance improves as the Swift compiler matures.

  • Batteries included. Swift PNG comes with built-in color targets with support for premultiplied alpha. Convolution and deconvolution helper functions make implementing custom color targets a breeze.

  • First-class iPhone optimization support. Swift PNG requires no custom setup or third-party plugins to handle iPhone-optimized PNG images. iPhone-optimized images just work, on all platforms. Reproduce pngcrush’s output with bit width-aware alpha premultiplication, for seamless integration anywhere in your application stack.

  • Comprehensive metadata support. Swift PNG can parse and validate all public PNG chunks, which are accessible as strongly-typed metadata records.

  • Modern error handling. Swift PNG has a fully stateless and Swift-native error-handling system.

See also

swift-png's People

Contributors

gonsolo avatar harlanhaskins avatar sdggiesbrecht avatar tayloraswift avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

swift-png's Issues

Unit-tests match-lz77 and dictionary-semantics fail

swift run unit-test
Building for debugging...
Build complete! (0.11s)
 test 'decode-bitstream'             passed                                     
 test 'encode-bitstream'             passed                                     
[[1], [2], [3], [3], [1], [2], [3], [3], [1], [2], [3], [1], [2], [2], [2], [2], [2], [2], [0], [1], [2], [2], [2], [2], [2], [0], [1], [2], [2], [0], [0], [0], [0], [2], [3], [2], [1], [2], [3], [3], [1], [5], [1], [1], [3], [3], [1], [2], [3], [1], [2], [4], [4], [2], [1]]
 test 'match-lz77'                   failed                                     
 [ 0]: compressed lz77 tokens do not match expected output
 test 'compress-lz77-greedy'         passed  (6 cases)                          
 test 'compress-lz77-lazy'           passed  (6 cases)                          
 test 'compress-lz77-full'           passed  (6 cases)                          
 test 'filtering'                    passed  (8 cases)                          
 test 'premultiplication-8-bit'      passed                                     
 test 'premultiplication-16-bit'     passed                                     
 test 'dictionary-semantics'         failed                                     
 [ 0]: dictionary update/remove semantics are inconsistent

Unable to run swift build command

When we try to run the Swift Package commands like

  1. swift build
  2. swift tests

The build is failing with below reason. Any help is highly appreciated. Thanks

Screenshot 2024-04-12 at 10 11 43 PM

Move to camel cased API

API should be camelcased in alignment of the overwhelming majority of the Swift ecosystem.

Error building release configuration

swift build -c release
Building for production...
remark: Incremental compilation has been disabled: it is not compatible with whole module optimization
/Users/*******/Documents/swift-png/tests/unit/tests.swift:1:18: error: module 'PNG' was not compiled for testing
@testable import PNG
~~~~~~~~~~       ^
[22/27] Compiling PNGUnitTests main.swift

How do you use this in a project?

Can you add Installation instructions? swift build seems to work but not sure how to link it into an iOS app.

Alternatively, is there a way to add CocoaPods support?

`swift build` doesn't work: cannot find type 'SynchronousTests' in scope

$ swift build
Building for debugging...
error: emit-module command failed with exit code 1 (use -v to see invocation)
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:10:11: error: cannot find type 'SynchronousTests' in scope
enum Main:SynchronousTests
          ^~~~~~~~~~~~~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:9:1: error: 'Main' is annotated with @main and must provide a main static function of type () -> Void, () throws -> Void, () async -> Void, or () async throws -> Void
@main 
^
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:10:11: error: an enum with no cases cannot declare a raw type
enum Main:SynchronousTests
          ^
ld: warning: search path '/usr/local/lib' not found
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:10:11: error: cannot find type 'SynchronousTests' in scope
enum Main:SynchronousTests
          ^~~~~~~~~~~~~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:9:1: error: 'Main' is annotated with @main and must provide a main static function of type () -> Void, () throws -> Void, () async -> Void, or () async throws -> Void
@main 
^
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:10:11: error: an enum with no cases cannot declare a raw type
enum Main:SynchronousTests
          ^
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:272:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "error-handling")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:279:19: error: value of type 'Tests' has no member 'group'
            tests.group("decode-\(name)")
            ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:291:15: error: value of type 'Tests' has no member 'group'
        tests.group("decode-iphone-optimized")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:301:15: error: value of type 'Tests' has no member 'group'
        tests.group("encode-iphone-optimized")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNGIntegration/Main.swift:316:23: error: value of type 'Tests' has no member 'group'
                tests.group("encode-\(level)-\(name)")
                ~~~~~ ^~~~~
error: fatalError
ld: warning: search path '/usr/local/lib' not found
error: emit-module command failed with exit code 1 (use -v to see invocation)
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:10:11: error: cannot find type 'SynchronousTests' in scope
enum Main:SynchronousTests
          ^~~~~~~~~~~~~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:9:1: error: 'Main' is annotated with @main and must provide a main static function of type () -> Void, () throws -> Void, () async -> Void, or () async throws -> Void
@main 
^
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:10:11: error: an enum with no cases cannot declare a raw type
enum Main:SynchronousTests
          ^
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:10:11: error: cannot find type 'SynchronousTests' in scope
enum Main:SynchronousTests
          ^~~~~~~~~~~~~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:9:1: error: 'Main' is annotated with @main and must provide a main static function of type () -> Void, () throws -> Void, () async -> Void, or () async throws -> Void
@main 
^
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:10:11: error: an enum with no cases cannot declare a raw type
enum Main:SynchronousTests
          ^
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:15:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "decode-bitstream")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:19:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "encode-bitstream")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:23:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "match-lz77")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:27:15: error: value of type 'Tests' has no member 'group'
        tests.group("compress-lz77-greedy")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:37:15: error: value of type 'Tests' has no member 'group'
        tests.group("compress-lz77-lazy")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:47:15: error: value of type 'Tests' has no member 'group'
        tests.group("compress-lz77-full")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:57:15: error: value of type 'Tests' has no member 'group'
        tests.group("filtering")
        ~~~~~ ^~~~~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:67:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "premultiplication-8-bit")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:71:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "premultiplication-16-bit")
        ~~~~~ ^~
/Users/wadetregaskis/Documents/swift-png/Tests/PNG/Main.swift:75:15: error: value of type 'Tests' has no member 'do'
        tests.do(name: "dictionary-semantics")
        ~~~~~ ^~
ld: warning: search path '/usr/local/lib' not found
clang: error: unable to execute command: Interrupt: 2
clang: error: linker command failed due to signal (use -v to see invocation)
[12/24] Linking decompression-benchmark

update “unofficial” version docs

the current release version doesn’t build on swift ≥4.1 so everyone seems to be using the unofficial master build which has a different API from the documented version

latest tag is outdated

I'm seeing lots of changes since the latest tag, any plans for releasing a new tag? Any reason for not cutting a release yet? :) I noticed due to the example code not working for my version, which was the latest tag.

Also is there a built in way to resize images? If there is I can't find it for some reason

modernize library benchmarks

we need to modernize swift-png’s benchmarks. this will involve:

  1. moving the benchmarks into a nested SPM project, with a separate Package.swift manifest. this frees up the benchmarks to adopt additional dependencies, and is the model @karwa ’s swift-url uses, and has already been adopted by swift-json.

  2. updating the benchmarking code to use modern stdlib features, like ContinuousClock.

  3. configuring benchmarks to run as part of the project’s CI pipeline, the way swift-json currently does it.

  4. integrate the library’s performance reporting system into the CI pipeline, and automate this process. (right now it is a completely manual pre-submit procedure!)

  5. add standards to the CI pipeline, so that major performance regressions will fail the status checks.

  6. backport items # 4 and # 5 to swift-json so that it can also benefit from these improvements.

  7. copy this setup to swift-jpeg, so it can also benefit from this infrastructure, as part of tayloraswift/jpeg#3 .

Leaving Array's buffer uninitialised is breach of contract

https://github.com/kelvin13/swift-png/blob/075dfb248ae327822635370e9d4f94a5d3fe93b2/sources/png/decoder.swift#L289

https://developer.apple.com/documentation/swift/array/init(unsafeuninitializedcapacity:initializingwith:):

Discussion

Inside the closure, set the initializedCount parameter to the number of elements that are initialized by the closure. The memory in the range buffer[0..<initializedCount] must be initialized at the end of the closure’s execution, and the memory in the range buffer[initializedCount...] must be uninitialized. This postcondition must hold even if the initializer closure throws an error.

Compressed image is bigger than the original

Once again, thanks for the library! This issue is related to my previous one. I'm basically trying to compress/optimize for file size as much as I can, yet the image I get from the .compress (with level 13) call is bigger than the original one by a huge margin, I imagine because extra bits are being used/padded per pixel.

Any recommendation to aggressively reduce file size?

Screenshot 000807

Issues building on Windows

Package cannot be build on Windows running swift build because of missing module _Builtin_intrinsics.intel:

swift build
warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\unit\common

warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\integration\common

warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\compression\common

Building for debugging...
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel
       ^
c:\Users\1\Documents\swift-png\sources\png\dictionary.swift:3:8: error: no such module '_Builtin_intrinsics.intel'
import _Builtin_intrinsics.intel

This issue could be solved with passing define NO_INTRINSICS to Swift compiler invokations. But this exposes a bunch of compile errors:

swift build -Xswiftc -DNO_INTRINSICS
warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\unit\common

warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\integration\common

warning: 'swift-png': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target
    c:\Users\1\Documents\swift-png\tests\compression\common

Building for debugging...
c:\Users\1\Documents\swift-png\sources\png\os.swift:10:14: warning: unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)
    #warning("unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)")
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\sources\png\os.swift:10:14: warning: unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)
    #warning("unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)")
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\sources\png\os.swift:10:14: warning: unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)
    #warning("unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)")
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\sources\png\os.swift:10:14: warning: unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)
    #warning("unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)")
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\sources\png\os.swift:10:14: warning: unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)
    #warning("unsupported or untested platform (please open an issue at https://github.com/kelvin13/swift-png/issues)")
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:5:55: error: incorrect argument label in call (have 'path:', expected 'stream:')
guard var image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
                                                      ^~~~~
                                                       stream
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:5:45: error: static method 'decompress(stream:)' requires that 'String' conform to '_PNGBytestreamSource'
guard var image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
                                            ^
c:\Users\1\Documents\swift-png\sources\png\decoder.swift:1018:10: note: where 'Source' = 'String'
    func decompress<Source>(stream:inout Source) throws -> Self
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:13:73: error: cannot infer key path type from context; consider explicitly specifying a root type
let rgba:[PNG.RGBA<UInt8>] = image.unpack(as: PNG.RGBA<UInt8>.self).map(\.straightened)
                                                                        ^
                                                                         <#Root#>
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:5: error: generic parameter 'Destination' could not be inferred
try standard.compress(path: "\(path)-rgb8.png")
    ^
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: in call to function 'compress(stream:level:hint:)'
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:29: error: extra argument 'path' in call
try standard.compress(path: "\(path)-rgb8.png")
                     ~~~~~~~^~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:23: error: missing argument for parameter 'stream' in call
try standard.compress(path: "\(path)-rgb8.png")
                      ^
                      stream: &<#_#>,
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: 'compress(stream:level:hint:)' declared here
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:5: error: generic parameter 'Destination' could not be inferred
try apple.compress(path: "\(path)-bgr8.png")
    ^
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: in call to function 'compress(stream:level:hint:)'
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:26: error: extra argument 'path' in call
try apple.compress(path: "\(path)-bgr8.png")
                  ~~~~~~~^~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:20: error: missing argument for parameter 'stream' in call
try apple.compress(path: "\(path)-bgr8.png")
                   ^
                   stream: &<#_#>,
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: 'compress(stream:level:hint:)' declared here
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:5:55: error: incorrect argument label in call (have 'path:', expected 'stream:')
guard var image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
                                                      ^~~~~
                                                       stream
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:5:45: error: static method 'decompress(stream:)' requires that 'String' conform to '_PNGBytestreamSource'
guard var image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
                                            ^
c:\Users\1\Documents\swift-png\sources\png\decoder.swift:1018:10: note: where 'Source' = 'String'
    func decompress<Source>(stream:inout Source) throws -> Self
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:13:73: error: cannot infer key path type from context; consider explicitly specifying a root type
let rgba:[PNG.RGBA<UInt8>] = image.unpack(as: PNG.RGBA<UInt8>.self).map(\.straightened)
                                                                        ^
                                                                         <#Root#>
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:29: error: extra argument 'path' in call
try standard.compress(path: "\(path)-rgb8.png")
                     ~~~~~~~^~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:23: error: missing argument for parameter 'stream' in call
try standard.compress(path: "\(path)-rgb8.png")
                      ^
                      stream: &<#_#>,
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: 'compress(stream:level:hint:)' declared here
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:22:5: error: generic parameter 'Destination' could not be inferred
try standard.compress(path: "\(path)-rgb8.png")
    ^
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: in call to function 'compress(stream:level:hint:)'
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:26: error: extra argument 'path' in call
try apple.compress(path: "\(path)-bgr8.png")
                  ~~~~~~~^~~~~~~~~~~~~~~~~~~
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:20: error: missing argument for parameter 'stream' in call
try apple.compress(path: "\(path)-bgr8.png")
                   ^
                   stream: &<#_#>,
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: 'compress(stream:level:hint:)' declared here
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^
c:\Users\1\Documents\swift-png\examples\iphone-optimized\main.swift:29:5: error: generic parameter 'Destination' could not be inferred
try apple.compress(path: "\(path)-bgr8.png")
    ^
c:\Users\1\Documents\swift-png\sources\png\encoder.swift:560:10: note: in call to function 'compress(stream:level:hint:)'
    func compress<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
         ^

Creating in-memory image

I'm looking to generate PNG images in memory rather than loading from a file - is there a way to construct an image of a given size with, for example, all pixels initialized to a given color? I don't see anything obvious in the api file but I wanted to see if I was missing something.

Thank you for creating this library.

How to load from NSImage?

First of all, thanks for the library! I have loaded my image into an NSImage (I use the native APIs to do some manipulations) afterwards instead of saving it to a file, I would like to pass the in-memory data directly to swift-png to save it already compressed. Could you give me a hand and detail what is necessary to achieve this? I would greatly appreciate it!

Windows support

I tried out the Windows support in Swift 5.4 and got the following error:

https://github.com/kelvin13/png.git @ 3.0.2: error: invalidManifestFormat("C:\Users\Gon Solo\AppData\Local\Temp\TemporaryFile.VDuarB.swift:19:12: error: unsupported or untested platform (please open an issue at https://github.com/kelvin13/png/issues)\r\r\n #error("unsupported or untested platform (please open an issue at https://github.com/kelvin13/png/issues)\")\r\r\n ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", diagnosticFile: nil) in https://github.com/kelvin13/png.git

spin-off gzip library

swift-png contains a high-quality implementation of LZ77 which is already pretty decoupled from the rest of the library, and would be useful to other server applications. we should split it off into its own module.

Gzip compression API should be failable, and return nil for very short inputs

calling the compression API with data shorter than 2 bytes is violating many preconditions, leading to runtime crashes!

it would never make sense to run a compression algorithm on data that small. the compressed file would be dozens of times larger than the original input. we should impose a minimum data length of at least 8 bytes, or implement a separate path using https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art053 as inspiration

utils/benchmark cannot compile baseline

utils/benchmark    
clang -Wall -Wpedantic -lpng benchmarks/decompression/baseline/main.c -o benchmarks/decompression/baseline/main
benchmarks/decompression/baseline/main.c:6:10: fatal error: 'png.h' file not found
#include <png.h>
         ^~~~~~~
1 error generated.

reenable macos ci builds

travis ci builds on macos are currently disabled until travis supports the xcode 11 environment.

Custom Chunk Reading?

Sometimes there may be data embedded in custom chunks in an image. How would one use swift-png to check for these custom chunks? For example, TavernAI uses PNG cards that have a base64 string encoded into a "chara" chunk. How would I get this using swift-png? Sorry, I know this is an issue and not a support forum, but I'm stumped!

provide single-stage conversion API

the library should provide a convenience function that takes any format of PNG and normalizes it to a user-provided format in a single function call. (right now we don’t do this because some checks are unnecessary if certain things are known about the PNGs beforehand. however these are all per-image, nor per-pixel checks so it really wouldn’t be that much less efficient)

API should look like

func convert<Component>(_ path:String, to format:PixelFormat) throws 
    -> ([Component], Int, Int) where Component:BinaryInteger

let (data, width, height):([UInt16], Int, Int) = try convert("example.png", to: .rgba) 
// .rgba, .grayscale, .planar

Performance in debug builds

Using this library in an application test suite where debug builds are enabled encoding a single 1024x1024 image takes several minutes pegging the cpu (M1) at 100% and using 300mb+ of memory.

Is there some workaround for this? I don't mind png coding being a bit slower in tests but several minutes is a showstopper. I can't seem to find any way to selectively enable optimizations for a swift package included via Xcode's "Package Dependencies" (setting the whole test target to -Os doesn't seem to help either for some reason...)

Strip image of any profiles, comments or these PNG chunks

Is there a function to strip the image of any profiles, comments or these PNG chunks: bKGD,cHRM,EXIF,gAMA,iCCP,iTXt,sRGB,tEXt,zCCP,zTXt,date. To remove the orientation chunk, orNT, set the orientation to undefined, e.g., -orient Undefined.

fails to load png file in MacOS sandboxed environment, even if App has all the right flags set

sandboxed MacOS App cannot open a User-Selected PNG file, even when the app has set all the right bits. (Tested with reading other files with code not in swift-png.)

Reading the same file from within the App's sandbox (~/Library/Containers/my-app/) succeeds. According to this stackoverflow post, it's because the library accesses the file via a simple string path, rather than the blessed URL returned by the file importer dialog.

https://stackoverflow.com/questions/74534788/macos-swift-app-on-xcode-14-1-cannot-read-user-selected-file

request that swift-png entry points accept file URLS to enable its use in sandboxed MacOS apps. thank you!

(am brand new to git, please interpret protocol errors as naïveté, not belligerence, thanks)

Building Zlib module fails

Sorry if this is totally the wrong place for this issue, but I am a bit out of my depth. :/

Trying to add maxpng to a swift project, and compile on mac os, I am getting some compile errors related to zlib.

Running macOS 10.13, Xcode 9.0.1

Output:

Compile Swift Module 'MaxPNG' (1 sources)
/usr/include/zconf.h:247:14: note: while building module 'Darwin' imported from /usr/include/zconf.h:247:
#    include <stddef.h>
             ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "sys/cdefs.h"
        ^
/usr/include/sys/cdefs.h:587:10: error: 'sys/_symbol_aliasing.h' file not found
#include <sys/_symbol_aliasing.h>
         ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/usr/include/zlib.h"
        ^
/usr/include/zlib.h:34:10: note: in file included from /usr/include/zlib.h:34:
#include "zconf.h"
         ^
/usr/include/zconf.h:247:14: error: could not build module 'Darwin'
#    include <stddef.h>
             ^
/Users/bspaulding/source/swift-catsdogs/.build/checkouts/maxpng.git-4539351761082512968/Sources/maxpng.swift:1:8: error: could not build Objective-C module 'Zlib'
import Zlib
       ^

Unit tests don't compile on Windows

swift run PNGTests
Building for debugging...
c:\Users\1\Documents\tmp1\swift-png\Tests\PNG\Main.swift:9:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
c:\Users\1\Documents\tmp1\swift-png\Tests\PNG\Main.swift:1:1: note: top-level code defined in this source file
@testable import PNG
^
c:\Users\1\Documents\tmp1\swift-png\Tests\PNG\Main.swift:9:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
c:\Users\1\Documents\tmp1\swift-png\Tests\PNG\Main.swift:1:1: note: top-level code defined in this source file
@testable import PNG
^

Version of swift:

swift --version
compnerd.org Swift version 5.7.1 (swift-5.7.1-RELEASE)
Target: x86_64-unknown-windows-msvc

These unit tests build and run on macOS normally. Version of swift on macOS is the same as on Windows.

Possible to only extract headers?

I have a use case where I would like to check whether a PNG image contains a single color, by using its histogram.

Is there an option anywhere to only parse the headers of the stream?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.