diff -r f84ff77deaea -r 93f557cbe600 XPMReader.st --- a/XPMReader.st Mon Sep 01 11:52:06 2003 +0200 +++ b/XPMReader.st Mon Sep 01 16:47:57 2003 +0200 @@ -131,7 +131,166 @@ "Modified: 24.4.1997 / 20:29:40 / cg" ! ! -!XPMReader methodsFor:'reading from file'! +!XPMReader methodsFor:'reading'! + +readImage + "read an XPM-image from my inStream. Return the receiver + (with all relevant instance variables set for the image) + or nil on error" + + |line + srcIndex "{ Class: SmallInteger }" + dstIndex "{ Class: SmallInteger }" + colorMapSize + s bitsPerPixel key lastKey lastChar1 lastChar2 c1 c2 lastXLation| + + line := inStream nextLine. + (line notNil and:[line startsWith:'/* XPM']) ifFalse:[ + ^ self fileFormatError:'format error (expected XPM)'. + ]. + + line := inStream nextLine. + [line notNil and:[(line startsWith:'/*') or:[line isBlank or:[(line startsWith:' *')]]]] whileTrue:[ + line := inStream nextLine. + ]. + (line notNil and:[line startsWith:'static char']) ifFalse:[ + ^ self fileFormatError:'format error (expected static char)'. + ]. + line := inStream nextLine. + (line notNil and:[line startsWith:'/*']) ifTrue:[ + [line notNil + and:[(line startsWith:'/*') or:[line startsWith:' *']]] whileTrue:[ + line := inStream nextLine. + ]. + ]. + line notNil ifTrue:[ + line := line withoutSeparators + ]. + (line notNil and:[line startsWith:'"']) ifFalse:[ + ^ self fileFormatError:'format error (expected "ww hh nn mm)'. + ]. + s := ReadStream on:line. + s next. "skip quote" + width := Integer readFrom:s. + height := Integer readFrom:s. + colorMapSize := Integer readFrom:s. + charsPerPixel := Integer readFrom:s. + + charsPerPixel ~~ 1 ifTrue:[ + characterTranslation := Dictionary new:colorMapSize. + ] ifFalse:[ + characterTranslation := Array new:256. + ]. + + self readColorMap:colorMapSize. + + "actually, could make it an image with less depth most of the time ..." + +" + bitsPerPixel := ((colorMapSize - 1) log:2) truncated + 1. +" + colorMapSize > 256 ifTrue:[ + bitsPerPixel := 24. + data := ByteArray new:(width * height * 3). + ] ifFalse:[ + bitsPerPixel := 8. + data := ByteArray new:(width * height). + ]. + + dstIndex := 1. + 1 to:height do:[:row | + line := inStream nextLine withoutSpaces. + [line notNil and:[line startsWith:'/*']] whileTrue:[ + line := inStream nextLine withoutSpaces. + ]. + line notNil ifTrue:[ + line := line withoutSeparators + ]. + (line notNil and:[line startsWith:'"']) ifFalse:[ + ^ self fileFormatError:'format error (expected pixels)'. + ]. + charsPerPixel == 1 ifTrue:[ + srcIndex := 2. "skip dquote" + 1 to:width do:[:col | + key := line at:srcIndex. + key ~~ lastKey ifTrue:[ + lastXLation := characterTranslation at:key asciiValue. + lastKey := key + ]. + data at:dstIndex put:lastXLation. + srcIndex := srcIndex + 1. + dstIndex := dstIndex + 1 + ] + ] ifFalse:[ + charsPerPixel == 2 ifTrue:[ + "/ sorry, but this ugly code does a lot for speed, + "/ when reading big Xpm files (factor=5 for banner8.xpm) ... + srcIndex := 2."skip dquote" + lastChar1 := lastChar2 := nil. + key := String new:2. + 1 to:width do:[:col | + c1 := line at:srcIndex. + c2 := line at:srcIndex+1. + (c1 ~~ lastChar1 or:[c2 ~~ lastChar2]) ifTrue:[ + key at:1 put:c1. + key at:2 put:c2. + lastXLation := characterTranslation at:key. + lastChar1 := c1. + lastChar2 := c2. + ]. + bitsPerPixel == 24 ifTrue:[ + data at:dstIndex put:(colorMap at:lastXLation+1) redByte. + data at:dstIndex+1 put:(colorMap at:lastXLation+1) greenByte. + data at:dstIndex+2 put:(colorMap at:lastXLation+1) blueByte. + dstIndex := dstIndex + 3. + ] ifFalse:[ + data at:dstIndex put:lastXLation. + dstIndex := dstIndex + 1. + ]. + srcIndex := srcIndex + 2. + ] + ] ifFalse:[ + s := line readStream. + s next. "/ skip dquote + 1 to:width do:[:col | + key := s next:charsPerPixel. +"/ data at:dstIndex put:(characterTranslation at:key). + key ~= lastKey ifTrue:[ + lastXLation := characterTranslation at:key. + lastKey := key + ]. + data at:dstIndex put:lastXLation. + dstIndex := dstIndex + 1 + ] + ] + ] + ]. + + bitsPerPixel == 24 ifTrue:[ + photometric := #rgb. + samplesPerPixel := 3. + bitsPerSample := #(8 8 8). + ] ifFalse:[ + photometric := #palette. + samplesPerPixel := 1. + bitsPerSample := Array with:bitsPerPixel. + ]. + + maskPixelValue notNil ifTrue:[ + self buildMaskFromColor:maskPixelValue + ]. + + " + XPMReader fromStream:('../../goodies/bitmaps/xpmBitmaps/FATAL.xpm' asFilename readStream) + " + + "Created: / 24.9.1995 / 06:20:06 / claus" + "Modified: / 24.9.1995 / 07:07:33 / claus" + "Modified: / 5.7.1996 / 17:27:59 / stefan" + "Modified: / 27.7.1998 / 20:01:56 / cg" +! ! + +!XPMReader methodsFor:'reading-private'! colorNameFrom:aStream "read either a color-name or value specified in X-notation @@ -294,185 +453,9 @@ ]. colorMap := MappedPalette redVector:redMap greenVector:greenMap blueVector:blueMap. -! - -readImage - "read an XPM-image from my inStream. Return the receiver - (with all relevant instance variables set for the image) - or nil on error" - - |line - srcIndex "{ Class: SmallInteger }" - dstIndex "{ Class: SmallInteger }" - colorMapSize - s bitsPerPixel key lastKey lastChar1 lastChar2 c1 c2 lastXLation| - - line := inStream nextLine. - (line notNil and:[line startsWith:'/* XPM']) ifFalse:[ - ^ self fileFormatError:'format error (expected XPM)'. - ]. - - line := inStream nextLine. - [line notNil and:[(line startsWith:'/*') or:[line isBlank or:[(line startsWith:' *')]]]] whileTrue:[ - line := inStream nextLine. - ]. - (line notNil and:[line startsWith:'static char']) ifFalse:[ - ^ self fileFormatError:'format error (expected static char)'. - ]. - line := inStream nextLine. - (line notNil and:[line startsWith:'/*']) ifTrue:[ - [line notNil - and:[(line startsWith:'/*') or:[line startsWith:' *']]] whileTrue:[ - line := inStream nextLine. - ]. - ]. - line notNil ifTrue:[ - line := line withoutSeparators - ]. - (line notNil and:[line startsWith:'"']) ifFalse:[ - ^ self fileFormatError:'format error (expected "ww hh nn mm)'. - ]. - s := ReadStream on:line. - s next. "skip quote" - width := Integer readFrom:s. - height := Integer readFrom:s. - colorMapSize := Integer readFrom:s. - charsPerPixel := Integer readFrom:s. - - charsPerPixel ~~ 1 ifTrue:[ - characterTranslation := Dictionary new:colorMapSize. - ] ifFalse:[ - characterTranslation := Array new:256. - ]. - - self readColorMap:colorMapSize. - - "actually, could make it an image with less depth most of the time ..." - -" - bitsPerPixel := ((colorMapSize - 1) log:2) truncated + 1. -" - colorMapSize > 256 ifTrue:[ - bitsPerPixel := 24. - data := ByteArray new:(width * height * 3). - ] ifFalse:[ - bitsPerPixel := 8. - data := ByteArray new:(width * height). - ]. - - dstIndex := 1. - 1 to:height do:[:row | - line := inStream nextLine withoutSpaces. - [line notNil and:[line startsWith:'/*']] whileTrue:[ - line := inStream nextLine withoutSpaces. - ]. - line notNil ifTrue:[ - line := line withoutSeparators - ]. - (line notNil and:[line startsWith:'"']) ifFalse:[ - ^ self fileFormatError:'format error (expected pixels)'. - ]. - charsPerPixel == 1 ifTrue:[ - srcIndex := 2. "skip dquote" - 1 to:width do:[:col | - key := line at:srcIndex. - key ~~ lastKey ifTrue:[ - lastXLation := characterTranslation at:key asciiValue. - lastKey := key - ]. - data at:dstIndex put:lastXLation. - srcIndex := srcIndex + 1. - dstIndex := dstIndex + 1 - ] - ] ifFalse:[ - charsPerPixel == 2 ifTrue:[ - "/ sorry, but this ugly code does a lot for speed, - "/ when reading big Xpm files (factor=5 for banner8.xpm) ... - srcIndex := 2."skip dquote" - lastChar1 := lastChar2 := nil. - key := String new:2. - 1 to:width do:[:col | - c1 := line at:srcIndex. - c2 := line at:srcIndex+1. - (c1 ~~ lastChar1 or:[c2 ~~ lastChar2]) ifTrue:[ - key at:1 put:c1. - key at:2 put:c2. - lastXLation := characterTranslation at:key. - lastChar1 := c1. - lastChar2 := c2. - ]. - bitsPerPixel == 24 ifTrue:[ - data at:dstIndex put:(colorMap at:lastXLation+1) redByte. - data at:dstIndex+1 put:(colorMap at:lastXLation+1) greenByte. - data at:dstIndex+2 put:(colorMap at:lastXLation+1) blueByte. - dstIndex := dstIndex + 3. - ] ifFalse:[ - data at:dstIndex put:lastXLation. - dstIndex := dstIndex + 1. - ]. - srcIndex := srcIndex + 2. - ] - ] ifFalse:[ - s := line readStream. - s next. "/ skip dquote - 1 to:width do:[:col | - key := s next:charsPerPixel. -"/ data at:dstIndex put:(characterTranslation at:key). - key ~= lastKey ifTrue:[ - lastXLation := characterTranslation at:key. - lastKey := key - ]. - data at:dstIndex put:lastXLation. - dstIndex := dstIndex + 1 - ] - ] - ] - ]. - - bitsPerPixel == 24 ifTrue:[ - photometric := #rgb. - samplesPerPixel := 3. - bitsPerSample := #(8 8 8). - ] ifFalse:[ - photometric := #palette. - samplesPerPixel := 1. - bitsPerSample := Array with:bitsPerPixel. - ]. - - maskPixelValue notNil ifTrue:[ - self buildMaskFromColor:maskPixelValue - ]. - - " - XPMReader fromStream:('../../goodies/bitmaps/xpmBitmaps/FATAL.xpm' asFilename readStream) - " - - "Created: / 24.9.1995 / 06:20:06 / claus" - "Modified: / 24.9.1995 / 07:07:33 / claus" - "Modified: / 5.7.1996 / 17:27:59 / stefan" - "Modified: / 27.7.1998 / 20:01:56 / cg" ! ! -!XPMReader methodsFor:'writing to file'! - -colorNameOf:aColor - "generate a name for a color. If its a standard color, - return its name; otherwise return the hex representation." - - #(white black red green blue - yellow magenta cyan orange) do:[:aStandardColorName | - aColor = (Color name:aStandardColorName) ifTrue:[ - ^ aStandardColorName. - ] - ]. - ^ '#' - , (aColor redByte hexPrintString:2) - , (aColor greenByte hexPrintString:2) - , (aColor blueByte hexPrintString:2) - - "Created: / 27.2.1997 / 11:48:40 / cg" - "Modified: / 6.6.1998 / 20:58:49 / cg" -! +!XPMReader methodsFor:'writing'! save:image onFile:aFileName "save image as XPM file on aFileName. @@ -575,10 +558,31 @@ "Modified: / 28.7.1998 / 21:52:13 / cg" ! ! +!XPMReader methodsFor:'writing-private'! + +colorNameOf:aColor + "generate a name for a color. If its a standard color, + return its name; otherwise return the hex representation." + + #(white black red green blue + yellow magenta cyan orange) do:[:aStandardColorName | + aColor = (Color name:aStandardColorName) ifTrue:[ + ^ aStandardColorName. + ] + ]. + ^ '#' + , (aColor redByte hexPrintString:2) + , (aColor greenByte hexPrintString:2) + , (aColor blueByte hexPrintString:2) + + "Created: / 27.2.1997 / 11:48:40 / cg" + "Modified: / 6.6.1998 / 20:58:49 / cg" +! ! + !XPMReader class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.53 2003-05-05 16:50:53 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.54 2003-09-01 14:47:55 cg Exp $' ! ! XPMReader initialize!