leptonic

  1. leptonic
    1. Description
    2. Author
    3. Repository
    4. Requirements
    5. Installing
    6. Using the leptonic egg
    7. Leptonic egg api
      1. Format-type procedures
      2. Foreign types
      3. Reading image files
      4. Writing image files
      5. Deallocating image data
      6. Scaling
      7. Unsharp mask
      8. Pixel data input/output
      9. Image manipulation
      10. Image analysis
      11. Effects
      12. Dithering
      13. Threshold
      14. Conversion
      15. Error messages
      16. Serializing data 32bit to 8bit, 8bit to 32bit
    8. Versions

Description

This egg provides a Scheme interface to the leptonica image processing library authored by Dan Bloomberg. The egg offers a subset of the extensive leptonica C-API, focusing on a set of high-level leptonica functions that are likely to be useful to Scheme programmers.

Author

Jules Altfas

Repository

https://codeberg.org/jrapdx/leptonic

Requirements

The egg has these dependencies:

The image libraries are available on many platforms through their respective package systems. Installing from source is an option if one or more are not otherwise available.

Installing

On unix platforms, the egg should install normally with chicken-install -s leptonic, or alternatively, clone/download the repo and run chicken-install -s in the local directory.

On Windows, the leptonica library needs to be installed before installing the egg. Make sure libleptonica-6.dll is in a directory on the exec path. Then chicken-install should compile/install the egg without errors.

Programs using/importing leptonic need to be linked with the leptonica library.

  1. Install image libraries through the system package manager or from source if not otherwise available.
  2. Install the leptonica library. (See the leptonica site at http://www.leptonica.org/source/README.html for detailed instructions for compiling from source.)

Using the leptonic egg

The leptonica library abstracts image data into one of several C-structs which are used by functions to read/write image files, perform scaling, morphing, modifying and coverting images. An advantage of this approach is the simplicity and uniformity it provides for library users. libleptonica includes a wealth of high- and low-level functions for these purposes. A selection of the library’s high-level functions are represented in this egg.

The primary C-struct is “Pix” with fields including width, height, depth (1,2,4,8,32 bits/pixel), samples/pixel, xres, yres, colormap, and img-data (array of unsigned-int32). Users should regard Pix and other structures as opaque as the “internals” are handled by the procedures. Most of the Scheme procedures take/return ‘ppix’ (ptr to struct Pix) along with other arguments.

A major benefit of leptonica is that image processing is decoupled from input/output format, greatly simplifying programs that handle image files. A typical usage pattern starts with reading an image file with ‘pix-read’ (or ‘pix-read-FORMAT’), returning a ppix (ptr to Pix). Manipulations are applied and finally, ‘pix-write’ or ‘pix-write-FORMAT’ writes ppix data to an output file.

Leptonic egg api

Format-type procedures

[procedure] n->ftype N
[procedure] ftype->n TYPE

TABLE. leptonica image formats

integer symbol
0 IFF_UNKNOWN
1 IFF_BMP
2 IFF_JFIF_JPEG
3 IFF_PNG
4 IFF_TIFF
5 IFF_TIFF_PACKBITS
6 IFF_TIFF_RLE
7 IFF_TIFF_G3
8 IFF_TIFF_G4
9 IFF_TIFF_LZW
10 IFF_TIFF_ZIP
11 IFF_PNM
12 IFF_PS
13 IFF_GIF
14 IFF_JP2
15 IFF_WEBP
16 IFF_LPDF
17 IFF_TIFF_JPEG
18 IFF_DEFAULT
19 IFF_SPIX

Foreign types

(define-foreign-type pix (struct Pix))
(define-foreign-type ppix (c-ptr (struct Pix)))
(define-foreign-type pixa (struct Pixa))
(define-foreign-type ppixa (c-ptr (struct Pixa)))
(define-foreign-type fpix (struct FPix)) ;; float pix
(define-foreign-type pfpix (c-ptr (struct FPix))) 
(define-foreign-type fpixa (struct FPixa)) ;; array of FPix
(define-foreign-type pfpixa (c-ptr (struct FPixa)))

Use (include "leptonic-types.scm") to make these available.

Reading image files

[procedure] pix-read FILENAME
[procedure] pix-read-header FILENAME PFMT PW PH PBPS PSPP PISCMAP
(import leptonic)
(define-external fmt unsigned-int32)
(define-external w unsigned-int32)
(define-external h unsigned-int32)
(define-external bps unsigned-int32)
(define-external spp unsigned-int32)
(define-external cmap unsigned-int32)
(pix-read-header "img1.jpg" (location fmt) (location w)
                            (location h) (location bps)
                            (location spp) (location cmap))
;; fmt -> 2, w -> 898, h -> 606, bps -> 8, spp -> 3, cmap -> 0
;; image is 24bpp (bps * spp)
[procedure] pix-get-width PPIX
[procedure] pix-get-height PPIX
[procedure] get-implied-fmt FILENAME
[procedure] find-file-fmt FILENAME PFMT
(define-external fmt int)
(define r (find-file-fmt "file0.png" (location fmt)))
;; r -> 0 (no error), fmt -> 3

Writing image files

[procedure] pix-write FILENAME PPIX FORMAT
[procedure] pix-write-jpeg FILENAME PPIX QUALITY PROGRESSIVE
[procedure] pix-write-png FILENAME PPIX GAMMA
[procedure] pix-write-webp FILENAME PPIX QUALITY LOSSLESS
[procedure] pix-copy PPIXD PPIX

Deallocating image data

[procedure] pix-destroy PTR-TO-PPIX
(define-external ppx ppix (pix-read "img0.jpg"))
...
(pix-destroy (location ppx))
[procedure] pix-free-data PPIX

Scaling

[procedure] pix-scale PPIX SCALEX SCALEY
[procedure] pix-scale-general PPIX SCALEX SCALEY SHARPFRAC SHARPWIDTH
(define-external ppix0 ppix (pix-read "img0.webp"))
(define scaledpix (pix-scale-general ppix0 1.2 1.2 0.25 1))
...
(define res (pix-write scaledpix "img0-1.2x.webp" scaledpix 15))
;; res -> 0
[procedure] pix-scale-smooth PPIX SCALEX SCALEY
[procedure] pix-scale-to-size PPIX WIDTH HEIGHT

Unsharp mask

[procedure] pix-unsharp-mask PPIX SMOOTHING AMOUNT
[procedure] pix-unsharp-mask-fast PPIX HALFWIDTH AMOUNT DIRECTION

Pixel data input/output

[procedure] pix-create WIDTH HEIGHT DEPTH
[procedure] pix-get-data PPIX
[procedure] pix-extract-data PPIX
[procedure] pix-set-data PPIX DATAPTR
[procedure] pix-get-pixel PPIX X Y PTR-PIXVAL
[procedure] pix-set-pixel PPIX X Y PIXEL-VALUE
[procedure] pix-get-rgb-component PPIX COLOR
[procedure] extract-rgb-vals PIXEL PRED PGREEN PBLUE
[procedure] pix-get-rgb-line PPIX ROW PR PG PB
(import chicken.number-vector leptonic)
(define red (make-u8vector img-width))
(define green (make-u8vector img-width))
(define blue (make-u8vector img-width))
(define r (pix-get-rgb-line ppix row (location red)
                           (locaton green) (location blue)))
(if (zero? r)
    ;; use red, green, blue vectors ...
    ;; handle error)
[procedure] pix-get-raster-data PPIX PUBYTE PNBYTES

Image manipulation

[procedure] pix-modify-sat PPIXD PPIX SAT
[procedure] pix-invert PPIXD PPIX
[procedure] pix-and PPIXD PPIX0 PPIX1
[procedure] pix-or PPIXD PPIX0 PPIX1
[procedure] pix-xor PPIXD PPIX0 PPIX1
[procedure] pix-shiftRGB PPIX RFRAC GFRAC BFRAC
[procedure] pix-contrast PPIXD PPIX FACTOR
[procedure] pix-mod-brightness PPIXD PPIX FACTOR
[procedure] pix-mod-hue PPIXD PPIX FACTOR
[procedure] pix-equalize PPIXD PPIX FRAC SUBSAMPLE
[procedure] pix-gamma PPIXD PPIX GAMMA MIN MAX
[procedure] pix-remove-alpha PPIX
[procedure] pix-map-to-color PPIXD PPIX SRCVAL DSTVAL
[procedure] pix-colorize-gray PPIX PIXEL CMAP?
[procedure] pix-bilateral PPIX SPATIAL RANGE NCOMPS REDUCTION
[procedure] pix-warp-stereo PPIX ZBEND ZSHIFTT ZSHIFTB YBENDT YBENDB RLEFT
[procedure] pix-blend-color PPIXD PPIX1 PPIX2 X Y FRACT TRANSPARENT TRANSPIX

Image analysis

[procedure] pix-sizes-equal PPIX1 PPIX2
[procedure] pix-get-pixel-avg PPIX PPIXM X Y FACTOR PVAL
[procedure] pix-compare-gray-or-RGB PPIX1 PPIX2 CMPTYPE PLOT PSAME PDIFF PRMSDIFF PPIXDIFF
[procedure] pix-color-content PPIX RREF GREF BREF MINGRAY RCONT GCONT BCONT
(import scheme.base leptonic)
(include "leptonic-types.scm")
(define-external imgpix ppix (pix-read "myimage.jpg"))
(define-external rcont ppix)
(define-external gcont ppix)
(define-external bcont ppix)
(define r (pix-color-content imgpix 0 0 0 20 (location rcont)
    (location gcont) (location bcont)))
(if (zero? r)
    (begin
       ;; -- use the ppixs: rcont, gcont, bcont --
       (pix-destroy (location imgpix))
       (pix-destroy (location rcont))
       (pix-destroy (location gcont))
       (pix-destroy (location bcont)))
    ;; -- handle error --)
[procedure] pix-color-fraction PPIX DARKTHR LIGHTTHR DIFFTHR FACTOR PIXFRAC COLORFRAC
[procedure] pix-color-magnitude PPIX RREF GREF BREF TYPE

Effects

[procedure] pix-clean-image PPIX CONTRAST ROTATE SCALE OPEN-SIZE
[procedure] gen-bin-maze WIDTH HEIGHT X Y SIDEWALL AHEAD
(import scheme.base chicken.foreign leptonic)
(include "leptonic-types.scm")
;; generate maze, 100x75px, starts at x=5,y=70px
(define-external maze ppix (gen-bin-maze 100 75 5 70 .52 .48))
(pix-write "maze.jpg" maze 2)
(pix-destroy (location maze))
[procedure] pix-sobel-edge-filter PPIX ORIENTATION

Dithering

[procedure] pix-dither-2bpp PPIX CMAP?
[procedure] pix-dither-2bpp-spec PPIX LOWCLIP UPCLIP CMAP?
[procedure] pix-dither-binary PPIX
[procedure] pix-dither-bin-spec PPIX LOWCLIP UPCLIP

Threshold

[procedure] pix-threshold-to-binary PPIX THRESH
[procedure] pix-threshold-to-2bpp PPIX NLEVELS CMAP?
[procedure] pix-threshold-to-4bpp PPIX NLEVELS CMAP?
[procedure] pix-threshold-on-8bpp PPIX NLEVELS CMAP?

Conversion

[procedure] pix-RGB-to-gray PPIX RWT GWT BWT
[procedure] pix-RGB-to-gray-fast PPIX

<procedure>pix->32bit PPIX </procedure>

[procedure] pix->16bit PPIX
[procedure] pix->8bit PPIX
[procedure] pix->4bit PPIX
[procedure] pix->2bit PPIX
[procedure] pix->1bit PPIX
[procedure] pix-RGB->HSV PPIXD PPIX
[procedure] pix-HSV->RGB PPIXD PPIX
[procedure] pix-RGB->XYZ PPIX
[procedure] pix-RGB->YUV PPIXD PPIX
[procedure] pix-YUV->RGB PPIXD PPIX
[procedure] pix-RGB->hue PPIX
[procedure] pix-RGB->sat PPIX
[procedure] pix-RGB->value PPIX
[procedure] pix-RGB->Lab PPIX
[procedure] fpixa-Lab->RGB PFPIXA
[procedure] fpixa-Lab->XYZ PFPIXA
[procedure] fpixa-XYZ->Lab PFPIXA
[procedure] fpixa-XYZ->RGB PFPIXA

Error messages

[procedure] set-msg-level LEVEL

Serializing data 32bit to 8bit, 8bit to 32bit

These routines are not from leptonica, but provided to facilitate conversion of 32 bpp data to 8 bpp arrays (in RGB order) and vice versa.

[procedure] u32->u8''3 PTR32 LEN PTR8*
[procedure] u8''3->u32 PTR8 LEN PTR32*
(import scheme.base 
        chicken.foreign 
        chicken.number-vector
        leptonic)

(include "leptonic-types.scm")

(define-external ppx0 ppix (pix-read "input.png"))
(define data0 (pix-get-data ppx0))

(define w (pix-get-width ppx0))
(define h (pix-get-height ppx0))
(define len (* w h))

(define v8 (make-u8vector (* len 3) 0))
(u32->u8*3 data0 len (location v8))

;; ... modify v8 ...

(define-external ppx1 ppix (pix-create w h 32))
(define data1 (pix-get-data ppx1))

(u8*3->u32 (location v8) len data1)

(define fmt (get-implied-fmt "output.png"))
(pix-write "output.png" ppx1 fmt)

(pix-destroy (location ppx0))
(pix-destroy (location ppx1))

Note: if u8vector ‘v8’ is not modified, then output to data1 (in u8*3->u32), will be identical to the input data in data0. IOW “output.png” will be a copy of “input.png”. Comparing the two image files serves as a test of the procedures: if everything is working properly, the image files should be completely indistinguishable.

Versions