diff options
Diffstat (limited to 'ipl/gprocs/imrutils.icn')
-rw-r--r-- | ipl/gprocs/imrutils.icn | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/ipl/gprocs/imrutils.icn b/ipl/gprocs/imrutils.icn new file mode 100644 index 0000000..97b8c34 --- /dev/null +++ b/ipl/gprocs/imrutils.icn @@ -0,0 +1,332 @@ +############################################################################ +# +# File: imrutils.icn +# +# Subject: Procedures to deal with image records +# +# Author: Ralph E. Griswold +# +# Date: January 23, 2002 +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ +# +# Procedures to manipulate image strings as records. +# +# imrcath(imr1, imr2) +# concatenates imr1 and imr2 horizontally +# +# imrcatv(imr1, imr2) +# concatenates imr1 and imr2 vertically +# +# imrcopy(imr) create copy of imr +# +# imrdraw(win, x, y, imr) +# draws an image record +# +# imrfliph(imr) flips an image record horizontally +# +# imrflipv(imr) flips an image record vertically +# +# imrnegative(imr) +# produces "negative" of image; intended for +# grayscale palettes +# +# imropen(imr) opens a hidden window with an image record +# +# imror(imr) forms inclusive "or" of two images +# +# imrpshift(imr, ir) +# shifts colors by mapping rotated palette +# +# imrrot180(imr) +# rotates an image record 180 degrees +# +# imrrot90cw(imr) +# rotates an image record 90 degrees clockwise +# +# imrshifth(imr, i) +# shifts an image record horizontally by i pixels +# with wrap-around; positive i to the right, +# negative to the left. +# +# imrshiftv(imr, i) +# shifts an image record vertically by i pixels +# with wrap-around; positive i to the top, +# negative to the bottom. +# +# imstoimr(s) converts an image string to an image record +# +# imrtoims(imr) converts an image record to an image string +# +# Note: All the procedures that produce image records modify their +# argument records; they do not return modified copies. +# +############################################################################ +# +# Possible additions: +# +# Make stripes from one (or more) rows/columns. +# +# Convert from one palette to another. +# +############################################################################ +# +# Requires: Version 9 graphics +# +############################################################################ +# +# Links: strings, wopen +# +############################################################################ + +link strings +link wopen + +record ImageRecord(width, palette, pixels) + +procedure imrcath(imr1, imr2) #: horizontally concatenate image records + local imr, i, rows1, rows2 + + if *imr1.pixels / imr1.width ~= *imr2.pixels / imr2.width then fail + if imr1.palette ~== imr2.palette then fail + + imr := ImageRecord() + imr.width := imr1.width + imr2.width + imr.palette := imr1.palette + + rows1 := [] + + imr1.pixels ? { + while put(rows1, move(imr1.width)) + } + + rows2 := [] + + imr2.pixels ? { + while put(rows2, move(imr2.width)) + } + + imr.pixels := "" + + every i := 1 to *rows1 do + imr.pixels ||:= rows1[i] || rows2[i] + + return imr + +end + +procedure imrcatv(imr1, imr2) #: vertically concatenate image records + local imr + + if imr1.width ~= imr2.width then fail + if imr1.palette ~== imr2.palette then fail + + imr := ImageRecord() + imr.width := imr1.width + imr.palette := imr1.palette # CHECK + imr.pixels := imr1.pixels || imr2.pixels + + return imr + +end + +procedure imrcopy(imr) + + return copy(imr) + +end + +procedure imrdraw(win, x, y, imr) #: draw image record + + if type(win) ~== "window" then { + win :=: x :=: y :=: imr + win := \&window | runerr(140, &window) + } + + /x := 0 + /y := 0 + + return DrawImage(win, x, y, imrtoims(imr)) + +end + +procedure imrflipd(imr) #: flip image record diagonally + local height, columns, i, row + + height := *imr.pixels / imr.width + columns := list(height, "") + + imr.pixels ? { + while row := move(imr.width) do + every i := 1 to imr.width do + columns[i] ||:= row[i] + } + + imr.pixels := "" + + every imr.pixels ||:= !columns + + imr.width := height + + return imr + +end + +procedure imrfliph(imr) #: flip image record horizontally + local pixels + + pixels := "" + + imr.pixels ? { + while pixels ||:= reverse(move(imr.width)) + } + + imr.pixels := pixels + + return imr + +end + +procedure imrflipv(imr) #: flip image record vertically + local pixels + + pixels := "" + + imr.pixels ? { + while pixels := move(imr.width) || pixels + } + + imr.pixels := pixels + + return imr + +end + +procedure imrnegative(imr) #: form negative of image record + local chars + + chars := PaletteChars(imr.palette) + + imr.pixels := map(imr.pixels, chars, reverse(chars)) + + return imr + +end + +procedure imropen(imr) #: open window with image record + local win + + win := WOpen("canvas=hidden","size=" || imr.width || "," || + *imr.pixels / imr.width) + + imrdraw(win, 0, 0, imr) | { + WClose(win) + fail + } + + return win + +end + +procedure imrpshift(imr, i) #: map shifted palette + local chars + + chars := PaletteChars(imr.palette) + + imr.pixels := map(imr.pixels, chars, rotate(chars, i)) + + return imr + +end + +procedure imrrot180(imr) #: rotate image record 180 degrees + + imr.pixels := reverse(imr.pixels) + + return imr + +end + +procedure imrrot90cw(imr) #: rotate image record 90 deg. clockwise + local height, columns, i, row + + height := *imr.pixels / imr.width + columns := list(imr.width, "") + + imr.pixels ? { + while row := move(imr.width) do + every i := 1 to imr.width do + columns[i] := row[i] || columns[i] + } + + imr.pixels := "" + + every imr.pixels ||:= !columns + + imr.width := height + + return imr + +end + +# Note: Since shifted out pixels enter in the top or bottom row, depending +# on the direction of the shift, one full pass over the width raises the +# image one pixel. + +procedure imrshifth(imr, i) #: shift image record horizontally + + imr.pixels := rotate(imr.pixels, i) + + return imr + +end + +# See note on imrshifth() + +procedure imrshiftv(imr, i) #: shift image record vertically + + /i := 1 + + imr.pixels := rotate(imr.pixels, i * imr.width) + + return imr + +end + +procedure imrtoims(imr) #: convert image record to image string + + return imr.width || "," || imr.palette || "," || imr.pixels + +end + +procedure imstoimr(s) #: convert image string to image record + local imr + + imr := ImageRecord() + + s ? { + imr.width := tab(upto(',')) | fail + move(1) + imr.palette := tab(upto(',')) | fail + move(1) + imr.pixels := tab(0) + } + + return imr + +end + +procedure imror(imr) #: form inclusive "or" of two images + local chars + + chars := PaletteChars(imr.palette) + + imr.pixels := map(imr.pixels, chars, reverse(chars)) + + return imr + +end |