GIFReader.st
changeset 710 c644d7932605
parent 708 47d402971287
child 712 6403dd3407eb
equal deleted inserted replaced
709:813553f7bd20 710:c644d7932605
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 'From Smalltalk/X, Version:3.2.1 on 14-oct-1997 at 11:13:24 pm'                 !
       
    14 
       
    15 ImageReader subclass:#GIFReader
    13 ImageReader subclass:#GIFReader
    16 	instanceVariableNames:'redMap greenMap blueMap pass xpos ypos rowByteSize remainBitCount
    14 	instanceVariableNames:'redMap greenMap blueMap pass xpos ypos rowByteSize remainBitCount
    17 		bufByte bufStream prefixTable suffixTable clearCode eoiCode
    15 		bufByte bufStream prefixTable suffixTable clearCode eoiCode
    18 		freeCode codeSize maxCode interlace'
    16 		freeCode codeSize maxCode interlace'
    19 	classVariableNames:'ImageSeparator Extension Terminator'
    17 	classVariableNames:'ImageSeparator Extension Terminator'
   146         self flushBits
   144         self flushBits
   147 
   145 
   148     "Created: 14.10.1997 / 18:57:33 / cg"
   146     "Created: 14.10.1997 / 18:57:33 / cg"
   149 !
   147 !
   150 
   148 
   151 nextBitsPut: t1 
   149 nextBitsPut: anInteger
   152     | t2 t3 t4 |
   150         | integer writeBitCount shiftCount |
   153     t4 := 0.
   151         shiftCount _ 0.
   154     remainBitCount = 0
   152         remainBitCount = 0
   155             ifTrue: 
   153                 ifTrue:
   156                     [t3 := 8.
   154                         [writeBitCount _ 8.
   157                     t2 := t1]
   155                         integer _ anInteger]
   158             ifFalse: 
   156                 ifFalse:
   159                     [t3 := remainBitCount.
   157                         [writeBitCount _ remainBitCount.
   160                     t2 := bufByte + (t1 bitShift: 8 - remainBitCount)].
   158                         integer _ bufByte + (anInteger bitShift: 8 - remainBitCount)].
   161     [t3 < codeSize]
   159         [writeBitCount < codeSize]
   162             whileTrue: 
   160                 whileTrue:
   163                     [self nextBytePut: ((t2 bitShift: t4) bitAnd: 255).
   161                         [self nextBytePut: ((integer bitShift: shiftCount) bitAnd: 255).
   164                     t4 := t4 - 8.
   162                         shiftCount _ shiftCount - 8.
   165                     t3 := t3 + 8].
   163                         writeBitCount _ writeBitCount + 8].
   166     (remainBitCount := t3 - codeSize) = 0
   164         (remainBitCount _ writeBitCount - codeSize) = 0
   167             ifTrue: [self nextBytePut: (t2 bitShift: t4)]
   165                 ifTrue: [self nextBytePut: (integer bitShift: shiftCount)]
   168             ifFalse: [bufByte := t2 bitShift: t4].
   166                 ifFalse: [bufByte _ integer bitShift: shiftCount].
   169     ^ t1
   167         ^anInteger
   170 
   168 
   171     "Modified: 14.10.1997 / 19:20:24 / cg"
   169     "Modified: 15.10.1997 / 16:50:30 / cg"
   172 !
   170 !
   173 
   171 
   174 nextBytePut: t1 
   172 nextBytePut: aByte
   175     bufStream nextPut: t1.
   173         bufStream nextPut: aByte.
   176     bufStream size >= 254 ifTrue: [self flushBuffer]
   174         bufStream size >= 254 ifTrue: [self flushBuffer]
   177 
   175 
   178     "Created: 14.10.1997 / 18:40:01 / cg"
   176     "Modified: 15.10.1997 / 16:50:52 / cg"
   179     "Modified: 14.10.1997 / 18:40:36 / cg"
   177 !
   180 !
   178 
   181 
   179 readPixelFrom: bits 
   182 readPixelFrom: t1 
   180     | pixel |
   183     | t2 |
       
   184     ypos >= height ifTrue: [^ nil].
   181     ypos >= height ifTrue: [^ nil].
   185     t2 := t1 at: ypos * rowByteSize + xpos + 1.
   182     pixel := bits at: ypos * rowByteSize + xpos + 1.
   186     self updatePixelPosition.
   183     self updatePixelPosition.
   187     ^ t2
   184     ^ pixel
   188 
   185 
   189     "Created: 14.10.1997 / 18:43:50 / cg"
   186     "Created: 14.10.1997 / 18:43:50 / cg"
       
   187     "Modified: 15.10.1997 / 16:46:43 / cg"
   190 !
   188 !
   191 
   189 
   192 setParameters:bitsPerPixel 
   190 setParameters:bitsPerPixel 
   193     clearCode := 1 bitShift:bitsPerPixel.
   191     clearCode := 1 bitShift:bitsPerPixel.
   194     eoiCode := clearCode + 1.
   192     eoiCode := clearCode + 1.
   234         ^ self error: 'can''t happen'
   232         ^ self error: 'can''t happen'
   235 
   233 
   236     "Modified: 14.10.1997 / 18:44:27 / cg"
   234     "Modified: 14.10.1997 / 18:44:27 / cg"
   237 !
   235 !
   238 
   236 
   239 writeCode: t1 
   237 writeCode: aCode 
   240     self nextBitsPut: t1
   238     self nextBitsPut: aCode
   241 
   239 
   242     "Created: 14.10.1997 / 18:38:35 / cg"
   240     "Created: 14.10.1997 / 18:38:35 / cg"
   243     "Modified: 14.10.1997 / 18:40:50 / cg"
   241     "Modified: 15.10.1997 / 17:01:47 / cg"
   244 !
   242 !
   245 
   243 
   246 writeCodeAndCheckCodeSize: t1 
   244 writeCodeAndCheckCodeSize: t1 
   247     self writeCode: t1.
   245     self writeCode: t1.
   248     self checkCodeSize
   246     self checkCodeSize
   705 
   703 
   706     "Created: 14.10.1997 / 17:40:12 / cg"
   704     "Created: 14.10.1997 / 17:40:12 / cg"
   707     "Modified: 14.10.1997 / 18:59:22 / cg"
   705     "Modified: 14.10.1997 / 18:59:22 / cg"
   708 !
   706 !
   709 
   707 
   710 writeBitDataFor:image 
   708 writeBitDataFor: image
   711     | t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 |
   709         "using modified Lempel-Ziv Welch algorithm."
   712 
   710 
   713     t1 := image bits.
   711         | bits bitsPerPixel
   714     pass := 0.
   712           maxBits maxMaxCode tSize initCodeSize ent tShift fCode pixel index disp nomatch |
   715     xpos := 0.
   713 
   716     ypos := 0.
   714         bitsPerPixel := image bitsPerPixel.
   717     rowByteSize := width * 8 + 31 // 32 * 4.
   715         bits := image bits.
   718     remainBitCount := 0.
   716 
   719     bufByte := 0.
   717         pass := 0.
   720     bufStream := WriteStream on: (ByteArray new: 256).
   718         xpos := 0.
   721     t2 := 12.
   719         ypos := 0.
   722     t3 := 1 bitShift: t2.
   720         rowByteSize := width * 8 + 31 // 32 * 4.
   723     t4 := 5003.
   721         remainBitCount := 0.
   724     prefixTable := Array new: t4.
   722         bufByte := 0.
   725     suffixTable := Array new: t4.
   723         bufStream := WriteStream on: (ByteArray new: 256).
   726     t5 := image bitsPerPixel <= 1
   724 
   727                             ifTrue: [2]
   725         maxBits := 12.
   728                             ifFalse: [image bitsPerPixel].
   726         maxMaxCode := 1 bitShift: maxBits.
   729     outStream nextPut: t5.  "/ codeLen
   727         tSize := 5003.
   730     self setParameters: t5.
   728         prefixTable := Array new: tSize.
   731     t7 := 0.
   729         suffixTable := Array new: tSize.
   732     t8 := t4.
   730 
   733     [t8 < 65536] whileTrue:[ 
   731         initCodeSize := bitsPerPixel <= 1 ifTrue: [2] ifFalse: [bitsPerPixel].
   734         t7 := t7 + 1.
   732         outStream nextPut: initCodeSize.
   735         t8 := t8 * 2
   733         self setParameters: initCodeSize.
   736     ].
   734 
   737     t7 := 8 - t7.
   735         tShift := 0.
   738     1 to: t4 do: [:t13 | suffixTable at: t13 put: -1].
   736         fCode := tSize.
   739 
   737         [fCode < 65536] whileTrue:
   740     self writeCodeAndCheckCodeSize: clearCode.
   738                 [tShift := tShift + 1.
   741     t6 := self readPixelFrom: t1.
   739                 fCode := fCode * 2].
   742     [(t9 := self readPixelFrom: t1) == nil] whileFalse:[ 
   740         tShift := 8 - tShift.
   743         t8 := (t9 bitShift: t2) + t6.
   741         1 to: tSize do: [:i | suffixTable at: i put: -1].
   744         t10 := ((t9 bitShift: t7) bitXor: t6) + 1.
   742 
   745         (suffixTable at: t10) = t8 ifTrue: [
   743         self writeCodeAndCheckCodeSize: clearCode.
   746             t6 := prefixTable at: t10
   744         ent := self readPixelFrom: bits.
   747         ] ifFalse:[ 
   745         [(pixel := self readPixelFrom: bits) == nil] whileFalse:
   748             t12 := true.
       
   749             (suffixTable at: t10) >= 0 ifTrue:[ 
       
   750                 t11 := t4 - t10 + 1.
       
   751                 t10 = 1 ifTrue: [t11 := 1].
       
   752 
       
   753                 [
   746                 [
   754                     (t10 := t10 - t11) < 1 ifTrue: [t10 := t10 + t4].
   747                 fCode := (pixel bitShift: maxBits) + ent.
   755                     (suffixTable at: t10) = t8 ifTrue:[ 
   748                 index := ((pixel bitShift: tShift) bitXor: ent) + 1.
   756                         t6 := prefixTable at: t10.
   749                 (suffixTable at: index) = fCode
   757                         t12 := false
   750                         ifTrue: [ent := prefixTable at: index]
   758                     ].
   751                         ifFalse:
   759                     t12 and: [(suffixTable at: t10) > 0]
   752                                 [nomatch := true.
   760                 ] whileTrue
   753                                 (suffixTable at: index) >= 0
   761             ].
   754                                         ifTrue:
   762             t12 ifTrue:[
   755                                                 [disp := tSize - index + 1.
   763                 self writeCodeAndCheckCodeSize: t6.
   756                                                 index = 1 ifTrue: [disp := 1].
   764                 t6 := t9.
   757                                                 "probe"
   765                 freeCode < t3 ifTrue:[ 
   758                                                 [(index := index - disp) < 1 ifTrue: [index := index + tSize].
   766                     prefixTable at: t10 put: freeCode.
   759                                                 (suffixTable at: index) = fCode
   767                     suffixTable at: t10 put: t8.
   760                                                         ifTrue:
   768                     freeCode := freeCode + 1
   761                                                                 [ent := prefixTable at: index.
   769                 ] ifFalse:[ 
   762                                                                 nomatch := false.
   770                     self writeCodeAndCheckCodeSize: clearCode.
   763                                                                 "continue whileFalse:"].
   771                     1 to: t4 do: [:t13 | suffixTable at: t13 put: -1].
   764                                                 nomatch and: [(suffixTable at: index) > 0]]
   772                     self setParameters: t5
   765                                                         whileTrue: ["probe"]].
   773                 ]
   766                                 "nomatch"
   774             ]
   767                                 nomatch ifTrue:
   775         ]
   768                                         [self writeCodeAndCheckCodeSize: ent.
   776     ].
   769                                         ent := pixel.
   777     prefixTable := suffixTable := nil.
   770                                         freeCode < maxMaxCode
   778     self writeCodeAndCheckCodeSize: t6.
   771                                                 ifTrue:
   779     self writeCodeAndCheckCodeSize: eoiCode.
   772                                                         [prefixTable at: index put: freeCode.
   780     self flushCode.
   773                                                         suffixTable at: index put: fCode.
   781     outStream nextPut: 0.
   774                                                         freeCode := freeCode + 1]
   782     outStream nextPut: Terminator
   775                                                 ifFalse:
   783 
   776                                                         [self writeCodeAndCheckCodeSize: clearCode.
   784     "Created: 14.10.1997 / 18:33:54 / cg"
   777                                                         1 to: tSize do: [:i | suffixTable at: i put: -1].
   785     "Modified: 14.10.1997 / 20:31:11 / cg"
   778                                                         self setParameters: initCodeSize]]]].
       
   779         prefixTable := suffixTable := nil.
       
   780         self writeCodeAndCheckCodeSize: ent.
       
   781         self writeCodeAndCheckCodeSize: eoiCode.
       
   782         self flushCode.
       
   783 
       
   784         outStream nextPut: 0.        "zero-length packet"
       
   785         outStream nextPut: Terminator.
       
   786 
       
   787     "Modified: 15.10.1997 / 16:49:20 / cg"
   786 !
   788 !
   787 
   789 
   788 writeHeaderFor:image
   790 writeHeaderFor:image
   789     "save image as GIF file on aFileName"
   791     "save image as GIF file on aFileName"
   790 
   792 
   833 ! !
   835 ! !
   834 
   836 
   835 !GIFReader class methodsFor:'documentation'!
   837 !GIFReader class methodsFor:'documentation'!
   836 
   838 
   837 version
   839 version
   838     ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.57 1997-10-15 11:24:53 cg Exp $'
   840     ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.58 1997-10-15 15:06:20 cg Exp $'
   839 ! !
   841 ! !
   840 GIFReader initialize!
   842 GIFReader initialize!