Depth32Image.st
changeset 6841 3f4935787091
parent 6302 d393dae43c28
child 6846 6c9367f0ecb8
--- a/Depth32Image.st	Thu Apr 23 23:26:11 2015 +0200
+++ b/Depth32Image.st	Thu Apr 23 23:31:10 2015 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1995 by Claus Gittinger
 	      All Rights Reserved
@@ -11,6 +13,8 @@
 "
 "{ Package: 'stx:libview' }"
 
+"{ NameSpace: Smalltalk }"
+
 Image subclass:#Depth32Image
 	instanceVariableNames:''
 	classVariableNames:''
@@ -74,6 +78,40 @@
 
 !Depth32Image methodsFor:'accessing-pixels'!
 
+colorAtX:x y:y
+    "retrieve a pixel at x/y; return a color.
+     Pixels start at x=0 , y=0 for upper left pixel, end at
+     x = width-1, y=height-1 for lower right pixel"
+
+    |index "{ Class: SmallInteger }"
+     rVal gVal bVal|
+
+    photometric ~~ #rgb ifTrue:[^ super colorAtX:x y:y].
+
+    index := 1 + (((width * y) + x) * 4).
+    rVal := bytes at:(index).
+    gVal := bytes at:(index + 1).
+    bVal := bytes at:(index + 2).
+
+    ^ Color redByte:rVal greenByte:gVal blueByte:bVal
+!
+
+colorAtX:x y:y put:aColor
+    "set the pixel at x/y to aColor.
+     Pixels start at x=0 , y=0 for upper left pixel, end at
+     x = width-1, y=height-1 for lower right pixel."
+
+    |index "{ Class: SmallInteger }"|
+
+    photometric ~~ #rgb ifTrue:[^ super colorAtX:x y:y put:aColor].
+
+    index := 1 + (((width * y) + x) * 4).
+    bytes at:(index) put:(aColor redByte).
+    bytes at:(index + 1) put:(aColor greenByte).
+    bytes at:(index + 2) put:(aColor blueByte).
+    bytes at:(index + 3) put:255.               "alpha channel"
+!
+
 pixelAtX:x y:y
     "retrieve a pixel at x/y; return a pixelValue.
      Pixels start at x=0 , y=0 for upper left pixel, end at
@@ -83,7 +121,7 @@
 
     pixelFunction notNil ifTrue:[^ pixelFunction value:x value:y].
 
-    pixelIndex := (width * 4 * y) + 1 + (x * 4).
+    pixelIndex := 1 + (((width * y) + x) * 4).
 
     "left pixel in high bits"
     ^ bytes doubleWordAt:pixelIndex MSB:true.
@@ -99,14 +137,34 @@
 
     |pixelIndex "{ Class: SmallInteger }"|
 
-    pixelIndex := (width * 4 * y) + 1 + (x * 4).
+    pixelIndex := 1 + (((width * y) + x) * 4).
     bytes isNil ifTrue:[
-	self createPixelStore
+        self createPixelStore
     ].
     bytes doubleWordAt:pixelIndex put:aPixelValue MSB:true
 
     "Created: / 24-04-1997 / 19:00:28 / cg"
     "Modified: / 06-06-2007 / 12:20:57 / cg"
+!
+
+rowAt:y putAll:pixelArray startingAt:startIndex
+    "store a single rows bits from bits in the pixelArray argument;
+     Return the pixelArray.
+     Notice: row coordinate starts at 0."
+
+    |bytes dstIdx pixel|
+
+    bytes := self bits.
+    dstIdx := (y * self bytesPerRow) + 1.
+    0 to:width-1 do:[:col |
+        pixel := pixelArray at:(startIndex + col).
+        bytes at:dstIdx put:((pixel bitShift:-24) bitAnd:16rFF).
+        bytes at:dstIdx+1 put:((pixel bitShift:-16) bitAnd:16rFF).
+        bytes at:dstIdx+2 put:((pixel bitShift:-8) bitAnd:16rFF).
+        bytes at:dstIdx+3 put:(pixel bitAnd:16rFF).
+        dstIdx := dstIdx + 4.
+    ].
+    ^ pixelArray
 ! !
 
 !Depth32Image methodsFor:'converting rgb images'!
@@ -600,6 +658,37 @@
     "Modified: / 29-05-2007 / 12:19:04 / cg"
 ! !
 
+!Depth32Image methodsFor:'image manipulations'!
+
+negative
+    |bytes index newImage newBytes nBytes r g b|
+
+    photometric ~~ #rgb ifTrue:[
+        ^ super negative.
+    ].
+    bytes := self bits.
+
+    newImage := self copy.
+    nBytes := bytes size.
+    newImage bits:(newBytes := ByteArray new:nBytes).
+    index := 1.
+    [index < nBytes] whileTrue:[
+        r := bytes at:index.
+        newBytes at:index put:(255-r).
+        index := index + 1.
+        g := bytes at:index.
+        newBytes at:index put:(255-g).
+        index := index + 1.
+        b := bytes at:index.
+        newBytes at:index put:(255-b).
+        index := index + 1.
+        b := bytes at:index.
+        newBytes at:index put:b.
+        index := index + 1.
+    ].
+    ^ newImage
+! !
+
 !Depth32Image methodsFor:'initialization'!
 
 initialize
@@ -675,6 +764,38 @@
     "Created: 24.4.1997 / 19:00:28 / cg"
 !
 
+bitsPerSample
+    "return the number of bits per sample.
+     The return value is an array of bits-per-plane."
+
+    bitsPerSample notNil ifTrue:[^ bitsPerSample].
+    ^ #(8 8 8 8)
+!
+
+blueBitsOf:pixel
+    "given a pixel-value, return the blue component as byteValue (0..255)"
+
+    ^ (pixel bitShift:-8) bitAnd:16rFF.
+!
+
+blueComponentOf:pixel
+    "given a pixel-value, return the blue component in percent (0..100)"
+
+    ^ (100.0 / 255.0) *  ((pixel bitShift:-8) bitAnd:16rFF).
+!
+
+blueMaskForPixelValue
+    "return the mask used with translation from pixelValues to blueBits"
+
+    ^ 16rFF
+!
+
+blueShiftForPixelValue
+    "return the shift amount used with translation from pixelValues to blueBits"
+
+    ^ -8
+!
+
 bytesPerRow
     "return the number of bytes in one scanline of the image"
 
@@ -683,17 +804,82 @@
     "Created: 24.4.1997 / 19:00:28 / cg"
 !
 
+greenBitsOf:pixel
+    "given a pixel-value, return the green component as byteValue (0..255)"
+
+    ^ (pixel bitShift:-16) bitAnd:16rFF.
+!
+
+greenComponentOf:pixel
+    "given a pixel-value, return the green component in percent (0..100)"
+
+    ^ (100.0 / 255.0) * ((pixel bitShift:-16) bitAnd:16rFF).
+!
+
+greenMaskForPixelValue
+    "return the mask used with translation from pixelValues to redBits"
+
+    ^ 16rFF
+!
+
+greenShiftForPixelValue
+    "return the shift amount used with translation from pixelValues to greenBits"
+
+    ^ -16
+!
+
 hasAlphaChannel
     ^ true
+!
+
+redBitsOf:pixel
+    "given a pixel-value, return the red component as byteValue (0..255)"
+
+    ^ (pixel bitShift:-24) bitAnd:16rFF.
+!
+
+redComponentOf:pixel
+    "given a pixel-value, return the red component in percent (0..100)"
+
+    ^ (100.0 / 255.0) * ((pixel bitShift:-24) bitAnd:16rFF).
+!
+
+redMaskForPixelValue
+    "return the mask used with translation from pixelValues to redBits"
+
+    ^ 16rFF
+!
+
+redShiftForPixelValue
+    "return the shift amount used with translation from pixelValues to redBits"
+
+    ^ -24
+!
+
+rgbFromValue:pixelValue
+    "given a pixel value, return the corresponding 24bit rgbValue (rrggbb, red is MSB)."
+
+    ^ pixelValue rightShift:8     "lsb is alpha channel"
+!
+
+samplesPerPixel
+    "return the number of samples per pixel in the image."
+
+    samplesPerPixel notNil ifTrue:[^ samplesPerPixel].
+    ^ 4
+!
+
+valueFromRedBits:redBits greenBits:greenBits blueBits:blueBits
+    ^ (((((redBits bitShift:8) bitOr:greenBits) bitShift:8) bitOr:blueBits) bitShift:8) bitOr:255
 ! !
 
 !Depth32Image class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Depth32Image.st,v 1.13 2014-03-02 13:59:52 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Depth32Image.st,v 1.14 2015-04-23 21:31:10 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libview/Depth32Image.st,v 1.13 2014-03-02 13:59:52 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Depth32Image.st,v 1.14 2015-04-23 21:31:10 stefan Exp $'
 ! !