--- a/GIFReader.st Mon Jan 15 18:37:08 1996 +0100
+++ b/GIFReader.st Thu Jan 18 22:14:07 1996 +0100
@@ -11,10 +11,10 @@
"
ImageReader subclass:#GIFReader
- instanceVariableNames:'redMap greenMap blueMap'
- classVariableNames:''
- poolDictionaries:''
- category:'Graphics-Images support'
+ instanceVariableNames:'redMap greenMap blueMap'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Graphics-Images support'
!
!GIFReader class methodsFor:'documentation'!
@@ -111,7 +111,7 @@
hasColorMap hasLocalColorMap interlaced id
leftOffs topOffs codeLen
compressedData compressedSize
- tmp srcOffset dstOffset
+ tmp srcOffset dstOffset isGif89
h "{ Class: SmallInteger }"|
inStream := aStream.
@@ -126,12 +126,15 @@
"all I had for testing where GIF87a files;
I hope later versions work too ..."
+ isGif89 := false.
(id ~= 'GIF87a') ifTrue:[
- (id startsWith:'GIF') ifFalse:[
- 'GIFReader: not a gif file' errorPrintNL.
- ^ nil
- ].
- 'GIFReader: not a GIF87a file - hope that works' errorPrintNL.
+ (id startsWith:'GIF') ifFalse:[
+ 'GIFReader: not a gif file' errorPrintNL.
+ ^ nil
+ ].
+ id ~= 'GIF89a' ifTrue:[
+ 'GIFReader: not a GIF87a/GIF89a file - hope that works' errorPrintNL.
+ ]
].
"get screen dimensions (not used)"
@@ -155,14 +158,21 @@
"get colorMap"
hasColorMap ifTrue:[
- self readColorMap:colorMapSize
+ self readColorMap:colorMapSize
].
- "image separator"
+ "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: corrupted gif file (no imgSep)' errorPrintNL.
- ^ nil
+ ('GIFReader: corrupted gif file (no IMAGESEP): ' , (byte printStringRadix:16)) errorPrintNL.
+ ^ nil
].
"get image data"
@@ -185,12 +195,12 @@
"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 descr. overwrites"
+ bitsPerPixel := (flag bitAnd:2r00000111) + 1.
+ colorMapSize := 1 bitShift:bitsPerPixel.
" 'local colormap' printNewline. "
- "overwrite colormap"
- self readColorMap:colorMapSize
+ "overwrite colormap"
+ self readColorMap:colorMapSize
].
"get codelen for decompression"
@@ -202,9 +212,9 @@
index := 1.
count := aStream nextByte.
[count notNil and:[count ~~ 0]] whileTrue:[
- aStream nextBytes:count into:compressedData startingAt:index.
- index := index + count.
- count := aStream nextByte
+ aStream nextBytes:count into:compressedData startingAt:index.
+ index := index + count.
+ count := aStream nextByte
].
compressedSize := index - 1.
@@ -213,54 +223,54 @@
"/ 'GIFReader: decompressing ...' infoPrintNL.
self class decompressGIFFrom:compressedData
- count:compressedSize
- into:data
- startingAt:1
- codeLen:(codeLen + 1).
+ count:compressedSize
+ into:data
+ startingAt:1
+ codeLen:(codeLen + 1).
interlaced ifTrue:[
- Transcript showCr:'deinterlacing'.
- tmp := ByteArray new:(data size).
+ Transcript showCr:'deinterlacing'.
+ 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
].
photometric := #palette.
@@ -280,6 +290,8 @@
GIFReader fromFile:'../fileIn/bitmaps/claus.gif
GIFReader fromFile:'../fileIn/bitmaps/garfield.gif'
"
+
+ "Modified: 18.1.1996 / 22:13:38 / cg"
!
makeGreyscale
@@ -303,11 +315,87 @@
greenMap at:i put:(inStream nextByte).
blueMap at:i put:(inStream nextByte)
]
+!
+
+readExtension:aStream
+ "get gif89 extension"
+
+ |type blockSize subBlockSize
+ aspNum aspDen left top width height cWidth cHeight fg bg|
+
+ type := aStream nextByte.
+ type == $R asciiValue ifTrue:[
+ "/ Ratio extension
+ 'GIFREADER: ratio extension ignored' infoPrintNL.
+ 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
+ ]
+ ] ifFalse:[
+ type == 16rFE ifTrue:[
+ "/ comment extension
+ 'GIFREADER: comment extension ignored' infoPrintNL.
+ [(blockSize := aStream nextByte) ~~ 0] whileTrue:[
+ aStream skip:blockSize
+ ].
+ ] ifFalse:[
+ type == 16r01 ifTrue:[
+ "/ plaintext extension
+ 'GIFREADER: plaintext extension ignored' infoPrintNL.
+ 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.
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ]
+ ] ifFalse:[
+ type == 16rF9 ifTrue:[
+ "/ graphic control extension
+ 'GIFREADER: plaintext extension ignored' infoPrintNL.
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ]
+ ] ifFalse:[
+ type == 16rFF ifTrue:[
+ "/ application extension
+ 'GIFREADER: application extension ignored' infoPrintNL.
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ]
+ ] ifFalse:[
+ "/ unknown extension
+ 'GIFREADER: unknown extension ignored' infoPrintNL.
+ [(subBlockSize := aStream nextByte) > 0] whileTrue:[
+ aStream skip:subBlockSize
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+
+ "Created: 18.1.1996 / 22:00:51 / cg"
+ "Modified: 18.1.1996 / 22:12:07 / cg"
! !
!GIFReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.21 1995-12-07 16:48:43 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.22 1996-01-18 21:14:07 cg Exp $'
! !
GIFReader initialize!