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. 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. # 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 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> ==== 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.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 subtract 9 from 17?