├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── sdl2-image.asd └── src ├── autowrap.lisp ├── conditions.lisp ├── general.lisp ├── library.lisp ├── package.lisp └── spec ├── SDL_image.aarch64-apple-darwin9.spec ├── SDL_image.h ├── SDL_image.i386-unknown-freebsd.spec ├── SDL_image.i686-apple-darwin9.spec ├── SDL_image.i686-pc-linux-gnu.spec ├── SDL_image.i686-pc-windows-msvc.spec ├── SDL_image.powerpc64-pc-linux-gnu.spec ├── SDL_image.powerpc64le-pc-linux-gnu.spec ├── SDL_image.x86_64-apple-darwin9.spec ├── SDL_image.x86_64-pc-linux-gnu.spec ├── SDL_image.x86_64-pc-windows-msvc.spec └── SDL_image.x86_64-unknown-freebsd.spec /.gitattributes: -------------------------------------------------------------------------------- 1 | src/spec/*.spec linguist-language=Common Lisp 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.fasl 2 | *.lx??fsl 3 | *.dx??fsl 4 | src/sdl2-cffi.lisp 5 | src/sdl2-macros.lisp 6 | .plant/ 7 | .#* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Ryan Pavlik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cl-sdl2-image 2 | 3 | This is a (currently) brief but usable wrap for SDL2_image. Currently, this exports the following: 4 | 5 | * `(sdl2-image:init LIST-OF-FORMATS)`: Initialize and load `LIST-OF-FORMATS`, which should be a list of any combination of the keyword `:png`, `:jpg`, and `:tif`. This calls `IMG_Init()`. 6 | * `(sdl2-image:quit)`: This calls `IMG_Quit()`. 7 | * `(sdl2-image:load-image FILENAME)`: This calls `IMG_Load()` on the filename, and returns an `SDL-SURFACE`. 8 | 9 | These functions act more or less like their wrapped equivalents; see the SDL_image 2.0 documentation for details. 10 | 11 | ## Regenerating CFFI Bindings 12 | 13 | This library uses [cl-autowrap](https://github.com/rpav/cl-autowrap) to generate CFFI bindings. If you need to regenerate the bindings, follow these steps: 14 | 15 | 1. Delete the existing bindings: 16 | 17 | ``` 18 | $ rm -f src/spec/SDL_image.*.spec 19 | ``` 20 | 21 | 2. Reload the system in a REPL. This action will automatically regenerate the bindings: 22 | 23 | ``` 24 | ${LISP-sbcl} \ 25 | --load "sdl2-image.asd" \ 26 | --eval "(ql:quickload '(:sdl2-image))" \ 27 | --eval "(uiop:quit)" 28 | ``` 29 | 30 | In most cases, this process should work without issues. However, if you encounter problems (usually due to environment-specific factors like missing include headers), you can use the `C_INCLUDE_PATH` environment variable to specify additional include paths: 31 | 32 | ``` 33 | C_INCLUDE_PATH=/data1/include:/data1/lib/include \ 34 | ${LISP-sbcl} \ 35 | --load "sdl2-image.asd" \ 36 | --eval "(ql:quickload '(:sdl2-image))" \ 37 | --eval "(uiop:quit)" 38 | ``` 39 | 40 | This approach allows you to provide the necessary include paths without modifying the source code. 41 | 42 | ## Issues 43 | 44 | If you require further functions, please file an issue, **pull request**, or inquire in `#lispgames` on freenode. 45 | 46 | If you can't load `libSDL2_image`, please ensure that you have SDL_image 2.0 installed, and not just 1.2. Earlier versions will not work correctly. In the case of Windows, please ensure this, along with SDL2's DLLs, are installed in the same directory as your Lisp `.exe`. 47 | 48 | If you are sure all of this is correct, and it still will not load, please [file an issue](https://github.com/lispgames/cl-sdl2-image/issues/new) and specify: 49 | 50 | * Your platform and architecture 51 | * Your lisp 52 | * The absolute path to your installed `.so`, `.dll`, or the appropriate OSX framework 53 | -------------------------------------------------------------------------------- /sdl2-image.asd: -------------------------------------------------------------------------------- 1 | (defpackage :sdl2-image.asdf 2 | (:use #:cl #:asdf)) 3 | 4 | (in-package :sdl2-image.asdf) 5 | 6 | (defsystem :sdl2-image 7 | :description "Bindings for sdl2_image using autowrap" 8 | :author "Ryan Pavlik" 9 | :maintainer ("Michael Fiano ") 10 | :license "MIT" 11 | :version "1.0" 12 | :depends-on (#:alexandria 13 | #:defpackage-plus 14 | #:cl-autowrap 15 | #:sdl2) 16 | :pathname "src" 17 | :serial t 18 | :components 19 | ((:file "package") 20 | (:file "library") 21 | (:file "autowrap") 22 | (:file "conditions") 23 | (:file "general") 24 | 25 | (:module autowrap-spec 26 | :pathname "spec" 27 | :components 28 | ((:static-file "SDL_image.h"))))) 29 | -------------------------------------------------------------------------------- /src/autowrap.lisp: -------------------------------------------------------------------------------- 1 | (cl:in-package :sdl2-ffi) 2 | 3 | (autowrap:c-include 4 | `(sdl2-image autowrap-spec "SDL_image.h") 5 | :function-package :sdl2-ffi.functions 6 | :spec-path '(sdl2-image autowrap-spec) 7 | :exclude-sources ("/usr/local/lib/clang/([^/]*)/include/(?!stddef.h)" 8 | "/usr/include/" 9 | #+darwin "/opt/homebrew/include/SDL2" 10 | "/usr/include/arm-linux-gnueabihf" 11 | "/usr/local/include/SDL2") 12 | :include-sources ("SDL_image.h") 13 | :sysincludes (cl:append 14 | #+darwin '("/opt/homebrew/include") 15 | (cl:if (uiop:getenv "C_INCLUDE_PATH") 16 | (uiop:split-string (uiop:getenv "C_INCLUDE_PATH") :separator ":"))) 17 | :exclude-constants ("^__") 18 | :symbol-exceptions (("SDL_RWops" . "SDL-RWOPS")) 19 | :no-accessors cl:t 20 | :release-p cl:t) 21 | -------------------------------------------------------------------------------- /src/conditions.lisp: -------------------------------------------------------------------------------- 1 | (in-package :sdl2-image) 2 | 3 | (define-condition sdl-image-error (sdl2::sdl-rc-error) ()) 4 | 5 | (defmacro check-rc (form) 6 | (with-gensyms (rc) 7 | `(let ((,rc ,form)) 8 | (when (< ,rc 0) 9 | (error 'sdl-image-error :rc ,rc :string (sdl-get-error))) 10 | ,rc))) 11 | 12 | (defmacro check-non-zero (form) 13 | (with-gensyms (rc) 14 | `(let ((,rc ,form)) 15 | (unless (/= ,rc 0) 16 | (error 'sdl-image-error :rc ,rc :string (sdl-get-error))) 17 | ,rc))) 18 | 19 | (defmacro check-true (form) 20 | (with-gensyms (rc) 21 | `(let ((,rc ,form)) 22 | (unless (sdl-true-p ,rc) 23 | (error 'sdl-image-error :rc ,rc :string (sdl-get-error))) 24 | ,rc))) 25 | 26 | (defmacro check-null (form) 27 | (with-gensyms (wrapper) 28 | `(let ((,wrapper ,form)) 29 | (if (cffi:null-pointer-p (autowrap:ptr ,wrapper)) 30 | (error 'sdl-image-error :rc ,wrapper :string (sdl-get-error)) 31 | ,wrapper)))) 32 | 33 | (defmacro check= (value-form check-form) 34 | (with-gensyms (rc) 35 | `(let ((,rc ,check-form)) 36 | (unless (= ,rc ,value-form) 37 | (error 'sdl-image-error :rc ,rc :string (sdl-get-error))) 38 | t))) 39 | -------------------------------------------------------------------------------- /src/general.lisp: -------------------------------------------------------------------------------- 1 | (in-package :sdl2-image) 2 | 3 | (defun linked-version () 4 | (c-let ((version sdl2-ffi:sdl-version :from (img-linked-version))) 5 | (values (version :major) (version :minor) (version :patch)))) 6 | 7 | (autowrap:define-bitmask-from-enum (img-initflags sdl2-ffi:img-init-flags)) 8 | 9 | (defun init (flags) 10 | (let ((flags (mask-apply 'img-initflags flags))) 11 | (check= flags (img-init flags)))) 12 | 13 | (defun quit () (img-quit)) 14 | 15 | (defun load-image (filename) 16 | (check-null (img-load (namestring (merge-pathnames filename))))) 17 | 18 | (defmacro load-from-rw-wrapper (file-specifier load-macro) 19 | `(let ((rwops-object (sdl2:rw-from-file (namestring ,file-specifier) "rb"))) 20 | (unwind-protect (check-null ,load-macro) 21 | (sdl2:rw-close rwops-object)))) 22 | 23 | (defmacro define-loader-function (file-type) 24 | (let* ((wrapper-name (intern (string-upcase (format 'nil 25 | "load-~a-rw" 26 | file-type)))) 27 | (original-name (intern (format 'nil 28 | "IMG-~a" 29 | (symbol-name wrapper-name))))) 30 | `(progn (defun ,wrapper-name (file-specifier) 31 | (load-from-rw-wrapper file-specifier 32 | (,original-name rwops-object))) 33 | (export ',wrapper-name)))) 34 | 35 | (defun load-type-rw (file-specifier file-type-hint) 36 | "Load a given file of a specified type and return an SDL surface object. The specified file type hint is a string representing one of the file types supported by sdl2 image. The supported types are documented in the official sdl2 image documentation. The original API had an argument indicating whether or not to automatically free the rwops pointer. However since an rwops structure is generated internally, this has been omitted and is automaticalaly freed" 37 | (load-from-rw-wrapper file-specifier 38 | (img-load-typed-rw rwops-object 39 | 0 40 | file-type-hint))) 41 | 42 | (define-loader-function "bmp") 43 | (define-loader-function "cur") 44 | (define-loader-function "gif") 45 | (define-loader-function "ico") 46 | (define-loader-function "jpg") 47 | (define-loader-function "lbm") 48 | (define-loader-function "pcx") 49 | (define-loader-function "png") 50 | (define-loader-function "tga") 51 | (define-loader-function "tif") 52 | (define-loader-function "xcf") 53 | (define-loader-function "xpm") 54 | (define-loader-function "xv") 55 | 56 | (defun save-png (surface filename) 57 | "Write a surface to a PNG file." 58 | (check-rc (img-save-png surface filename))) 59 | -------------------------------------------------------------------------------- /src/library.lisp: -------------------------------------------------------------------------------- 1 | (in-package :sdl2-image) 2 | 3 | (cffi:define-foreign-library libsdl2-image 4 | ;; I have no idea if this is the correct framework, file an issue 5 | ;; and let me know! 6 | (:darwin (:or (:framework "SDL2_image") (:default "libSDL2_image"))) 7 | (:unix (:or "libSDL2_image-2.0.so.0" "libSDL2_image" "libSDL2_image.so.1.1")) 8 | (:windows "SDL2_image.dll") 9 | (t (:default "libSDL2_image"))) 10 | 11 | (cffi:use-foreign-library libsdl2-image) 12 | -------------------------------------------------------------------------------- /src/package.lisp: -------------------------------------------------------------------------------- 1 | (in-package defpackage+-user-1) 2 | 3 | (defpackage+ :sdl2-image 4 | (:use #:cl #:alexandria #:autowrap.minimal #:plus-c #:sdl2-ffi.functions) 5 | (:export-only 6 | 7 | ;; Conditions 8 | #:sdl-image-error 9 | 10 | ;; General 11 | #:linked-version 12 | #:init #:quit #:load-image #:load-type-rw #:save-png 13 | )) 14 | 15 | (in-package :sdl2-image) 16 | 17 | ;; Variables 18 | 19 | -------------------------------------------------------------------------------- /src/spec/SDL_image.h: -------------------------------------------------------------------------------- 1 | #include 2 | --------------------------------------------------------------------------------