--- a/GIFReader.st Tue Nov 18 15:29:43 2014 +0100
+++ b/GIFReader.st Tue Nov 18 18:39:15 2014 +0100
@@ -49,27 +49,27 @@
license for the use of the Graphics Interchange Format(sm) in computer
software; computer software utilizing GIF(sm) must acknowledge ownership of the
Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
- User and Technical Documentation.
+ User and Technical Documentation.
The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated.
Notice:
- there has been some annoyance regarding a patent on the compression algorithm
- used in gif. This patent is now obsolete. However, there is no warranty from
- exept, regarding any legal problems, when using GIF.
- We therefore highly recommend to use newer (and especially: royalty-free) formats,
- such as PNG.
+ there has been some annoyance regarding a patent on the compression algorithm
+ used in gif. This patent is now obsolete. However, there is no warranty from
+ exept, regarding any legal problems, when using GIF.
+ We therefore highly recommend to use newer (and especially: royalty-free) formats,
+ such as PNG.
[See also:]
- Image Form Icon
- BlitImageReader FaceReader JPEGReader PBMReader PCXReader
- ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader
- XBMReader XPMReader XWDReader
+ Image Form Icon
+ BlitImageReader FaceReader JPEGReader PBMReader PCXReader
+ ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader
+ XBMReader XPMReader XWDReader
[author:]
- Claus Gittinger
+ Claus Gittinger
"
!
@@ -78,7 +78,7 @@
saving an animated gif sequence:
a view showing rainfall:
- [exBegin]
+ [exBegin]
|BG CLR N1 H W v WIND drops gen newDrops draw remove move buffer|
BG := Color black.
@@ -98,20 +98,20 @@
buffer := Form extent:(v extent) depth:24 onDevice:v device.
[
- [v shown] whileTrue:[
- draw value.
- v displayForm:buffer.
- move value:WIND.
- remove value.
- newDrops value.
- WIND := (WIND+(Random nextBetween:-1 and:1)) clampBetween:-5 and:5.
- Delay waitForSeconds:0.1.
- ]
+ [v shown] whileTrue:[
+ draw value.
+ v displayForm:buffer.
+ move value:WIND.
+ remove value.
+ newDrops value.
+ WIND := (WIND+(Random nextBetween:-1 and:1)) clampBetween:-5 and:5.
+ Delay waitForSeconds:0.1.
+ ]
] fork.
- [exEnd]
+ [exEnd]
saving those images:
- [exBegin]
+ [exBegin]
|seq img BG CLR N1 H W v drops gen gen1 buffer|
BG := Color black.
@@ -131,19 +131,19 @@
seq := OrderedCollection new.
500 timesRepeat:[
- move value:WIND.
- remove value.
- newDrops value.
- draw value.
- seq add:(ImageFrame new delay:100; image:(Depth8Image fromForm:buffer)).
- WIND := (WIND+(Random nextBetween:-1 and:1)) clampBetween:-5 and:5.
+ move value:WIND.
+ remove value.
+ newDrops value.
+ draw value.
+ seq add:(ImageFrame new delay:100; image:(Depth8Image fromForm:buffer)).
+ WIND := (WIND+(Random nextBetween:-1 and:1)) clampBetween:-5 and:5.
].
img := seq first image.
img imageSequence:(seq copyFrom:2).
img imageSequence do:[:each | each image colorMap:img colorMap].
GIFReader save:img onFile:'/tmp/img.gif'
- [exEnd]
+ [exEnd]
"
! !
@@ -192,7 +192,7 @@
(id = 'GIF87a') ifFalse:[
(id startsWith:'GIF') ifFalse:[^ false].
- id ~= 'GIF89a' ifTrue:[
+ id ~= 'GIF89a' ifTrue:[
'GIFReader [info]: not a GIF87a/GIF89a file - hope that works' infoPrintCR.
]
].
@@ -207,13 +207,10 @@
"read a stream containing a GIF image (or an image sequence).
Leave image description in instance variables."
- |byte index flag count fileColorMap
+ |byte flag fileColorMap
colorMapSize bitsPerPixel scrWidth scrHeight
- hasColorMap hasLocalColorMap interlaced id
- codeLen
- compressedData compressedSize
- tmp srcOffset dstOffset isGif89 atEnd
- h "{ Class: SmallInteger }"
+ hasColorMap interlaced id
+ isGif89 atEnd
img firstImage firstOffset firstFrameDelay frame imageCount|
inStream := aStream.
@@ -224,7 +221,7 @@
id := ByteArray new:6.
(aStream nextBytes:6 into:id startingAt:1) ~~ 6 ifTrue:[
- ^ self fileFormatError:'not a gif file (short read)'.
+ ^ self fileFormatError:'not a gif file (short read)'.
].
id := id asString.
@@ -233,12 +230,12 @@
isGif89 := false.
(id ~= 'GIF87a') ifTrue:[
- (id startsWith:'GIF') ifFalse:[
- ^ self fileFormatError:('not a gif file (id=''' , id , ''')').
- ].
- id ~= 'GIF89a' ifTrue:[
- 'GIFReader [info]: not a GIF87a/GIF89a file - hope that works' infoPrintCR.
- ]
+ (id startsWith:'GIF') ifFalse:[
+ ^ self fileFormatError:('not a gif file (id=''' , id , ''')').
+ ].
+ id ~= 'GIF89a' ifTrue:[
+ 'GIFReader [info]: not a GIF87a/GIF89a file - hope that works' infoPrintCR.
+ ]
].
"get screen dimensions (not used)"
@@ -261,7 +258,7 @@
"get colorMap"
hasColorMap ifTrue:[
- fileColorMap := self readColorMap:colorMapSize.
+ fileColorMap := self readColorMap:colorMapSize.
].
colorMap := fileColorMap.
@@ -272,91 +269,91 @@
imageCount := 0.
atEnd := false.
[atEnd] whileFalse:[
- "gif89a extensions"
+ "gif89a extensions"
- byte := aStream nextByte.
- byte isNil ifTrue:[
- "/ atEnd-Terminator missing
- atEnd := true
- ] ifFalse:[
- byte == Extension ifTrue:[
+ byte := aStream nextByte.
+ byte isNil ifTrue:[
+ "/ atEnd-Terminator missing
+ atEnd := true
+ ] ifFalse:[
+ byte == Extension ifTrue:[
"/ 'Ext' infoPrintCR.
- self readExtension:aStream.
- ] ifFalse:[
- (byte == Terminator) ifTrue:[
- atEnd := true
- ] ifFalse:[
- "must be image separator"
- (byte ~~ ImageSeparator) ifTrue:[
- ^ self fileFormatError:('corrupted gif file (no IMAGESEP): ' , (byte printStringRadix:16)).
- ].
+ self readExtension:aStream.
+ ] ifFalse:[
+ (byte == Terminator) ifTrue:[
+ atEnd := true
+ ] ifFalse:[
+ "must be image separator"
+ (byte ~~ ImageSeparator) ifTrue:[
+ ^ self fileFormatError:('corrupted gif file (no IMAGESEP): ' , (byte printStringRadix:16)).
+ ].
"/ 'Img' infoPrintCR.
- fileColorMap notNil ifTrue:[
- colorMap := fileColorMap.
- ].
- Object primitiveFailureSignal handle:[:ex |
- ^ self fileFormatError:('corrupted gif file').
- ] do:[
- self readImage:aStream.
- ].
+ fileColorMap notNil ifTrue:[
+ colorMap := fileColorMap.
+ ].
+ Object primitiveFailureSignal handle:[:ex |
+ ^ self fileFormatError:('corrupted gif file').
+ ] do:[
+ self readImage:aStream.
+ ].
- maskPixel notNil ifTrue:[
- "/
- "/ ok, there is a maskValue
- "/ build a Depth1Image for it.
- "/
- self buildMaskFromColor:maskPixel
- ].
+ maskPixel notNil ifTrue:[
+ "/
+ "/ ok, there is a maskValue
+ "/ build a Depth1Image for it.
+ "/
+ self buildMaskFromColor:maskPixel
+ ].
- imageCount == 0 ifTrue:[
- img := self makeImage.
- "/ remember first image in case more come later.
- firstImage := img.
- firstFrameDelay := frameDelay.
- firstOffset := (leftOffs @ topOffs).
- ] ifFalse:[
- imageCount == 1 ifTrue:[
- imageSequence := ImageSequence new.
- img imageSequence:imageSequence.
+ imageCount == 0 ifTrue:[
+ img := self makeImage.
+ "/ remember first image in case more come later.
+ firstImage := img.
+ firstFrameDelay := frameDelay.
+ firstOffset := (leftOffs @ topOffs).
+ ] ifFalse:[
+ imageCount == 1 ifTrue:[
+ imageSequence := ImageSequence new.
+ img imageSequence:imageSequence.
- "/ add frame for first image.
- frame := ImageFrame new image:firstImage.
- frame delay:firstFrameDelay.
- frame offset:firstOffset.
- imageSequence add:frame.
- ].
- img := self makeImage.
- img imageSequence:imageSequence.
+ "/ add frame for first image.
+ frame := ImageFrame new image:firstImage.
+ frame delay:firstFrameDelay.
+ frame offset:firstOffset.
+ imageSequence add:frame.
+ ].
+ img := self makeImage.
+ img imageSequence:imageSequence.
- "/ add frame for this image.
- frame := ImageFrame new image:img.
- frame delay:frameDelay.
- frame offset:(leftOffs @ topOffs).
- imageSequence add:frame.
- ].
+ "/ add frame for this image.
+ frame := ImageFrame new image:img.
+ frame delay:frameDelay.
+ frame offset:(leftOffs @ topOffs).
+ imageSequence add:frame.
+ ].
- imageCount := imageCount + 1.
+ imageCount := imageCount + 1.
- frameDelay := nil.
+ frameDelay := nil.
- aStream atEnd ifTrue:[
- atEnd := true.
- ]
- ]
- ].
- ].
+ aStream atEnd ifTrue:[
+ atEnd := true.
+ ]
+ ]
+ ].
+ ].
].
imageSequence notNil ifTrue:[
- iterationCount notNil ifTrue:[
- iterationCount == 0 ifTrue:[
- imageSequence loop:true.
- ] ifFalse:[
- imageSequence loop:false.
- imageSequence iterationCount:iterationCount.
- ]
- ]
+ iterationCount notNil ifTrue:[
+ iterationCount == 0 ifTrue:[
+ imageSequence loop:true.
+ ] ifFalse:[
+ imageSequence loop:false.
+ imageSequence iterationCount:iterationCount.
+ ]
+ ]
].
"
@@ -380,7 +377,7 @@
|rgbVector|
rgbVector := inStream nextBytes:colorMapSize*3.
- ^ MappedPalette rgbBytesVector:rgbVector
+ ^ MappedPalette rgbBytesVector:rgbVector
!
readExtension:aStream
@@ -394,136 +391,136 @@
type := aStream nextByte.
type == $R codePoint ifTrue:[
- "/
- "/ Ratio extension
- "/
- "/ 'GIFREADER [info]: ratio extension ignored' infoPrintCR.
- blockSize := aStream nextByte.
- (blockSize == 2) ifTrue:[
- aspNum := aStream nextByte.
- aspDen := aStream nextByte
- ] ifFalse:[
- aStream skip:blockSize
- ].
+ "/
+ "/ Ratio extension
+ "/
+ "/ 'GIFREADER [info]: ratio extension ignored' infoPrintCR.
+ blockSize := aStream nextByte.
+ (blockSize == 2) ifTrue:[
+ aspNum := aStream nextByte.
+ aspDen := aStream nextByte
+ ] ifFalse:[
+ aStream skip:blockSize
+ ].
- "/ eat subblocks
- [(subBlockSize := aStream nextByte) > 0] whileTrue:[
- aStream skip:subBlockSize
- ].
- ^ self
+ "/ eat subblocks
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ].
+ ^ self
].
type == 16r01 ifTrue:[
- "/
- "/ plaintext extension
- "/
- "/ 'GIFREADER [info]: plaintext extension ignored' infoPrintCR.
- subBlockSize := aStream nextByte.
- left := aStream nextShortMSB:false.
- top := aStream nextShortMSB:false.
- width := aStream nextShortMSB:false.
- height := aStream nextShortMSB:false.
- cWidth := aStream nextByte.
- cHeight := aStream nextByte.
- fg := aStream nextByte.
- bg := aStream nextByte.
- aStream skip:12.
- "/ eat subblocks
- [(subBlockSize := aStream nextByte) > 0] whileTrue:[
- aStream skip:subBlockSize
- ].
- ^ self
+ "/
+ "/ plaintext extension
+ "/
+ "/ 'GIFREADER [info]: plaintext extension ignored' infoPrintCR.
+ subBlockSize := aStream nextByte.
+ left := aStream nextShortMSB:false.
+ top := aStream nextShortMSB:false.
+ width := aStream nextShortMSB:false.
+ height := aStream nextShortMSB:false.
+ cWidth := aStream nextByte.
+ cHeight := aStream nextByte.
+ fg := aStream nextByte.
+ bg := aStream nextByte.
+ aStream skip:12.
+ "/ eat subblocks
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ].
+ ^ self
].
type == 16rF9 ifTrue:[
- "/
- "/ graphic control extension
- "/
- "/ 'GIFREADER [info]: graphic control extension' infoPrintCR.
+ "/
+ "/ graphic control extension
+ "/
+ "/ 'GIFREADER [info]: graphic control extension' infoPrintCR.
- [(subBlockSize := aStream nextByte) ~~ 0 and:[subBlockSize notNil]] whileTrue:[
- "/ type bitAnd:1 means: animationMask is transparent pixel
- "/ to be implemented in Image ...
+ [(subBlockSize := aStream nextByte) ~~ 0 and:[subBlockSize notNil]] whileTrue:[
+ "/ type bitAnd:1 means: animationMask is transparent pixel
+ "/ to be implemented in Image ...
- animationType := aStream nextByte.
- animationTime := aStream nextShortMSB:false.
- animationMask := aStream nextByte.
+ animationType := aStream nextByte.
+ animationTime := aStream nextShortMSB:false.
+ animationMask := aStream nextByte.
- subBlockSize := subBlockSize - 4.
+ subBlockSize := subBlockSize - 4.
- (animationType bitTest: 1) ifTrue:[
- maskPixel := animationMask.
+ (animationType bitTest: 1) ifTrue:[
+ maskPixel := animationMask.
"/ 'GIFREADER [info]: mask: ' infoPrint. (maskPixel printStringRadix:16) infoPrintCR.
- ].
+ ].
"/ 'GIFREADER [info]: animationTime: ' infoPrint. (animationTime * (1/100)) infoPrintCR.
"/ 'GIFREADER [info]: animationType: ' infoPrint. (animationType) infoPrintCR.
"/ 'GIFREADER [info]: animationMask: ' infoPrint. (animationMask) infoPrintCR.
- frameDelay := (animationTime * (1/100)) * 1000.
+ frameDelay := (animationTime * (1/100)) * 1000.
- subBlockSize ~~ 0 ifTrue:[
- aStream skip:subBlockSize
- ].
- ].
- ^ self
+ subBlockSize ~~ 0 ifTrue:[
+ aStream skip:subBlockSize
+ ].
+ ].
+ ^ self
].
type == 16rFE ifTrue:[
- "/
- "/ comment extension
- "/
- "/ 'GIFREADER [info]: comment extension' infoPrintCR.
- [(blockSize := aStream nextByte) ~~ 0] whileTrue:[
- aStream skip:blockSize
- ].
- ^ self
+ "/
+ "/ comment extension
+ "/
+ "/ 'GIFREADER [info]: comment extension' infoPrintCR.
+ [(blockSize := aStream nextByte) ~~ 0] whileTrue:[
+ aStream skip:blockSize
+ ].
+ ^ self
].
type == 16rFF ifTrue:[
- "/
- "/ application extension
- "/
- "/ 'GIFREADER [info]: application extension' infoPrintCR.
- subBlockSize := aStream nextByte.
- appID := (aStream nextBytes:8 ) asString.
- appAUTH := aStream nextBytes:3.
+ "/
+ "/ application extension
+ "/
+ "/ 'GIFREADER [info]: application extension' infoPrintCR.
+ subBlockSize := aStream nextByte.
+ appID := (aStream nextBytes:8 ) asString.
+ appAUTH := aStream nextBytes:3.
- subBlockSize := aStream nextByte.
+ subBlockSize := aStream nextByte.
- ok := false.
- appID = 'NETSCAPE' ifTrue:[
- appAUTH asString = '2.0' ifTrue:[
- subBlockSize == 3 ifTrue:[
- b := aStream nextByte.
- iterationCount := aStream nextShortMSB:false.
- subBlockSize := aStream nextByte.
- ok := true.
+ ok := false.
+ appID = 'NETSCAPE' ifTrue:[
+ appAUTH asString = '2.0' ifTrue:[
+ subBlockSize == 3 ifTrue:[
+ b := aStream nextByte.
+ iterationCount := aStream nextShortMSB:false.
+ subBlockSize := aStream nextByte.
+ ok := true.
"/ ('GIFREADER [info]: NETSCAPE application extension - iterationCount = ') infoPrint.
"/ iterationCount infoPrintCR.
- ]
- ]
- ].
+ ]
+ ]
+ ].
- ok ifFalse:[
- ('GIFREADER [info]: application extension (' , appID , ') ignored') infoPrintCR.
- ].
+ ok ifFalse:[
+ ('GIFREADER [info]: application extension (' , appID , ') ignored') infoPrintCR.
+ ].
- [subBlockSize > 0] whileTrue:[
- aStream skip:subBlockSize.
- subBlockSize := aStream nextByte.
- ].
- ^ self
+ [subBlockSize > 0] whileTrue:[
+ aStream skip:subBlockSize.
+ subBlockSize := aStream nextByte.
+ ].
+ ^ self
].
type == 16r2C ifTrue:[
- "/
- "/ image descriptor extension
- "/
- "/ 'GIFREADER [info]: image descriptor extension ignored' infoPrintCR.
- [(subBlockSize := aStream nextByte) > 0] whileTrue:[
- aStream skip:subBlockSize
- ].
- ^ self
+ "/
+ "/ image descriptor extension
+ "/
+ "/ 'GIFREADER [info]: image descriptor extension ignored' infoPrintCR.
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ].
+ ^ self
].
"/
@@ -531,7 +528,7 @@
"/
'GIFREADER [info]: unknown extension ignored' infoPrintCR.
[(subBlockSize := aStream nextByte) > 0] whileTrue:[
- aStream skip:subBlockSize
+ aStream skip:subBlockSize
]
"Modified: / 02-06-2010 / 12:21:53 / cg"
@@ -568,20 +565,20 @@
"if image has a local colormap, this one is used"
hasLocalColorMap ifTrue:[
- "local descr. overwrites"
- bitsPerPixel := (flag bitAnd:2r00000111) + 1.
- colorMapSize := 1 bitShift:bitsPerPixel.
- "overwrite colormap"
- colorMap := self readColorMap:colorMapSize.
+ "local descr. overwrites"
+ bitsPerPixel := (flag bitAnd:2r00000111) + 1.
+ colorMapSize := 1 bitShift:bitsPerPixel.
+ "overwrite colormap"
+ colorMap := self readColorMap:colorMapSize.
].
"get codelen for decompression"
codeLen := aStream nextByte.
(aStream respondsTo:#fileSize) ifTrue:[
- initialBuffSize := aStream fileSize.
+ initialBuffSize := aStream fileSize.
] ifFalse:[
- initialBuffSize := 512.
+ initialBuffSize := 512.
].
compressedData := ByteArray uninitializedNew:initialBuffSize.
@@ -589,17 +586,17 @@
index := 1.
count := aStream nextByte.
[count notNil and:[count ~~ 0]] whileTrue:[
- (compressedData size < (index+count)) ifTrue:[
- |t|
+ (compressedData size < (index+count)) ifTrue:[
+ |t|
- t := ByteArray uninitializedNew:(index+count*3//2).
- t replaceBytesFrom:1 to:index-1 with:compressedData startingAt:1.
- compressedData := t.
- ].
+ t := ByteArray uninitializedNew:(index+count*3//2).
+ t replaceBytesFrom:1 to:index-1 with:compressedData startingAt:1.
+ compressedData := t.
+ ].
- aStream nextBytes:count into:compressedData startingAt:index blockSize:4096.
- index := index + count.
- count := aStream nextByte
+ aStream nextBytes:count into:compressedData startingAt:index blockSize:4096.
+ index := index + count.
+ count := aStream nextByte
].
compressedSize := index - 1.
@@ -608,54 +605,54 @@
"/ 'GIFReader: decompressing ...' infoPrintCR.
self class decompressGIFFrom:compressedData
- count:compressedSize
- into:data
- startingAt:1
- codeLen:(codeLen + 1).
+ count:compressedSize
+ into:data
+ startingAt:1
+ codeLen:(codeLen + 1).
interlaced ifTrue:[
"/ 'GIFREADER: deinterlacing ...' infoPrintCR.
- tmp := ByteArray new:(data size).
+ tmp := ByteArray new:(data size).
- "phase 1: 0, 8, 16, 24, ..."
+ "phase 1: 0, 8, 16, 24, ..."
- srcOffset := 1.
- 0 to:(h - 1) by:8 do:[:dstRow |
- dstOffset := dstRow * width + 1.
- tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
- with:data startingAt:srcOffset.
- srcOffset := srcOffset + width.
- ].
+ srcOffset := 1.
+ 0 to:(h - 1) by:8 do:[:dstRow |
+ dstOffset := dstRow * width + 1.
+ tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
+ with:data startingAt:srcOffset.
+ srcOffset := srcOffset + width.
+ ].
- "phase 2: 4, 12, 20, 28, ..."
+ "phase 2: 4, 12, 20, 28, ..."
- 4 to:(h - 1) by:8 do:[:dstRow |
- dstOffset := dstRow * width + 1.
- tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
- with:data startingAt:srcOffset.
- srcOffset := srcOffset + width.
- ].
+ 4 to:(h - 1) by:8 do:[:dstRow |
+ dstOffset := dstRow * width + 1.
+ tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
+ with:data startingAt:srcOffset.
+ srcOffset := srcOffset + width.
+ ].
- "phase 3: 2, 6, 10, 14, ..."
+ "phase 3: 2, 6, 10, 14, ..."
- 2 to:(h - 1) by:4 do:[:dstRow |
- dstOffset := dstRow * width + 1.
- tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
- with:data startingAt:srcOffset.
- srcOffset := srcOffset + width.
- ].
+ 2 to:(h - 1) by:4 do:[:dstRow |
+ dstOffset := dstRow * width + 1.
+ tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
+ with:data startingAt:srcOffset.
+ srcOffset := srcOffset + width.
+ ].
- "phase 4: 1, 3, 5, 7, ..."
+ "phase 4: 1, 3, 5, 7, ..."
- 1 to:(h - 1) by:2 do:[:dstRow |
- dstOffset := dstRow * width + 1.
- tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
- with:data startingAt:srcOffset.
- srcOffset := srcOffset + width.
- ].
+ 1 to:(h - 1) by:2 do:[:dstRow |
+ dstOffset := dstRow * width + 1.
+ tmp replaceFrom:dstOffset to:(dstOffset + width - 1)
+ with:data startingAt:srcOffset.
+ srcOffset := srcOffset + width.
+ ].
- data := tmp.
- tmp := nil.
+ data := tmp.
+ tmp := nil.
].
"Created: / 13.1.1998 / 10:44:05 / cg"
@@ -670,17 +667,17 @@
|cmap usedPixelValues unusedValues|
(cmap := image colorMap) size > 0 ifTrue:[
- cmap size < 256 ifTrue:[
- maskPixel := cmap size.
- ^ self
- ]
+ cmap size < 256 ifTrue:[
+ maskPixel := cmap size.
+ ^ self
+ ]
].
image compressColorMap.
usedPixelValues := image usedValues.
usedPixelValues size < (1 bitShift:image depth) ifFalse:[
- Image informationLostQuerySignal
- raiseRequestWith:image
- errorString:('GIF writer cannot assign a transparent pixel - all pixelValues used by image').
+ Image informationLostQuerySignal
+ raiseRequestWith:image
+ errorString:('GIF writer cannot assign a transparent pixel - all pixelValues used by image').
].
"/ there must be an unused pixelValue
@@ -694,7 +691,7 @@
checkCodeSize
(freeCode > maxCode and: [codeSize < 12])
- ifTrue:
+ ifTrue:
[codeSize := codeSize + 1.
maxCode := (1 bitShift: codeSize) - 1]
@@ -703,7 +700,7 @@
flushBits
remainBitCount = 0
- ifFalse:
+ ifFalse:
[self nextBytePut: bufByte.
remainBitCount := 0].
self flushBuffer
@@ -727,24 +724,24 @@
!
nextBitsPut: anInteger
- | integer writeBitCount shiftCount |
- shiftCount := 0.
- remainBitCount = 0
- ifTrue:
- [writeBitCount := 8.
- integer := anInteger]
- ifFalse:
- [writeBitCount := remainBitCount.
- integer := bufByte + (anInteger bitShift: 8 - remainBitCount)].
- [writeBitCount < codeSize]
- whileTrue:
- [self nextBytePut: ((integer bitShift: shiftCount) bitAnd: 255).
- shiftCount := shiftCount - 8.
- writeBitCount := writeBitCount + 8].
- (remainBitCount := writeBitCount - codeSize) = 0
- ifTrue: [self nextBytePut: (integer bitShift: shiftCount)]
- ifFalse: [bufByte := integer bitShift: shiftCount].
- ^anInteger
+ | integer writeBitCount shiftCount |
+ shiftCount := 0.
+ remainBitCount = 0
+ ifTrue:
+ [writeBitCount := 8.
+ integer := anInteger]
+ ifFalse:
+ [writeBitCount := remainBitCount.
+ integer := bufByte + (anInteger bitShift: 8 - remainBitCount)].
+ [writeBitCount < codeSize]
+ whileTrue:
+ [self nextBytePut: ((integer bitShift: shiftCount) bitAnd: 255).
+ shiftCount := shiftCount - 8.
+ writeBitCount := writeBitCount + 8].
+ (remainBitCount := writeBitCount - codeSize) = 0
+ ifTrue: [self nextBytePut: (integer bitShift: shiftCount)]
+ ifFalse: [bufByte := integer bitShift: shiftCount].
+ ^anInteger
"Modified: 15.10.1997 / 16:50:30 / cg"
!
@@ -756,10 +753,10 @@
"Modified: 15.10.1997 / 16:50:52 / cg"
!
-readPixelFrom: bits
+readPixelFrom: bits
| pixel |
ypos >= height ifTrue: [^ nil].
- (maskPixel notNil
+ (maskPixel notNil
and:[(mask pixelAtX:xpos y:ypos) == 0]) ifTrue:[
pixel := maskPixel
] ifFalse:[
@@ -772,7 +769,7 @@
"Modified: 15.10.1997 / 16:46:43 / cg"
!
-setParameters:bitsPerPixel
+setParameters:bitsPerPixel
clearCode := 1 bitShift:bitsPerPixel.
eoiCode := clearCode + 1.
freeCode := clearCode + 2.
@@ -787,34 +784,34 @@
xpos := 0.
interlace == true ifFalse:[
- ypos := ypos + 1.
- ^ self
+ ypos := ypos + 1.
+ ^ self
].
pass == 0 ifTrue:[
- (ypos := ypos + 8) >= height ifTrue:[
- pass := pass + 1.
- ypos := 4
- ].
- ^ self
+ (ypos := ypos + 8) >= height ifTrue:[
+ pass := pass + 1.
+ ypos := 4
+ ].
+ ^ self
].
pass == 1 ifTrue:[
- (ypos := ypos + 8) >= height ifTrue:[
- pass := pass + 1.
- ypos := 2
- ].
- ^ self
+ (ypos := ypos + 8) >= height ifTrue:[
+ pass := pass + 1.
+ ypos := 2
+ ].
+ ^ self
].
pass == 2 ifTrue:[
- (ypos := ypos + 4) >= height ifTrue:[
- pass := pass + 1.
- ypos := 1
- ].
- ^ self
+ (ypos := ypos + 4) >= height ifTrue:[
+ pass := pass + 1.
+ ypos := 1
+ ].
+ ^ self
].
pass == 3 ifTrue:[
- ypos := ypos + 2.
- ^ self
+ ypos := ypos + 2.
+ ^ self
].
^ self error: 'can''t happen'
@@ -834,9 +831,9 @@
self writeShort:height.
interlace == true ifTrue:[
- t1 := 64
+ t1 := 64
] ifFalse:[
- t1 := 0 "/ no local colormap
+ t1 := 0 "/ no local colormap
].
outStream nextPut:t1. "/ another flag
@@ -864,8 +861,8 @@
tShift := 0.
fCode := tSize.
[fCode < 65536] whileTrue:[
- tShift := tShift + 1.
- fCode := fCode * 2
+ tShift := tShift + 1.
+ fCode := fCode * 2
].
tShift := 8 - tShift.
"/ 1 to: tSize do: [:i | suffixTable at: i put: -1]. - cg changed initialization above
@@ -873,38 +870,38 @@
self writeCodeAndCheckCodeSize: clearCode.
ent := self readPixelFrom: bits.
[(pixel := self readPixelFrom: bits) == nil] whileFalse:[
- fCode := (pixel bitShift: maxBits) + ent.
- index := ((pixel bitShift: tShift) bitXor: ent) + 1.
- (suffixTable at: index) = fCode
- ifTrue: [ent := prefixTable at: index]
- ifFalse:[
- nomatch := true.
- (suffixTable at: index) >= 0
- ifTrue:[
- disp := tSize - index + 1.
- index = 1 ifTrue: [disp := 1].
- "probe"
- [(index := index - disp) < 1 ifTrue: [index := index + tSize].
- (suffixTable at: index) = fCode
- ifTrue:[
- ent := prefixTable at: index.
- nomatch := false.
- "continue whileFalse:"].
- nomatch and: [(suffixTable at: index) > 0]]
- whileTrue: ["probe"]].
- "nomatch"
- nomatch ifTrue:[
- self writeCodeAndCheckCodeSize: ent.
- ent := pixel.
- freeCode < maxMaxCode
- ifTrue:[
- prefixTable at: index put: freeCode.
- suffixTable at: index put: fCode.
- freeCode := freeCode + 1]
- ifFalse:[
- self writeCodeAndCheckCodeSize: clearCode.
- suffixTable from:1 to:tSize put:-1.
- self setParameters: initCodeSize]]]].
+ fCode := (pixel bitShift: maxBits) + ent.
+ index := ((pixel bitShift: tShift) bitXor: ent) + 1.
+ (suffixTable at: index) = fCode
+ ifTrue: [ent := prefixTable at: index]
+ ifFalse:[
+ nomatch := true.
+ (suffixTable at: index) >= 0
+ ifTrue:[
+ disp := tSize - index + 1.
+ index = 1 ifTrue: [disp := 1].
+ "probe"
+ [(index := index - disp) < 1 ifTrue: [index := index + tSize].
+ (suffixTable at: index) = fCode
+ ifTrue:[
+ ent := prefixTable at: index.
+ nomatch := false.
+ "continue whileFalse:"].
+ nomatch and: [(suffixTable at: index) > 0]]
+ whileTrue: ["probe"]].
+ "nomatch"
+ nomatch ifTrue:[
+ self writeCodeAndCheckCodeSize: ent.
+ ent := pixel.
+ freeCode < maxMaxCode
+ ifTrue:[
+ prefixTable at: index put: freeCode.
+ suffixTable at: index put: fCode.
+ freeCode := freeCode + 1]
+ ifFalse:[
+ self writeCodeAndCheckCodeSize: clearCode.
+ suffixTable from:1 to:tSize put:-1.
+ self setParameters: initCodeSize]]]].
prefixTable := suffixTable := nil.
self writeCodeAndCheckCodeSize: ent.
self writeCodeAndCheckCodeSize: eoiCode.
@@ -914,14 +911,14 @@
"Modified: / 02-06-2010 / 12:24:20 / cg"
!
-writeCode: aCode
+writeCode: aCode
self nextBitsPut: aCode
"Created: 14.10.1997 / 18:38:35 / cg"
"Modified: 15.10.1997 / 17:01:47 / cg"
!
-writeCodeAndCheckCodeSize: t1
+writeCodeAndCheckCodeSize: t1
self writeCode: t1.
self checkCodeSize
@@ -938,7 +935,7 @@
outStream nextPutAll: 'GIF89a' asByteArray.
self writeShort:width. "/ screen size
- self writeShort:height.
+ self writeShort:height.
t1 := 128.
t1 := t1 bitOr:(bitsPerPixel - 1 bitShift:5).
t1 := t1 bitOr:(bitsPerPixel - 1).
@@ -947,20 +944,20 @@
outStream nextPut:0. "/ aspect ratio
0 to:(1 bitShift:bitsPerPixel)-1 do:[:pixel |
- |clr red green blue|
+ |clr red green blue|
- 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.
- ].
+ 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.
+ ].
"Created: / 14.10.1997 / 17:41:28 / cg"
"Modified: / 31.10.1997 / 16:12:13 / cg"
@@ -988,21 +985,21 @@
|convertedImage|
image depth ~~ 8 ifTrue:[
- Error handle:[:ex |
- ^ Image cannotRepresentImageSignal
- raiseWith:image
- errorString:('GIF failed to convert image to depth8: ', ex description).
- "/ ex return.
- ] do:[
- convertedImage := Image newForDepth:8.
- convertedImage fromImage:image photometric:#palette.
- ].
- convertedImage notNil ifTrue:[
- ^ self save:convertedImage onFile:aFileName
- ].
- ^ Image cannotRepresentImageSignal
- raiseWith:image
- errorString:('GIF (currently) only supports depth8 images (cannot convert)').
+ Error handle:[:ex |
+ ^ Image cannotRepresentImageSignal
+ raiseWith:image
+ errorString:('GIF failed to convert image to depth8: ', ex description).
+ "/ ex return.
+ ] do:[
+ convertedImage := Image newForDepth:8.
+ convertedImage fromImage:image photometric:#palette.
+ ].
+ convertedImage notNil ifTrue:[
+ ^ self save:convertedImage onFile:aFileName
+ ].
+ ^ Image cannotRepresentImageSignal
+ raiseWith:image
+ errorString:('GIF (currently) only supports depth8 images (cannot convert)').
].
super save:image onFile:aFileName.
@@ -1023,9 +1020,9 @@
"save image in GIF-file-format onto aStream"
image depth ~~ 8 ifTrue:[
- ^ Image cannotRepresentImageSignal
- raiseWith:image
- errorString:('GIF (currently) only supports depth8 images').
+ ^ Image cannotRepresentImageSignal
+ raiseWith:image
+ errorString:('GIF (currently) only supports depth8 images').
].
outStream := aStream.
@@ -1033,7 +1030,7 @@
mask := image mask.
mask notNil ifTrue:[
- self assignTransparentPixelIn:image
+ self assignTransparentPixelIn:image
].
byteOrder := #lsb.
@@ -1047,24 +1044,24 @@
self writeHeaderFor:image.
maskPixel notNil ifTrue:[
- self writeMaskExtensionHeaderFor:image.
+ self writeMaskExtensionHeaderFor:image.
].
self writeBitDataFor:image.
image imageSequence notEmptyOrNil ifTrue:[
- image imageSequence do:[:eachFrame |
- outStream nextPut:Extension.
- outStream nextPut:16rF9. "/ graphic control extension
- outStream nextPut:4. "/ sub block size
- outStream nextPut:0. "/ animation type 0
- outStream nextPutShort:(eachFrame delay / 10) rounded asInteger MSB:false.
- outStream nextPut:0. "/ animation mask
- outStream nextPut:0. "/ subblock size
+ image imageSequence do:[:eachFrame |
+ outStream nextPut:Extension.
+ outStream nextPut:16rF9. "/ graphic control extension
+ outStream nextPut:4. "/ sub block size
+ outStream nextPut:0. "/ animation type 0
+ outStream nextPutShort:(eachFrame delay / 10) rounded asInteger MSB:false.
+ outStream nextPut:0. "/ animation mask
+ outStream nextPut:0. "/ subblock size
- self writeBitDataFor:eachFrame image.
-
- ].
+ self writeBitDataFor:eachFrame image.
+
+ ].
].
outStream nextPut: Terminator.
@@ -1084,11 +1081,11 @@
!GIFReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.106 2014-11-15 16:36:59 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.107 2014-11-18 17:39:15 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.106 2014-11-15 16:36:59 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.107 2014-11-18 17:39:15 cg Exp $'
! !