--- a/docs/01-installation.markdown Mon Dec 23 15:26:57 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Installation
-============
-
-cl-netpbm can be installed with Quicklisp:
-
- (ql:quickload :cl-netpbm)
-
-The `cl-netpbm` system provides all the functionality of the library. It has no
-dependencies.
-
-The `cl-netpbm/test` system provides the unit tests. It depends on `1am` and
-`external-program`, and also requires [ImageMagick][im] for its fuzz testing.
-
-[im]: https://www.imagemagick.org/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/01-usage.markdown Mon Dec 23 15:27:04 2019 -0500
@@ -0,0 +1,164 @@
+Usage
+=====
+
+The [netpbm image formats (PPM, PGM, and PBM)][netpbm] are a family of very
+simple image formats. You can convert to/from these formats with third-party
+tools like [ImageMagick][im].
+
+Instead of trying to link `libjpeg` into your Lisp program with CFFI, you can
+use this library to read/write images in the simple netpbm format and then use
+a third-party tool to convert to whatever other format(s) you need.
+
+cl-netpbm provides functions for both reading and writing images, as well as
+a little bit of sugar for working with OpenGL textures.
+
+[netpbm]: https://en.wikipedia.org/wiki/Netpbm_format
+[im]: https://www.imagemagick.org/
+
+[TOC]
+
+Reading Images
+--------------
+
+The `netpbm:read-from-stream` function can be used to read a netpbm file from
+stream. The stream *must* be a binary input stream with `element-type` of
+`(unsigned-byte 8)`.
+
+Three values are returned: a 2D array of pixels, the format of the image
+(`:pbm`, `:pgm`, or `:ppm`), and the bit depth of the image:
+
+ (with-open-file (f "foo.ppm" :element-type '(unsigned-byte 8))
+ (netpbm:read-from-stream f))
+ ; =>
+ #2A((#(255 0 0) #(0 255 0) #(0 0 255))
+ (#(255 0 0) #(0 255 0) #(0 0 255))
+ (#(255 0 0) #(0 255 0) #(0 0 255))
+ (#(255 0 0) #(0 255 0) #(0 0 255)))
+ :PPM
+ 255
+
+A `netpbm:read-from-file` function is also provided to save you some
+boilerplate:
+
+ (netpbm:read-from-file "foo.ppm")
+
+See the [API reference](../reference) for these functions for more information.
+
+Image Arrays
+------------
+
+When an image is read a 2D array of pixels is returned.
+
+The first array dimension is the columns of the image and the second array
+dimension is the rows. This means to access pixel `(x, y)` of the image you use
+`(aref image x y)`. The `y` dimension starts at the top of the image and grows
+downwards, so:
+
+* `(aref image 0 0)` returns the top-left pixel.
+* `(aref image width height)` returns the bottom-right pixel.
+
+The `element-type` of the array (i.e. the type of the pixels) depends on the
+format of the image that was read:
+
+* Pixels of PBM images are of type `bit`.
+* Pixels of PGM images are of type `(integer 0 ,bit-depth)`.
+* Pixels of PPM images are of type `(simple-array (integer 0 ,bit-depth) (3))`.
+
+Lower values represent darker colors, e.g. for PBM images `0` is black and `1`
+is white, for PGM `0` is black, `1` is very dark gray, etc.
+
+(Note that the actual PBM image format on disk is backwards from all the other
+netpbm formats — in PBM a `1` bit represents black. cl-netpbm flips the bits
+when reading/writing PBM files for consistency on the Lisp side of things.)
+
+Writing Images
+--------------
+
+An image array can be written to a stream with `netpbm:write-to-stream`. The
+stream *must* be a binary output stream with `element-type` of `(unsigned-byte
+8)`. The input image array must have the appropriate contents for the desired
+output format (e.g. integers for `:pbm` and `:pgm`, 3-element vectors for
+`:pgm`):
+
+ (with-open-file (f "foo.pbm"
+ :direction :output
+ :element-type '(unsigned-byte 8))
+ (netpbm:write-to-stream
+ f #2A((0 0 0 0 0 0 0 0 0 0)
+ (0 1 1 1 1 1 1 1 1 0)
+ (0 1 0 0 1 1 0 0 0 0)
+ (0 1 0 0 1 0 1 0 0 0)
+ (0 0 1 1 0 0 0 1 1 0)
+ (0 0 0 0 0 0 0 0 0 0))
+ :format :pbm
+ :encoding :binary))
+ ; => Write an "R" character into "foo.pbm"
+
+`netpbm:write-to-file` is provided for convenience:
+
+ (netpbm:write-to-file "foo.pbm" image :format :pbm)
+
+See the [API reference](../reference) for these functions for more information.
+
+Example: Inverting an Image
+---------------------------
+
+For a concrete example, let's invert an image.
+
+First we'll get a kitten photo to work with and convert it to PPM with
+ImageMagick:
+
+ wget 'https://upload.wikimedia.org/wikipedia/commons/7/75/Cute_grey_kitten.jpg' -O kitten.jpg
+ convert -resize x600 kitten.jpg kitten.ppm
+
+The initial kitten ([source](https://en.m.wikipedia.org/wiki/File:Cute_grey_kitten.jpg)):
+
+![kitten photo](../assets/kitten.jpg)
+
+Now we can write our Lisp code:
+
+ (defun invert-value (value)
+ (- 255 value))
+
+ (defun invert-pixel (pixel)
+ (map-into pixel #'invert-value pixel))
+
+ (defun invert-image (image)
+ (destructuring-bind (width height) (array-dimensions image)
+ (dotimes (y height)
+ (dotimes (x width)
+ (invert-pixel (aref image x y))))))
+
+ (let ((image (netpbm:read-from-file "kitten.ppm")))
+ (invert-image image)
+ (netpbm:write-to-file "kitten-inverted.ppm" image))
+
+And convert it back into JPG:
+
+ convert kitten-inverted.ppm kitten-inverted.jpg
+
+And now we have an inverted kitten:
+
+![kitten photo](../assets/kitten-inverted.jpg)
+
+OpenGL Textures
+---------------
+
+cl-netpbm's image array layout (column major, 3-element vectors for RGB pixels,
+y-axis from top to bottom) is meant to be simple for humans to code against.
+If you're working with OpenGL and were hoping to use cl-netpbm to easily load
+textures (instead of fiddling around with FFI'ing out to something like
+[STB](https://github.com/nothings/stb)) this won't work, because OpenGL expects
+a different format (a flat array of `single-float`s, y-axis from bottom to top).
+
+For your convenience, cl-netpbm provides two additional functions that will
+return an array in the format OpenGL expects: `netpbm:read-texture-from-stream`
+and `netpbm:read-texture-from-file`.
+
+Remember, though, that the netpbm formats are designed for simplicity, not
+efficiency. If you're just going through [an OpenGL
+tutorial](https://learnopengl.com/) and want to load a texture without screwing
+around with CFFI, cl-netpbm can help you out. But if you're creating an actual
+game where performance matters, you'll likely want to replace it with something
+much more efficient.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/02-reference.markdown Mon Dec 23 15:27:04 2019 -0500
@@ -0,0 +1,148 @@
+# API Reference
+
+The following is a list of all user-facing parts of cl-netpbm.
+
+If there are backwards-incompatible changes to anything listed here, they will
+be noted in the changelog and the author will feel bad.
+
+Anything not listed here is subject to change at any time with no warning, so
+don't touch it.
+
+[TOC]
+
+## Package `NETPBM`
+
+### `READ-FROM-FILE` (function)
+
+ (READ-FROM-FILE PATH)
+
+Read a PPM image file from `path`, returning an array of pixels and more.
+
+ The primary return value will be a 2D array with dimensions `(width height)`.
+ Each element of the array will be a single pixel whose type depends on the
+ image file format:
+
+ * PBM: `bit`
+ * PGM: `(integer 0 maximum-value)`
+ * PPM: `(simple-array (integer 0 maximum-value) (3))`
+
+ Two other values are returned:
+
+ * The format of the image that was read (one of `:pbm`, `:pgm`, `:ppm`).
+ * The bit depth of the image.
+
+
+
+### `READ-FROM-STREAM` (function)
+
+ (READ-FROM-STREAM STREAM)
+
+Read a PPM image file from `stream`, returning an array of pixels and more.
+
+ `stream` must be a binary input stream, specifically of `(unsigned-byte 8)`s
+ unless you *really* know what you're doing.
+
+ The primary return value will be a 2D array with dimensions `(width height)`.
+ Each element of the array will be a single pixel whose type depends on the
+ image file format:
+
+ * PBM: `bit`
+ * PGM: `(integer 0 maximum-value)`
+ * PPM: `(simple-array (integer 0 maximum-value) (3))`
+
+ Two other values are returned:
+
+ * The format of the image that was read (one of `:pbm`, `:pgm`, `:ppm`).
+ * The bit depth of the image.
+
+
+
+### `READ-TEXTURE-FROM-FILE` (function)
+
+ (READ-TEXTURE-FROM-FILE PATH)
+
+Read a PPM image file from `path`, returning an OpenGL-style array and more.
+
+ The primary return value will be an OpenGL-style array of type:
+
+ (simple-array (single-float 0.0 1.0) (* width height 3))
+
+ The vertical axis of the image will be flipped, which is what OpenGL expects.
+
+ Three values are returned: the array, the width, and the height.
+
+
+
+### `READ-TEXTURE-FROM-STREAM` (function)
+
+ (READ-TEXTURE-FROM-STREAM STREAM)
+
+Read a PPM image file from `stream`, returning an OpenGL-style array and more.
+
+ `stream` must be a binary input stream, specifically of `(unsigned-byte 8)`s
+ unless you *really* know what you're doing. The stream must contain a PPM
+ formatted image — PBM and PGM images are not supported.
+
+ The primary return value will be an OpenGL-style array of type:
+
+ (simple-array (single-float 0.0 1.0) (* width height 3))
+
+ The vertical axis of the image will be flipped, which is what OpenGL expects.
+
+ Three values are returned: the array, the width, and the height.
+
+
+
+### `WRITE-TO-FILE` (function)
+
+ (WRITE-TO-FILE PATH DATA &KEY (IF-EXISTS NIL IF-EXISTS-GIVEN) (FORMAT :PPM) (ENCODING :BINARY)
+ (MAXIMUM-VALUE (ECASE FORMAT (:PBM 1) ((:PGM :PPM) 255))))
+
+Write a PPM image array `data` to a file at `path`.
+
+ Nothing is returned.
+
+ `format` must be one of `:pbm`, `:pgm`, `:ppm`.
+
+ `encoding` must be one of `:binary`, `:ascii`.
+
+ `maximum-value` must be the desired bit depth of the image (the maximum value
+ any particular pixel can have). For PBM images it must be `1`.
+
+ For PBM and PGM images, `data` must be a two dimensional array of integers
+ between `0` and `maximum-value` inclusive.
+
+ For PPM images, `data` must be a two dimensional array of pixels, each of
+ which must be a 3 element vector of integers between `0` and `maximum-value`
+ inclusive.
+
+
+
+### `WRITE-TO-STREAM` (function)
+
+ (WRITE-TO-STREAM STREAM DATA &KEY (FORMAT :PPM) (ENCODING :BINARY)
+ (MAXIMUM-VALUE (ECASE FORMAT (:PBM 1) ((:PGM :PPM) 255))))
+
+Write a PPM image array `data` to `stream`.
+
+ Nothing is returned.
+
+ `stream` must be a binary output stream, specifically of `(unsigned-byte 8)`s
+ unless you *really* know what you're doing.
+
+ `format` must be one of `:pbm`, `:pgm`, `:ppm`.
+
+ `encoding` must be one of `:binary`, `:ascii`.
+
+ `maximum-value` must be the desired bit depth of the image (the maximum value
+ any particular pixel can have). For PBM images it must be `1`.
+
+ For PBM and PGM images, `data` must be a two dimensional array of integers
+ between `0` and `maximum-value` inclusive.
+
+ For PPM images, `data` must be a two dimensional array of pixels, each of
+ which must be a 3 element vector of integers between `0` and `maximum-value`
+ inclusive.
+
+
+
--- a/docs/02-usage.markdown Mon Dec 23 15:26:57 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-Usage
-=====
-
-The [netpbm image formats (PPM, PGM, and PBM)][netpbm] are a family of very
-simple image formats. You can convert to/from these formats with third-party
-tools like [ImageMagick][im].
-
-Instead of trying to link `libjpeg` into your Lisp program with CFFI, you can
-use this library to read/write images in the simple netpbm format and then use
-a third-party tool to convert to whatever other format(s) you need.
-
-cl-netpbm provides functions for both reading and writing images, as well as
-a little bit of sugar for working with OpenGL textures.
-
-[netpbm]: https://en.wikipedia.org/wiki/Netpbm_format
-[im]: https://www.imagemagick.org/
-
-[TOC]
-
-Reading Images
---------------
-
-The `netpbm:read-from-stream` function can be used to read a netpbm file from
-stream. The stream *must* be a binary input stream with `element-type` of
-`(unsigned-byte 8)`.
-
-Three values are returned: a 2D array of pixels, the format of the image
-(`:pbm`, `:pgm`, or `:ppm`), and the bit depth of the image:
-
- (with-open-file (f "foo.ppm" :element-type '(unsigned-byte 8))
- (netpbm:read-from-stream f))
- ; =>
- #2A((#(255 0 0) #(0 255 0) #(0 0 255))
- (#(255 0 0) #(0 255 0) #(0 0 255))
- (#(255 0 0) #(0 255 0) #(0 0 255))
- (#(255 0 0) #(0 255 0) #(0 0 255)))
- :PPM
- 255
-
-A `netpbm:read-from-file` function is also provided to save you some
-boilerplate:
-
- (netpbm:read-from-file "foo.ppm")
-
-See the [API reference](../reference) for these functions for more information.
-
-Image Arrays
-------------
-
-When an image is read a 2D array of pixels is returned.
-
-The first array dimension is the columns of the image and the second array
-dimension is the rows. This means to access pixel `(x, y)` of the image you use
-`(aref image x y)`. The `y` dimension starts at the top of the image and grows
-downwards, so:
-
-* `(aref image 0 0)` returns the top-left pixel.
-* `(aref image width height)` returns the bottom-right pixel.
-
-The `element-type` of the array (i.e. the type of the pixels) depends on the
-format of the image that was read:
-
-* Pixels of PBM images are of type `bit`.
-* Pixels of PGM images are of type `(integer 0 ,bit-depth)`.
-* Pixels of PPM images are of type `(simple-array (integer 0 ,bit-depth) (3))`.
-
-Lower values represent darker colors, e.g. for PBM images `0` is black and `1`
-is white, for PGM `0` is black, `1` is very dark gray, etc.
-
-(Note that the actual PBM image format on disk is backwards from all the other
-netpbm formats — in PBM a `1` bit represents black. cl-netpbm flips the bits
-when reading/writing PBM files for consistency on the Lisp side of things.)
-
-Writing Images
---------------
-
-An image array can be written to a stream with `netpbm:write-to-stream`. The
-stream *must* be a binary output stream with `element-type` of `(unsigned-byte
-8)`. The input image array must have the appropriate contents for the desired
-output format (e.g. integers for `:pbm` and `:pgm`, 3-element vectors for
-`:pgm`):
-
- (with-open-file (f "foo.pbm"
- :direction :output
- :element-type '(unsigned-byte 8))
- (netpbm:write-to-stream
- f #2A((0 0 0 0 0 0 0 0 0 0)
- (0 1 1 1 1 1 1 1 1 0)
- (0 1 0 0 1 1 0 0 0 0)
- (0 1 0 0 1 0 1 0 0 0)
- (0 0 1 1 0 0 0 1 1 0)
- (0 0 0 0 0 0 0 0 0 0))
- :format :pbm
- :encoding :binary))
- ; => Write an "R" character into "foo.pbm"
-
-`netpbm:write-to-file` is provided for convenience:
-
- (netpbm:write-to-file "foo.pbm" image :format :pbm)
-
-See the [API reference](../reference) for these functions for more information.
-
-Example: Inverting an Image
----------------------------
-
-For a concrete example, let's invert an image.
-
-First we'll get a kitten photo to work with and convert it to PPM with
-ImageMagick:
-
- wget 'https://upload.wikimedia.org/wikipedia/commons/7/75/Cute_grey_kitten.jpg' -O kitten.jpg
- convert -resize x600 kitten.jpg kitten.ppm
-
-The initial kitten ([source](https://en.m.wikipedia.org/wiki/File:Cute_grey_kitten.jpg)):
-
-![kitten photo](../assets/kitten.jpg)
-
-Now we can write our Lisp code:
-
- (defun invert-value (value)
- (- 255 value))
-
- (defun invert-pixel (pixel)
- (map-into pixel #'invert-value pixel))
-
- (defun invert-image (image)
- (destructuring-bind (width height) (array-dimensions image)
- (dotimes (y height)
- (dotimes (x width)
- (invert-pixel (aref image x y))))))
-
- (let ((image (netpbm:read-from-file "kitten.ppm")))
- (invert-image image)
- (netpbm:write-to-file "kitten-inverted.ppm" image))
-
-And convert it back into JPG:
-
- convert kitten-inverted.ppm kitten-inverted.jpg
-
-And now we have an inverted kitten:
-
-![kitten photo](../assets/kitten-inverted.jpg)
-
-OpenGL Textures
----------------
-
-cl-netpbm's image array layout (column major, 3-element vectors for RGB pixels,
-y-axis from top to bottom) is meant to be simple for humans to code against.
-If you're working with OpenGL and were hoping to use cl-netpbm to easily load
-textures (instead of fiddling around with FFI'ing out to something like
-[STB](https://github.com/nothings/stb)) this won't work, because OpenGL expects
-a different format (a flat array of `single-float`s, y-axis from bottom to top).
-
-For your convenience, cl-netpbm provides two additional functions that will
-return an array in the format OpenGL expects: `netpbm:read-texture-from-stream`
-and `netpbm:read-texture-from-file`.
-
-Remember, though, that the netpbm formats are designed for simplicity, not
-efficiency. If you're just going through [an OpenGL
-tutorial](https://learnopengl.com/) and want to load a texture without screwing
-around with CFFI, cl-netpbm can help you out. But if you're creating an actual
-game where performance matters, you'll likely want to replace it with something
-much more efficient.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/03-changelog.markdown Mon Dec 23 15:27:04 2019 -0500
@@ -0,0 +1,11 @@
+Changelog
+=========
+
+Here's the list of changes in each released version.
+
+[TOC]
+
+v1.0.0
+------
+
+Initial version.
--- a/docs/03-reference.markdown Mon Dec 23 15:26:57 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-# API Reference
-
-The following is a list of all user-facing parts of cl-netpbm.
-
-If there are backwards-incompatible changes to anything listed here, they will
-be noted in the changelog and the author will feel bad.
-
-Anything not listed here is subject to change at any time with no warning, so
-don't touch it.
-
-[TOC]
-
-## Package `NETPBM`
-
-### `READ-FROM-FILE` (function)
-
- (READ-FROM-FILE PATH)
-
-Read a PPM image file from `path`, returning an array of pixels and more.
-
- The primary return value will be a 2D array with dimensions `(width height)`.
- Each element of the array will be a single pixel whose type depends on the
- image file format:
-
- * PBM: `bit`
- * PGM: `(integer 0 maximum-value)`
- * PPM: `(simple-array (integer 0 maximum-value) (3))`
-
- Two other values are returned:
-
- * The format of the image that was read (one of `:pbm`, `:pgm`, `:ppm`).
- * The bit depth of the image.
-
-
-
-### `READ-FROM-STREAM` (function)
-
- (READ-FROM-STREAM STREAM)
-
-Read a PPM image file from `stream`, returning an array of pixels and more.
-
- `stream` must be a binary input stream, specifically of `(unsigned-byte 8)`s
- unless you *really* know what you're doing.
-
- The primary return value will be a 2D array with dimensions `(width height)`.
- Each element of the array will be a single pixel whose type depends on the
- image file format:
-
- * PBM: `bit`
- * PGM: `(integer 0 maximum-value)`
- * PPM: `(simple-array (integer 0 maximum-value) (3))`
-
- Two other values are returned:
-
- * The format of the image that was read (one of `:pbm`, `:pgm`, `:ppm`).
- * The bit depth of the image.
-
-
-
-### `READ-TEXTURE-FROM-FILE` (function)
-
- (READ-TEXTURE-FROM-FILE PATH)
-
-Read a PPM image file from `path`, returning an OpenGL-style array and more.
-
- The primary return value will be an OpenGL-style array of type:
-
- (simple-array (single-float 0.0 1.0) (* width height 3))
-
- The vertical axis of the image will be flipped, which is what OpenGL expects.
-
- Three values are returned: the array, the width, and the height.
-
-
-
-### `READ-TEXTURE-FROM-STREAM` (function)
-
- (READ-TEXTURE-FROM-STREAM STREAM)
-
-Read a PPM image file from `stream`, returning an OpenGL-style array and more.
-
- `stream` must be a binary input stream, specifically of `(unsigned-byte 8)`s
- unless you *really* know what you're doing. The stream must contain a PPM
- formatted image — PBM and PGM images are not supported.
-
- The primary return value will be an OpenGL-style array of type:
-
- (simple-array (single-float 0.0 1.0) (* width height 3))
-
- The vertical axis of the image will be flipped, which is what OpenGL expects.
-
- Three values are returned: the array, the width, and the height.
-
-
-
-### `WRITE-TO-FILE` (function)
-
- (WRITE-TO-FILE PATH DATA &KEY (IF-EXISTS NIL IF-EXISTS-GIVEN) (FORMAT :PPM) (ENCODING :BINARY)
- (MAXIMUM-VALUE (ECASE FORMAT (:PBM 1) ((:PGM :PPM) 255))))
-
-Write a PPM image array `data` to a file at `path`.
-
- Nothing is returned.
-
- `format` must be one of `:pbm`, `:pgm`, `:ppm`.
-
- `encoding` must be one of `:binary`, `:ascii`.
-
- `maximum-value` must be the desired bit depth of the image (the maximum value
- any particular pixel can have). For PBM images it must be `1`.
-
- For PBM and PGM images, `data` must be a two dimensional array of integers
- between `0` and `maximum-value` inclusive.
-
- For PPM images, `data` must be a two dimensional array of pixels, each of
- which must be a 3 element vector of integers between `0` and `maximum-value`
- inclusive.
-
-
-
-### `WRITE-TO-STREAM` (function)
-
- (WRITE-TO-STREAM STREAM DATA &KEY (FORMAT :PPM) (ENCODING :BINARY)
- (MAXIMUM-VALUE (ECASE FORMAT (:PBM 1) ((:PGM :PPM) 255))))
-
-Write a PPM image array `data` to `stream`.
-
- Nothing is returned.
-
- `stream` must be a binary output stream, specifically of `(unsigned-byte 8)`s
- unless you *really* know what you're doing.
-
- `format` must be one of `:pbm`, `:pgm`, `:ppm`.
-
- `encoding` must be one of `:binary`, `:ascii`.
-
- `maximum-value` must be the desired bit depth of the image (the maximum value
- any particular pixel can have). For PBM images it must be `1`.
-
- For PBM and PGM images, `data` must be a two dimensional array of integers
- between `0` and `maximum-value` inclusive.
-
- For PPM images, `data` must be a two dimensional array of pixels, each of
- which must be a 3 element vector of integers between `0` and `maximum-value`
- inclusive.
-
-
-
--- a/docs/04-changelog.markdown Mon Dec 23 15:26:57 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-Changelog
-=========
-
-Here's the list of changes in each released version.
-
-[TOC]
-
-v1.0.0
-------
-
-Initial version.