'From Squeak 1.21 of July 17, 1997 on 21 October 1997 at 9:33:29 pm'! !ColorForm class methodsFor: 'all' stamp: 'hmm 10/19/97 21:19'! fromForm: aForm "ColorForm fromForm: Form fromUser" | used map usedColors new colors depth | used _ aForm tallyPixelValues. colors _ aForm colors. usedColors _ OrderedCollection new. map _ Bitmap new: colors size. 1 to: used size do: [:i | (used at: i) > 0 ifTrue: [ map at: i put: usedColors size. usedColors add: (colors at: i). ] ]. depth _ usedColors size > 16 ifTrue: [8] ifFalse: [usedColors size > 4 ifTrue: [4] ifFalse: [usedColors size > 2 ifTrue: [2] ifFalse: [1]]]. new _ (self extent: aForm extent depth: depth) colors: usedColors. new copyBits: new boundingBox from: aForm at: 0@0 colorMap: map. ^new! ! !Form methodsFor: 'accessing' stamp: 'hmm 10/19/97 21:02'! colors depth <= 8 ifTrue: [^(0 to: (1 bitShift: depth)-1) collect: [:i | Color colorFromPixelValue: i depth: depth]]. self error: 'I don''t compute colormaps for RGB images'! ! !ImageReadWriter methodsFor: 'stream access' stamp: 'hmm 10/2/97 22:42'! close "close if you can" (stream respondsTo: #close) ifTrue: [ stream closed ifFalse: [stream close]]! ! !ImageReadWriter methodsFor: 'private' stamp: 'hmm 10/2/97 22:42'! on: aStream "Read it all into memory and use that as a stream to read from. TK 29 May 96" (aStream respondsTo: #binary) ifTrue: [aStream binary]. "stream _ ReadWriteStream with: (aStream contentsOfEntireFile). stream reset." stream _ aStream! ! !GIFReadWriter methodsFor: 'accessing' stamp: 'hmm 10/21/97 21:17'! nextPutImage: anImage | bits | anImage depth > 8 ifTrue: [ self error: 'GIF does not support Forms deeper than 8-bits']. width _ anImage width. height _ anImage height. bitsPerPixel _ anImage depth. colorPalette _ anImage colors. bits _ anImage bits. bitsPerPixel < 8 ifTrue: [bits _ (self unpackImage: anImage) bits]. interlace _ false. self writeHeader. self writeBitData: bits. self close. ^ anImage ! ! !GIFReadWriter methodsFor: 'private-encoding' stamp: 'hmm 10/18/97 15:27'! readPixelFrom: bits | pixel word | ypos >= height ifTrue: [^nil]. word _ bits at: (ypos * (rowByteSize//4) + (xpos//4) + 1). pixel _ (word bitShift: (xpos bitAnd: 3) * 8 - 24) bitAnd: 255. self updatePixelPosition. ^pixel! ! !GIFReadWriter methodsFor: 'private-encoding' stamp: 'hmm 10/21/97 21:21'! writeHeader | byte c | stream setType: 'GIFf' creator: 'c2gf'. self nextPutAll: 'GIF87a' asByteArray. self writeWord: width. "Screen Width" self writeWord: height. "Screen Height" byte _ 16r80. "has color map" byte _ byte bitOr: ((bitsPerPixel - 1) bitShift: 5). "color resolution" byte _ byte bitOr: bitsPerPixel - 1. "bits per pixel" self nextPut: byte. self nextPut: 0. "background color." self nextPut: 0. "null (future expansion)" 0 to: colorPalette size-1 do: [:i | c _ colorPalette at: i+1. c isTransparent ifTrue: [c _ Color white]. self nextPut: ((c red * 255.0) asInteger bitAnd: 255); nextPut: ((c green * 255.0) asInteger bitAnd: 255); nextPut: ((c blue * 255.0) asInteger bitAnd: 255)]. self nextPut: ImageSeparator. self writeWord: 0. "Image Left" self writeWord: 0. "Image Top" self writeWord: width. "Image Width" self writeWord: height. "Image Height" byte _ interlace ifTrue: [16r40] ifFalse: [0]. self nextPut: byte! ! !GIFReadWriter methodsFor: 'private' stamp: 'hmm 10/21/97 21:20'! unpackImage: anImage | map resultImage | map _ Bitmap new: 16. 0 to: 15 do: [:i | map at: i+1 put: i]. resultImage _ Form extent: anImage extent depth: 8. resultImage copyBits: anImage boundingBox from: anImage at: 0@0 clippingBox: anImage boundingBox rule: Form paint fillColor: nil map: map. ^anImage! !