--- a/PNGReader.st Fri Nov 15 12:26:54 2002 +0100
+++ b/PNGReader.st Fri Nov 15 22:13:43 2002 +0100
@@ -12,6 +12,8 @@
+"{ Package: 'stx:libview2' }"
+
ImageReader subclass:#PNGReader
instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode
redBytes greenBytes blueBytes'
@@ -105,8 +107,7 @@
(self processChunk:type len:len) ifFalse:[^ false].
- inStream skip:4.
-"/ crc := inStream nextLongMSB:true.
+ crc := inStream nextLongMSB:true. "/ ignored - for now
^ true
"Created: 21.6.1996 / 21:09:36 / cg"
@@ -163,6 +164,10 @@
type = 'zTXt' ifTrue:[^ self processZTXTChunkLen:len].
type = 'PLTE' ifTrue:[^ self processPLTEChunkLen:len].
+ type = 'pHYs' ifTrue:[^ self processPHYSChunkLen:len].
+ type = 'tRNS' ifTrue:[^ self processTRNSChunkLen:len].
+ type = 'IHDR' ifTrue:[^ self processIHDRChunkLen:len].
+
('PNGReader: unrecognized chunk: ' , type , ' ignored.') infoPrintCR.
inStream skip:len.
@@ -180,13 +185,77 @@
!
processIDATChunkLen:len
+ interlaceMode == 0 ifTrue: [
+ ^ self processNonInterlacedDATA:len
+ ].
+ ^ self processInterlacedDATA:len
+!
+
+processIHDRChunkLen:len
+ "header chunk - currently unhandled"
+
+ |width height bitsPerChannel interlaceMethod palette image bitsPerPixel bytesPerScanline rowSize|
+
+self halt.
+ width := inStream nextLongMSB:true. "/ 1..4
+ height := inStream nextLongMSB:true. "/ 5..8
+ bitsPerChannel := inStream nextByte. "/ 9
+ colorType := inStream nextByte. "/ 10
+ inStream nextByte. "/ 11
+ inStream nextByte. "/ 12
+ interlaceMethod := inStream nextByte. "/ 13
+
+ (#(2 4 6) includes: colorType) ifTrue:[
+ depth := 32.
+ palette := self class defaultPalette.
+ image := Image extent: width @ height depth: depth palette: palette
+ ].
+ (#(0 3) includes: colorType) ifTrue:[
+ depth := bitsPerChannel min: 8.
+ image := Image extent: width @ height
+ depth: depth
+ palette: (colorType = 0
+ ifTrue: [self grayColorsFor: depth]
+ ifFalse: [palette := self class defaultPalette])].
+ bitsPerPixel := (BPP at: colorType + 1) at: bitsPerChannel highBit.
+ bytesPerScanline := (width * bitsPerPixel + 7) // 8.
+ rowSize := image width * image depth + 31 >> 5
+!
+
+processInterlacedDATA:len
inStream skip:len.
^ true
+!
- "Created: 21.6.1996 / 21:15:35 / cg"
+processNonInterlacedDATA:len
+ | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
+
+ zlibReader := Net.ZLibReadStream on:inStream from: 1 to:len.
+ prevScanline := ByteArray new: bytesPerScanline.
+ thisScanline := ByteArray new: bytesPerScanline.
+ 0 to: height - 1 do:
+ [:index |
+ filter := (zlibReader next: 1) first.
+ filtersSeen add: filter.
+ (filter isNil or: [(filter between: 0 and: 4) not]) ifTrue: [^self].
+ thisScanline := zlibReader next: bytesPerScanline into: thisScanline startingAt: 1.
+ self filterScanline: filter count: bytesPerScanline.
+ self copyPixels: index.
+ temp := prevScanline.
+ prevScanline := thisScanline.
+ thisScanline := temp]
+!
+
+processPHYSChunkLen:len
+ "physical pixel chunk - currently unhandled"
+
+ 'PNGReader: unhandled chunk type: PHYS' infoPrintCR.
+ ^ false
!
processPLTEChunkLen:len
+ "read a color palette"
+
|n "{ Class: SmallInteger }"|
(len \\ 3) ~~ 0 ifTrue:[
@@ -250,7 +319,7 @@
inStream := aStream.
aStream binary.
- "GIF-files are always msb (network-world)"
+ "PNG-files are always msb (network-world)"
byteOrder := #msb.
header := ByteArray new:8.
@@ -277,49 +346,11 @@
'PNGReader: invalid interlaceMode' infoPrintCR.
^ nil.
].
-
- colorType == 0 ifTrue:[
- photometric := #blackIs0.
- samplesPerPixel := 1.
- bitsPerSample := Array with:depth.
- ] ifFalse:[ colorType == 2 ifTrue:[
- depth < 8 ifTrue:[
- 'PNGReader: invalid colorType/depth combination' infoPrintCR.
- ^ nil.
- ].
- photometric := #rgb.
- samplesPerPixel := 3.
- bitsPerSample := Array with:depth with:depth with:depth.
- ] ifFalse:[ colorType == 3 ifTrue:[
- depth == 16 ifTrue:[
- 'PNGReader: invalid colorType/depth combination' infoPrintCR.
- ^ nil.
- ].
- photometric := #palette.
- samplesPerPixel := 1.
- bitsPerSample := Array with:depth.
- ] ifFalse:[ colorType == 4 ifTrue:[
- depth < 8 ifTrue:[
- 'PNGReader: invalid colorType/depth combination' infoPrintCR.
- ^ nil.
- ].
- photometric := #blackIs0.
- samplesPerPixel := 2.
- bitsPerSample := Array with:depth with:depth.
- ] ifFalse:[ colorType == 6 ifTrue:[
- depth < 8 ifTrue:[
- 'PNGReader: invalid colorType/depth combination' infoPrintCR.
- ^ nil.
- ].
- photometric := #rgb.
- samplesPerPixel := 4.
- bitsPerSample := Array with:depth with:depth with:depth with:depth.
- ] ifFalse:[
- ('PNGReader: invalid colorType: ' , colorType printString , '.') infoPrintCR.
+ (self setColorType:colorType) ifFalse:[
^ nil
- ]]]]].
+ ].
- [self getChunk] whileTrue:[ ].
+ [self getChunk] whileTrue.
photometric == #palette ifTrue:[
redBytes isNil ifTrue:[
@@ -339,11 +370,68 @@
"
"Modified: 21.6.1996 / 21:44:34 / cg"
+!
+
+setColorType:colorType
+ colorType == 0 ifTrue:[
+ photometric := #blackIs0.
+ samplesPerPixel := 1.
+ bitsPerSample := Array with:depth.
+ ^ true.
+ ].
+
+ colorType == 2 ifTrue:[
+ depth < 8 ifTrue:[
+ 'PNGReader: invalid colorType/depth combination' infoPrintCR.
+ ^ false.
+ ].
+ photometric := #rgb.
+ samplesPerPixel := 3.
+ bitsPerSample := Array with:depth with:depth with:depth.
+ ^ true.
+ ].
+
+ colorType == 3 ifTrue:[
+ depth == 16 ifTrue:[
+ 'PNGReader: invalid colorType/depth combination' infoPrintCR.
+ ^ false.
+ ].
+ photometric := #palette.
+ samplesPerPixel := 1.
+ bitsPerSample := Array with:depth.
+ ^ true.
+ ].
+
+ colorType == 4 ifTrue:[
+ depth < 8 ifTrue:[
+ 'PNGReader: invalid colorType/depth combination' infoPrintCR.
+ ^ false.
+ ].
+ photometric := #blackIs0.
+ samplesPerPixel := 2.
+ bitsPerSample := Array with:depth with:depth.
+ ^ true.
+ ].
+
+ colorType == 6 ifTrue:[
+ depth < 8 ifTrue:[
+ 'PNGReader: invalid colorType/depth combination' infoPrintCR.
+ ^ false.
+ ].
+ photometric := #rgb.
+ samplesPerPixel := 4.
+ bitsPerSample := Array with:depth with:depth with:depth with:depth.
+ ^ true.
+ ].
+
+ ('PNGReader: invalid colorType: ' , colorType printString , '.') infoPrintCR.
+ ^ false
! !
!PNGReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.3 1997-06-30 20:56:07 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.4 2002-11-15 21:13:43 cg Exp $'
! !
+
PNGReader initialize!