diff -r 813553f7bd20 -r c644d7932605 GIFReader.st --- a/GIFReader.st Wed Oct 15 13:25:17 1997 +0200 +++ b/GIFReader.st Wed Oct 15 17:06:20 1997 +0200 @@ -10,8 +10,6 @@ hereby transferred. " -'From Smalltalk/X, Version:3.2.1 on 14-oct-1997 at 11:13:24 pm' ! - ImageReader subclass:#GIFReader instanceVariableNames:'redMap greenMap blueMap pass xpos ypos rowByteSize remainBitCount bufByte bufStream prefixTable suffixTable clearCode eoiCode @@ -148,45 +146,45 @@ "Created: 14.10.1997 / 18:57:33 / cg" ! -nextBitsPut: t1 - | t2 t3 t4 | - t4 := 0. - remainBitCount = 0 - ifTrue: - [t3 := 8. - t2 := t1] - ifFalse: - [t3 := remainBitCount. - t2 := bufByte + (t1 bitShift: 8 - remainBitCount)]. - [t3 < codeSize] - whileTrue: - [self nextBytePut: ((t2 bitShift: t4) bitAnd: 255). - t4 := t4 - 8. - t3 := t3 + 8]. - (remainBitCount := t3 - codeSize) = 0 - ifTrue: [self nextBytePut: (t2 bitShift: t4)] - ifFalse: [bufByte := t2 bitShift: t4]. - ^ t1 +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 - "Modified: 14.10.1997 / 19:20:24 / cg" + "Modified: 15.10.1997 / 16:50:30 / cg" ! -nextBytePut: t1 - bufStream nextPut: t1. - bufStream size >= 254 ifTrue: [self flushBuffer] +nextBytePut: aByte + bufStream nextPut: aByte. + bufStream size >= 254 ifTrue: [self flushBuffer] - "Created: 14.10.1997 / 18:40:01 / cg" - "Modified: 14.10.1997 / 18:40:36 / cg" + "Modified: 15.10.1997 / 16:50:52 / cg" ! -readPixelFrom: t1 - | t2 | +readPixelFrom: bits + | pixel | ypos >= height ifTrue: [^ nil]. - t2 := t1 at: ypos * rowByteSize + xpos + 1. + pixel := bits at: ypos * rowByteSize + xpos + 1. self updatePixelPosition. - ^ t2 + ^ pixel "Created: 14.10.1997 / 18:43:50 / cg" + "Modified: 15.10.1997 / 16:46:43 / cg" ! setParameters:bitsPerPixel @@ -236,11 +234,11 @@ "Modified: 14.10.1997 / 18:44:27 / cg" ! -writeCode: t1 - self nextBitsPut: t1 +writeCode: aCode + self nextBitsPut: aCode "Created: 14.10.1997 / 18:38:35 / cg" - "Modified: 14.10.1997 / 18:40:50 / cg" + "Modified: 15.10.1997 / 17:01:47 / cg" ! writeCodeAndCheckCodeSize: t1 @@ -707,82 +705,86 @@ "Modified: 14.10.1997 / 18:59:22 / cg" ! -writeBitDataFor:image - | t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 | +writeBitDataFor: image + "using modified Lempel-Ziv Welch algorithm." + + | bits bitsPerPixel + maxBits maxMaxCode tSize initCodeSize ent tShift fCode pixel index disp nomatch | + + bitsPerPixel := image bitsPerPixel. + bits := image bits. + + pass := 0. + xpos := 0. + ypos := 0. + rowByteSize := width * 8 + 31 // 32 * 4. + remainBitCount := 0. + bufByte := 0. + bufStream := WriteStream on: (ByteArray new: 256). - t1 := image bits. - pass := 0. - xpos := 0. - ypos := 0. - rowByteSize := width * 8 + 31 // 32 * 4. - remainBitCount := 0. - bufByte := 0. - bufStream := WriteStream on: (ByteArray new: 256). - t2 := 12. - t3 := 1 bitShift: t2. - t4 := 5003. - prefixTable := Array new: t4. - suffixTable := Array new: t4. - t5 := image bitsPerPixel <= 1 - ifTrue: [2] - ifFalse: [image bitsPerPixel]. - outStream nextPut: t5. "/ codeLen - self setParameters: t5. - t7 := 0. - t8 := t4. - [t8 < 65536] whileTrue:[ - t7 := t7 + 1. - t8 := t8 * 2 - ]. - t7 := 8 - t7. - 1 to: t4 do: [:t13 | suffixTable at: t13 put: -1]. + maxBits := 12. + maxMaxCode := 1 bitShift: maxBits. + tSize := 5003. + prefixTable := Array new: tSize. + suffixTable := Array new: tSize. + + initCodeSize := bitsPerPixel <= 1 ifTrue: [2] ifFalse: [bitsPerPixel]. + outStream nextPut: initCodeSize. + self setParameters: initCodeSize. + + tShift := 0. + fCode := tSize. + [fCode < 65536] whileTrue: + [tShift := tShift + 1. + fCode := fCode * 2]. + tShift := 8 - tShift. + 1 to: tSize do: [:i | suffixTable at: i put: -1]. - self writeCodeAndCheckCodeSize: clearCode. - t6 := self readPixelFrom: t1. - [(t9 := self readPixelFrom: t1) == nil] whileFalse:[ - t8 := (t9 bitShift: t2) + t6. - t10 := ((t9 bitShift: t7) bitXor: t6) + 1. - (suffixTable at: t10) = t8 ifTrue: [ - t6 := prefixTable at: t10 - ] ifFalse:[ - t12 := true. - (suffixTable at: t10) >= 0 ifTrue:[ - t11 := t4 - t10 + 1. - t10 = 1 ifTrue: [t11 := 1]. - + self writeCodeAndCheckCodeSize: clearCode. + ent := self readPixelFrom: bits. + [(pixel := self readPixelFrom: bits) == nil] whileFalse: [ - (t10 := t10 - t11) < 1 ifTrue: [t10 := t10 + t4]. - (suffixTable at: t10) = t8 ifTrue:[ - t6 := prefixTable at: t10. - t12 := false - ]. - t12 and: [(suffixTable at: t10) > 0] - ] whileTrue - ]. - t12 ifTrue:[ - self writeCodeAndCheckCodeSize: t6. - t6 := t9. - freeCode < t3 ifTrue:[ - prefixTable at: t10 put: freeCode. - suffixTable at: t10 put: t8. - freeCode := freeCode + 1 - ] ifFalse:[ - self writeCodeAndCheckCodeSize: clearCode. - 1 to: t4 do: [:t13 | suffixTable at: t13 put: -1]. - self setParameters: t5 - ] - ] - ] - ]. - prefixTable := suffixTable := nil. - self writeCodeAndCheckCodeSize: t6. - self writeCodeAndCheckCodeSize: eoiCode. - self flushCode. - outStream nextPut: 0. - outStream nextPut: Terminator + 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. + 1 to: tSize do: [:i | suffixTable at: i put: -1]. + self setParameters: initCodeSize]]]]. + prefixTable := suffixTable := nil. + self writeCodeAndCheckCodeSize: ent. + self writeCodeAndCheckCodeSize: eoiCode. + self flushCode. - "Created: 14.10.1997 / 18:33:54 / cg" - "Modified: 14.10.1997 / 20:31:11 / cg" + outStream nextPut: 0. "zero-length packet" + outStream nextPut: Terminator. + + "Modified: 15.10.1997 / 16:49:20 / cg" ! writeHeaderFor:image @@ -835,6 +837,6 @@ !GIFReader class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.57 1997-10-15 11:24:53 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.58 1997-10-15 15:06:20 cg Exp $' ! ! GIFReader initialize!