diff -r 37dc71e1e59b -r da5ad69ff368 GIFReader.st --- a/GIFReader.st Wed Feb 11 17:16:43 2009 +0100 +++ b/GIFReader.st Wed Feb 11 17:19:55 2009 +0100 @@ -124,6 +124,171 @@ !GIFReader methodsFor:'AEG-Changes'! +fromStream:aStream + "read a stream containing a GIF image (or an image sequence). + Leave image description in instance variables." + + |byte index flag count fileColorMap + colorMapSize bitsPerPixel scrWidth scrHeight + hasColorMap hasLocalColorMap interlaced id + codeLen + compressedData compressedSize + tmp srcOffset dstOffset isGif89 atEnd + h "{ Class: SmallInteger }" + img firstImage firstOffset firstFrameDelay frame imageCount| + + inStream := aStream. + aStream binary. + + "GIF-files are always lsb (intel-world)" + byteOrder := #lsb. + + id := ByteArray new:6. + (aStream nextBytes:6 into:id startingAt:1) ~~ 6 ifTrue:[ + ^ self fileFormatError:'not a gif file (short read)'. + ]. + id := id asString. + + "all I had for testing where GIF87a files; + I hope later versions work too ..." + + 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. + ] + ]. + + "get screen dimensions (not used)" + scrWidth := aStream nextShortMSB:false. + scrHeight := aStream nextShortMSB:false. + + "get flag byte" + flag := aStream nextByte. + hasColorMap := (flag bitAnd:2r10000000) ~~ 0. + "bitsPerRGB := ((flag bitAnd:2r01110000) bitShift:-4) + 1. " + "colorMapSorted := ((flag bitAnd:2r00001000) ~~ 0. " + bitsPerPixel := (flag bitAnd:2r00000111) + 1. + colorMapSize := 1 bitShift:bitsPerPixel. + + "get background (not used)" + aStream nextByte. + + "aspect ratio (not used)" + aStream nextByte. + + "get colorMap" + hasColorMap ifTrue:[ + fileColorMap := self readColorMap:colorMapSize. + ]. + colorMap := fileColorMap. + + photometric := #palette. + samplesPerPixel := 1. + bitsPerSample := #(8). + + imageCount := 0. + atEnd := false. + [atEnd] whileFalse:[ + "gif89a extensions" + + 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)). + ]. +"/ 'Img' infoPrintCR. + + 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 + ]. + + 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 this image. + frame := ImageFrame new image:img. + frame delay:frameDelay. + frame offset:(leftOffs @ topOffs). + imageSequence add:frame. + ]. + + imageCount := imageCount + 1. + + frameDelay := nil. + + aStream atEnd ifTrue:[ + atEnd := true. + ] + ] + ]. + ]. + ]. + + imageSequence notNil ifTrue:[ + iterationCount notNil ifTrue:[ + iterationCount == 0 ifTrue:[ + imageSequence loop:true. + ] ifFalse:[ + imageSequence loop:false. + imageSequence iterationCount:iterationCount. + ] + ] + ]. + + " + Image fromFile:'/home/cg/work/stx/goodies/bitmaps/gifImages/animated/vrml.gif' + Image fromFile:'/home/cg/work/stx/goodies/bitmaps/gifImages/animated/arrow.gif' + " + + "Modified: / 5.7.1996 / 17:32:01 / stefan" + "Modified: / 21.8.1998 / 22:20:00 / cg" +! + readExtension:aStream "get gif89 extension" @@ -732,168 +897,6 @@ outStream nextPut:0. ! ! -!GIFReader methodsFor:'reading'! - -fromStream:aStream - "read a stream containing a GIF image (or an image sequence). - Leave image description in instance variables." - - |byte index flag count fileColorMap - colorMapSize bitsPerPixel scrWidth scrHeight - hasColorMap hasLocalColorMap interlaced id - codeLen - compressedData compressedSize - tmp srcOffset dstOffset isGif89 atEnd - h "{ Class: SmallInteger }" - img firstImage firstOffset firstFrameDelay frame imageCount| - - inStream := aStream. - aStream binary. - - "GIF-files are always lsb (intel-world)" - byteOrder := #lsb. - - id := ByteArray new:6. - (aStream nextBytes:6 into:id startingAt:1) ~~ 6 ifTrue:[ - ^ self fileFormatError:'not a gif file (short read)'. - ]. - id := id asString. - - "all I had for testing where GIF87a files; - I hope later versions work too ..." - - 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. - ] - ]. - - "get screen dimensions (not used)" - scrWidth := aStream nextShortMSB:false. - scrHeight := aStream nextShortMSB:false. - - "get flag byte" - flag := aStream nextByte. - hasColorMap := (flag bitAnd:2r10000000) ~~ 0. - "bitsPerRGB := ((flag bitAnd:2r01110000) bitShift:-4) + 1. " - "colorMapSorted := ((flag bitAnd:2r00001000) ~~ 0. " - bitsPerPixel := (flag bitAnd:2r00000111) + 1. - colorMapSize := 1 bitShift:bitsPerPixel. - - "get background (not used)" - aStream nextByte. - - "aspect ratio (not used)" - aStream nextByte. - - "get colorMap" - hasColorMap ifTrue:[ - fileColorMap := self readColorMap:colorMapSize. - ]. - colorMap := fileColorMap. - - photometric := #palette. - samplesPerPixel := 1. - bitsPerSample := #(8). - - imageCount := 0. - atEnd := false. - [atEnd] whileFalse:[ - "gif89a extensions" - - byte := aStream nextByte. - 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)). - ]. -"/ 'Img' infoPrintCR. - - 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 - ]. - - 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 this image. - frame := ImageFrame new image:img. - frame delay:frameDelay. - frame offset:(leftOffs @ topOffs). - imageSequence add:frame. - ]. - - imageCount := imageCount + 1. - - frameDelay := nil. - - aStream atEnd ifTrue:[ - atEnd := true. - ] - ] - ]. - ]. - - imageSequence notNil ifTrue:[ - iterationCount notNil ifTrue:[ - iterationCount == 0 ifTrue:[ - imageSequence loop:true. - ] ifFalse:[ - imageSequence loop:false. - imageSequence iterationCount:iterationCount. - ] - ] - ]. - - " - Image fromFile:'/home/cg/work/stx/goodies/bitmaps/gifImages/animated/vrml.gif' - Image fromFile:'/home/cg/work/stx/goodies/bitmaps/gifImages/animated/arrow.gif' - " - - "Modified: / 5.7.1996 / 17:32:01 / stefan" - "Modified: / 21.8.1998 / 22:20:00 / cg" -! ! - !GIFReader methodsFor:'writing to file'! save:image onFile:aFileName @@ -983,7 +986,7 @@ !GIFReader class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.94 2009-02-11 16:16:43 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.95 2009-02-11 16:19:55 cg Exp $' ! ! GIFReader initialize!