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! |