*** empty log message ***
authorClaus Gittinger <cg@exept.de>
Mon, 30 Jun 2008 11:36:58 +0200
changeset 2509 866b56cabe7e
parent 2508 39db50fe8137
child 2510 491f20d60c08
*** empty log message ***
PNGReader.st
--- a/PNGReader.st	Sat Jun 28 14:24:40 2008 +0200
+++ b/PNGReader.st	Mon Jun 30 11:36:58 2008 +0200
@@ -9,14 +9,11 @@
  other person.  No title to or ownership of the software is
  hereby transferred.
 "
-
-
-
 "{ Package: 'stx:libview2' }"
 
 ImageReader subclass:#PNGReader
 	instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode
-		redBytes greenBytes blueBytes'
+		redBytes greenBytes blueBytes bytesPerScanline globalDataChunk'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Graphics-Images-Readers'
@@ -60,6 +57,7 @@
 examples
 "
     PNGReader fromFile:'/home/cg/AudioExplorer_51_files/use_small.png'
+    PNGReader fromFile:'\\Exeptn\tmp\images\expeccoScreenshot4020_5526507.png'
 "
 ! !
 
@@ -166,10 +164,24 @@
 !
 
 processChunk:type len:len
+    |chunk|
+
+    type = 'IDAT' ifTrue:[
+        "---since the compressed data can span multiple
+        chunks, stitch them all together first. later,
+        if memory is an issue, we need to figure out how
+        to do this on the fly---"
+        chunk := inStream next:len.
+        globalDataChunk := globalDataChunk isNil 
+                                ifTrue: [chunk] 
+                                ifFalse:[globalDataChunk,chunk].
+        ^ true
+"/        ^ self processIDATChunkLen:len
+    ].
+
     type = 'gAMA' ifTrue:[^ self processGAMAChunkLen:len].
     type = 'sBIT' ifTrue:[^ self processSBITChunkLen:len].
     type = 'tEXt' ifTrue:[^ self processTEXTChunkLen:len].
-    type = 'IDAT' ifTrue:[^ self processIDATChunkLen:len].
     type = 'tIME' ifTrue:[^ self processTIMEChunkLen:len].
     type = 'bKGD' ifTrue:[^ self processBKGDChunkLen:len].
     type = 'zTXt' ifTrue:[^ self processZTXTChunkLen:len].
@@ -195,6 +207,13 @@
     "Created: 21.6.1996 / 21:10:52 / cg"
 !
 
+processGlobalIDATChunk
+    interlaceMode == 0 ifTrue: [
+        ^ self processNonInterlacedGlobalDATA
+    ]. 
+    ^ self processInterlacedGlobalDATA
+!
+
 processIDATChunkLen:len
     interlaceMode == 0 ifTrue: [
         ^ self processNonInterlacedDATA:len
@@ -205,7 +224,7 @@
 processIHDRChunkLen:len
     "header chunk - currently unhandled"
 
-    |width height bitsPerChannel interlaceMethod palette image bitsPerPixel bytesPerScanline rowSize|
+    |bitsPerChannel interlaceMethod palette image bitsPerPixel rowSize|
 
 self halt.        
     width := inStream nextLongMSB:true.   "/ 1..4
@@ -241,7 +260,30 @@
 processNonInterlacedDATA:len
     | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
 
-    zlibReader := ZLibReadStream on:inStream from: 1 to:len.
+    zlibReader := ZipStream readOpenAsZipStreamOn:inStream. 
+    "/ zlibReader := ZLibReadStream on:inStream from: 1 to:len.
+
+    prevScanline := ByteArray new: self bytesPerRow.
+    thisScanline := ByteArray new: self bytesPerRow.
+    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]
+!
+
+processNonInterlacedGlobalDATA
+    | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
+
+    zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream). 
+    bytesPerScanline := self bytesPerRow.
+
     prevScanline := ByteArray new: bytesPerScanline.
     thisScanline := ByteArray new: bytesPerScanline.
     0 to: height - 1 do: 
@@ -421,6 +463,10 @@
         
     [self getChunk] whileTrue.
 
+    globalDataChunk notNil ifTrue:[
+        self processGlobalIDATChunk
+    ].
+
     photometric == #palette ifTrue:[
         redBytes isNil ifTrue:[
             'PNGReader: missing palette chunk.' infoPrintCR.
@@ -444,7 +490,7 @@
 !PNGReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.10 2003-11-19 15:38:33 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.11 2008-06-30 09:36:58 cg Exp $'
 ! !
 
 PNGReader initialize!