XPMReader.st
changeset 1737 a1ed08195ee7
parent 1710 ad35e6a18e98
child 1743 2f206c9f1319
equal deleted inserted replaced
1736:a8f1fcc3e6bc 1737:a1ed08195ee7
    11 "
    11 "
    12 
    12 
    13 "{ Package: 'stx:libview2' }"
    13 "{ Package: 'stx:libview2' }"
    14 
    14 
    15 ImageReader subclass:#XPMReader
    15 ImageReader subclass:#XPMReader
    16 	instanceVariableNames:''
    16 	instanceVariableNames:'charsPerPixel maskPixelValue characterTranslation'
    17 	classVariableNames:''
    17 	classVariableNames:''
    18 	poolDictionaries:''
    18 	poolDictionaries:''
    19 	category:'Graphics-Images-Support'
    19 	category:'Graphics-Images-Support'
    20 !
    20 !
    21 
    21 
   122     (line startsWith:'/* XPM') ifFalse:[^ false].
   122     (line startsWith:'/* XPM') ifFalse:[^ false].
   123     ^ true
   123     ^ true
   124 
   124 
   125     "
   125     "
   126      XPMReader isValidImageFile:'fooBar'    
   126      XPMReader isValidImageFile:'fooBar'    
   127      XPMReader isValidImageFile:'bitmaps/xpmBitmaps/device_images/ljet.xpm'      
   127      XPMReader isValidImageFile:'../../goodies/bitmaps/xpmBitmaps/device_images/ljet.xpm'      
   128      XPMReader isValidImageFile:'bitmaps/gifImages/garfield.gif' 
   128      XPMReader isValidImageFile:'bitmaps/gifImages/garfield.gif' 
   129     "
   129     "
   130 
   130 
   131     "Modified: 24.4.1997 / 20:29:40 / cg"
   131     "Modified: 24.4.1997 / 20:29:40 / cg"
   132 ! !
   132 ! !
   149 	s := s copyWith:aStream next
   149 	s := s copyWith:aStream next
   150     ].
   150     ].
   151     ^ s
   151     ^ s
   152 !
   152 !
   153 
   153 
   154 fromStream:aStream
   154 readColorMap:colorMapSize
   155     "read an XPM-image from aStream. Return the receiver 
   155     |redMap greenMap blueMap s key lineDone state
   156      (with all relevant instance variables set for the image) 
   156      symbolicName monoName greyName grey4Name colorName|
   157      or nil on error"
       
   158 
       
   159     |line 
       
   160      srcIndex "{ Class: SmallInteger }"
       
   161      dstIndex "{ Class: SmallInteger }"
       
   162      colorName monoName greyName grey4Name symbolicName colorMapSize redMap greenMap blueMap
       
   163      charsPerPixel xlation s bitsPerPixel lineDone maskPixelValue
       
   164      state key lastKey lastChar1 lastChar2 c1 c2 lastXLation|
       
   165 
       
   166     inStream := aStream.
       
   167 
       
   168     line := aStream nextLine.
       
   169     (line notNil and:[line startsWith:'/* XPM']) ifFalse:[
       
   170         ^ self fileFormatError:'format error (expected XPM)'.
       
   171     ].
       
   172 
       
   173     line := aStream nextLine.
       
   174     [line notNil and:[(line startsWith:'/*') or:[line isBlank or:[(line startsWith:' *')]]]] whileTrue:[
       
   175         line := aStream nextLine.
       
   176     ].
       
   177     (line notNil and:[line startsWith:'static char']) ifFalse:[
       
   178         ^ self fileFormatError:'format error (expected static char)'.
       
   179     ].
       
   180     line := aStream nextLine.
       
   181     (line notNil and:[line startsWith:'/*']) ifTrue:[
       
   182         [line notNil 
       
   183          and:[(line startsWith:'/*') or:[line startsWith:' *']]] whileTrue:[
       
   184             line := aStream nextLine.
       
   185         ].
       
   186     ].
       
   187     line notNil ifTrue:[
       
   188         line := line withoutSeparators
       
   189     ].
       
   190     (line notNil and:[line startsWith:'"']) ifFalse:[
       
   191         ^ self fileFormatError:'format error (expected "ww hh nn mm)'.
       
   192     ].
       
   193     s := ReadStream on:line.
       
   194     s next.  "skip quote"
       
   195     width := Integer readFrom:s.
       
   196     height := Integer readFrom:s.
       
   197     colorMapSize := Integer readFrom:s.
       
   198     charsPerPixel := Integer readFrom:s.
       
   199     charsPerPixel ~~ 1 ifTrue:[
       
   200         xlation := Dictionary new:colorMapSize.
       
   201     ] ifFalse:[
       
   202         xlation := Array new:256.
       
   203     ].
       
   204 
   157 
   205     redMap := ByteArray new:colorMapSize.
   158     redMap := ByteArray new:colorMapSize.
   206     greenMap := ByteArray new:colorMapSize.
   159     greenMap := ByteArray new:colorMapSize.
   207     blueMap := ByteArray new:colorMapSize.
   160     blueMap := ByteArray new:colorMapSize.
   208     colorMap := Colormap redVector:redMap greenVector:greenMap blueVector:blueMap.
   161     colorMap := Colormap redVector:redMap greenVector:greenMap blueVector:blueMap.
       
   162 
   209     1 to:colorMapSize do:[:colorIndex |
   163     1 to:colorMapSize do:[:colorIndex |
   210         |index line color t word|
   164         |index line color t word|
   211 
   165 
   212         line := aStream nextLine.
   166         line := inStream nextLine.
   213         [line notNil and:[line startsWith:'/*']] whileTrue:[
   167         [line notNil and:[line startsWith:'/*']] whileTrue:[
   214             [line notNil and:[(line endsWith:'*/') not]] whileTrue:[
   168             [line notNil and:[(line endsWith:'*/') not]] whileTrue:[
   215                 line := aStream nextLine.
   169                 line := inStream nextLine.
   216             ].
   170             ].
   217             line := aStream nextLine.
   171             line := inStream nextLine.
   218         ].
   172         ].
   219         line notNil ifTrue:[
   173         line notNil ifTrue:[
   220             line := line withoutSeparators
   174             line := line withoutSeparators
   221         ].
   175         ].
   222         (line notNil and:[line startsWith:'"']) ifFalse:[
   176         (line notNil and:[line startsWith:'"']) ifFalse:[
   225 
   179 
   226         s := ReadStream on:line.
   180         s := ReadStream on:line.
   227         s next. "skip quote"
   181         s next. "skip quote"
   228         charsPerPixel ~~ 1 ifTrue:[
   182         charsPerPixel ~~ 1 ifTrue:[
   229             key := s next:charsPerPixel.
   183             key := s next:charsPerPixel.
   230             xlation at:key put:colorIndex - 1.
   184             characterTranslation at:key put:colorIndex - 1.
   231         ] ifFalse:[
   185         ] ifFalse:[
   232             index := s next asciiValue.
   186             index := s next asciiValue.
   233             xlation at:index put:colorIndex - 1.
   187             characterTranslation at:index put:colorIndex - 1.
   234         ].
   188         ].
   235 
   189 
   236         lineDone := false.
   190         lineDone := false.
   237         state := nil.
   191         state := nil.
   238 
   192 
   337             redMap at:colorIndex put:(color red asFloat * 255.0 // 100).
   291             redMap at:colorIndex put:(color red asFloat * 255.0 // 100).
   338             greenMap at:colorIndex put:(color green asFloat * 255.0 // 100).
   292             greenMap at:colorIndex put:(color green asFloat * 255.0 // 100).
   339             blueMap at:colorIndex put:(color blue asFloat * 255.0 // 100).
   293             blueMap at:colorIndex put:(color blue asFloat * 255.0 // 100).
   340         ].
   294         ].
   341     ].
   295     ].
       
   296 !
       
   297 
       
   298 readImage
       
   299     "read an XPM-image from my inStream. Return the receiver 
       
   300      (with all relevant instance variables set for the image) 
       
   301      or nil on error"
       
   302 
       
   303     |line 
       
   304      srcIndex "{ Class: SmallInteger }"
       
   305      dstIndex "{ Class: SmallInteger }"
       
   306      colorMapSize   
       
   307      s bitsPerPixel key lastKey lastChar1 lastChar2 c1 c2 lastXLation|
       
   308 
       
   309     line := inStream nextLine.
       
   310     (line notNil and:[line startsWith:'/* XPM']) ifFalse:[
       
   311         ^ self fileFormatError:'format error (expected XPM)'.
       
   312     ].
       
   313 
       
   314     line := inStream nextLine.
       
   315     [line notNil and:[(line startsWith:'/*') or:[line isBlank or:[(line startsWith:' *')]]]] whileTrue:[
       
   316         line := inStream nextLine.
       
   317     ].
       
   318     (line notNil and:[line startsWith:'static char']) ifFalse:[
       
   319         ^ self fileFormatError:'format error (expected static char)'.
       
   320     ].
       
   321     line := inStream nextLine.
       
   322     (line notNil and:[line startsWith:'/*']) ifTrue:[
       
   323         [line notNil 
       
   324          and:[(line startsWith:'/*') or:[line startsWith:' *']]] whileTrue:[
       
   325             line := inStream nextLine.
       
   326         ].
       
   327     ].
       
   328     line notNil ifTrue:[
       
   329         line := line withoutSeparators
       
   330     ].
       
   331     (line notNil and:[line startsWith:'"']) ifFalse:[
       
   332         ^ self fileFormatError:'format error (expected "ww hh nn mm)'.
       
   333     ].
       
   334     s := ReadStream on:line.
       
   335     s next.  "skip quote"
       
   336     width := Integer readFrom:s.
       
   337     height := Integer readFrom:s.
       
   338     colorMapSize := Integer readFrom:s.
       
   339     charsPerPixel := Integer readFrom:s.
       
   340 
       
   341     charsPerPixel ~~ 1 ifTrue:[
       
   342         characterTranslation := Dictionary new:colorMapSize.
       
   343     ] ifFalse:[
       
   344         characterTranslation := Array new:256.
       
   345     ].
       
   346 
       
   347     self readColorMap:colorMapSize.
   342 
   348 
   343     "actually, could make it an image with less depth most of the time ..."
   349     "actually, could make it an image with less depth most of the time ..."
   344 
   350 
   345 "
   351 "
   346     bitsPerPixel := ((colorMapSize - 1) log:2) truncated + 1.
   352     bitsPerPixel := ((colorMapSize - 1) log:2) truncated + 1.
   353         data := ByteArray new:(width * height).
   359         data := ByteArray new:(width * height).
   354     ].
   360     ].
   355 
   361 
   356     dstIndex := 1.
   362     dstIndex := 1.
   357     1 to:height do:[:row |
   363     1 to:height do:[:row |
   358         line := aStream nextLine withoutSpaces.
   364         line := inStream nextLine withoutSpaces.
   359         [line notNil and:[line startsWith:'/*']] whileTrue:[
   365         [line notNil and:[line startsWith:'/*']] whileTrue:[
   360             line := aStream nextLine withoutSpaces.
   366             line := inStream nextLine withoutSpaces.
   361         ].
   367         ].
   362         line notNil ifTrue:[
   368         line notNil ifTrue:[
   363             line := line withoutSeparators
   369             line := line withoutSeparators
   364         ].
   370         ].
   365         (line notNil and:[line startsWith:'"']) ifFalse:[
   371         (line notNil and:[line startsWith:'"']) ifFalse:[
   368         charsPerPixel == 1 ifTrue:[
   374         charsPerPixel == 1 ifTrue:[
   369             srcIndex := 2. "skip dquote"
   375             srcIndex := 2. "skip dquote"
   370             1 to:width do:[:col |
   376             1 to:width do:[:col |
   371                 key := line at:srcIndex.
   377                 key := line at:srcIndex.
   372                 key ~~ lastKey ifTrue:[
   378                 key ~~ lastKey ifTrue:[
   373                     lastXLation := xlation at:key asciiValue.
   379                     lastXLation := characterTranslation at:key asciiValue.
   374                     lastKey := key
   380                     lastKey := key
   375                 ].
   381                 ].
   376                 data at:dstIndex put:lastXLation.
   382                 data at:dstIndex put:lastXLation.
   377                 srcIndex := srcIndex + 1.
   383                 srcIndex := srcIndex + 1.
   378                 dstIndex := dstIndex + 1
   384                 dstIndex := dstIndex + 1
   388                     c1 := line at:srcIndex.
   394                     c1 := line at:srcIndex.
   389                     c2 := line at:srcIndex+1.
   395                     c2 := line at:srcIndex+1.
   390                     (c1 ~~ lastChar1 or:[c2 ~~ lastChar2]) ifTrue:[
   396                     (c1 ~~ lastChar1 or:[c2 ~~ lastChar2]) ifTrue:[
   391                         key at:1 put:c1.
   397                         key at:1 put:c1.
   392                         key at:2 put:c2.
   398                         key at:2 put:c2.
   393                         lastXLation := xlation at:key.
   399                         lastXLation := characterTranslation at:key.
   394                         lastChar1 := c1.
   400                         lastChar1 := c1.
   395                         lastChar2 := c2.
   401                         lastChar2 := c2.
   396                     ].
   402                     ].
   397                     bitsPerPixel == 24 ifTrue:[
   403                     bitsPerPixel == 24 ifTrue:[
   398                         data at:dstIndex   put:(colorMap at:lastXLation+1) redByte.
   404                         data at:dstIndex   put:(colorMap at:lastXLation+1) redByte.
   408             ] ifFalse:[
   414             ] ifFalse:[
   409                 s := line readStream.
   415                 s := line readStream.
   410                 s next. "/ skip dquote
   416                 s next. "/ skip dquote
   411                 1 to:width do:[:col |
   417                 1 to:width do:[:col |
   412                     key := s next:charsPerPixel.
   418                     key := s next:charsPerPixel.
   413 "/                data at:dstIndex put:(xlation at:key).
   419 "/                data at:dstIndex put:(characterTranslation at:key).
   414                     key ~= lastKey ifTrue:[
   420                     key ~= lastKey ifTrue:[
   415                         lastXLation := xlation at:key.
   421                         lastXLation := characterTranslation at:key.
   416                         lastKey := key
   422                         lastKey := key
   417                     ].
   423                     ].
   418                     data at:dstIndex put:lastXLation.
   424                     data at:dstIndex put:lastXLation.
   419                     dstIndex := dstIndex + 1
   425                     dstIndex := dstIndex + 1
   420                 ]
   426                 ]
   435     maskPixelValue notNil ifTrue:[
   441     maskPixelValue notNil ifTrue:[
   436         self buildMaskFromColor:maskPixelValue
   442         self buildMaskFromColor:maskPixelValue
   437     ].
   443     ].
   438 
   444 
   439     "
   445     "
   440      XPMReader fromStream:('bitmaps/ljet.xpm' asFilename readStream)
   446      XPMReader fromStream:('../../goodies/bitmaps/xpmBitmaps/FATAL.xpm' asFilename readStream)
   441      XPMReader fromStream:('bitmaps/magtape.xpm' asFilename readStream)
       
   442      XPMReader fromStream:('bitmaps/pixmap.xpm' asFilename readStream) 
       
   443      XPMReader fromStream:('bitmaps/SBrowser.xbm' asFilename readStream)
       
   444     "
   447     "
   445 
   448 
   446     "Created: / 24.9.1995 / 06:20:06 / claus"
   449     "Created: / 24.9.1995 / 06:20:06 / claus"
   447     "Modified: / 24.9.1995 / 07:07:33 / claus"
   450     "Modified: / 24.9.1995 / 07:07:33 / claus"
   448     "Modified: / 5.7.1996 / 17:27:59 / stefan"
   451     "Modified: / 5.7.1996 / 17:27:59 / stefan"
   571 ! !
   574 ! !
   572 
   575 
   573 !XPMReader class methodsFor:'documentation'!
   576 !XPMReader class methodsFor:'documentation'!
   574 
   577 
   575 version
   578 version
   576     ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.49 2003-03-02 18:39:45 stefan Exp $'
   579     ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.50 2003-04-04 17:07:22 cg Exp $'
   577 ! !
   580 ! !
   578 
   581 
   579 XPMReader initialize!
   582 XPMReader initialize!