home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
gprocs
/
putpixel.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
5KB
|
164 lines
############################################################################
#
# File: putpixel.icn
#
# Subject: Procedure to write quantized, processed pixel
#
# Author: Gregg M. Townsend
#
# Date: August 14, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# These procedures assist pixel-by-pixel image construction.
#
# PutPixel(W, x, y, k) draws a single pixel after applying
# dithering, color quantization, and
# gamma correction.
#
# PixInit(gamma, cquant, gquant, drandom)
# initializes parameters for PutPixel().
#
############################################################################
#
# PutPixel([win,] x, y, colr) sets the pixel at (x,y) to the given color
# after applying dithering, color quantization, and gamma correction.
# It is designed for constructing images a pixel at a time. The window's
# foreground color is left set to the adjusted color.
#
# Colr can be any value acceptable to Fg. Mutable colors are not
# dithered, quantized, or gamma-corrected.
#
# PixInit(gamma, cquant, gquant, drandom) may be called before PutPixel
# to establish non-default parameters. The default gamma value is 1.0
# (that is, no correction beyond Icon's usual gamma correction).
# cquant and gquant specify the number of color and grayscale quantization
# steps; the defaults are 6 and 16 respectively. If gquant + cquant ^ 3
# exceeds 256 there is a potential for running out of colors. drandom
# is the fraction (0 to 1) of the dithering to be done randomly; the
# default is zero.
#
############################################################################
#
# Requires: Version 9 graphics
#
############################################################################
global XPP_qtab, XPP_gtab, XPP_dtab, XPP_rtab, XPP_gadjust
# PixInit -- set parameters and build tables
procedure PixInit(gamma, cquant, gquant, drandom) #: initialize pixel processing
local PIXRANGE, NRANDOM, cstep, gstep, indx, appx, gcor, i
/gamma := 1.0 # gamma correction factor
/cquant := 6 # color quantization steps
/gquant := 16 # grayscale quantization
/drandom := 0.0 # fraction of dithering to do randomly
NRANDOM := 500 # size of random number table
PIXRANGE := 255 # pixel value range 0..255
if gamma < 0.01 then # ensure legal values
gamma := 2.5
cquant <:= 2
gquant <:= 2
drandom <:= 0.0
drandom >:= 1.0
cstep := (PIXRANGE / (cquant-1.0)) # color step size
gstep := (PIXRANGE / (gquant-1.0)) # grayscale step size
# build 4 x 4 dither table (choose one)
# XPP_dtab := [0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5] # ordered dither
XPP_dtab := [0,6,9,15,11,13,2,4,7,1,14,8,12,10,5,3] # magic square dither
every i := 1 to 16 do # normalize
XPP_dtab[i] := (XPP_dtab[i]/15.0 - 0.5) * (cstep - 3) * (1.0 - drandom)
# build list of scaled random numbers for dithering
XPP_rtab := list(NRANDOM)
every !XPP_rtab := (?0 - 0.5) * 2 * (cstep - 3) * drandom
# build table for combined quantization and gamma correction
XPP_qtab := list(PIXRANGE+1)
every i := 0 to PIXRANGE do {
indx := integer((i + cstep / 2) / cstep)
appx := cstep * indx
gcor := PIXRANGE * ((real(appx) / real(PIXRANGE)) ^ (1.0 / gamma))
XPP_qtab[i+1] := integer(gcor + 0.5)
}
# build similar table for grayscale
XPP_gtab := list(PIXRANGE+1)
every i := 0 to PIXRANGE do {
indx := integer((i + gstep / 2) / gstep)
appx := gstep * indx
gcor := PIXRANGE * ((real(appx) / real(PIXRANGE)) ^ (1.0 / gamma))
XPP_gtab[i+1] := integer(gcor + 0.5)
}
# grayscale adjustment for different quantization
XPP_gadjust := (gstep - 3) / (cstep - 3)
return
end
# PutPixel -- write a pixel
procedure PutPixel(win, x, y, color) #: write pixel
local i, r, g, b
initial if /XPP_qtab then PixInit()
# default win to &window if omitted
if type(win) ~== "window" then {
win :=: x :=: y :=: color
win := &window
}
# convert color to 8-bit r, g, b
if type(color) == "integer" then {
# mutable -- don't quantize
Fg(win, color)
DrawPoint(win, x, y)
return
}
(color | ColorValue(color) | fail) ? (
(r := tab(many(&digits))) & move(1) &
(g := tab(many(&digits))) & move(1) &
(b := tab(many(&digits)))
)
# convert three 0..65535 ints to 0..255
r := (r + 255) / 257
g := (g + 255) / 257
b := (b + 255) / 257
# get dither table index based on coordinates
i := iand(x, 3) + 4 * iand(y, 3) + 1
if r = g = b then {
g := integer(g + XPP_gadjust * (XPP_dtab[i] + ?XPP_rtab))
(g <:= 1) | (g >:= 256)
r := g := b := 257 * XPP_gtab[g]
}
else {
r := integer(r + XPP_dtab[i] + ?XPP_rtab + 1.5)
g := integer(g - XPP_dtab[i] + ?XPP_rtab + 1.5)
b := integer(b + XPP_dtab[i] + ?XPP_rtab + 1.5)
(r <:= 1) | (r >:= 256)
(g <:= 1) | (g >:= 256)
(b <:= 1) | (b >:= 256)
r := 257 * XPP_qtab[r]
g := 257 * XPP_qtab[g]
b := 257 * XPP_qtab[b]
}
# finally, put the pixel on the screen
Fg(win, r || "," || g || "," || b)
DrawPoint(win, x, y)
return
end