PCXReader.st
changeset 29 e04e1aceff6f
parent 27 93da277c5ddd
child 32 6bdcb6da4d4f
equal deleted inserted replaced
28:8daff0234d2e 29:e04e1aceff6f
    21 
    21 
    22 PCXReader comment:'
    22 PCXReader comment:'
    23 COPYRIGHT (c) 1994 by Claus Gittinger
    23 COPYRIGHT (c) 1994 by Claus Gittinger
    24 	      All Rights Reserved
    24 	      All Rights Reserved
    25 
    25 
    26 $Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.1 1994-10-10 02:32:51 claus Exp $
    26 $Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.2 1994-10-28 03:16:37 claus Exp $
    27 '!
    27 '!
    28 
       
    29 !PCXReader class methodsFor:'testing'!
       
    30 
       
    31 isValidPCXHeader:aHeader
       
    32     "return true, if aHeader looks like a PCX image header"
       
    33 
       
    34     "check id"
       
    35     ((aHeader at:1) ~~ 16r0A) ifTrue:[
       
    36 	^ false
       
    37     ].
       
    38 
       
    39     "check version"
       
    40     (#(0 2 3 5) includes:(aHeader at:2)) ifFalse:[
       
    41 	^ false
       
    42     ].
       
    43 
       
    44     ^ true
       
    45 !
       
    46 
       
    47 isValidImageFile:aFilename
       
    48     "return true, if aFilename contains a PCX image"
       
    49 
       
    50     |fileSize header inStream|
       
    51 
       
    52     inStream := self streamReadingFile:aFilename.
       
    53     inStream isNil ifTrue:[^ false].
       
    54 
       
    55     inStream binary.
       
    56     fileSize := inStream size.
       
    57 
       
    58     fileSize < 128 ifTrue:[
       
    59 	inStream close.
       
    60 	^ false
       
    61     ].
       
    62 
       
    63     header := ByteArray uninitializedNew:128.
       
    64     inStream nextBytes:128 into:header.
       
    65     inStream close.
       
    66 
       
    67     (self isValidPCXHeader:header) ifFalse:[
       
    68 	^ false
       
    69     ].
       
    70     ^ true
       
    71 ! !
       
    72 
    28 
    73 !PCXReader class methodsFor:'documentation'!
    29 !PCXReader class methodsFor:'documentation'!
    74 
    30 
    75 copyright
    31 copyright
    76 "
    32 "
    86 "
    42 "
    87 !
    43 !
    88 
    44 
    89 version
    45 version
    90 "
    46 "
    91 $Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.1 1994-10-10 02:32:51 claus Exp $
    47 $Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.2 1994-10-28 03:16:37 claus Exp $
    92 "
    48 "
    93 !
    49 !
    94 
    50 
    95 documentation
    51 documentation
    96 "
    52 "
    97     this class provides methods for loading PCX bitmap files..
    53     this class provides methods for loading PCX bitmap files.
    98 "
    54     Due to not having too many examples for testing, this could fail
       
    55     to read some files. (especially, I have no uncompressed files
       
    56     for testing).
       
    57 "
       
    58 ! !
       
    59 
       
    60 !PCXReader class methodsFor:'testing'!
       
    61 
       
    62 isValidPCXHeader:aHeader
       
    63     "return true, if aHeader looks like a PCX image header"
       
    64 
       
    65     "check id"
       
    66     ((aHeader at:1) ~~ 16r0A) ifTrue:[
       
    67 	^ false
       
    68     ].
       
    69 
       
    70     "check version"
       
    71     (#(0 2 3 5) includes:(aHeader at:2)) ifFalse:[
       
    72 	^ false
       
    73     ].
       
    74 
       
    75     ^ true
       
    76 !
       
    77 
       
    78 isValidImageFile:aFilename
       
    79     "return true, if aFilename contains a PCX image"
       
    80 
       
    81     |count header inStream|
       
    82 
       
    83     inStream := self streamReadingFile:aFilename.
       
    84     inStream isNil ifTrue:[^ false].
       
    85 
       
    86     inStream binary.
       
    87 
       
    88     header := ByteArray uninitializedNew:128.
       
    89     count := inStream nextBytes:128 into:header.
       
    90     inStream close.
       
    91 
       
    92     ((count == 128) and:[self isValidPCXHeader:header]) ifFalse:[
       
    93 	^ false
       
    94     ].
       
    95     ^ true
    99 ! !
    96 ! !
   100 
    97 
   101 !PCXReader class methodsFor:'initialization'!
    98 !PCXReader class methodsFor:'initialization'!
   102 
    99 
   103 initialize
   100 initialize
   116       dstIndex "{Class: SmallInteger }"
   113       dstIndex "{Class: SmallInteger }"
   117       rowIndex "{Class: SmallInteger }"
   114       rowIndex "{Class: SmallInteger }"
   118       h        "{Class: SmallInteger }"
   115       h        "{Class: SmallInteger }"
   119       byte     "{Class: SmallInteger }"
   116       byte     "{Class: SmallInteger }"
   120       nByte    "{Class: SmallInteger }"
   117       nByte    "{Class: SmallInteger }"
   121       idx2
   118       bytesPerRow "{Class: SmallInteger }"
   122       dataBytes bytesPerRow value|
   119       value       "{Class: SmallInteger }"
       
   120       idx2        "{Class: SmallInteger }"
       
   121       dataBytes buffer 
       
   122       bufferIndex "{Class: SmallInteger }"
       
   123       nBuffer     "{Class: SmallInteger }"|
   123 
   124 
   124     version := header at:2.
   125     version := header at:2.
   125 "/    'version=' print. version printNL.
   126 "/    'version=' print. version printNL.
   126     compression := header at:3.
   127     compression := header at:3.
   127 "/    'compression=' print. compression printNL.
   128 "/    'compression=' print. compression printNL.
   174 	    bMap at:i put:(rawMap at:srcIndex).
   175 	    bMap at:i put:(rawMap at:srcIndex).
   175 	    srcIndex := srcIndex + 1.
   176 	    srcIndex := srcIndex + 1.
   176 	].
   177 	].
   177     ].
   178     ].
   178 
   179 
   179     data := dataBytes := ByteArray new:(height * bytesPerRow).
       
   180 
       
   181     compression == 1 ifTrue:[
   180     compression == 1 ifTrue:[
       
   181 	data := dataBytes := ByteArray new:(height * bytesPerRow).
       
   182 
       
   183 	buffer := ByteArray new:4096.
       
   184 	bufferIndex := 1.
       
   185 	nBuffer := 0.
       
   186 
   182 	rowIndex := 1.
   187 	rowIndex := 1.
   183 	h := height.
   188 	h := height.
   184 	1 to:h do:[:row |
   189 	1 to:h do:[:row |
   185 	    dstIndex := rowIndex.
   190 	    dstIndex := rowIndex.
   186 	    endIndex := dstIndex + bytesPerRow.
   191 	    endIndex := dstIndex + bytesPerRow.
   187 	    [dstIndex <= endIndex] whileTrue:[
   192 	    [dstIndex < endIndex] whileTrue:[
   188 		byte := inStream nextByte.
   193 		nBuffer == 0 ifTrue:[
   189 		((byte bitAnd:16rC0) ~~ 16rC0) ifTrue:[
   194 		    nBuffer := inStream nextBytes:4096 into:buffer.
       
   195 		    bufferIndex := 1.
       
   196 		].
       
   197 		byte := buffer at:bufferIndex.
       
   198 		bufferIndex := bufferIndex + 1. nBuffer := nBuffer - 1.
       
   199 		((byte bitAnd:2r11000000) ~~ 2r11000000) ifTrue:[
   190 		    dataBytes at:dstIndex put:byte.
   200 		    dataBytes at:dstIndex put:byte.
   191 		    dstIndex := dstIndex + 1.
   201 		    dstIndex := dstIndex + 1.
   192 		] ifFalse:[
   202 		] ifFalse:[
   193 		    nByte := byte bitAnd:2r00111111.
   203 		    nByte := byte bitAnd:2r00111111.
   194 		    value := inStream nextByte.
   204 		    nBuffer == 0 ifTrue:[
       
   205 			nBuffer := inStream nextBytes:4096 into:buffer.
       
   206 			bufferIndex := 1.
       
   207 		    ].
       
   208 		    value := buffer at:bufferIndex.
       
   209 		    bufferIndex := bufferIndex + 1. nBuffer := nBuffer - 1.
   195 		    value notNil ifTrue:[
   210 		    value notNil ifTrue:[
   196 			idx2 := endIndex min:(dstIndex + nByte - 1).
   211 			idx2 := endIndex min:(dstIndex + nByte - 1).
   197 			dataBytes from:dstIndex to:idx2 put:value.
   212 			dataBytes from:dstIndex to:idx2 put:value.
   198 			dstIndex := dstIndex + nByte.
   213 			dstIndex := dstIndex + nByte.
   199 		    ]
   214 		    ]
   200 		].
   215 		].
   201 	    ].
   216 	    ].
   202 	    rowIndex := rowIndex + bytesPerRow
   217 	    rowIndex := rowIndex + bytesPerRow
   203 	]
   218 	]
       
   219 
       
   220 "/        rowIndex := 1.
       
   221 "/        h := height.
       
   222 "/        1 to:h do:[:row |
       
   223 "/            dstIndex := rowIndex.
       
   224 "/            endIndex := dstIndex + bytesPerRow.
       
   225 "/            [dstIndex < endIndex] whileTrue:[
       
   226 "/                byte := inStream next.
       
   227 "/                ((byte bitAnd:2r11000000) ~~ 2r11000000) ifTrue:[
       
   228 "/                    dataBytes at:dstIndex put:byte.
       
   229 "/                    dstIndex := dstIndex + 1.
       
   230 "/                ] ifFalse:[
       
   231 "/                    nByte := byte bitAnd:2r00111111.
       
   232 "/                    value := inStream next.
       
   233 "/                    value notNil ifTrue:[
       
   234 "/                        idx2 := endIndex min:(dstIndex + nByte - 1).
       
   235 "/                        dataBytes from:dstIndex to:idx2 put:value.
       
   236 "/                        dstIndex := dstIndex + nByte.
       
   237 "/                    ]
       
   238 "/                ].
       
   239 "/            ].
       
   240 "/            rowIndex := rowIndex + bytesPerRow
       
   241 "/        ]
   204     ] ifFalse:[
   242     ] ifFalse:[
   205 	"
   243 	"
   206 	 actually untested ...
   244 	 actually untested ...
   207 	"
   245 	"
   208 	inStream nextBytes:(height * bytesPerRow) into:data
   246 	data := dataBytes := ByteArray uninitializedNew:(height * bytesPerRow).
       
   247 	inStream nextBytes:(height * bytesPerRow) into:data.
       
   248 	nBuffer := 0.
   209     ].
   249     ].
   210 
   250 
   211     (version == 5) ifTrue:[
   251     (version == 5) ifTrue:[
   212 	"read the 256-entry colormap"
   252 	"read the 256-entry colormap"
   213 
   253 
   214 	(byte := inStream next) == 16rC0 ifFalse:[
   254 	nBuffer ~~ 0 ifTrue:[
   215 	   'PCXREADER: no valid 256-entry palette' printNL.
   255 	    byte := buffer at:bufferIndex.
       
   256 	    bufferIndex := bufferIndex + 1. nBuffer := nBuffer - 1.
       
   257 	] ifFalse:[
       
   258 	    byte := inStream next
       
   259 	].
       
   260 
       
   261 	byte == 16rC0 ifFalse:[
       
   262 	   'PCXREADER: no valid 256-entry palette (got' errorPrint. 
       
   263 	   byte errorPrint. '; expected ' errorPrint. 16rC0 errorPrint. ')' errorPrintNL.
   216 	].
   264 	].
   217 	rawMap := ByteArray uninitializedNew:(256*3).
   265 	rawMap := ByteArray uninitializedNew:(256*3).
   218 	inStream nextBytes:(256*3) into:rawMap.
   266 	nBuffer ~~ 0 ifTrue:[
       
   267 	    rawMap replaceFrom:1 to:(256*3) with:buffer startingAt:bufferIndex.
       
   268 	    nBuffer < (256*3) ifTrue:[
       
   269 		inStream nextBytes:((256*3)-nBuffer) into:rawMap startingAt:nBuffer+1
       
   270 	    ]
       
   271 	] ifFalse:[
       
   272 	    inStream nextBytes:(256*3) into:rawMap.
       
   273 	].
   219 	rMap := Array new:256.
   274 	rMap := Array new:256.
   220 	gMap := Array new:256.
   275 	gMap := Array new:256.
   221 	bMap := Array new:256.
   276 	bMap := Array new:256.
   222 	srcIndex := 1.
   277 	srcIndex := 1.
   223 	1 to:256 do:[:i |
   278 	1 to:256 do:[:i |
   235     bitsPerSample := #(8).
   290     bitsPerSample := #(8).
   236     colorMap := Array with:rMap with:gMap with:bMap.
   291     colorMap := Array with:rMap with:gMap with:bMap.
   237 
   292 
   238     "
   293     "
   239      |i f|
   294      |i f|
   240      i := Image fromFile:'/LocalLibrary/Images/OS2/dos3.ico'.
   295      i := Image fromFile:'somefile.pcx'.
   241      f := i asFormOn:Display.
   296      i inspect.
   242      v displayOpaqueForm:(f magnifyBy:2@2) x:5 y:5
       
   243     "
   297     "
   244 !
   298 !
   245 
   299 
   246 fromFile:aFilename 
   300 fromFile:aFilename 
   247     | fileSize header img |
   301     | fileSize header img |