Colormap.st
author Claus Gittinger <cg@exept.de>
Tue, 22 Aug 2000 15:56:47 +0200
changeset 3265 408fac627dc4
parent 2483 6b77b75e74bb
child 3271 51d0adbc1aa0
permissions -rw-r--r--
category change

"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libview' }"

SequenceableCollection subclass:#Colormap
	instanceVariableNames:'redVector greenVector blueVector'
	classVariableNames:''
	poolDictionaries:''
	category:'Graphics-Images-Support'
!

!Colormap class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    Colormaps are used with images (and Forms) to keep the byte-to-color
    mapping.
    Externally, either colors or pixel values can be accessed.
    Internally, the values are stored as 3 separate byte-arrays
    (i.e. individual components can be 0..255).
    This was done to avoid overhead due to allocation of many color
    instances.


    [author:]
        Claus Gittinger

    [see also:]
        Color Image Form
"
! !

!Colormap class methodsFor:'instance creation'!

fromColors:aColorArray
    "given a sequenceable collection of colors, return a new instance
     of myself"

    ^ self withColors:aColorArray

    "
     Colormap 
        fromColors:(Array with:Color black
                          with:Color red
                          with:Color white)
    "

    "Modified: 25.2.1997 / 19:00:31 / cg"
!

new:numColors
    ^ self withColors:(Array new:numColors withAll:Color black)
!

redVector:r greenVector:g blueVector:b
    "given vectors of red/green/and blue pixelValues,
     return a new instance of myself.
     The values must be in the range 0..255."

    ^ self new redVector:r greenVector:g blueVector:b

    "
     Colormap 
        redVector:#[0 127 255]
        greenVector:#[0 127 255]
        blueVector:#[0 127 255]
    "

    "Modified: 23.4.1996 / 22:16:00 / cg"
!

withColors:aColorArray
    "given a sequenceable collection of colors, return a new instance
     of myself. Renamed from #fromColors: for ST-80 compatibility."

    ^ self new colors:aColorArray

    "
     Colormap 
        withColors:(Array with:Color black
                          with:Color red
                          with:Color white)
    "

    "Created: 25.2.1997 / 18:59:09 / cg"
    "Modified: 25.2.1997 / 19:03:08 / cg"
! !

!Colormap methodsFor:'accessing'!

at:index 
    "return the color for a index. 
     Notice that index range is 1..."

    |r g b idx "{ Class: SmallInteger }" |

    idx := index.
    r := redVector at:idx.
    g := greenVector at:idx.
    b := blueVector at:idx.

    ^ Color redByte:r greenByte:g blueByte:b

    "Created: 2.5.1996 / 12:21:40 / cg"
    "Modified: 8.6.1996 / 14:25:30 / cg"
!

at:index put:aColor
    "set the color for a index. Return aColor (sigh).
     Notice that index range is 1..."

    |r g b idx "{ Class: SmallInteger }" |

    r := (aColor red * 255 / 100) rounded.
    g := (aColor green * 255 / 100) rounded.
    b := (aColor blue * 255 / 100) rounded.

    idx := index.
    redVector at:idx put:r.
    greenVector at:idx put:g.
    blueVector at:idx put:b.
    ^ aColor

    "Modified: 2.5.1996 / 17:29:29 / cg"
!

blueAt:index
    "return the blue component for some index.
     The returned value is scaled from the internal 0.. 255 to
     a percentage value 0..100"

    ^ (blueVector at:index) * 100 / 255

    "Modified: 2.5.1996 / 17:29:17 / cg"
!

colors
    "ST-80 compatibility: return a collection containing the colors I hold"

    ^ self asArray
!

colors:aCollectionOfColors
    "setup the receiver from colors given in a sequenceable collection of colors"

    |sz "{Class: SmallInteger }"|

    sz := aCollectionOfColors size.
    redVector := ByteArray new:sz.
    greenVector := ByteArray new:sz.
    blueVector := ByteArray new:sz.

    1 to:sz do:[:i |
        |clr r g b|

        clr := aCollectionOfColors at:i.
        clr notNil ifTrue:[
            redVector at:i put:(clr redByte).
            greenVector at:i put:(clr greenByte).
            blueVector at:i put:(clr blueByte).
        ]
    ].

    "Modified: 25.2.1997 / 19:02:47 / cg"
!

greenAt:index
    "return the green component for some index.
     The returned value is scaled from the internal 0.. 255 to
     a percentage value 0..100"

    ^ (greenVector at:index) * 100 / 255

    "Modified: 2.5.1996 / 17:29:36 / cg"
!

redAt:index
    "return the red component for some index.
     The returned value is scaled from the internal 0.. 255 to
     a percentage value 0..100"

    ^ (redVector at:index) * 100 / 255

    "Modified: 2.5.1996 / 17:29:44 / cg"
! !

!Colormap methodsFor:'accessing-internals'!

blueVector
    "return the blueVector"

    ^ blueVector

    "Modified: 2.5.1996 / 12:44:17 / cg"
!

blueVector:something
    "set blueVector"

    blueVector := something.
!

greenVector
    "return greenVector"

    ^ greenVector
!

greenVector:something
    "set greenVector"

    greenVector := something.
!

redVector
    "return redVector"

    ^ redVector
!

redVector:something
    "set redVector"

    redVector := something.
!

redVector:r greenVector:g blueVector:b
    "set the red, green and blueVectors"

    redVector := r.
    greenVector := g.
    blueVector := b.

    "Modified: 23.4.1996 / 22:13:31 / cg"
! !

!Colormap methodsFor:'converting'!

asArray
    "return the receiver as an array containing my colors"

    |r g b n "{ Class: SmallInteger }" 
     scale array|

    n := redVector size.
    array := Array new:n.
    scale := Color scalingValue / 255.0.

    1 to:n do:[:idx |
        r := redVector at:idx.
        g := greenVector at:idx.
        b := blueVector at:idx.

        array at:idx put:(Color
                            scaledRed:(r * scale) rounded
                            scaledGreen:(g * scale) rounded
                            scaledBlue:(b * scale) rounded)
    ].
    ^ array

    "Created: 11.7.1996 / 20:19:45 / cg"
    "Modified: 11.7.1996 / 21:34:16 / cg"
! !

!Colormap methodsFor:'copying'!

copyFrom:start to:stop
    ^ self class withColors:(self asArray copyFrom:start to:stop)
!

postCopy
    redVector := redVector copy.
    greenVector := greenVector copy.
    blueVector := blueVector copy.

    "Created: 5.7.1996 / 14:52:15 / cg"
! !

!Colormap methodsFor:'misc'!

grow:howBig
    "change the receivers size - not allowed"

    howBig == self size ifTrue:[^ self].

    ^ self shouldNotImplement

!

scaleValuesBy:scaleFactor
    "multiply all values by scaleFactor; finally round to integer.
     This can be used to brighten/darken an images colormap"

    |sz "{ Class: SmallInteger }" |

    sz := redVector size.
    1 to:sz do:[:index |
        redVector at:index put:((redVector at:index) * scaleFactor) rounded.
        greenVector at:index put:((greenVector at:index) * scaleFactor) rounded.
        blueVector at:index put:((blueVector at:index) * scaleFactor) rounded.
    ]

    "Modified: 2.5.1996 / 12:46:07 / cg"
! !

!Colormap methodsFor:'queries'!

indexOfPaintNearest: color
    |minDistance minIndex dist
     sz "{ Class: SmallInteger }"|

    minDistance := (self at:1) deltaFrom:color.
    minIndex := 1.
    sz := self size.
    2 to:sz do:[:idx |
        dist := (self at:idx) deltaFrom:color.
        dist < minDistance ifTrue:[
            minDistance := dist.
            minIndex := idx.
        ]
    ].
    ^ minIndex

    "Created: 6.3.1997 / 15:45:39 / cg"
!

size
    "return the number of colors in the receiver"

    ^ redVector size

    "Modified: 23.4.1996 / 22:13:43 / cg"
! !

!Colormap methodsFor:'storing'!

storeOn:aStream
    "append a representation to aStream, from which the receiver
     can be reconstructed"

    aStream nextPutAll:'(' , self class name ,' redVector:'.
    redVector storeOn:aStream.
    aStream nextPutAll:' greenVector:'.
    greenVector storeOn:aStream.
    aStream nextPutAll:' blueVector:'.
    blueVector storeOn:aStream.
    aStream nextPutAll:')'

    "Created: 30.5.1996 / 16:28:27 / ca"
    "Modified: 30.5.1996 / 16:32:44 / ca"
! !

!Colormap class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview/Colormap.st,v 1.27 2000-08-22 13:56:15 cg Exp $'
! !