--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PCXReader.st Mon Oct 10 03:32:51 1994 +0100
@@ -0,0 +1,275 @@
+"
+ COPYRIGHT (c) 1994 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+'From Smalltalk/X, Version:2.10.3 on 22-sep-1994 at 7:31:01 pm'!
+
+ImageReader subclass:#PCXReader
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Graphics-Support'
+!
+
+PCXReader comment:'
+COPYRIGHT (c) 1994 by Claus Gittinger
+ All Rights Reserved
+
+$Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.1 1994-10-10 02:32:51 claus Exp $
+'!
+
+!PCXReader class methodsFor:'testing'!
+
+isValidPCXHeader:aHeader
+ "return true, if aHeader looks like a PCX image header"
+
+ "check id"
+ ((aHeader at:1) ~~ 16r0A) ifTrue:[
+ ^ false
+ ].
+
+ "check version"
+ (#(0 2 3 5) includes:(aHeader at:2)) ifFalse:[
+ ^ false
+ ].
+
+ ^ true
+!
+
+isValidImageFile:aFilename
+ "return true, if aFilename contains a PCX image"
+
+ |fileSize header inStream|
+
+ inStream := self streamReadingFile:aFilename.
+ inStream isNil ifTrue:[^ false].
+
+ inStream binary.
+ fileSize := inStream size.
+
+ fileSize < 128 ifTrue:[
+ inStream close.
+ ^ false
+ ].
+
+ header := ByteArray uninitializedNew:128.
+ inStream nextBytes:128 into:header.
+ inStream close.
+
+ (self isValidPCXHeader:header) ifFalse:[
+ ^ false
+ ].
+ ^ true
+! !
+
+!PCXReader class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1994 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+version
+"
+$Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.1 1994-10-10 02:32:51 claus Exp $
+"
+!
+
+documentation
+"
+ this class provides methods for loading PCX bitmap files..
+"
+! !
+
+!PCXReader class methodsFor:'initialization'!
+
+initialize
+ "tell Image-class, that a new fileReader is present"
+
+ Image fileFormats at:'.pcx' put:self.
+! !
+
+!PCXReader methodsFor:'reading from file'!
+
+fromStreamWithHeader:header
+ | inDepth version compression nPlanes xmin ymin xmax ymax
+ paletteType rawMap rMap gMap bMap
+ endIndex "{Class: SmallInteger }"
+ srcIndex "{Class: SmallInteger }"
+ dstIndex "{Class: SmallInteger }"
+ rowIndex "{Class: SmallInteger }"
+ h "{Class: SmallInteger }"
+ byte "{Class: SmallInteger }"
+ nByte "{Class: SmallInteger }"
+ idx2
+ dataBytes bytesPerRow value|
+
+ version := header at:2.
+"/ 'version=' print. version printNL.
+ compression := header at:3.
+"/ 'compression=' print. compression printNL.
+ (#(0 1) includes:compression) ifFalse:[
+ self error:'PCXREADER: unknown compression'.
+ ^ nil
+ ].
+ inDepth := header at:4.
+"/ 'depth=' print. inDepth printNL.
+ nPlanes := header at:66.
+"/ 'planes=' print. nPlanes printNL.
+ bytesPerRow := header wordAt:67.
+"/ 'bytesPerRow=' print. bytesPerRow printNL.
+ paletteType := header at:69.
+
+ "
+ although it would be easy to implement ...
+ I have no test pictures for other formats.
+ So its not (yet) implemented
+ "
+ ((inDepth ~~ 8) or:[nPlanes ~~ 1]) ifTrue:[
+ 'PCXReader: can only handle 1-plane 256 color images' errorPrintNL.
+ ^ nil
+ ].
+
+ xmin := header wordAt:5.
+ ymin := header wordAt:7.
+ xmax := header wordAt:9.
+ ymax := header wordAt:11.
+
+ width := (xmax - xmin + 1).
+ height := (ymax - ymin + 1).
+"/ 'width=' print. width printNL.
+"/ 'height=' print. width printNL.
+
+ (version == 2) ifTrue:[
+ "read the 16-entry colormap"
+
+ rawMap := ByteArray uninitializedNew:(16*3).
+ rawMap replaceFrom:1 to:(16*3) with:header startingAt:17.
+ rMap := Array new:16.
+ gMap := Array new:16.
+ bMap := Array new:16.
+ srcIndex := 1.
+ 1 to:16 do:[:i |
+ rMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ gMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ bMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ ].
+ ].
+
+ data := dataBytes := ByteArray new:(height * bytesPerRow).
+
+ compression == 1 ifTrue:[
+ rowIndex := 1.
+ h := height.
+ 1 to:h do:[:row |
+ dstIndex := rowIndex.
+ endIndex := dstIndex + bytesPerRow.
+ [dstIndex <= endIndex] whileTrue:[
+ byte := inStream nextByte.
+ ((byte bitAnd:16rC0) ~~ 16rC0) ifTrue:[
+ dataBytes at:dstIndex put:byte.
+ dstIndex := dstIndex + 1.
+ ] ifFalse:[
+ nByte := byte bitAnd:2r00111111.
+ value := inStream nextByte.
+ value notNil ifTrue:[
+ idx2 := endIndex min:(dstIndex + nByte - 1).
+ dataBytes from:dstIndex to:idx2 put:value.
+ dstIndex := dstIndex + nByte.
+ ]
+ ].
+ ].
+ rowIndex := rowIndex + bytesPerRow
+ ]
+ ] ifFalse:[
+ "
+ actually untested ...
+ "
+ inStream nextBytes:(height * bytesPerRow) into:data
+ ].
+
+ (version == 5) ifTrue:[
+ "read the 256-entry colormap"
+
+ (byte := inStream next) == 16rC0 ifFalse:[
+ 'PCXREADER: no valid 256-entry palette' printNL.
+ ].
+ rawMap := ByteArray uninitializedNew:(256*3).
+ inStream nextBytes:(256*3) into:rawMap.
+ rMap := Array new:256.
+ gMap := Array new:256.
+ bMap := Array new:256.
+ srcIndex := 1.
+ 1 to:256 do:[:i |
+ rMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ gMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ bMap at:i put:(rawMap at:srcIndex).
+ srcIndex := srcIndex + 1.
+ ].
+ ].
+
+ photometric := #palette.
+ samplesPerPixel := 1.
+ bitsPerSample := #(8).
+ colorMap := Array with:rMap with:gMap with:bMap.
+
+ "
+ |i f|
+ i := Image fromFile:'/LocalLibrary/Images/OS2/dos3.ico'.
+ f := i asFormOn:Display.
+ v displayOpaqueForm:(f magnifyBy:2@2) x:5 y:5
+ "
+!
+
+fromFile:aFilename
+ | fileSize header img |
+
+ inStream := self class streamReadingFile:aFilename.
+ inStream isNil ifTrue:[^ nil].
+
+ inStream binary.
+ fileSize := inStream size.
+
+ fileSize < 128 ifTrue:[
+ inStream close.
+ self error:'PCXREADER: short file'.
+ ^ nil
+ ].
+
+ header := ByteArray uninitializedNew:128.
+ inStream nextBytes:128 into:header.
+
+ (self class isValidPCXHeader:header) ifFalse:[
+ inStream close.
+ self error:'PCXREADER: wrong header'.
+ ^ nil
+ ].
+
+ img := self fromStreamWithHeader:header.
+ inStream close.
+ ^ img
+! !
+
+PCXReader initialize!