--- a/GIFReader.st Tue Jun 24 13:16:55 1997 +0200
+++ b/GIFReader.st Tue Jun 24 15:30:20 1997 +0200
@@ -104,6 +104,34 @@
"Modified: 10.1.1997 / 15:40:34 / cg"
! !
+!GIFReader methodsFor:'accessing'!
+
+image
+ "return the first image as read"
+
+ ^ imageSequence first
+
+ "Modified: 21.6.1997 / 18:32:38 / cg"
+ "Created: 21.6.1997 / 18:37:05 / cg"
+!
+
+images
+ "return a collection of all images as represented by myself"
+
+ ^ imageSequence
+
+ "Created: 21.6.1997 / 12:01:34 / cg"
+ "Modified: 21.6.1997 / 18:32:38 / cg"
+! !
+
+!GIFReader methodsFor:'queries'!
+
+numberOfImages
+ ^ imageSequence size
+
+ "Created: 21.6.1997 / 18:33:59 / cg"
+! !
+
!GIFReader methodsFor:'reading from file'!
checkGreyscaleColormap
@@ -134,7 +162,7 @@
hasColorMap hasLocalColorMap interlaced id
leftOffs topOffs codeLen
compressedData compressedSize
- tmp srcOffset dstOffset isGif89
+ tmp srcOffset dstOffset isGif89 atEnd
h "{ Class: SmallInteger }"|
inStream := aStream.
@@ -182,156 +210,170 @@
"get colorMap"
hasColorMap ifTrue:[
- self readColorMap:colorMapSize
- ].
-
- "skip gif89a extensions "
- byte := aStream nextByte.
- [byte == 16r21] whileTrue:[
- "/ extension
- self readExtension:aStream.
- byte := aStream nextByte.
- ].
-
- "must now be image separator"
- (byte ~~ 16r2C) ifTrue:[
- ('GIFReader [info]: corrupted gif file (no IMAGESEP): ' , (byte printStringRadix:16)) infoPrintCR.
- ^ nil
- ].
-
- "get image data"
- leftOffs := aStream nextShortMSB:false.
- topOffs := aStream nextShortMSB:false.
- width := aStream nextShortMSB:false.
- height := aStream nextShortMSB:false.
-
- dimensionCallBack notNil ifTrue:[
- dimensionCallBack value:self
- ].
-
-"
-'width ' print. width printNewline.
-'height ' print. height printNewline.
-"
-
- "another flag byte"
- flag := aStream nextByte.
- interlaced := (flag bitAnd:2r01000000) ~~ 0.
- hasLocalColorMap := (flag bitAnd:2r10000000) ~~ 0.
- "localColorMapSorted := (flag bitAnd:2r00100000) ~~ 0. "
-
- "if image has a local colormap, this one is used"
-
- hasLocalColorMap ifTrue:[
- "local descr. overwrites"
- bitsPerPixel := (flag bitAnd:2r00000111) + 1.
- colorMapSize := 1 bitShift:bitsPerPixel.
-" 'local colormap' printNewline. "
- "overwrite colormap"
- self readColorMap:colorMapSize
- ].
-
- "get codelen for decompression"
- codeLen := aStream nextByte.
-
- compressedData := ByteArray uninitializedNew:(aStream size).
-
- "get compressed data"
- index := 1.
- count := aStream nextByte.
- [count notNil and:[count ~~ 0]] whileTrue:[
- aStream nextBytes:count into:compressedData startingAt:index blockSize:4096.
- index := index + count.
- count := aStream nextByte
- ].
- compressedSize := index - 1.
-
- h := height.
- data := ByteArray new:((width + 1) * (h + 1)).
-"/ 'GIFReader: decompressing ...' infoPrintCR.
-
- self class decompressGIFFrom:compressedData
- count:compressedSize
- into:data
- startingAt:1
- codeLen:(codeLen + 1).
-
- interlaced ifTrue:[
-"/ 'GIFREADER: deinterlacing ...' infoPrintCR.
- tmp := ByteArray new:(data size).
-
- "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.
- ].
-
- "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.
- ].
-
- "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.
- ].
-
- "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.
- ].
-
- data := tmp.
- tmp := nil
+ self readColorMap:colorMapSize.
+ colorMap := Colormap
+ redVector:redMap
+ greenVector:greenMap
+ blueVector:blueMap.
].
photometric := #palette.
samplesPerPixel := 1.
bitsPerSample := #(8).
- "check if only grey values are used,
- could make it a greyscale image if so (currently not done)"
+ atEnd := false.
+ [atEnd] whileFalse:[
+ "gif89a extensions"
+ byte := aStream nextByte.
+
+ [byte == 16r21] whileTrue:[
+ "/ extension
+ self readExtension:aStream.
+ byte := aStream nextByte.
+ ].
+
+ (byte == 16r3B) ifTrue:[ "trailer"
+ atEnd := true
+ ] ifFalse:[
+ "must be image separator"
+ (byte ~~ 16r2C) ifTrue:[
+ ('GIFReader [info]: corrupted gif file (no IMAGESEP): ' , (byte printStringRadix:16)) infoPrintCR.
+ ^ nil
+ ].
+
+ "get image data"
+ leftOffs := aStream nextShortMSB:false.
+ topOffs := aStream nextShortMSB:false.
+ width := aStream nextShortMSB:false.
+ height := aStream nextShortMSB:false.
+
+ dimensionCallBack notNil ifTrue:[
+ dimensionCallBack value:self
+ ].
+
+"/
+"/ 'width ' print. width printNewline.
+"/ 'height ' print. height printNewline.
+"/
-"/ self checkGreyscaleColormap ifTrue:[
-"/ self makeGreyscale
-"/ ].
+ "another flag byte"
+ flag := aStream nextByte.
+ interlaced := (flag bitAnd:2r01000000) ~~ 0.
+ hasLocalColorMap := (flag bitAnd:2r10000000) ~~ 0.
+ "localColorMapSorted := (flag bitAnd:2r00100000) ~~ 0. "
+
+ "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"
+ self readColorMap:colorMapSize.
+ colorMap := Colormap
+ redVector:redMap
+ greenVector:greenMap
+ blueVector:blueMap.
+ ].
+
+
+ "get codelen for decompression"
+ codeLen := aStream nextByte.
+
+ compressedData := ByteArray uninitializedNew:(aStream size).
+
+ "get compressed data"
+ index := 1.
+ count := aStream nextByte.
+ [count notNil and:[count ~~ 0]] whileTrue:[
+ aStream nextBytes:count into:compressedData startingAt:index blockSize:4096.
+ index := index + count.
+ count := aStream nextByte
+ ].
+ compressedSize := index - 1.
- colorMap := Colormap
- redVector:redMap
- greenVector:greenMap
- blueVector:blueMap.
+ h := height.
+ data := ByteArray new:((width + 1) * (h + 1)).
+"/ 'GIFReader: decompressing ...' infoPrintCR.
+
+ self class decompressGIFFrom:compressedData
+ count:compressedSize
+ into:data
+ startingAt:1
+ codeLen:(codeLen + 1).
+
+ interlaced ifTrue:[
+"/ 'GIFREADER: deinterlacing ...' infoPrintCR.
+ tmp := ByteArray new:(data size).
+
+ "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.
+ ].
+
+ "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.
+ ].
+
+ "phase 3: 2, 6, 10, 14, ..."
- maskPixelValue notNil ifTrue:[
- "/
- "/ ok, there is a maskValue
- "/ build a Depth1Image for it.
- "/
- self buildMaskFromColor:maskPixelValue
+ 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, ..."
+
+ 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.
+
+ imageSequence isNil ifTrue:[
+ imageSequence := OrderedCollection new.
+ ].
+ maskPixelValue notNil ifTrue:[
+ "/
+ "/ ok, there is a maskValue
+ "/ build a Depth1Image for it.
+ "/
+ self buildMaskFromColor:maskPixelValue
+ ].
+
+ imageSequence add:(self image).
+
+ aStream atEnd ifTrue:[
+ atEnd := true.
+ ]
+ ]
+ ].
].
"
GIFReader fromFile:'../fileIn/bitmaps/claus.gif
GIFReader fromFile:'../fileIn/bitmaps/garfield.gif'
+ GIFReader new fromStream:('/home2/cg/.misc/circum.gif' asFilename readStream)
"
"Modified: 5.7.1996 / 17:32:01 / stefan"
- "Modified: 24.4.1997 / 21:13:06 / cg"
+ "Modified: 21.6.1997 / 18:36:49 / cg"
!
makeGreyscale
@@ -362,7 +404,9 @@
|type blockSize subBlockSize
aspNum aspDen left top width height cWidth cHeight fg bg
- animationType animationTime animationMask|
+ animationType animationTime animationMask
+ appID appAUTH
+ iterationCount b|
type := aStream nextByte.
type == $R asciiValue ifTrue:[
@@ -420,10 +464,11 @@
animationTime := aStream nextShortMSB:false.
animationMask := aStream nextByte.
- animationType == 1 ifTrue:[
+ (animationType bitTest: 1) ifTrue:[
maskPixelValue := animationMask.
"/ 'GIFREADER [info]: mask: ' infoPrint. (maskPixelValue printStringRadix:16) infoPrintCR.
].
+ 'GIFREADER [info]: animationTime: ' infoPrint. (animationTime * (1/100)) infoPrintCR.
[(subBlockSize := aStream nextByte) > 0] whileTrue:[
aStream skip:subBlockSize
@@ -446,7 +491,35 @@
"/
"/ application extension
"/
- 'GIFREADER [info]: application extension ignored' infoPrintCR.
+ subBlockSize := aStream nextByte.
+ appID := (aStream nextBytes:8 ) asString.
+ appAUTH := aStream nextBytes:3.
+
+ subBlockSize := aStream nextByte.
+
+ appID = 'NETSCAPE' ifTrue:[
+ appAUTH asString = '2.0' ifTrue:[
+ subBlockSize == 3 ifTrue:[
+ b := aStream nextByte.
+ iterationCount := aStream nextShortMSB:false.
+ subBlockSize := aStream nextByte.
+ ]
+ ]
+ ].
+
+ ('GIFREADER [info]: application extension (' , appID , ') ignored') infoPrintCR.
+ [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
].
@@ -461,12 +534,12 @@
aStream skip:subBlockSize
]
- "Modified: 11.4.1997 / 00:55:15 / cg"
+ "Modified: 21.6.1997 / 11:59:05 / cg"
! !
!GIFReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.48 1997-04-24 19:20:58 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.49 1997-06-24 13:30:20 cg Exp $'
! !
GIFReader initialize!