partial support for depth>8 images;
authorClaus Gittinger <cg@exept.de>
Mon, 07 Jun 2004 11:28:21 +0200
changeset 1847 d7e8ec4f3696
parent 1846 65558eb9f4d3
child 1848 61d531486cf1
partial support for depth>8 images; +editColor +refactoring
ImageEditor.st
--- a/ImageEditor.st	Mon Jun 07 11:27:44 2004 +0200
+++ b/ImageEditor.st	Mon Jun 07 11:28:21 2004 +0200
@@ -175,15 +175,19 @@
         colorMap add: (Color redByte: (g*255//26) ceiling greenByte: (g*255//26) ceiling blueByte: (g*255//26) ceiling)
     ].
 
-    ^Dictionary new
-        at: '8-plane' put: colorMap;
-        at: '8-plane + mask' put: colorMap;
-        at: '4-plane' put: (colorMap copyFrom: 1 to: 16);
-        at: '4-plane + mask' put: (colorMap copyFrom: 1 to: 16);
-        at: '2-plane' put: (colorMap copyFrom: 1 to: 4);
-        at: '2-plane + mask' put: (colorMap copyFrom: 1 to: 4);
-        at: '1-plane' put: (colorMap copyFrom: 1 to: 2);
-        at: '1-plane + mask' put: (colorMap copyFrom: 1 to: 2);
+    ^ Dictionary new
+        at: #depth24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF);
+        at: #masked24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF);
+        at: #depth16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F);
+        at: #masked16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F);
+        at: #depth8  put: colorMap;
+        at: #masked8 put: colorMap;
+        at: #depth4  put: (colorMap copyFrom: 1 to: 16);
+        at: #masked4 put: (colorMap copyFrom: 1 to: 16);
+        at: #depth2  put: (colorMap copyFrom: 1 to: 4);
+        at: #masked2 put: (colorMap copyFrom: 1 to: 4);
+        at: #depth1  put: (colorMap copyFrom: 1 to: 2);
+        at: #masked1 put: (colorMap copyFrom: 1 to: 2);
         yourself
 !
 
@@ -193,6 +197,23 @@
     ^#('8x8' '16x16' '22x22' '32x32' '48x48' '64x64')
 
     "Modified: / 31.7.1998 / 01:57:34 / cg"
+!
+
+namesOfColorMaps
+    ^ Dictionary new
+        at: #depth24 put: '24-plane';
+        at: #masked24 put: '24-plane + mask';
+        at: #depth16 put: '16-plane';
+        at: #masked16 put: '16-plane + mask';
+        at: #depth8  put: ' 8-plane';
+        at: #masked8 put: ' 8-plane + mask';
+        at: #depth4  put: ' 4-plane';
+        at: #masked4 put: ' 4-plane + mask';
+        at: #depth2  put: ' 2-plane';
+        at: #masked2 put: ' 2-plane + mask';
+        at: #depth1  put: ' 1-plane';
+        at: #masked1 put: ' 1-plane + mask' ;
+        yourself
 ! !
 
 !ImageEditor class methodsFor:'help specs'!
@@ -1041,6 +1062,7 @@
                           model: selectionOfColorMap
                           comboList: listOfColorMaps
                           useIndex: false
+                          hidePullDownMenuButton: false
                         )
                        )
                      
@@ -1561,58 +1583,61 @@
      the MenuEditor may not be able to read the specification."
 
     "
-     MenuEditor new openOnClass:ImageEditor andSelector:#menuSpec
-     (Menu new fromLiteralArrayEncoding:(ImageEditor menuSpec)) startUp
+     MenuEditor new openOnClass:ImageEditor andSelector:#colorMapMenu
+     (Menu new fromLiteralArrayEncoding:(ImageEditor colorMapMenu)) startUp
     "
 
     <resource: #menu>
 
-    ^
-     
-       #(#Menu
-          
-           #(
-             #(#MenuItem
-                #label: 'Add Color'
-                #translateLabel: true
-                #value: #addColorToColormap
-                #enabled: #hasColormap
-            )
-             #(#MenuItem
-                #label: 'Pick and Add Color'
-                #translateLabel: true
-                #value: #pickAndAddColorToColormap
-                #enabled: #hasColormap
-            )
-             #(#MenuItem
-                #label: '-'
-            )
-             #(#MenuItem
-                #label: 'Brighter'
-                #translateLabel: true
-                #value: #makeSelectedColorBrighter
-                #enabled: #hasColormap
-            )
-             #(#MenuItem
-                #label: 'Darker'
-                #translateLabel: true
-                #value: #makeSelectedColorDarker
-                #enabled: #hasColormap
-            )
-             #(#MenuItem
-                #label: '-'
-            )
-             #(#MenuItem
-                #label: 'Inspect Color'
-                #translateLabel: true
-                #value: #inspectColor
-                #enabled: #hasColormap
-            )
-          ) nil
-          nil
+    ^ 
+     #(Menu
+        (
+         (MenuItem
+            enabled: hasColormap
+            label: 'Add Color'
+            itemValue: addColorToColormap
+            translateLabel: true
+          )
+         (MenuItem
+            enabled: hasColormap
+            label: 'Pick and Add Color'
+            itemValue: pickAndAddColorToColormap
+            translateLabel: true
+          )
+         (MenuItem
+            label: '-'
+          )
+         (MenuItem
+            enabled: hasColormap
+            label: 'Brighter'
+            itemValue: makeSelectedColorBrighter
+            translateLabel: true
+          )
+         (MenuItem
+            enabled: hasColormap
+            label: 'Darker'
+            itemValue: makeSelectedColorDarker
+            translateLabel: true
+          )
+         (MenuItem
+            enabled: hasColormap
+            label: 'Edit Color'
+            itemValue: editSelectedColor
+            translateLabel: true
+          )
+         (MenuItem
+            label: '-'
+          )
+         (MenuItem
+            enabled: hasColormap
+            label: 'Inspect Color'
+            itemValue: inspectColor
+            translateLabel: true
+          )
+         )
+        nil
+        nil
       )
-
-    "Created: / 12.3.1999 / 00:19:00 / cg"
 !
 
 menu
@@ -1933,36 +1958,36 @@
                         #label: '8-Plane'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '8-plane'
+                        #argument: #depth8
                         #choice: #colorMapMode
-                        #choiceValue: '8-plane'
+                        #choiceValue: #depth8
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap4
                         #label: '4-Plane'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '4-plane'
+                        #argument: #depth4
                         #choice: #colorMapMode
-                        #choiceValue: '4-plane'
+                        #choiceValue: #depth4
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap2
                         #label: '2-Plane'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '2-plane'
+                        #argument: #depth2
                         #choice: #colorMapMode
-                        #choiceValue: '2-plane'
+                        #choiceValue: #depth2
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap1
                         #label: '1-Plane'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '1-plane'
+                        #argument: #depth1
                         #choice: #colorMapMode
-                        #choiceValue: '1-plane'
+                        #choiceValue: #depth1
                       )
                      #(#MenuItem
                         #label: '-'
@@ -1972,36 +1997,36 @@
                         #label: '8-Plane + Mask'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '8-plane + mask'
+                        #argument: #masked8
                         #choice: #colorMapMode
-                        #choiceValue: '8-plane + mask'
+                        #choiceValue: #masked8
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap4M
                         #label: '4-Plane + Mask'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '4-plane + mask'
+                        #argument: #masked4
                         #choice: #colorMapMode
-                        #choiceValue: '4-plane + mask'
+                        #choiceValue: #masked4
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap2M
                         #label: '2-Plane + Mask'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '2-plane + mask'
+                        #argument: #masked2
                         #choice: #colorMapMode
-                        #choiceValue: '2-plane + mask'
+                        #choiceValue: #masked2
                       )
                      #(#MenuItem
                         #activeHelpKey: #colorMap1M
                         #label: '1-Plane + Mask'
                         #itemValue: #colorMapMode:
                         #translateLabel: true
-                        #argument: '1-plane + mask'
+                        #argument: #masked1
                         #choice: #colorMapMode
-                        #choiceValue: '1-plane + mask'
+                        #choiceValue: #masked1
                       )
                      )
                     nil
@@ -2812,29 +2837,36 @@
 findColorMapMode
     "finds the colorMapMode for a new image"
 
-    |image listOfColors|
+    |image listOfColors colorMapModeKey|
 
     image := self image.
-    image depth > 8 ifTrue: [
-        colorMapMode value: ''. 
-        self listOfColors removeAll. 
-        ^ nil
+
+    image mask notNil ifTrue: [             
+        colorMapModeKey := 'masked' , image depth printString.
+    ] ifFalse:[
+        colorMapModeKey := 'depth' , image depth printString.
     ].
 
-    colorMapMode value:(image depth printString, '-plane').
-
-    (listOfColors := self listOfColors) isEmpty ifTrue:[   
-        self colorMapMode: colorMapMode value.
-        listOfColors := self listOfColors.
-        image := self image.
+    colorMapMode value:colorMapModeKey.
+
+    image depth > 12 ifTrue:[
+        self listOfColors removeAll.
+        listOfColors := image colorMap.
+        listOfColors isEmptyOrNil ifTrue:[
+            listOfColors := Array with:Color black with:Color white.
+        ].
+    ] ifFalse:[
+        (listOfColors := self listOfColors) isEmpty ifTrue:[   
+            self colorMapMode: colorMapMode value.
+            listOfColors := self listOfColors.
+            image := self image.
+        ].                               
     ].                               
     imageEditView drawingColors:(Array
                                     with: (listOfColors at:1) 
                                     with: (listOfColors at:2 ifAbsent:[listOfColors at:1])).
 
     image mask notNil ifTrue: [             
-        colorMapMode value:(colorMapMode value, ' + mask').
-
         (listOfColors detect: [:clr| clr = (Color colorId:0)] ifNone: nil) isNil
         ifTrue:[
             listOfColors addFirst:(Color colorId:0).
@@ -2893,14 +2925,12 @@
 
     changedObject == imageEditView ifTrue:[
         something == #imageColors ifTrue:[
-            self listOfColors contents:img colorMap.
-            self findColorMapMode.
+            self updateListOfColorsAndColormapMode.
             ^ self.
         ].
         something == #image ifTrue:[
             self imagePreView image:img.
-            self listOfColors contents:img colorMap.
-            self findColorMapMode.
+            self updateListOfColorsAndColormapMode.
             self tileModeHolder value ifTrue:[
                 self imagePreView tileMode:true tileOffset:(img extent).
             ].
@@ -2970,6 +3000,29 @@
 
 
 
+!
+
+updateListOfColorsAndColormapMode
+    |colorMap image|
+
+    image := self image.
+    colorMap := image colorMap.
+    colorMap size <= 4096 ifTrue:[
+        self listOfColors contents:colorMap.
+    ] ifFalse:[
+        self listOfColors removeAll.
+        colorMap isFixedPalette ifTrue:[
+            image colorMap:nil.
+            image photometric:#rgb.
+            image samplesPerPixel:3.
+            
+            image bitsPerSample:(Array 
+                                    with:(colorMap bitsRed)
+                                    with:(colorMap bitsGreen)
+                                    with:(colorMap bitsBlue)).
+        ].
+    ].
+    self findColorMapMode.
 ! !
 
 !ImageEditor methodsFor:'data access'!
@@ -3200,7 +3253,7 @@
 !ImageEditor methodsFor:'menu modes'!
 
 colorMapMode
-    "returns colorMapMode"
+    "returns the colorMapMode"
 
     colorMapMode isNil ifTrue: [colorMapMode := '' asValue].
 
@@ -3253,7 +3306,7 @@
 !ImageEditor methodsFor:'queries'!
 
 hasMask
-    ^ colorMapMode value notNil and:[colorMapMode value endsWith:'mask']
+    ^ colorMapMode value notNil and:[colorMapMode value startsWith:'mask']
 
     "Created: / 18.8.1998 / 17:17:38 / cg"
 !
@@ -3409,13 +3462,17 @@
             self warn:'No space for more colors in colormap.'.
             ^ self
         ].
-        (self confirm:'No space for more colors in colormap.\Change depth first.' withCRs)
+        (self confirm:'No space for more colors in colormap.\Change depth ?' withCRs)
         ifFalse:[
             ^ self
         ].
 
         imageEditView makeUndo.
-        newMode := (depth*2) printString , (colorMapMode value copyFrom:2).
+        img mask notNil ifTrue:[
+            newMode := 'masked' , (depth*2) printString.
+        ] ifFalse:[
+            newMode := 'depth' , (depth*2) printString.
+        ].
         self colorMapMode:newMode.
     ] ifFalse:[
         imageEditView makeUndo.
@@ -3425,17 +3482,6 @@
     listOfColors := self listOfColors.
     oldCListSize := listOfColors size.
 
-"/    (colorMapMode value asString endsWith:'mask') ifTrue:[
-"/        cMap last = Color noColor ifTrue:[
-"/            cMap := cMap copyWithoutLast:1
-"/        ] ifFalse:[
-"/            cMap first = Color noColor ifTrue:[
-"/                cMap := cMap copyFrom:2
-"/            ]
-"/        ].
-"/    ].
-"/
-
     newColorMap := cMap copyWith:newColor.
 
     newImage := img species new
@@ -3600,12 +3646,9 @@
         oldImage := self image.
 
         prevMode := colorMapMode value.
-        oldImage depth > 8 ifTrue:[
-            prevMode := nil
-        ].
 
         newColorMap := self class listOfColorMaps at:aMode.
-        depth       := (newColorMap size log: 2) asInteger. 
+        depth       := (newColorMap size log:2) asInteger. 
 
         useNearest := false.
         depth == 1 ifTrue:[
@@ -3744,7 +3787,7 @@
             image := newImage fromImage:oldImage
         ].
 
-        (aMode asString endsWith:'mask') ifTrue:[
+        (aMode asString startsWith:'mask') ifTrue:[
             image mask isNil ifTrue:[
                 (Dialog confirm:'Generate mask from black ?' default:false) ifTrue:[
                     maskThreshold := 0.1.
@@ -3897,6 +3940,20 @@
     MaskClipboard := mask subImageIn: (0@0 extent:mask extent).
 !
 
+editSelectedColor
+    self processSelectedColorWith:[:clr | 
+        |editor|
+
+        editor := ColorEditDialog new.
+        editor color:clr.
+        editor open.
+        editor accepted ifFalse:[
+            AbortOperationRequest raise.
+        ].
+        editor color
+    ]
+!
+
 fetchImageData
     |image|
 
@@ -4002,7 +4059,7 @@
 !
 
 processSelectedColorWith:aBlock
-    |img cMap clr newImage selectedColorIndex oldSelection|
+    |img cMap modifiedColormap clr newImage selectedColorIndex oldSelection|
 
     selectedColorIndex := self selectedColorIndexOrNil.
     selectedColorIndex isNil ifTrue:[^ self].
@@ -4015,9 +4072,9 @@
     ].
     imageEditView makeUndo.
 
-    cMap := cMap asArray.
-    clr := cMap at:selectedColorIndex.
-    cMap at:selectedColorIndex put:(aBlock value:clr).
+    modifiedColormap := cMap asArray copy.
+    clr := modifiedColormap at:selectedColorIndex.
+    modifiedColormap at:selectedColorIndex put:(aBlock value:clr).
 
     newImage := img species new
                     width:img width
@@ -4025,7 +4082,7 @@
                     depth:img depth
                     fromArray:img bits.
 
-    newImage colorMap:cMap.  
+    newImage colorMap:modifiedColormap.  
     newImage fileName:img fileName.
     newImage mask:(img mask copy).
 
@@ -4085,7 +4142,10 @@
         ^ nil
     ].
     clrIndex := self selectionOfColor value.
-    img mask notNil ifTrue: [ clrIndex := clrIndex - 1 ].
+    img mask notNil ifTrue: [ 
+        clrIndex == 1 ifTrue:[^ nil].
+        clrIndex := clrIndex - 1 
+    ].
     ^ clrIndex
 !
 
@@ -4593,13 +4653,17 @@
 doNewImage
     "opens a dialog with choices of size and color map for creating a new image"
 
-    |aspects width height cMapString cMap imageClass image szString|
+    |aspects width height cMapString cMapMode cMap imageClass image szString defaultSize|
+
+    defaultSize := (self class listOfDefaultSizes includes:'32x32') 
+                        ifTrue:['32x32'] 
+                        ifFalse:[self class listOfDefaultSizes first].
 
     aspects  := IdentityDictionary new
         at:#listOfSizes         put: self class listOfDefaultSizes asValue;
-        at:#listOfColorMaps     put: self class listOfColorMaps keys asSortedCollection asValue;
-        at:#selectionOfSize     put: (LastSizeString ? self class listOfDefaultSizes first copy) asValue;
-        at:#selectionOfColorMap put: (LastColormapMode ? self class listOfColorMaps keys asSortedCollection first) asValue;
+        at:#listOfColorMaps     put: self class namesOfColorMaps values asSortedCollection asValue;
+        at:#selectionOfSize     put: (LastSizeString ? defaultSize) asValue;
+        at:#selectionOfColorMap put: (LastColormapMode ? self class namesOfColorMaps values asSortedCollection first) asValue;
         yourself.
 
     (self openDialogInterface:#dialogSpecForNewImage withBindings:aspects)
@@ -4609,27 +4673,24 @@
         height := 128 min: (Integer readFromString: (szString copy reverse upTo: $x) reverse onError:[24]).
 
         cMapString := (aspects at:#selectionOfColorMap) value.
-        cMap       := (self class listOfColorMaps at: (colorMapMode value: (aspects at:#selectionOfColorMap) value) value).
-        imageClass := Image implementorForDepth: ((cMap size log: 2) asInteger).
-        image      := imageClass width: width height: height fromArray: (ByteArray new: width*height).
+        cMapMode   := self class namesOfColorMaps keyAtEqualValue:cMapString.
+        cMap       := self class listOfColorMaps at:cMapMode.
+        imageClass := Image implementorForDepth:(cMap size highBit-1).
+        image      := imageClass width: width height: height.
+        image bits:(ByteArray new:(image bytesPerRow*height)).
 
         LastSizeString := szString.
         LastColormapMode := cMapString.
 
-        (colorMapMode value endsWith: 'mask')
-        ifTrue:
-        [
+        (cMapMode startsWith: 'mask') ifTrue:[
             image mask: (Depth1Image width: width height: height depth: 1 fromArray: (ByteArray new: width*height)) clearMaskedPixels
         ].
         image colorMap: cMap.
+        (imageEditView image: image) notNil ifTrue:[
+            self updateListOfColorsAndColormapMode.
+            self updateLabelsAndHistory.
+        ].
         image fillRectangleX:0 y:0 width:width height:height with:Color white.
-        (imageEditView image: image) notNil
-        ifTrue:
-        [
-            self listOfColors contents: cMap.
-            self findColorMapMode.
-            self updateLabelsAndHistory.
-        ]
     ]
 !