--- a/AppModel.st Wed Oct 15 19:58:09 1997 +0200
+++ b/AppModel.st Tue Oct 21 20:27:06 1997 +0200
@@ -10,6 +10,8 @@
hereby transferred.
"
+'From Smalltalk/X, Version:3.2.1 on 18-oct-1997 at 4:25:23 pm' !
+
Model subclass:#ApplicationModel
instanceVariableNames:'builder resources device masterApplication'
classVariableNames:'DefaultLabels DefaultVisuals'
@@ -918,18 +920,18 @@
1) nil in which case no interest is registered
2) a selector in which case the receiver is understood to be self
3) an Array in which case the size is two where the first element is the
- message to be sent and the second element is the receiver."
+ message to be sent and the second element is the receiver."
aSelectorOrArray isNil ifTrue: [^ aValueModel].
- (aSelectorOrArray isKindOf:Array) ifTrue:[
+ (aSelectorOrArray isArray) ifTrue:[
aValueModel onChangeSend:(aSelectorOrArray at: 1) to:(aSelectorOrArray at: 2)
] ifFalse: [
aValueModel onChangeSend:aSelectorOrArray to:self
].
^aValueModel
-
+ "Modified: 18.10.1997 / 15:05:58 / cg"
!
valueHolderFor:aSelector initialValue:anObject
@@ -947,11 +949,12 @@
to be the reciever. If it is an Array, then the first element is the change message and
the second element is the interested object. "
- (self builder bindings includesKey:aSelector) ifFalse:[
+ (builder bindings includesKey:aSelector) ifFalse:[
^ self registerInterestIn:(ValueHolder with:anObject) using:aSelectorOrArray
].
- ^ self builder aspectAt:aSelector
+ ^ builder aspectAt:aSelector
+ "Modified: 18.10.1997 / 15:41:13 / cg"
! !
!ApplicationModel methodsFor:'initialization'!
@@ -1486,6 +1489,6 @@
!ApplicationModel class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/Attic/AppModel.st,v 1.60 1997-10-15 16:07:03 ca Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/Attic/AppModel.st,v 1.61 1997-10-21 18:26:38 cg Exp $'
! !
ApplicationModel initialize!
--- a/ApplicationModel.st Wed Oct 15 19:58:09 1997 +0200
+++ b/ApplicationModel.st Tue Oct 21 20:27:06 1997 +0200
@@ -10,6 +10,8 @@
hereby transferred.
"
+'From Smalltalk/X, Version:3.2.1 on 18-oct-1997 at 4:25:23 pm' !
+
Model subclass:#ApplicationModel
instanceVariableNames:'builder resources device masterApplication'
classVariableNames:'DefaultLabels DefaultVisuals'
@@ -918,18 +920,18 @@
1) nil in which case no interest is registered
2) a selector in which case the receiver is understood to be self
3) an Array in which case the size is two where the first element is the
- message to be sent and the second element is the receiver."
+ message to be sent and the second element is the receiver."
aSelectorOrArray isNil ifTrue: [^ aValueModel].
- (aSelectorOrArray isKindOf:Array) ifTrue:[
+ (aSelectorOrArray isArray) ifTrue:[
aValueModel onChangeSend:(aSelectorOrArray at: 1) to:(aSelectorOrArray at: 2)
] ifFalse: [
aValueModel onChangeSend:aSelectorOrArray to:self
].
^aValueModel
-
+ "Modified: 18.10.1997 / 15:05:58 / cg"
!
valueHolderFor:aSelector initialValue:anObject
@@ -947,11 +949,12 @@
to be the reciever. If it is an Array, then the first element is the change message and
the second element is the interested object. "
- (self builder bindings includesKey:aSelector) ifFalse:[
+ (builder bindings includesKey:aSelector) ifFalse:[
^ self registerInterestIn:(ValueHolder with:anObject) using:aSelectorOrArray
].
- ^ self builder aspectAt:aSelector
+ ^ builder aspectAt:aSelector
+ "Modified: 18.10.1997 / 15:41:13 / cg"
! !
!ApplicationModel methodsFor:'initialization'!
@@ -1486,6 +1489,6 @@
!ApplicationModel class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/ApplicationModel.st,v 1.60 1997-10-15 16:07:03 ca Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/ApplicationModel.st,v 1.61 1997-10-21 18:26:38 cg Exp $'
! !
ApplicationModel initialize!
--- a/GIFReader.st Wed Oct 15 19:58:09 1997 +0200
+++ b/GIFReader.st Tue Oct 21 20:27:06 1997 +0200
@@ -10,6 +10,8 @@
hereby transferred.
"
+'From Smalltalk/X, Version:3.2.1 on 21-oct-1997 at 5:07:17 pm' !
+
ImageReader subclass:#GIFReader
instanceVariableNames:'redMap greenMap blueMap pass xpos ypos rowByteSize remainBitCount
bufByte bufStream prefixTable suffixTable clearCode eoiCode
@@ -84,6 +86,15 @@
!GIFReader class methodsFor:'testing'!
+canRepresent:anImage
+ "return true, if anImage can be represented in my file format.
+ GIF supports depth 8 images only."
+
+ ^ anImage depth == 8
+
+ "Created: 17.10.1997 / 20:19:20 / cg"
+!
+
isValidImageFile:aFileName
"return true, if aFileName contains a GIF image"
@@ -804,27 +815,42 @@
outStream nextPut:0. "/ background (not used)
outStream nextPut:0. "/ aspect ratio
- n := 0.
- image colorMap notNil ifTrue:[
- image colorMap do:[:clr |
- |red green blue|
+ 0 to:(1 bitShift:bitsPerPixel)-1 do:[:pixel |
+ |clr red green blue|
- clr isNil ifTrue:[
- "/ unused colorMap slot
- red := green := blue := 0.
- ] ifFalse:[
- red := (clr redByte).
- green := (clr greenByte).
- blue := (clr blueByte).
- ].
- outStream
- nextPut:red; nextPut:green; nextPut:blue.
- n := n + 1.
- ]
- ].
- n+1 to:(1 bitShift:bitsPerPixel) do:[:i |
- outStream nextPut:0; nextPut:0; nextPut:0
- ].
+ clr := image colorFromValue:pixel.
+ clr isNil ifTrue:[
+ "/ unused colorMap slot
+ red := green := blue := 0.
+ ] ifFalse:[
+ red := (clr redByte).
+ green := (clr greenByte).
+ blue := (clr blueByte).
+ ].
+ outStream
+ nextPut:red; nextPut:green; nextPut:blue.
+ ].
+"/ n := 0.
+"/ image colorMap notNil ifTrue:[
+"/ image colorMap do:[:clr |
+"/ |red green blue|
+"/
+"/ clr isNil ifTrue:[
+"/ "/ unused colorMap slot
+"/ red := green := blue := 0.
+"/ ] ifFalse:[
+"/ red := (clr redByte).
+"/ green := (clr greenByte).
+"/ blue := (clr blueByte).
+"/ ].
+"/ outStream
+"/ nextPut:red; nextPut:green; nextPut:blue.
+"/ n := n + 1.
+"/ ]
+"/ ].
+"/ n+1 to:(1 bitShift:bitsPerPixel) do:[:i |
+"/ outStream nextPut:0; nextPut:0; nextPut:0
+"/ ].
outStream nextPut:ImageSeparator.
self writeShort:0. "/
self writeShort:0. "/
@@ -839,12 +865,12 @@
outStream nextPut:t1 "/ another flag
"Created: 14.10.1997 / 17:41:28 / cg"
- "Modified: 15.10.1997 / 19:54:30 / cg"
+ "Modified: 21.10.1997 / 04:52:18 / cg"
! !
!GIFReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.59 1997-10-15 17:58:09 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.60 1997-10-21 18:26:40 cg Exp $'
! !
GIFReader initialize!
--- a/MIMETypes.st Wed Oct 15 19:58:09 1997 +0200
+++ b/MIMETypes.st Tue Oct 21 20:27:06 1997 +0200
@@ -53,45 +53,55 @@
initialize
"initialize wellKnown facts"
- TypeToImageReaderClassMapping isNil ifTrue:[TypeToImageReaderClassMapping := Dictionary new].
- TypeToImageReaderClassMapping at:'image/jpeg' put:JPEGReader.
- TypeToImageReaderClassMapping at:'image/gif' put:GIFReader.
- TypeToImageReaderClassMapping at:'image/tiff' put:TIFFReader.
+ |t|
+
+ (t := TypeToImageReaderClassMapping) isNil ifTrue:[
+ TypeToImageReaderClassMapping := t := Dictionary new
+ ].
+ t at:'image/jpeg' put:JPEGReader.
+ t at:'image/gif' put:GIFReader.
+ t at:'image/tiff' put:TIFFReader.
- FileSuffixToTypeMapping isNil ifTrue:[FileSuffixToTypeMapping := Dictionary new].
- FileSuffixToTypeMapping at:'jpg' put:'image/jpeg'.
- FileSuffixToTypeMapping at:'gif' put:'image/gif'.
- FileSuffixToTypeMapping at:'tif' put:'image/tiff'.
+ (t := FileSuffixToTypeMapping) isNil ifTrue:[
+ FileSuffixToTypeMapping := t := Dictionary new
+ ].
+ t at:'jpg' put:'image/jpeg'.
+ t at:'gif' put:'image/gif'.
+ t at:'tif' put:'image/tiff'.
- FileSuffixToTypeMapping at:'htm' put:'text/html'.
- FileSuffixToTypeMapping at:'html' put:'text/html'.
- FileSuffixToTypeMapping at:'ps' put:'application/postscript'.
-
- FileSuffixToImageReaderClassMapping isNil ifTrue:[FileSuffixToImageReaderClassMapping := Dictionary new].
- FileSuffixToImageReaderClassMapping at:'jpg' put:JPEGReader.
- FileSuffixToImageReaderClassMapping at:'gif' put:GIFReader.
- FileSuffixToImageReaderClassMapping at:'tif' put:TIFFReader.
+ t at:'htm' put:'text/html'.
+ t at:'html' put:'text/html'.
+ t at:'ps' put:'application/postscript'.
- CharSetToFontMapping isNil ifTrue:[CharSetToFontMapping := Dictionary new].
- CharSetToFontMapping at:'iso2022-jp' put:'jis*0208*'.
- CharSetToFontMapping at:'x-iso2022-jp' put:'jis*0208*'.
- CharSetToFontMapping at:'x-euc-jp' put:'jis*0208*'.
- CharSetToFontMapping at:'x-shift-jis' put:'jis*0208*'.
- CharSetToFontMapping at:'x-sjis' put:'jis*0208*'.
- CharSetToFontMapping at:'x-jis7' put:'jis*0208*'.
- CharSetToFontMapping at:'jis7' put:'jis*0208*'.
- CharSetToFontMapping at:'euc' put:'jis*0208*'.
- CharSetToFontMapping at:'euc-jp' put:'jis*0208*'.
- CharSetToFontMapping at:'sjis' put:'jis*0208*'.
+ (t := FileSuffixToImageReaderClassMapping) isNil ifTrue:[
+ FileSuffixToImageReaderClassMapping := t := Dictionary new
+ ].
+ t at:'jpg' put:JPEGReader.
+ t at:'gif' put:GIFReader.
+ t at:'tif' put:TIFFReader.
- CharSetToFontMapping at:'big5' put:'big5*'.
+ (t := CharSetToFontMapping) isNil ifTrue:[
+ CharSetToFontMapping := t := Dictionary new
+ ].
+ t at:'iso2022-jp' put:'jis*0208*'.
+ t at:'x-iso2022-jp' put:'jis*0208*'.
+ t at:'x-euc-jp' put:'jis*0208*'.
+ t at:'x-shift-jis' put:'jis*0208*'.
+ t at:'x-sjis' put:'jis*0208*'.
+ t at:'x-jis7' put:'jis*0208*'.
+ t at:'jis7' put:'jis*0208*'.
+ t at:'euc' put:'jis*0208*'.
+ t at:'euc-jp' put:'jis*0208*'.
+ t at:'sjis' put:'jis*0208*'.
- CharSetToFontMapping at:'gb2312' put:'gb*'.
- CharSetToFontMapping at:'hz-gb-2312' put:'gb*'.
- CharSetToFontMapping at:'x-gbk' put:'gb*'.
+ t at:'big5' put:'big5*'.
- CharSetToFontMapping at:'iso2022-kr' put:'ksc*'.
- CharSetToFontMapping at:'x-euc-kr' put:'ksc*'.
+ t at:'gb2312' put:'gb*'.
+ t at:'hz-gb-2312' put:'gb*'.
+ t at:'x-gbk' put:'gb*'.
+
+ t at:'iso2022-kr' put:'ksc*'.
+ t at:'x-euc-kr' put:'ksc*'.
"
self initialize
@@ -219,6 +229,6 @@
!MIMETypes class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/MIMETypes.st,v 1.9 1997-07-16 11:54:25 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/MIMETypes.st,v 1.10 1997-10-21 18:26:41 cg Exp $'
! !
MIMETypes initialize!
--- a/Make.proto Wed Oct 15 19:58:09 1997 +0200
+++ b/Make.proto Tue Oct 21 20:27:06 1997 +0200
@@ -1,4 +1,4 @@
-# $Header: /cvs/stx/stx/libview2/Make.proto,v 1.41 1997-09-20 22:19:47 cg Exp $
+# $Header: /cvs/stx/stx/libview2/Make.proto,v 1.42 1997-10-21 18:27:03 cg Exp $
#
# -------------- no need to change anything below ----------
@@ -23,21 +23,8 @@
#
# less frequently used/needed
-# if you want them included, uncomment the next lines:
+# these are compiled with +optSpace
#
-xxAUTOLOADEDOBJS= \
- SunReader.$(O) \
- WinIconRdr.$(O) \
- PBMReader.$(O) \
- PCXReader.$(O) \
- XWDReader.$(O) \
- STFormRdr.$(O) \
- TargaReader.$(O) \
- FaceReader.$(O) \
- BlitImgRdr.$(O) \
- JPEGReader.$(O) \
- ConvValue.$(O)
-
UNCRITICALOBJS= \
ClrValue.$(O) \
Icon.$(O) \
@@ -45,6 +32,7 @@
BlockValue.$(O) \
PrintConv.$(O) \
EventListener.$(O) \
+ MIMETypes.$(O) \
ActiveHelp.$(O) \
ActiveHelpView.$(O)
--- a/PBMReader.st Wed Oct 15 19:58:09 1997 +0200
+++ b/PBMReader.st Tue Oct 21 20:27:06 1997 +0200
@@ -1,4 +1,4 @@
-'From Smalltalk/X, Version:3.2.1 on 14-oct-1997 at 11:14:37 pm' !
+'From Smalltalk/X, Version:3.2.1 on 17-oct-1997 at 9:13:03 pm' !
ImageReader subclass:#PBMReader
instanceVariableNames:''
@@ -30,6 +30,27 @@
"
! !
+!PBMReader class methodsFor:'testing'!
+
+canRepresent:anImage
+ "return true, if anImage can be represented in my file format.
+ Currently, only 1bit B&W, 8bit-grey and 24bit RGB images are supported."
+
+ |depth photometric|
+
+ anImage photometric == #rgb ifTrue:[
+ ^ depth==24
+ ].
+ (depth := anImage depth) == 1 ifTrue:[^ true].
+ depth == 8 ifTrue:[
+ photometric := anImage photometric.
+ ^ (photometric == #blackIs0) or:[photometric == #whiteIs0]
+ ].
+ ^ false
+
+ "Modified: 17.10.1997 / 20:20:52 / cg"
+! !
+
!PBMReader methodsFor:'reading from file'!
readDepth8PGMStream:aStream
@@ -69,27 +90,6 @@
"Modified: 14.10.1997 / 19:44:05 / cg"
! !
-!PBMReader methodsFor:'testing '!
-
-canRepresent:anImage
- "return true, if anImage can be represented in my file format.
- Currently, only 1bit B&W, 8bit-grey and 24bit RGB images are supported."
-
- |depth photometric|
-
- anImage photometric == #rgb ifTrue:[
- ^ depth==24
- ].
- (depth := anImage depth) == 1 ifTrue:[^ true].
- depth == 8 ifTrue:[
- photometric := anImage photometric.
- ^ (photometric == #blackIs0) or:[photometric == #whiteIs0]
- ].
- ^ false
-
- "Modified: 14.10.1997 / 20:06:34 / cg"
-! !
-
!PBMReader methodsFor:'writing to file'!
save:image onFile:aFileName
--- a/SimpleDialog.st Wed Oct 15 19:58:09 1997 +0200
+++ b/SimpleDialog.st Tue Oct 21 20:27:06 1997 +0200
@@ -11,6 +11,8 @@
"
+'From Smalltalk/X, Version:3.2.1 on 18-oct-1997 at 4:26:08 pm' !
+
ApplicationModel subclass:#SimpleDialog
instanceVariableNames:'accept cancel close escapeIsCancel postBuildBlock postOpenBlock
preBuildBlock'
@@ -173,6 +175,21 @@
^ true
! !
+!SimpleDialog methodsFor:'forced actions'!
+
+doAccept
+ accept value:true
+
+ "Created: 18.10.1997 / 05:18:09 / cg"
+ "Modified: 18.10.1997 / 05:18:28 / cg"
+!
+
+doCancel
+ cancel value:true
+
+ "Created: 18.10.1997 / 05:18:22 / cg"
+! !
+
!SimpleDialog methodsFor:'initialization'!
initialize
@@ -224,6 +241,21 @@
!
openFor:anApplication interface:aSelector withBindings:bindings
+ "open the dialog for some appModel from a given specSymbol;
+ the application must provide an interfaceSpec for that symbol.
+ The bindings argument may provide overwriting bindings for the
+ dialog.
+ Return true if accepted, false if canceled"
+
+ ^ self
+ openFor:anApplication
+ interfaceSpec:(anApplication class interfaceSpecFor:aSelector)
+ withBindings:bindings
+
+ "Modified: 18.10.1997 / 04:43:13 / cg"
+!
+
+openFor:anApplication interfaceSpec:aSpec withBindings:bindings
"open the dialog for some appModel from a given spec;
the bindings argument may provide overwriting bindings for the
dialog.
@@ -231,10 +263,10 @@
builder addBindings:bindings.
self source:anApplication.
- ^ self openFrom:(anApplication class interfaceSpecFor:aSelector)
+ ^ self openFrom:aSpec
- "Created: 28.2.1997 / 14:09:06 / cg"
"Modified: 28.2.1997 / 16:22:00 / cg"
+ "Created: 18.10.1997 / 04:41:29 / cg"
!
openFrom:anInterfaceSpec
@@ -248,6 +280,55 @@
"Modified: 28.2.1997 / 16:40:36 / cg"
!
+postBuildWith:aBuilder
+ "this is sent after the dialogs widgets have been created
+ (but before the dialog is opened).
+ If a postBuildBlock was set, evaluate it here."
+
+ postBuildBlock notNil ifTrue:[
+ postBuildBlock numArgs == 0 ifTrue:[
+ postBuildBlock value
+ ] ifFalse:[
+ postBuildBlock value:aBuilder
+ ]
+ ].
+ super postBuildWith:aBuilder
+
+ "Created: 18.10.1997 / 05:17:12 / cg"
+!
+
+postOpenWith:aBuilder
+ "this is sent after the dialogs main window is opened.
+ If a postOpenBlock was set, evaluate it here."
+
+ postOpenBlock notNil ifTrue:[
+ postOpenBlock numArgs == 0 ifTrue:[
+ postOpenBlock value
+ ] ifFalse:[
+ postOpenBlock value:aBuilder
+ ]
+ ].
+ super postOpenWith:aBuilder
+
+ "Created: 18.10.1997 / 05:15:48 / cg"
+!
+
+preBuildWith:aBuilder
+ "this is sent before the dialogs widgets are created.
+ If a preBuildBlock was set, evaluate it here."
+
+ preBuildBlock notNil ifTrue:[
+ preBuildBlock numArgs == 0 ifTrue:[
+ preBuildBlock value
+ ] ifFalse:[
+ preBuildBlock value:aBuilder
+ ]
+ ].
+ super preBuildWith:aBuilder
+
+ "Created: 18.10.1997 / 15:02:27 / cg"
+!
+
preOpen
"arrange for #closeAccept & #closeCancel to be invoked when
either accept or close is triggered
@@ -272,5 +353,5 @@
!SimpleDialog class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/SimpleDialog.st,v 1.12 1997-07-28 11:19:13 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/SimpleDialog.st,v 1.13 1997-10-21 18:27:05 cg Exp $'
! !
--- a/WinIconRdr.st Wed Oct 15 19:58:09 1997 +0200
+++ b/WinIconRdr.st Tue Oct 21 20:27:06 1997 +0200
@@ -10,6 +10,8 @@
hereby transferred.
"
+'From Smalltalk/X, Version:3.2.1 on 21-oct-1997 at 5:07:02 pm' !
+
ImageReader subclass:#WindowsIconReader
instanceVariableNames:''
classVariableNames:''
@@ -36,7 +38,7 @@
documentation
"
this class provides methods for loading Windows and OS2 icon files.
- Image writing is not supported.
+ Image writing is only supported for BMP format with depth 1,4,8 and 24 bit images.
The reader tries to figure out which version of BMP/ICO is used.
It seems to be able to load most formats, but who knows ...
@@ -63,6 +65,15 @@
!WindowsIconReader class methodsFor:'testing'!
+canRepresent:anImage
+ "return true, if anImage can be represented in my file format.
+ BMP supports depth 1,4,8 and 24."
+
+ ^ (#(1 4 8 24) includes:anImage depth)
+
+ "Created: 17.10.1997 / 20:18:23 / cg"
+!
+
isValidImageFile:aFileName
"return true, if aFileName contains a valid windows bitmap-file image"
@@ -113,7 +124,7 @@
loadBMPWidth:w height:h depth:d compression:c from:aStream into:data
"helper: load a BMP image"
- |buff idx1 idx2 bytesPerRow|
+ |buff idx fileBytesPerRow imgBytesPerRow|
d == 8 ifTrue:[
(self class loadBMP8Width:w height:h compression:c from:aStream into:data) ifFalse:[
@@ -144,29 +155,31 @@
^ true
].
d == 24 ifTrue:[
- bytesPerRow := w * 3.
- ((aStream nextBytes:(h * bytesPerRow) into:data) ~~ (h * bytesPerRow)) ifTrue:[
- 'WinIconReader [warning]: read failed' infoPrintNL.
- ^ false
+ imgBytesPerRow := w * 3.
+ fileBytesPerRow := imgBytesPerRow.
+ (fileBytesPerRow bitAnd:3) ~~ 0 ifTrue:[
+ fileBytesPerRow := (fileBytesPerRow bitAnd:(3 bitInvert)) + 4.
].
+ "/
"/ stupid - last row comes first
+ "/
+ idx := imgBytesPerRow * (height - 1) + 1.
+ buff := ByteArray uninitializedNew:fileBytesPerRow.
- buff := ByteArray uninitializedNew:bytesPerRow.
- idx1 := 1.
- idx2 := 1 + (h-1 * bytesPerRow).
- [idx1 < idx2] whileTrue:[
- buff replaceFrom:1 to:bytesPerRow with:data startingAt:idx1.
- data replaceFrom:idx1 to:(idx1 + bytesPerRow - 1) with:data startingAt:idx2.
- data replaceFrom:idx2 to:(idx2 + bytesPerRow - 1) with:buff startingAt:1.
- idx1 := idx1 + bytesPerRow.
- idx2 := idx2 - bytesPerRow.
+ 1 to:height do:[:row |
+ (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
+ 'WinIconReader [warning]: read failed' infoPrintNL.
+ ^ false
+ ].
+ data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
+ idx := idx - imgBytesPerRow.
].
^ true
].
'WinIconReader [warning]: unsupported depth:' infoPrint. d infoPrintNL.
"Created: 17.9.1995 / 18:48:11 / claus"
- "Modified: 28.1.1997 / 01:46:07 / cg"
+ "Modified: 19.10.1997 / 00:01:56 / cg"
! !
!WindowsIconReader methodsFor:'reading from file'!
@@ -665,9 +678,126 @@
"Modified: 24.4.1997 / 22:03:48 / cg"
! !
+!WindowsIconReader methodsFor:'writing to file'!
+
+save:image onFile:aFileName
+ "save image as BMP file on aFileName.
+ Only depth 1,4,8 and 24 images can be represented in this format."
+
+ self saveBMP:image onFile:aFileName.
+
+ "Modified: 17.10.1997 / 20:16:53 / cg"
+!
+
+saveBMP:image onFile:fileName
+ "save image as BMP file on aFileName.
+ Only depth 1,4,8 and 24 images can be represented in this format."
+
+ |depth bhSize biSize biClrUsed biSizeImage bfOffBits rowBytes imgBytesPerRow data srcIndex row|
+
+ depth := image depth.
+ width := image width.
+ height := image height.
+
+ (#(1 4 8 24) includes:depth) ifFalse:[
+ ^ Image cannotRepresentImageSignal
+ raiseWith:image
+ errorString:('BMP format only supports depths 1,4,8 and 24').
+ ].
+ image mask notNil ifTrue:[
+ Image informationLostQuerySignal
+ raiseWith:image
+ errorString:('BMP format does not support an imageMask').
+ ].
+
+ bhSize := 14. "# bytes in file header"
+ biSize := 40. "info header size in bytes"
+ biClrUsed := (depth >= 24) ifTrue:[0] ifFalse:[1 << depth]. "No. color table entries"
+ bfOffBits := biSize + bhSize + (4*biClrUsed).
+ "/ bmp aligns rows on a longword boundary
+ rowBytes := ((depth min:24) * width + 31 // 32) * 4.
+ biSizeImage := height * rowBytes.
+
+ outStream := fileName asFilename writeStream.
+ outStream binary.
+ byteOrder := #lsb.
+
+ "Write the file header"
+ self writeShort:19778. "bfType = BM"
+ self writeLong:(bfOffBits + biSizeImage). "Entire file size in bytes"
+ self writeLong:0. "bfReserved"
+ self writeLong:bfOffBits. "Offset of bitmap data from start of hdr (and file)"
+
+ "Write the bitmap info header"
+ outStream position: bhSize+1.
+ self writeLong:biSize. "info header size in bytes"
+ self writeLong:width. "biWidth"
+ self writeLong:height. "biHeight"
+ self writeShort:1. "biPlanes"
+ self writeShort:(depth min:24). "biBitCount"
+ self writeLong:0. "biCompression"
+ self writeLong:biSizeImage. "size of image section in bytes"
+ self writeLong:2800. "biXPelsPerMeter"
+ self writeLong:2800. "biYPelsPerMeter"
+ self writeLong:biClrUsed.
+ self writeLong:0. "biClrImportant"
+ 1 to:biClrUsed do:[:i | "Color map"
+ |clr r g b|
+
+ clr := image colorFromValue:i-1.
+ clr isNil ifTrue:[
+ r := g := b := 0.
+ ] ifFalse:[
+ r := clr redByte.
+ g := clr greenByte.
+ b := clr blueByte.
+ ].
+
+ "/ put B,G,R
+ outStream nextPut:b.
+ outStream nextPut:g.
+ outStream nextPut:r.
+ outStream nextPut:0.
+ ].
+
+ imgBytesPerRow := image bytesPerRow.
+ data := image data.
+
+
+ "/ sorry, must extract rows individually
+ "/ (even if alignment is correct),
+ "/ since BMP saves rows bottom-to-top
+
+ row := ByteArray new:rowBytes.
+
+ srcIndex := 1 + (height * imgBytesPerRow).
+ 1 to:height do:[:i |
+ srcIndex := srcIndex - imgBytesPerRow.
+ row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
+ outStream nextPutAll:row.
+ ].
+
+ outStream close.
+
+ "
+ |i|
+
+ i := Image fromFile:'bitmaps/SBrowser.xbm'.
+ WindowsIconReader save:i onFile:'test.bmp'.
+ "
+ "
+ |i|
+
+ i := Image fromFile:'bitmaps/gifImages/garfield.gif'.
+ WindowsIconReader save:i onFile:'test.bmp'.
+ "
+
+ "Modified: 21.10.1997 / 05:02:02 / cg"
+! !
+
!WindowsIconReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/Attic/WinIconRdr.st,v 1.36 1997-09-10 21:28:18 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/Attic/WinIconRdr.st,v 1.37 1997-10-21 18:27:06 cg Exp $'
! !
WindowsIconReader initialize!
--- a/WindowsIconReader.st Wed Oct 15 19:58:09 1997 +0200
+++ b/WindowsIconReader.st Tue Oct 21 20:27:06 1997 +0200
@@ -10,6 +10,8 @@
hereby transferred.
"
+'From Smalltalk/X, Version:3.2.1 on 21-oct-1997 at 5:07:02 pm' !
+
ImageReader subclass:#WindowsIconReader
instanceVariableNames:''
classVariableNames:''
@@ -36,7 +38,7 @@
documentation
"
this class provides methods for loading Windows and OS2 icon files.
- Image writing is not supported.
+ Image writing is only supported for BMP format with depth 1,4,8 and 24 bit images.
The reader tries to figure out which version of BMP/ICO is used.
It seems to be able to load most formats, but who knows ...
@@ -63,6 +65,15 @@
!WindowsIconReader class methodsFor:'testing'!
+canRepresent:anImage
+ "return true, if anImage can be represented in my file format.
+ BMP supports depth 1,4,8 and 24."
+
+ ^ (#(1 4 8 24) includes:anImage depth)
+
+ "Created: 17.10.1997 / 20:18:23 / cg"
+!
+
isValidImageFile:aFileName
"return true, if aFileName contains a valid windows bitmap-file image"
@@ -113,7 +124,7 @@
loadBMPWidth:w height:h depth:d compression:c from:aStream into:data
"helper: load a BMP image"
- |buff idx1 idx2 bytesPerRow|
+ |buff idx fileBytesPerRow imgBytesPerRow|
d == 8 ifTrue:[
(self class loadBMP8Width:w height:h compression:c from:aStream into:data) ifFalse:[
@@ -144,29 +155,31 @@
^ true
].
d == 24 ifTrue:[
- bytesPerRow := w * 3.
- ((aStream nextBytes:(h * bytesPerRow) into:data) ~~ (h * bytesPerRow)) ifTrue:[
- 'WinIconReader [warning]: read failed' infoPrintNL.
- ^ false
+ imgBytesPerRow := w * 3.
+ fileBytesPerRow := imgBytesPerRow.
+ (fileBytesPerRow bitAnd:3) ~~ 0 ifTrue:[
+ fileBytesPerRow := (fileBytesPerRow bitAnd:(3 bitInvert)) + 4.
].
+ "/
"/ stupid - last row comes first
+ "/
+ idx := imgBytesPerRow * (height - 1) + 1.
+ buff := ByteArray uninitializedNew:fileBytesPerRow.
- buff := ByteArray uninitializedNew:bytesPerRow.
- idx1 := 1.
- idx2 := 1 + (h-1 * bytesPerRow).
- [idx1 < idx2] whileTrue:[
- buff replaceFrom:1 to:bytesPerRow with:data startingAt:idx1.
- data replaceFrom:idx1 to:(idx1 + bytesPerRow - 1) with:data startingAt:idx2.
- data replaceFrom:idx2 to:(idx2 + bytesPerRow - 1) with:buff startingAt:1.
- idx1 := idx1 + bytesPerRow.
- idx2 := idx2 - bytesPerRow.
+ 1 to:height do:[:row |
+ (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
+ 'WinIconReader [warning]: read failed' infoPrintNL.
+ ^ false
+ ].
+ data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
+ idx := idx - imgBytesPerRow.
].
^ true
].
'WinIconReader [warning]: unsupported depth:' infoPrint. d infoPrintNL.
"Created: 17.9.1995 / 18:48:11 / claus"
- "Modified: 28.1.1997 / 01:46:07 / cg"
+ "Modified: 19.10.1997 / 00:01:56 / cg"
! !
!WindowsIconReader methodsFor:'reading from file'!
@@ -665,9 +678,126 @@
"Modified: 24.4.1997 / 22:03:48 / cg"
! !
+!WindowsIconReader methodsFor:'writing to file'!
+
+save:image onFile:aFileName
+ "save image as BMP file on aFileName.
+ Only depth 1,4,8 and 24 images can be represented in this format."
+
+ self saveBMP:image onFile:aFileName.
+
+ "Modified: 17.10.1997 / 20:16:53 / cg"
+!
+
+saveBMP:image onFile:fileName
+ "save image as BMP file on aFileName.
+ Only depth 1,4,8 and 24 images can be represented in this format."
+
+ |depth bhSize biSize biClrUsed biSizeImage bfOffBits rowBytes imgBytesPerRow data srcIndex row|
+
+ depth := image depth.
+ width := image width.
+ height := image height.
+
+ (#(1 4 8 24) includes:depth) ifFalse:[
+ ^ Image cannotRepresentImageSignal
+ raiseWith:image
+ errorString:('BMP format only supports depths 1,4,8 and 24').
+ ].
+ image mask notNil ifTrue:[
+ Image informationLostQuerySignal
+ raiseWith:image
+ errorString:('BMP format does not support an imageMask').
+ ].
+
+ bhSize := 14. "# bytes in file header"
+ biSize := 40. "info header size in bytes"
+ biClrUsed := (depth >= 24) ifTrue:[0] ifFalse:[1 << depth]. "No. color table entries"
+ bfOffBits := biSize + bhSize + (4*biClrUsed).
+ "/ bmp aligns rows on a longword boundary
+ rowBytes := ((depth min:24) * width + 31 // 32) * 4.
+ biSizeImage := height * rowBytes.
+
+ outStream := fileName asFilename writeStream.
+ outStream binary.
+ byteOrder := #lsb.
+
+ "Write the file header"
+ self writeShort:19778. "bfType = BM"
+ self writeLong:(bfOffBits + biSizeImage). "Entire file size in bytes"
+ self writeLong:0. "bfReserved"
+ self writeLong:bfOffBits. "Offset of bitmap data from start of hdr (and file)"
+
+ "Write the bitmap info header"
+ outStream position: bhSize+1.
+ self writeLong:biSize. "info header size in bytes"
+ self writeLong:width. "biWidth"
+ self writeLong:height. "biHeight"
+ self writeShort:1. "biPlanes"
+ self writeShort:(depth min:24). "biBitCount"
+ self writeLong:0. "biCompression"
+ self writeLong:biSizeImage. "size of image section in bytes"
+ self writeLong:2800. "biXPelsPerMeter"
+ self writeLong:2800. "biYPelsPerMeter"
+ self writeLong:biClrUsed.
+ self writeLong:0. "biClrImportant"
+ 1 to:biClrUsed do:[:i | "Color map"
+ |clr r g b|
+
+ clr := image colorFromValue:i-1.
+ clr isNil ifTrue:[
+ r := g := b := 0.
+ ] ifFalse:[
+ r := clr redByte.
+ g := clr greenByte.
+ b := clr blueByte.
+ ].
+
+ "/ put B,G,R
+ outStream nextPut:b.
+ outStream nextPut:g.
+ outStream nextPut:r.
+ outStream nextPut:0.
+ ].
+
+ imgBytesPerRow := image bytesPerRow.
+ data := image data.
+
+
+ "/ sorry, must extract rows individually
+ "/ (even if alignment is correct),
+ "/ since BMP saves rows bottom-to-top
+
+ row := ByteArray new:rowBytes.
+
+ srcIndex := 1 + (height * imgBytesPerRow).
+ 1 to:height do:[:i |
+ srcIndex := srcIndex - imgBytesPerRow.
+ row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
+ outStream nextPutAll:row.
+ ].
+
+ outStream close.
+
+ "
+ |i|
+
+ i := Image fromFile:'bitmaps/SBrowser.xbm'.
+ WindowsIconReader save:i onFile:'test.bmp'.
+ "
+ "
+ |i|
+
+ i := Image fromFile:'bitmaps/gifImages/garfield.gif'.
+ WindowsIconReader save:i onFile:'test.bmp'.
+ "
+
+ "Modified: 21.10.1997 / 05:02:02 / cg"
+! !
+
!WindowsIconReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.36 1997-09-10 21:28:18 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.37 1997-10-21 18:27:06 cg Exp $'
! !
WindowsIconReader initialize!