GIFReader.st
changeset 714 c89f5c12538c
parent 713 548898fdd1dc
child 718 41ade132da98
equal deleted inserted replaced
713:548898fdd1dc 714:c89f5c12538c
     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 21-oct-1997 at 5:07:17 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'
   120 
   118 
   121     "Modified: 10.1.1997 / 15:40:34 / cg"
   119     "Modified: 10.1.1997 / 15:40:34 / cg"
   122 ! !
   120 ! !
   123 
   121 
   124 !GIFReader methodsFor:'private - writing'!
   122 !GIFReader methodsFor:'private - writing'!
       
   123 
       
   124 assignTransparentPixelIn:image
       
   125     "find an usused pixelValue in the colorMap (or image)."
       
   126 
       
   127     |cmap usedPixelValues|
       
   128 
       
   129     (cmap := image colorMap) size > 0 ifTrue:[
       
   130         cmap size < 256 ifTrue:[
       
   131             maskPixel := cmap size.
       
   132             ^ self
       
   133         ]
       
   134     ].
       
   135 
       
   136     usedPixelValues := image usedValues.
       
   137     usedPixelValues size < (1 bitShift:image depth) ifTrue:[
       
   138         "/ there must be an unused pixelValue
       
   139         maskPixel := ((0 to:(1 bitShift:image depth)-1) asSet removeAll:(usedPixelValues)) first.
       
   140     ] ifFalse:[
       
   141         Image informationLostQuerySignal
       
   142             raiseWith:image
       
   143             errorString:('GIF writer cannot assign a transparent pixel - all pixelValues used by image').
       
   144     ]
       
   145 !
   125 
   146 
   126 checkCodeSize
   147 checkCodeSize
   127     (freeCode > maxCode and: [codeSize < 12])
   148     (freeCode > maxCode and: [codeSize < 12])
   128             ifTrue: 
   149             ifTrue: 
   129                     [codeSize := codeSize + 1.
   150                     [codeSize := codeSize + 1.
   188 !
   209 !
   189 
   210 
   190 readPixelFrom: bits 
   211 readPixelFrom: bits 
   191     | pixel |
   212     | pixel |
   192     ypos >= height ifTrue: [^ nil].
   213     ypos >= height ifTrue: [^ nil].
   193     pixel := bits at: ypos * rowByteSize + xpos + 1.
   214     (maskPixel notNil 
       
   215     and:[(mask pixelAtX:xpos y:ypos) == 0]) ifTrue:[
       
   216         pixel := maskPixel
       
   217     ] ifFalse:[
       
   218         pixel := bits at: ypos * rowByteSize + xpos + 1.
       
   219     ].
   194     self updatePixelPosition.
   220     self updatePixelPosition.
   195     ^ pixel
   221     ^ pixel
   196 
   222 
   197     "Created: 14.10.1997 / 18:43:50 / cg"
   223     "Created: 14.10.1997 / 18:43:50 / cg"
   198     "Modified: 15.10.1997 / 16:46:43 / cg"
   224     "Modified: 15.10.1997 / 16:46:43 / cg"
   683             raiseWith:image
   709             raiseWith:image
   684             errorString:('file creation error: ' , aFileName asString).
   710             errorString:('file creation error: ' , aFileName asString).
   685     ].
   711     ].
   686     outStream binary.
   712     outStream binary.
   687 
   713 
   688     image mask notNil ifTrue:[
   714     mask := image mask.
   689         Image informationLostQuerySignal
   715     mask notNil ifTrue:[
   690             raiseWith:image
   716         self assignTransparentPixelIn:image
   691             errorString:('GFF writer does not (yet) support an imageMask').
       
   692     ].
   717     ].
   693 
   718 
   694     byteOrder := #lsb.
   719     byteOrder := #lsb.
   695     width := image width.
   720     width := image width.
   696     height := image height.
   721     height := image height.
   699     bitsPerSample := image bitsPerSample.
   724     bitsPerSample := image bitsPerSample.
   700     colorMap := image colorMap.
   725     colorMap := image colorMap.
   701     data := image bits.
   726     data := image bits.
   702 
   727 
   703     self writeHeaderFor:image.
   728     self writeHeaderFor:image.
       
   729     maskPixel notNil ifTrue:[
       
   730         self writeMaskExtensionHeaderFor:image.
       
   731     ].
       
   732 
   704     self writeBitDataFor:image.
   733     self writeBitDataFor:image.
       
   734 
       
   735     outStream nextPut: Terminator.
   705     outStream close.
   736     outStream close.
   706 
   737 
   707     "
   738     "
   708      |i|
   739      |i|
   709 
   740 
   717 !
   748 !
   718 
   749 
   719 writeBitDataFor: image
   750 writeBitDataFor: image
   720         "using modified Lempel-Ziv Welch algorithm."
   751         "using modified Lempel-Ziv Welch algorithm."
   721 
   752 
   722         | bits bitsPerPixel
   753         | bits bitsPerPixel t1
   723           maxBits maxMaxCode tSize initCodeSize ent tShift fCode pixel index disp nomatch |
   754           maxBits maxMaxCode tSize initCodeSize ent tShift fCode pixel index disp nomatch |
       
   755 
       
   756         outStream nextPut:ImageSeparator.
       
   757         self writeShort:0.       "/
       
   758         self writeShort:0.       "/
       
   759         self writeShort:width.   "/ image size
       
   760         self writeShort:height.
       
   761 
       
   762         interlace == true ifTrue:[
       
   763             t1 := 64
       
   764         ] ifFalse:[
       
   765             t1 := 0
       
   766         ].
       
   767         outStream nextPut:t1.       "/ another flag
   724 
   768 
   725         bitsPerPixel := image bitsPerPixel.
   769         bitsPerPixel := image bitsPerPixel.
   726         bits := image bits.
   770         bits := image bits.
   727 
   771 
   728         pass := 0.
   772         pass := 0.
   789                                                         self setParameters: initCodeSize]]]].
   833                                                         self setParameters: initCodeSize]]]].
   790         prefixTable := suffixTable := nil.
   834         prefixTable := suffixTable := nil.
   791         self writeCodeAndCheckCodeSize: ent.
   835         self writeCodeAndCheckCodeSize: ent.
   792         self writeCodeAndCheckCodeSize: eoiCode.
   836         self writeCodeAndCheckCodeSize: eoiCode.
   793         self flushCode.
   837         self flushCode.
   794 
       
   795         outStream nextPut: 0.        "zero-length packet"
   838         outStream nextPut: 0.        "zero-length packet"
   796         outStream nextPut: Terminator.
       
   797 
   839 
   798     "Modified: 15.10.1997 / 19:56:28 / cg"
   840     "Modified: 15.10.1997 / 19:56:28 / cg"
   799 !
   841 !
   800 
   842 
   801 writeHeaderFor:image
   843 writeHeaderFor:image
   802     "save image as GIF file on aFileName"
   844     "write the gif header"
   803 
   845 
   804     |bitsPerPixel t1 n|
   846     |bitsPerPixel t1 n|
   805 
   847 
   806     bitsPerPixel := image bitsPerPixel.
   848     bitsPerPixel := image bitsPerPixel.
   807 
   849 
   849 "/        ]
   891 "/        ]
   850 "/    ].
   892 "/    ].
   851 "/    n+1 to:(1 bitShift:bitsPerPixel) do:[:i |
   893 "/    n+1 to:(1 bitShift:bitsPerPixel) do:[:i |
   852 "/        outStream nextPut:0; nextPut:0; nextPut:0
   894 "/        outStream nextPut:0; nextPut:0; nextPut:0
   853 "/    ].
   895 "/    ].
   854     outStream nextPut:ImageSeparator.
   896 
   855     self writeShort:0.       "/
       
   856     self writeShort:0.       "/
       
   857     self writeShort:width.   "/ image size
       
   858     self writeShort:height.
       
   859 
       
   860     interlace == true ifTrue:[
       
   861         t1 := 64
       
   862     ] ifFalse:[
       
   863         t1 := 0
       
   864     ].
       
   865     outStream nextPut:t1       "/ another flag
       
   866 
   897 
   867     "Created: 14.10.1997 / 17:41:28 / cg"
   898     "Created: 14.10.1997 / 17:41:28 / cg"
   868     "Modified: 21.10.1997 / 04:52:18 / cg"
   899     "Modified: 21.10.1997 / 04:52:18 / cg"
       
   900 !
       
   901 
       
   902 writeMaskExtensionHeaderFor:image
       
   903     "write an extension header for the transparent pixel"
       
   904 
       
   905     outStream nextPut:Extension.
       
   906     outStream nextPut:16rF9.       "/ graphic control extension
       
   907     outStream nextPut:4.           "/ subBlockSize
       
   908 
       
   909     outStream nextPut:1.                "/ animationType
       
   910     outStream nextPutShort:1 MSB:false. "/ animationTime
       
   911     outStream nextPut:maskPixel.        "/ animationMask
       
   912 
       
   913     outStream nextPut:0.
   869 ! !
   914 ! !
   870 
   915 
   871 !GIFReader class methodsFor:'documentation'!
   916 !GIFReader class methodsFor:'documentation'!
   872 
   917 
   873 version
   918 version
   874     ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.60 1997-10-21 18:26:40 cg Exp $'
   919     ^ '$Header: /cvs/stx/stx/libview2/GIFReader.st,v 1.61 1997-10-22 15:19:46 ca Exp $'
   875 ! !
   920 ! !
   876 GIFReader initialize!
   921 GIFReader initialize!