Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== leptonic [[toc:]] === 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 leptonica library – https://github.com/DanBloomberg/leptonica, which is dependent on: ** libjpeg – https://sourceforge.net/projects/libjpeg-turbo/ ** libtiff – https://gitlab.com/libtiff/libtiff ** libpng – https://libpng.sourceforge.io/index.html ** libz – https://zlib.net/ ** libwebp – https://github.com/webmproject/libwebp ** libgif – https://giflib.sourceforge.net ** libopenjp2 – https://github.com/uclouvain/openjpeg 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. As of the most recent release, version 1.87.0, the recommended way to install on Windows is using Microsoft ''vcpkg''. A few issues arise using ''vcpkg'': * Selecting a location to install {{vcpkg}}. Probably installing directly on "C:" is the best option. In that case, the {{bin}} and {{lib}} directories will be in "c:/vcpkg/installed/x64-windows/". * Making sure the {{bin}} directory is on the executable path. It's necessary to manually add the {{bin}} directory to the path environment variable, not hard to do. Default {{leptonic.egg}} uses {{c:/vcpkg/installed/x64-windows/lib}}. If vcpkg is installed elsewhere, edit the .egg file accordingly. Another option is creating a symlink to {{C:/vcpkg}}. (On powershell, from c:\, use an invocation like {{new-item -itemtype SymbolicLink -path ".\vcpkg" -target "\directory-where-vcpkg-is-installed\vcpkg"}} * The {{vcpkg}} install uses the Windows convention for naming libraries, that is, with ".lib" extension and without "lib" prefix. Such library names may not be compatible with compiling on {{mingw}}. If the problem is encountered, copy the library file in the same directory and rename it. For example, copy {{../lib/leptonica-1.87.0.lib}} as {{../lib/libleptonica.dll.a}}. * Once these are done, {{`chicken-install`}} should work without error. Programs using/importing {{leptonic}} need to be linked with the leptonica library. # Install image libraries through the system package manager or from source if not otherwise available. # 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 most recently released ''leptonica'' version is 1.87.0. This release doesn't make changes incompatible with the API of this egg. Note that new procedures have been added in the current version of ''leptonic'' (0.2.4). 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. === Types and constants The following defined foreign types and constants are used throughout this extension. In Chicken Scheme modules/libraries {{define-foreign-type}} and {{define-constant}} aren't visible outside the file in which they're defined. For that reason it's essential to use {{(include "leptonic-types.scm")}} in Scheme files that import leptonic. ==== 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))) ==== Constants <constant>PI</constant> * value: 3.14159265359 <constant>HORZ-EDGES</constant> <constant>VERT-EDGES</constant> <constant>ALL-EDGES</constant> ---- <constant>HORZ</constant> <constant>VERT</constant> <constant>BOTH</constant> ---- <constant>CLR-RED</constant> <constant>CLR-GREEN</constant> <constant>CLR-BLUE</constant> ---- <constant>ROT-AM</constant> <constant>ROT-SHEAR</constant> <constant>ROT-SAMP</constant> ---- <constant>IN-WHITE</constant> <constant>IN-BLACK</constant> ---- <constant>CMP-SUBTRACT</constant> <constant>CMP-ABS-DIFF</constant> ---- <constant>CHOOSE-MIN</constant> <constant>CHOOSE-MAX</constant> ---- (import leptonic) (include "leptonic-types.scm") (define-external imgpix ppix (pix-read "img0.jpg")) (define-external rotpix ppix (pix-rotate imgpix (deg2rad -15) ROT-SAMP IN-BLACK 0 0)) (define result (pix-write "rotatedimg.jpg" rotpix (ftype->n 'IFF_JFIF_JPEG))); (if (zero? result) ;; "success" ;; "failed") (pix-destroy (location imgpix)) (pix-destroy (location rotpix)) === Leptonic egg api ==== NOTE: procedure arguments PPIXD PPIX ... A number of api procedures have two or more ppix arguments: ''e.g.'', PPIXD PPIX ... PPIXD is the "destination" ppix, and the next (PPIX, PPIX1), is the "source" ppix. There are 3 ways PPIXD can be used: * Set PPIXD #f (NULL). : The procedure returns a freshly allocated ppix. This is the typical case. ** (_procx_ #f ppixs ...) => allocates new ppix * Set PPIXD to an existing ppix. Procedure writes output to PPIXD, and returns PPIXD as the procedure result. *** (_procx_ ppixd ppixs ...) => ppixd * Set PPIXD to the the same ppix as the source ppix. The result is "in-place" modification of the source ppix. *** (_procx_ ppixs ppixs ...) => ppixs ==== Format-type procedures <procedure>n->ftype N</procedure> * in - N: {{int}} - range: 0-19 * returns: {{symbol}}, ''e.g.'', ’IFF_JFIF_JPEG <procedure>ftype->n TYPE</procedure> * in - TYPE: {{symbol}} * returns: {{int}}. (See TABLE.) TABLE. leptonica image formats <table> <tr><th>integer</th><th>symbol</th></tr> <tr><td>0</td><td>IFF_UNKNOWN</td></tr> <tr><td>1</td><td>IFF_BMP</td></tr> <tr><td>2</td><td>IFF_JFIF_JPEG</td></tr> <tr><td>3</td><td>IFF_PNG</td></tr> <tr><td>4</td><td>IFF_TIFF</td></tr> <tr><td>5</td><td>IFF_TIFF_PACKBITS</td></tr> <tr><td>6</td><td>IFF_TIFF_RLE</td></tr> <tr><td>7</td><td>IFF_TIFF_G3</td></tr> <tr><td>8</td><td>IFF_TIFF_G4</td></tr> <tr><td>9</td><td>IFF_TIFF_LZW</td></tr> <tr><td>10</td><td>IFF_TIFF_ZIP</td></tr> <tr><td>11</td><td>IFF_PNM</td></tr> <tr><td>12</td><td>IFF_PS</td></tr> <tr><td>13</td><td>IFF_GIF</td></tr> <tr><td>14</td><td>IFF_JP2</td></tr> <tr><td>15</td><td>IFF_WEBP</td></tr> <tr><td>16</td><td>IFF_LPDF</td></tr> <tr><td>17</td><td>IFF_TIFF_JPEG</td></tr> <tr><td>18</td><td>IFF_DEFAULT</td></tr> <tr><td>19</td><td>IFF_SPIX</td></tr> </table> ==== Error message redirection ''Leptonica'' by default emits error messages on ''stderr''. This is fine for command-line programs, but not for GUI applications. However, ''leptonica'' does have a ''handler'' API that redirects error messages through program-provided callback functions. The egg has 3 procedures interfacing with redirection functions: <procedure>lept-redirect</procedure> * calling {{(lept-redirect)}} redirects stderr messages to a buffer (~800 bytes), from which error text will be retrieved. <procedure>lept-errmsg</procedure> * {{(lept-errmsg)}} returns error text as a Scheme string which can be written to a GUI widget or other element. <procedure>lept-reset</procedure> * restores the original output of error messages to ''stderr''. (import leptonic) ;; a callback procedure (lambda () ... <read an image file ...> (if (not (zero? result)) ;; retrieve error text (write-to-widget (lept-errmsg)) ;; use image (display-image <img-data>)) ...) ;; call once at start of program (lept-redirect) ... ==== Read image file <procedure>pix-read FILENAME</procedure> * in - FILENAME: {{string}} * returns: ppix or #f on error. <procedure>pix-read-header FILENAME PFMT PW PH PBPS PSPP PISCMAP</procedure> * in - FILENAME: {{string}} * in - PFMT PW PH PBPS PSPP PISCMAP: {{ptr to unsigned-int32}} ** Other args are optional, pass #f to skip. ** Optionals: image-format, width, height, bits/sample, samples/pixel, has-colormap?(0=no/1=yes). ** ("Sample" equiv to "channel", re: bits/channel, channels/pixel.) (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> * in - PPIX * returns: width as {{int}}. <procedure>pix-get-height PPIX</procedure> * in - PPIX * returns: height as {{int}}. <procedure>get-implied-fmt FILENAME</procedure> * in - FILENAME: {{string}} * returns: format as {{int}}. <procedure>find-file-fmt FILENAME PFMT</procedure> * in - FILENAME: {{string}} * out - PFMT: {{ptr to int}} * returns: 0 on success, 1 if error/unrecognized format. (define-external fmt int) (define r (find-file-fmt "file0.png" (location fmt))) ;; r -> 0 (no error), fmt -> 3 ==== Write image file <procedure>pix-write FILENAME PPIX FORMAT</procedure> * in - FILENAME: {{string}} * in - PPIX * in - FORMAT {{int}} * returns: 0 on success, 1 if error. <procedure>pix-write-jpeg FILENAME PPIX QUALITY PROGRESSIVE</procedure> * in - FILENAME: {{string}} * in - PPIX * in - QUALITY: {{int32}} - 1 to 100, 75 is default * in - PROGRESSIVE: {{int32}} - 1=yes, 0=no * returns: 0 on success, 1 if error. <procedure>pix-write-png FILENAME PPIX GAMMA</procedure> * in - FILENAME: {{string}} * in - PPIX * in - GAMMA: {{float}} - 0.0 if not defined * returns: 0 on success, 1 if error. <procedure>pix-write-webp FILENAME PPIX QUALITY LOSSLESS</procedure> * in - FILENAME: {{string}} * in - PPIX * in - QUALITY: {{int32}} - 1 to 100 * in - LOSSLESS: {{int32}} - 1=yes, 0=no * returns: 0 on success, 1 if error. <procedure>pix-copy PPIXD PPIX</procedure> * in - PPIXD: #f or PPIX (see NOTE above) * in - PPIX * returns: copy of ppix ==== Deallocate image data <procedure>pix-destroy PTR-TO-PPIX</procedure> * in - PTR-TO-PPIX: {{ptr ppix}} * returns: no return value (import leptonic) (include "leptonic-types.scm") (define-external ppx ppix (pix-read "img0.jpg")) ... (pix-destroy (location ppx)) <procedure>pix-free-data PPIX</procedure> * in - PPIX ** Deallocates data member but not Pix structure itself, use {{(pix-destroy PPIX)}} when PPIX no longer needed. * returns: no return value ==== Scaling <procedure>pix-scale PPIX SCALEX SCALEY</procedure> * in - PPIX * in - SCALEX, SCALEY: {{float}} values. ** Uses: sharpening for scale factors 0.2-0.7, ** ‘linear interpolation’ for factors 0.7-1.4, and ** no sharpening when scale factors > 1.4. * returns: scaled ppix on success, #f on error. <procedure>pix-scale-general PPIX SCALEX SCALEY SHARPFRAC SHARPWIDTH</procedure> * in - PPIX * in - SCALEX/Y, SHARPFRAC: {{flaot}}. * in - SHARPWIDTH: {{int}}, 1 or 2. * returns: modified ppix. ** When max scalex/y is < 0.2, no sharpening applied. ** Between .2 and 1.4, sharpen according to input values. ** With scalex/y > 1.4, no sharpening is applied. ** For precise control, call {{(pix-scale-general ...)}} with sharpfrac 0.0 followed by call to {{(pix-unsharp-mask ...)}}. (import leptonic) (include "leptonic-types.scm") (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> * in - PPIX * in - SCALEX/Y: {{float}}. ** Scale factors MUST BE <0.7 * returns: modified ppix, or #f on error. <procedure>pix-scale-to-size PPIX WIDTH HEIGHT</procedure> * in - PPIX * in - WIDTH/HEIGHT: {{int32}} - pixels. ** To preserve aspect ratio, set width 0, use height as target. Or set height to 0 to use width as target. * returns: modified ppix or #f on error. ==== Unsharp mask <procedure>pix-unsharp-mask PPIX SMOOTHING AMOUNT</procedure> * in - PPIX * in - SMOOTHING: filter is odd {{int}} such as 3, 5, 7. Input is halfwidth = (size - 1)/2, ''i.e.'', 1, 2, 3. * in - AMOUNT is {{float}}, typically in range 0.2 to 0.7. * returns: modified ppix. <procedure>pix-unsharp-mask-fast PPIX HALFWIDTH AMOUNT DIRECTION</procedure> * in - PPIX * in - HALFWIDTH: {{int}}, 1 or 2 * in - AMOUNT = {{float}}, 0.2 to 0.7 * in - DIRECTION: {{int}}, {{HORZ}}, {{VERT}} or {{BOTH}} * returns: modified ppix. ==== Pixel data input/output <procedure>pix-create WIDTH HEIGHT DEPTH</procedure> * in - WIDTH/HEIGHT: {{int32}}, in pixels. * in - DEPTH: must be 1, 2, 4, 8, or 32 ** Pix->data is {{ptr to unsigned-int32}}, array length = w''h, elements initialized to 0 * returns: ppix on success, #f on error. <procedure>pix-get-data PPIX</procedure> * in - PPIX ** Returned data-array remains “owned” by ppix, array modified in place. * returns: {{ptr to unsigned-int32}} if successful, #f on error. <procedure>pix-extract-data PPIX</procedure> * in - PPIX ** Unlike {{pix-get-data}}, returned value is ptr to newly alloc copy of ppix->data. ppix->data is set to NULL if ppix->refcount == 1 * returns: {{ptr to unsigned-int32}} on success, #f on error. <procedure>pix-set-data PPIX DATAPTR</procedure> * in - PPIX * in - DATAPTR: {{ptr to unsigned-int32}} * returns: 0 if successful, 1 on error. ** Use {{pix-free-data}} prior to setting ppix data. <procedure>pix-get-pixel PPIX X Y PTR-PIXVAL</procedure> * in - PPIX * in - X, Y: {{int32}} - raster position * out - PTR-PIXVAL: {{ptr to unsigned-int32}} * returns: 0 on success, 1 on error <procedure>pix-set-pixel PPIX X Y PIXEL-VALUE</procedure> * in - PPIX * in - X, Y: {{int32}} - raster position * in - PIXEL-VALUE: {{unsigned-int32}} * returns: 0 on success, 1 on error <procedure>pix-get-rgb-component PPIX COLOR</procedure> * in - PPIX * in - COLOR: {{int32}}, one of {{CLR-RED}}, {{CLR-GREEN}}, {{CLR-BLUE}} * returns: ppix set to COLOR component, #f on error. <procedure>extract-rgb-vals PIXEL PRED PGREEN PBLUE</procedure> * in - a PIXEL: {{unsigned-int32}} * in - PRED, PGREEN, PBLUE - optional, {{ptr to int32}} or #f * returns: no return value. <procedure>pix-get-rgb-line PPIX ROW PR PG PB</procedure> * in - PPIX * in - ROW: {{int32}} * in - PR, PG, PB: {{ptr to unsigned-byte}}, array length = image width * returns: 0 if success, 1 on error. (import chicken.number-vector leptonic) (include "leptonic-types.scm") (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</procedure> * in - PPIX * out - PUBYTE: {{ptr to unsigned-byte}}, array-length = (* w h 3) * out - PNBYTES: {{ptr to size_t}} * returns: 0 on success, 1 if error. ==== Image manipulation <procedure>pix-modify-sat PPIXD PPIX SAT</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - SAT: {{float}} - from -1.0 to 1.0 * returns: modified ppix, or #f on error <procedure>pix-invert PPIXD PPIX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * returns: - inverted ppix or #f on error <procedure>pix-and PPIXD PPIX1 PPIX2</procedure> * in - PPIXD - #f or PPIX1 (see NOTE above) * in - PPIX1, PPIX2 - image data to be “anded” * returns: - PPIX1 AND PPIX2, or #f on error <procedure>pix-or PPIXD PPIX1 PPIX2</procedure> * in - PPIXD - #f or PPIX1 (see NOTE above) * in - PPIX1, PPIX2 - image data to be “ored” * returns: - PPIX1 OR PPIX2, or #f on error <procedure>pix-xor PPIXD PPIX1 PPIX2</procedure> * in - PPIXD - #f or PPIX1 (see NOTE above) * in - PPIX1, PPIX2 - image data to be “xored” * returns: - PPIX1 XOR PPIX2, or #f on error <procedure>pix-shiftRGB PPIX RFRAC GFRAC BFRAC</procedure> * in - PPIX * in - RFRAC, GFRAC, BFRAC: {{float}} - fractional amount of change per channel * returns: modified ppix or #f on error. <procedure>pix-contrast PPIXD PPIX FACTOR</procedure> * in- PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - FACTOR - amount, 0.0 to 1.0 * returns: modified ppix or #f if error. <procedure>pix-mod-brightness PPIXD PPIX FACTOR</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - FACTOR - amount -1.0 to 1.0 * returns: modified ppix or #f if error. <procedure>pix-mod-hue PPIXD PPIX FACTOR</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - FACTOR - amount -1.0 to 1.0 (1.0/-1.0 == 360 degrees, no hue change) * returns: modified ppix or #f if error. <procedure>pix-equalize PPIXD PPIX FRAC SUBSAMPLE</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - FRAC - 0.0 to 1.0 “equalization movement of pixels”, 1.0 == complete. * in - SUBSAMPLE - factor > 1 => reduced computation * returns: modified ppix or #f if error. <procedure>pix-gamma PPIXD PPIX GAMMA MIN MAX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - GAMMA - 1.0, no change, <1.0 darker, >1.0 lighter * in - M* in - MIN usually >=0, but may be < 0–black will be gray. * in - MAX - MAX usually <= 255, but may be > 255, then whites are gray… * returns: modified ppix or #f if error. <procedure>pix-remove-alpha PPIX</procedure> * in - PPIX * returns: ppix with alpha removed, or #f on error. <procedure>pix-map-to-color PPIXD PPIX SRCVAL DSTVAL</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * in - SRCVAL - color specified as 0xrrggbb00 * in - DSTVAL - color specified as 0xrrggbb00 * returns: modified ppix or #f if error. <procedure>pix-colorize-gray PPIX PIXEL CMAP?</procedure> * in - PPIX - 8bit (grayscale) * in - PIXEL - 32bit color spec, e.g., 0xrrggbb00 * in - CMAP? - add colormap, 0 or 1 * returns: modified ppix or #f if error. <procedure>pix-bilateral PPIX SPATIAL RANGE NCOMPS REDUCTION</procedure> * in - PPIX * in - SPATIAL - stddev of gaussian kernel, pixels, >0.5 * in - RANGE - stddev of gaussian range kernel, >5.0, typically 50.0 * in - NCOMPS - intermediate sums, 4..30 * in - REDUCTION - 1, 2, 4 * returns: modified ppix or #f if error. <procedure>pix-warp-stereo PPIX ZBEND ZSHIFTT ZSHIFTB YBENDT YBENDB RLEFT</procedure> * in - PPIX * in - ZBEND: {{int}} - horz sep (in px) red/cyan left/right sides * in - ZSHIFTT: {{int}} ** Push top of image plane away (>0) or towards (<0) viewer * in - ZSHIFTB: {{int}} - push bottom of image away or towards viewer * in - YBENDT: {{int}} - ** Param for displacement right/left edge, y= ybendt*(2x/w-1)^2 * in - RLEFT: {{int}} - 1 to put red filter on left, 0 otherwise * returns: modified ppix or #f on error. <procedure>pix-blend-color PPIXD PPIX1 PPIX2 X Y FRACT TRANSPARENT TRANSPIX</procedure> * in - PPIXD - #f or PPIX1 (see NOTE above) * in - PPIX1 - “blendee” * in - PPIX2 - “blender”, usually smaller area than PPIX1 * in - X, Y - origin of PPIX2 relative to origin of PPIX1 (pixels) * in - FRACT - blending fraction * in - TRANSPARENT - 1: use transparency, 0: don’t use transparency. * in - TRANSPIX - color in PPIX2 to be made transparent, typically 0 or 0xffffff00 * returns: blended ppix or #f on error. ==== Rotation <procedure>deg2rad DEG</procedure> * in - DEG: {{float}} - degrees to convert to radians * returns: radians as {{float}} <procedure>pix-rotate PPIX ANGLE TYPE INCOLOR WIDTH HEIGHT</procedure> * in - PPIX * in - ANGLE - radians, + is clockwise rotation. * in - TYPE - one of: {{ROT-AM}} (area-mapping), {{ROT-SHEAR}}, {{ROT-SAMP}} (sampling). * in - INCOLOR - fill-in from edges: select {{IN-WHITE}} or {{IN-BLACK}} * in - WIDTH HEIGHT - use image w/h, or 0 for default. * returns: ppix or #f if error. <procedure>pix-rotate-by-sampling PPIX XCENT YCENT ANGLE INCOLOR</procedure> * in - PPIX * in - XCENT YCENT - x, y center of rotation * in - ANGLE - radians, + is clockwise * in - INCOLOR - fill-in from edges: select {{IN-WHITE}} or {{IN-BLACK}} * returns: rotated ppix, or #f if error. (import leptonic) (include "leptonic-types.scm") (define-external imgpix ppix (pix-read "img0.jpg")) ;; rotate image about center 5 deg clockwise ;; get w and h (define-external rotpix ppis (pix-rotate-by-sampling imgpix (/ w 2) (/ h 2) (deg2rad 5) {{IN-BLACK}})) ... (pix-destroy (location imgpix)) (pix-destroy (location rotpix)) <procedure>pix-rotate-shear PPIX XCENT YCENT ANGLE INCOLOR</procedure> * in - PPIX * in - XCENT YCENT - x, y center of rotation * in - ANGLE - radians, + is clockwise * in - INCOLOR - fill-in from edges: select {{IN-WHITE}} or {{IN-BLACK}} ** (pix-rotate-shear ...) isn't recommended for angles >20deg (.35rad) * returns: rotated ppix, or #f if error. <procedure>pix-rotate-90 PPIX DIREC</procedure> * in - PPIX * in - DIREC: {{int}} : +1 for cw, -1 for ccw rotation * returns: rotated ppix or #f on error. <procedure>pix-flip-lr PPIXD PPIX</procedure> * in - PPIXD PPIX - #f or PPIX (see NOTE above) * returns: ppixd, image flipped left-right. <procedure>pix-flip-tb PPIXD PPIX</procedure> * in - PPIXD PPIX - #f or PPIX (see NOTE above) * returns: ppixd, image flipped top-bottom. ==== Image analysis <procedure>pix-sizes-equal PPIX1 PPIX2</procedure> * in - PPIX1 PPIX2 - ppix to compare * returns: 1 if {h,w,d} the same, 0 if not. <procedure>pix-get-pixel-avg PPIX PPIXM X Y FACTOR PVAL</procedure> * in - PPIX * in - PPIXM - (optional) 1bit mask of area to measure, may be #f * in - X Y - UL coords of mask relative to PPIX - ignored if PPIXM is #f * in - FACTOR - subsampling factor 1, 2, 4 * out - PVAL: {{ptr to unsigned-int}} - avg pixel val * returns: 0 if “OK”, 1 on error. <procedure>pix-compare-gray-or-RGB PPIX1 PPIX2 CMPTYPE PLOT PSAME PDIFF PRMSDIFF PPIXDIFF</procedure> * in - PPIX1, PPIX2 - image data to compare * in - CMPTYPE: {{CMP-SUBTRACT}} or {{CMP-ABS-DIFF}} * in - PLOT - plot type, use 0 for no plot. * out - PSAME PDIFF PRMSDIFF PPIXPTR - these are optional, use #f to skip. ** PSAME: {{ptr to int32}} => 1 if pixel values identical ** PDIFF: {{ptr to float}} => avg diff ** PRMSDIFF: {{ptr to float}} => rms of diff ** PPIXDIFF: {{ptr to ppix}} => 8bpp image - pixels set to PPIX1/2 diff * returns: 0 if “OK”, 1 if error. <procedure>pix-color-content PPIX RREF GREF BREF MINGRAY RCONT GCONT BCONT</procedure> * in - PPIX * in - RREF GREF BREF: {{int32}} - reference values for red,green,blue component. ** RREF/GREF/BREF must all be 0 or all not 0. When not 0, ref values describe an unbalanced white point, or mean color of background of scanned images. Set to 0 to turn off color transforms. * in - MINGRAY: {{int32}} ** Pixels less than mingray are set to 0,0,0. set mingray to 0 to turn off filtering dark pixels. * out - RCONT GCONT BCONT: {{ptr to ppix}} - (optional, set to #f if unused) ** If used, filled with R/G/B 8bpp ppix corresponding to component color content. * returns: 0 if “OK”, 1 on error. (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> * in - PPIX - 32bpp * in - DARKTHR: {{int32}} ** Threshold near black. Pixels below aren’t included in stats. Typical: 20 * in - LIGHTTHR: {{int32}} ** Threshold near white. Pixels above aren’t included in stats. Typical: 244 * in - DIFFTHR: {{int32}} ** Threshold for max diff between R/G/B values. When diff is less, pixel is considered insufficiently colorful. Typical: 60 * in - FACTOR: {{int32}} - Subsampling factor, 1, 2, 4. 1 is no subsampling. * out - PIXFRAC: {{ptr to float}} - optional, use #f to skip. ** Fraction of pixels considered for color content. * out - COLORFRAC: {{ptr to float}} - optional, use #f to skip. ** Fraction of pixels meeting criterion for sufficient color. 0.0 on error. * returns: 0 if “OK”, 1 on error. <procedure>pix-color-magnitude PPIX RREF GREF BREF TYPE</procedure> * in - PPIX - 32bpp or 8bpp w/cmap * in - RREF GREF BREF: {{int32}} ** Reference values for red, green, blue components, representing unbalanced white or avg background color of a scanned image. Image colors are adjusted according to the ref values. Set all to 0 to skip this adjustment. * in - TYPE - one of intermediate-diff: 1, avg-max-diff: 2, max_diff: 3 * returns: 8bpp ppix (amt of color in each src pixel) or #f on error. <procedure>pix-min-or-max PPIXD PPIX1 PPIX2 MIN-MAX?</procedure> * in - PPIXD PPIX1 - #f or PPIX1 (see NOTE above) ** PPIXD (destination ppix) is optional, if used, must be used with PPIX1. If #f, a new ppix is alloc and returned (typical case). Use PPIX1/PPIX1 for in-place modification of PPIX1. * in - MIN-MAX - select via {{CHOOSE-MIN}} or {{CHOOSE-MAX}} * returns: PPIXD (new alloc if needed) with min/max pixel values, #f if error. ==== Effects <procedure>pix-clean-image PPIX CONTRAST ROTATE SCALE OPEN-SIZE</procedure> * in - PPIX * in - CONTRAST: {{int32}} - 1 (lightest) to 10 (darkest) * in - ROTATE: {{int32}} - 0,1,2,3 (0,90,180,270 degrees cw) * in - SCALE: {{int32}} - 1 or 2 (for 2X upscaling) * in - OPEN-SIZE: {{int32}} - size for noise removal (0/1-none, 2,3 to use) * returns: cleaned ppix or #f if error. <procedure>gen-binary-maze WIDTH HEIGHT X Y SIDEWALL AHEAD</procedure> * in - WIDTH: {{int32}} - image width * in - HEIGHT: {{int32}} - image height * in - X: {{int32}} - x start of maze * in - Y: {{int32}} - y start of maze * in - SIDEWALL: {{float}} - probability of wall to side of direction * in - AHEAD: {{float}} - probability of wall drawn ahead of direction ** Generates binary (monochrome) maze * returns: ppix or #f on error. (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</procedure> * in - PPIX - 8bpp * in - ORIENTATION: {{int32}} ** filter edges: {{HORZ-EDGES}}, {{VERT-EDGES}} or {{ALL-EDGES}} * returns: 8bpp ppix or #f if error. ==== Dithering <procedure>pix-dither-2bpp PPIX CMAP?</procedure> * in - PPIX - 8bpp/graymap * in - CMAP? - generate colormap? 0=no, 1=yes ** Dithers to equally spaced gray values at 0, 85, 170, 255 * returns: dithered ppix or #f if error. <procedure>pix-dither-2bpp-spec PPIX LOWCLIP UPCLIP CMAP?</procedure> * in - PPIX - 8bpp/graymap * in - LOWCLIP - lower clipping point, should be 0 or a small number. * in - UPCLIP - upper clipping point, should be 255 or slightly less. * in - CMAP? - generate colormap, 0 or 1. * returns: dithered ppix or #f if error. <procedure>pix-dither-binary PPIX</procedure> * in - PPIX - 8bpp/grayscale image. * returns: dithered ppix or #f if error. <procedure>pix-dither-bin-spec PPIX LOWCLIP UPCLIP</procedure> * in - PPIX - 8bpp * in - LOWCLIP - lower clipping point, should be 0 or a small number. * in - UPCLIP - upper clipping point, should be 255 or slightly less. * returns: dithered ppix or #f if error. ==== Threshold <procedure>pix-threshold-to-binary PPIX THRESH</procedure> * in - PPIX - 4 or 8bpp * in - THRESH - if src pixel is < THRESH, dest is 1, else dest is 0. (Max pixel value for 8bpp == 255, 4bpp == 15.) * returns: dithered 1bpp ppix or #f on error. <procedure>pix-threshold-to-2bpp PPIX NLEVELS CMAP?</procedure> * in - PPIX - 8bpp * in - NLEVELS - 2..4 equally spaced levels in output ppix * in - CMAP? - 0/1 * returns: dithered 2bpp ppix or #f on error. <procedure>pix-threshold-to-4bpp PPIX NLEVELS CMAP?</procedure> * in - PPIX - 8bpp * in - NLEVELS - 2..16 equally spaced levels in output * in - CMAP? - 0/1 * returns: dithered 4bpp ppix or #f on error. <procedure>pix-threshold-on-8bpp PPIX NLEVELS CMAP?</procedure> * in - PPIX - 8bpp * in - NLEVELS - 2..256 equally spaced levels in output * in - CMAP? - 0/1 * returns: dithered 8bpp ppix or #f on error. ==== Conversion <procedure>pix-RGB-to-gray PPIX RWT GWT BWT</procedure> * in - PPIX - 32bpp RGB image * in - RWT GWT BWT: {{float}} values, weights should add up to 1. * returns: 8bpp ppix or #f if error. <procedure>pix-RGB-to-gray-fast PPIX</procedure> * in - PPIX - 32bpp RGB image * returns: 8bpp ppix or #f if error. <procedure>pix->32bit PPIX </procedure> * in - PPIX - 1, 2, 4, 8, 16, 24 or 32 bpp * returns: ppix or #f on error. <procedure>pix->16bit PPIX</procedure> * in - PPIX - 1, 8 bpp * returns: ppix or #f on error. <procedure>pix->8bit PPIX</procedure> * in - PPIX - 1, 2, 4, 8, 16, 24 or 32 bpp * returns: ppix or #f on error. <procedure>pix->4bit PPIX</procedure> * in - PPIX - 1, 2, 4, 8, 24 or 32 bpp * returns: ppix or #f on error. <procedure>pix->2bit PPIX</procedure> * in - PPIX - 1, 2, 4, 8, 24 or 32 bpp * returns: ppix or #f on error. <procedure>pix->1bit PPIX</procedure> * in - PPIX - 1, 2, 4, 8, 16, 24 or 32 bpp * returns: ppix or #f on error. <procedure>pix-RGB->HSV PPIXD PPIX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-HSV->RGB PPIXD PPIX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->XYZ PPIX</procedure> * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->YUV PPIXD PPIX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-YUV->RGB PPIXD PPIX</procedure> * in - PPIXD - #f or PPIX (see NOTE above) * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->hue PPIX</procedure> * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->sat PPIX</procedure> * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->value PPIX</procedure> * in - PPIX * returns: converted ppix or #f on error. <procedure>pix-RGB->Lab PPIX</procedure> * in - ppix * returns: converted PFPIXA or #f on error. <procedure>fpixa-Lab->RGB PFPIXA</procedure> * in - PFPIXA (Lab) * returns: converted PPIX or #f on error. <procedure>fpixa-Lab->XYZ PFPIXA</procedure> * in - PFPIXA (Lab) * returns: converted PFPIXA or #f on error. <procedure>fpixa-XYZ->Lab PFPIXA</procedure> * in - PFPIXA (XYZ) * returns: converted PFPIXA or #f on error. <procedure>fpixa-XYZ->RGB PFPIXA</procedure> * in - PFPIXA (XYZ) * returns: converted PPIX or #f on error. ==== Error messages <procedure>set-msg-level LEVEL</procedure> * in - LEVEL {{int32}} - 1:all 2:debug+ 3:info+ 4:warn+ 5:error+ 6:none * returns: - old level {{int32}} ==== Serializing data: 32bit to 8bit and 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> * in - PTR32: {{ptr to unsigned-int32}} * in - LEN: {{int}} - length of data - (image width * height) * out - PTR8: {{ptr to unsigned-byte}} * returns: number of 32bit pixels (should be equal to LEN) <procedure>u8*3->u32 PTR8 LEN PTR32</procedure> * in - PTR8: {{ptr to unsigned-byte}} * in - LEN: {{int}} - length of data (image width * height) * out - PTR32: {{ptr to unsigned-int32}} * returns: number of 32bit pixels (should be equal to LEN) (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 * 0.2.4 (Added error redirection procedures) * 0.2.2 (Added procedures) * 0.2.0 (initial release)
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you multiply 0 by 3?