PCXReader.st
changeset 561 bb8103acb292
parent 531 19c16bd5e0bf
child 566 f3cbbba715d9
equal deleted inserted replaced
560:4cce4f58bbbf 561:bb8103acb292
   179     version := header at:2.
   179     version := header at:2.
   180 "/    'version=' print. version printNL.
   180 "/    'version=' print. version printNL.
   181     compression := header at:3.
   181     compression := header at:3.
   182 "/    'compression=' print. compression printNL.
   182 "/    'compression=' print. compression printNL.
   183     (#(0 1) includes:compression) ifFalse:[
   183     (#(0 1) includes:compression) ifFalse:[
   184 	self error:'PCXREADER: unknown compression'.
   184         self error:'PCXREADER: unknown compression'.
   185 	^ nil
   185         ^ nil
   186     ].
   186     ].
   187 
   187 
   188     inDepth := header at:4.
   188     inDepth := header at:4.
   189 "/    'depth=' print. inDepth printNL.
   189 "/    'depth=' print. inDepth printNL.
   190     nPlanes := header at:66.
   190     nPlanes := header at:66.
   197      although it would be easy to implement ...
   197      although it would be easy to implement ...
   198      I have no test pictures for other formats.
   198      I have no test pictures for other formats.
   199      So its not (yet) implemented
   199      So its not (yet) implemented
   200     "
   200     "
   201     ((inDepth ~~ 8) or:[nPlanes ~~ 1]) ifTrue:[
   201     ((inDepth ~~ 8) or:[nPlanes ~~ 1]) ifTrue:[
   202 	'PCXReader: depth: ' errorPrint. inDepth errorPrint. 
   202         'PCXReader: depth: ' errorPrint. inDepth errorPrint. 
   203 	' planes:' errorPrint. nPlanes errorPrintNL.
   203         ' planes:' errorPrint. nPlanes errorPrintNL.
   204 	'PCXReader: can only handle 1-plane 256 color images' errorPrintNL.
   204         'PCXReader: can only handle 1-plane 256 color images' errorPrintNL.
   205 	^ nil
   205         ^ nil
   206     ].
   206     ].
   207 
   207 
   208     xmin := header wordAt:5 MSB:false. 
   208     xmin := header wordAt:5 MSB:false. 
   209     ymin := header wordAt:7 MSB:false.
   209     ymin := header wordAt:7 MSB:false.
   210     xmax := header wordAt:9 MSB:false. 
   210     xmax := header wordAt:9 MSB:false. 
   214     height := (ymax - ymin + 1).
   214     height := (ymax - ymin + 1).
   215 "/    'width=' print. width printNL.
   215 "/    'width=' print. width printNL.
   216 "/    'height=' print. width printNL.
   216 "/    'height=' print. width printNL.
   217 
   217 
   218     (version == 2) ifTrue:[
   218     (version == 2) ifTrue:[
   219 	"read the 16-entry colormap"
   219         "read the 16-entry colormap"
   220 
   220 
   221 	rawMap := ByteArray uninitializedNew:(16*3).
   221         rawMap := ByteArray uninitializedNew:(16*3).
   222 	rawMap replaceFrom:1 to:(16*3) with:header startingAt:17.
   222         rawMap replaceFrom:1 to:(16*3) with:header startingAt:17.
   223 	rMap := Array new:16.
   223         rMap := ByteArray new:16.
   224 	gMap := Array new:16.
   224         gMap := ByteArray new:16.
   225 	bMap := Array new:16.
   225         bMap := ByteArray new:16.
   226 	srcIndex := 1.
   226         srcIndex := 1.
   227 	1 to:16 do:[:i |
   227         1 to:16 do:[:i |
   228 	    rMap at:i put:(rawMap at:srcIndex).
   228             rMap at:i put:(rawMap at:srcIndex).
   229 	    srcIndex := srcIndex + 1.
   229             srcIndex := srcIndex + 1.
   230 	    gMap at:i put:(rawMap at:srcIndex).
   230             gMap at:i put:(rawMap at:srcIndex).
   231 	    srcIndex := srcIndex + 1.
   231             srcIndex := srcIndex + 1.
   232 	    bMap at:i put:(rawMap at:srcIndex).
   232             bMap at:i put:(rawMap at:srcIndex).
   233 	    srcIndex := srcIndex + 1.
   233             srcIndex := srcIndex + 1.
   234 	].
   234         ].
   235     ].
   235     ].
   236 
   236 
   237     compression == 1 ifTrue:[
   237     compression == 1 ifTrue:[
   238 	data := dataBytes := ByteArray uninitializedNew:(height * srcBytesPerRow).
   238         data := dataBytes := ByteArray uninitializedNew:(height * srcBytesPerRow).
   239 
   239 
   240 	buffer := ByteArray uninitializedNew:4096.
   240         buffer := ByteArray uninitializedNew:4096.
   241 	bufferIndex := 1.
   241         bufferIndex := 1.
   242 	bendIndex := 1.
   242         bendIndex := 1.
   243 
   243 
   244 	rowIndex := 1.
   244         rowIndex := 1.
   245 	h := height.
   245         h := height.
   246 	1 to:h do:[:row |
   246         1 to:h do:[:row |
   247 	    dstIndex := rowIndex.
   247             dstIndex := rowIndex.
   248 	    endIndex := dstIndex + srcBytesPerRow.
   248             endIndex := dstIndex + srcBytesPerRow.
   249 	    [dstIndex < endIndex] whileTrue:[
   249             [dstIndex < endIndex] whileTrue:[
   250 		bufferIndex == bendIndex ifTrue:[
   250                 bufferIndex == bendIndex ifTrue:[
   251 		    nBuffer := inStream nextBytes:4096 into:buffer.
   251                     nBuffer := inStream nextBytes:4096 into:buffer.
   252 		    bufferIndex := 1.
   252                     bufferIndex := 1.
   253 		    bendIndex := nBuffer + 1.
   253                     bendIndex := nBuffer + 1.
   254 		].
   254                 ].
   255 		byte := buffer at:bufferIndex.
   255                 byte := buffer at:bufferIndex.
   256 		bufferIndex := bufferIndex + 1.
   256                 bufferIndex := bufferIndex + 1.
   257 		((byte bitAnd:2r11000000) ~~ 2r11000000) ifTrue:[
   257                 ((byte bitAnd:2r11000000) ~~ 2r11000000) ifTrue:[
   258 		    dataBytes at:dstIndex put:byte.
   258                     dataBytes at:dstIndex put:byte.
   259 		    dstIndex := dstIndex + 1.
   259                     dstIndex := dstIndex + 1.
   260 		] ifFalse:[
   260                 ] ifFalse:[
   261 		    nByte := byte bitAnd:2r00111111.
   261                     nByte := byte bitAnd:2r00111111.
   262 		    bufferIndex == bendIndex ifTrue:[
   262                     bufferIndex == bendIndex ifTrue:[
   263 			nBuffer := inStream nextBytes:4096 into:buffer.
   263                         nBuffer := inStream nextBytes:4096 into:buffer.
   264 			bufferIndex := 1.
   264                         bufferIndex := 1.
   265 			bendIndex := nBuffer + 1.
   265                         bendIndex := nBuffer + 1.
   266 		    ].
   266                     ].
   267 		    value := buffer at:bufferIndex.
   267                     value := buffer at:bufferIndex.
   268 		    bufferIndex := bufferIndex + 1.
   268                     bufferIndex := bufferIndex + 1.
   269 		    idx2 := ((dstIndex + nByte) min:endIndex) - 1.
   269                     idx2 := ((dstIndex + nByte) min:endIndex) - 1.
   270 		    dataBytes from:dstIndex to:idx2 put:value.
   270                     dataBytes from:dstIndex to:idx2 put:value.
   271 		    dstIndex := dstIndex + nByte.
   271                     dstIndex := dstIndex + nByte.
   272 		].
   272                 ].
   273 	    ].
   273             ].
   274 	    rowIndex := endIndex.
   274             rowIndex := endIndex.
   275 	].
   275         ].
   276 
   276 
   277 	"/ have to compress - above code reads srcBytesPerRow
   277         "/ have to compress - above code reads srcBytesPerRow
   278 	"/ (to keep in sync with RLE); but we want width bytesPerRow
   278         "/ (to keep in sync with RLE); but we want width bytesPerRow
   279 	"/ Can compress in the data-area; leftover pixels are simply ignored
   279         "/ Can compress in the data-area; leftover pixels are simply ignored
   280 	"/ by other image processing code
   280         "/ by other image processing code
   281 	"/
   281         "/
   282 	srcBytesPerRow ~~ width ifTrue:[
   282         srcBytesPerRow ~~ width ifTrue:[
   283 	    dstIndex := width + 1.
   283             dstIndex := width + 1.
   284 	    srcIndex := srcBytesPerRow + 1.
   284             srcIndex := srcBytesPerRow + 1.
   285 	    2 to:h do:[:row |
   285             2 to:h do:[:row |
   286 		dataBytes replaceFrom:dstIndex to:dstIndex+width-1 with:dataBytes startingAt:srcIndex.
   286                 dataBytes replaceFrom:dstIndex to:dstIndex+width-1 with:dataBytes startingAt:srcIndex.
   287 		dstIndex := dstIndex + width.
   287                 dstIndex := dstIndex + width.
   288 		srcIndex := srcIndex + srcBytesPerRow
   288                 srcIndex := srcIndex + srcBytesPerRow
   289 	    ]
   289             ]
   290 	].
   290         ].
   291 	nBuffer := endIndex - bufferIndex.
   291         nBuffer := endIndex - bufferIndex.
   292     ] ifFalse:[
   292     ] ifFalse:[
   293 	"
   293         "
   294 	 uncompressed; actually untested ...
   294          uncompressed; actually untested ...
   295 	"
   295         "
   296 	data := dataBytes := ByteArray uninitializedNew:(height * width).
   296         data := dataBytes := ByteArray uninitializedNew:(height * width).
   297 	srcBytesPerRow ~~ width ifTrue:[
   297         srcBytesPerRow ~~ width ifTrue:[
   298 	    dstIndex := 1.
   298             dstIndex := 1.
   299 	    1 to:h do:[:row |
   299             1 to:h do:[:row |
   300 		inStream nextBytes:width into:data startingAt:dstIndex.
   300                 inStream nextBytes:width into:data startingAt:dstIndex.
   301 		dstIndex := dstIndex + width.
   301                 dstIndex := dstIndex + width.
   302 		inStream skip:(srcBytesPerRow - width).
   302                 inStream skip:(srcBytesPerRow - width).
   303 	    ]
   303             ]
   304 	] ifFalse:[
   304         ] ifFalse:[
   305 	    inStream nextBytes:(height * width) into:data.
   305             inStream nextBytes:(height * width) into:data.
   306 	].
   306         ].
   307 	nBuffer := 0.
   307         nBuffer := 0.
   308     ].
   308     ].
   309 
   309 
   310     (version == 5) ifTrue:[
   310     (version == 5) ifTrue:[
   311 	"read the 256-entry colormap"
   311         "read the 256-entry colormap"
   312 
   312 
   313 	nBuffer ~~ 0 ifTrue:[
   313         nBuffer ~~ 0 ifTrue:[
   314 	    byte := buffer at:bufferIndex.
   314             byte := buffer at:bufferIndex.
   315 	    bufferIndex := bufferIndex + 1. nBuffer := nBuffer - 1.
   315             bufferIndex := bufferIndex + 1. nBuffer := nBuffer - 1.
   316 	] ifFalse:[
   316         ] ifFalse:[
   317 	    byte := inStream next
   317             byte := inStream next
   318 	].
   318         ].
   319 
   319 
   320 	byte == 16r0C ifFalse:[
   320         byte == 16r0C ifFalse:[
   321 	   'PCXREADER: no valid 256-entry palette (got' errorPrint. 
   321            'PCXREADER: no valid 256-entry palette (got' errorPrint. 
   322 	   byte errorPrint. '; expected ' errorPrint. 16rC0 errorPrint. ')' errorPrintNL.
   322            byte errorPrint. '; expected ' errorPrint. 16rC0 errorPrint. ')' errorPrintNL.
   323 	].
   323         ].
   324 	rawMap := ByteArray uninitializedNew:(256*3).
   324         rawMap := ByteArray uninitializedNew:(256*3).
   325 	nBuffer ~~ 0 ifTrue:[
   325         nBuffer ~~ 0 ifTrue:[
   326 	    mapSize := buffer size - bufferIndex + 1.
   326             mapSize := buffer size - bufferIndex + 1.
   327 	    mapSize := mapSize min:(256*3).
   327             mapSize := mapSize min:(256*3).
   328 	    rawMap replaceFrom:1 to:mapSize with:buffer startingAt:bufferIndex.
   328             rawMap replaceFrom:1 to:mapSize with:buffer startingAt:bufferIndex.
   329 	    nBuffer < (256*3) ifTrue:[
   329             nBuffer < (256*3) ifTrue:[
   330 		inStream nextBytes:((256*3)-nBuffer) into:rawMap startingAt:nBuffer+1
   330                 inStream nextBytes:((256*3)-nBuffer) into:rawMap startingAt:nBuffer+1
   331 	    ]
   331             ]
   332 	] ifFalse:[
   332         ] ifFalse:[
   333 	    inStream nextBytes:(256*3) into:rawMap.
   333             inStream nextBytes:(256*3) into:rawMap.
   334 	].
   334         ].
   335 	rMap := Array new:256.
   335         rMap := Array new:256.
   336 	gMap := Array new:256.
   336         gMap := Array new:256.
   337 	bMap := Array new:256.
   337         bMap := Array new:256.
   338 	srcIndex := 1.
   338         srcIndex := 1.
   339 	1 to:256 do:[:i |
   339         1 to:256 do:[:i |
   340 	    rMap at:i put:(rawMap at:srcIndex).
   340             rMap at:i put:(rawMap at:srcIndex).
   341 	    srcIndex := srcIndex + 1.
   341             srcIndex := srcIndex + 1.
   342 	    gMap at:i put:(rawMap at:srcIndex).
   342             gMap at:i put:(rawMap at:srcIndex).
   343 	    srcIndex := srcIndex + 1.
   343             srcIndex := srcIndex + 1.
   344 	    bMap at:i put:(rawMap at:srcIndex).
   344             bMap at:i put:(rawMap at:srcIndex).
   345 	    srcIndex := srcIndex + 1.
   345             srcIndex := srcIndex + 1.
   346 	].
   346         ].
   347     ].
   347     ].
   348 
   348 
   349     photometric := #palette.
   349     photometric := #palette.
   350     samplesPerPixel := 1.
   350     samplesPerPixel := 1.
   351     bitsPerSample := #(8).
   351     bitsPerSample := #(8).
   355      |i f|
   355      |i f|
   356      i := Image fromFile:'somefile.pcx'.
   356      i := Image fromFile:'somefile.pcx'.
   357      i inspect.
   357      i inspect.
   358     "
   358     "
   359 
   359 
   360     "Modified: 16.4.1997 / 22:26:55 / cg"
   360     "Modified: 24.4.1997 / 19:38:52 / cg"
   361 ! !
   361 ! !
   362 
   362 
   363 !PCXReader class methodsFor:'documentation'!
   363 !PCXReader class methodsFor:'documentation'!
   364 
   364 
   365 version
   365 version
   366     ^ '$Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.20 1997-04-16 20:57:02 cg Exp $'
   366     ^ '$Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.21 1997-04-24 17:47:57 cg Exp $'
   367 ! !
   367 ! !
   368 PCXReader initialize!
   368 PCXReader initialize!