PNGReader.st
changeset 2683 8c7880d9cedb
parent 2509 866b56cabe7e
child 2695 6197b6af7f4f
--- a/PNGReader.st	Mon May 18 16:03:47 2009 +0200
+++ b/PNGReader.st	Mon May 18 16:43:34 2009 +0200
@@ -58,6 +58,8 @@
 "
     PNGReader fromFile:'/home/cg/AudioExplorer_51_files/use_small.png'
     PNGReader fromFile:'\\Exeptn\tmp\images\expeccoScreenshot4020_5526507.png'
+
+    PNGReader fromFile:'C:\Users\cg\Desktop\croquet\cobalt-base-current-build-20090210\cobalt-base-current-build-20090210\content\models\textures\checkerboard.png'
 "
 ! !
 
@@ -93,6 +95,7 @@
 
     "
      self isValidImageFile:'/home/cg/AudioExplorer_51_files/use_small.png'
+     self isValidImageFile:'C:\Users\cg\Desktop\croquet\cobalt-base-current-build-20090210\cobalt-base-current-build-20090210\content\models\textures\checkerboard.png'
     "
 
     "Modified: 21.6.1996 / 20:38:46 / cg"
@@ -100,62 +103,6 @@
 
 !PNGReader methodsFor:'private'!
 
-getChunk
-    |len type crc|
-
-    inStream atEnd ifTrue:[^ false].
-
-    len := inStream nextLongMSB:true.
-    type := String new:4.
-    (inStream nextBytes:4 into:type) ~~ 4 ifTrue:[^ false].
-
-"/ 'len: ' print. len print. ' type: ' print. type printCR.
-
-    type = 'IEND' ifTrue:[^ false].
-
-    (self processChunk:type len:len) ifFalse:[^ false].
-
-    crc := inStream nextLongMSB:true.  "/ ignored - for now
-    ^ true
-
-    "Created: 21.6.1996 / 21:09:36 / cg"
-    "Modified: 21.6.1996 / 21:20:26 / cg"
-!
-
-getIHDRChunk
-    |len type crc|
-
-    len := inStream nextLongMSB:true.
-
-    type := String new:4.
-    inStream nextBytes:4 into:type.
-
-    type = 'IHDR' ifFalse:[self halt. ^ false].
-    len == 13 ifFalse:[self halt. ^ false].
-
-    width := inStream nextLongMSB:true.        
-    height := inStream nextLongMSB:true.        
-
-    (width <= 0 or:[height <= 0]) ifTrue:[
-        'PNGReader: invalid dimension(s)' infoPrintCR.
-        ^ false.
-    ].
-    self reportDimension.
-
-    depth := inStream nextByte.
-    colorType := inStream nextByte.
-
-    compressionMethod := inStream nextByte.
-    filterMethod := inStream nextByte.
-    interlaceMode := inStream nextByte.
-
-    inStream skip:4.
-"/    crc := inStream nextLongMSB:true.
-    ^ true
-
-    "Modified: 21.6.1996 / 21:38:35 / cg"
-!
-
 processBKGDChunkLen:len
     inStream skip:len.
     ^ true
@@ -363,6 +310,62 @@
 
 !PNGReader methodsFor:'private-reading'!
 
+getChunk
+    |len type crc|
+
+    inStream atEnd ifTrue:[^ false].
+
+    len := inStream nextLongMSB:true.
+    type := String new:4.
+    (inStream nextBytes:4 into:type) ~~ 4 ifTrue:[^ false].
+
+    Transcript show:'len: '; show:len print; show:' type: '; showCR:type.
+
+    type = 'IEND' ifTrue:[^ false].
+
+    (self processChunk:type len:len) ifFalse:[^ false].
+
+    crc := inStream nextLongMSB:true.  "/ ignored - for now
+    ^ true
+
+    "Created: 21.6.1996 / 21:09:36 / cg"
+    "Modified: 21.6.1996 / 21:20:26 / cg"
+!
+
+getIHDRChunk
+    |len type crc|
+
+    len := inStream nextLongMSB:true.
+
+    type := String new:4.
+    inStream nextBytes:4 into:type.
+
+    type = 'IHDR' ifFalse:[self halt. ^ false].
+    len == 13 ifFalse:[self halt. ^ false].
+
+    width := inStream nextLongMSB:true.        
+    height := inStream nextLongMSB:true.        
+
+    (width <= 0 or:[height <= 0]) ifTrue:[
+        'PNGReader: invalid dimension(s)' infoPrintCR.
+        ^ false.
+    ].
+    self reportDimension.
+
+    depth := inStream nextByte.            "/ bits-per-channel
+    colorType := inStream nextByte.
+
+    compressionMethod := inStream nextByte.
+    filterMethod := inStream nextByte.
+    interlaceMode := inStream nextByte.
+
+    inStream skip:4.
+"/    crc := inStream nextLongMSB:true.
+    ^ true
+
+    "Modified: 21.6.1996 / 21:38:35 / cg"
+!
+
 setColorType:colorType
     colorType == 0 ifTrue:[
         photometric := #blackIs0.
@@ -436,10 +439,11 @@
     header := ByteArray new:8.
     aStream nextBytes:8 into:header.
 
-    header ~= #[137 80 78 71 13 10 26 10] ifTrue:[
+    header ~= (self pngHeader) ifTrue:[
         'PNGReader: not a png file.' infoPrintCR.
         ^ nil
     ].
+self halt.
     (self getIHDRChunk) ifFalse:[
         'PNGReader: required IHDR chunk missing.' infoPrintCR.
         ^ nil
@@ -479,6 +483,9 @@
                         blueVector:blueBytes.
     ].
 
+    photometric == #rgb ifTrue:[
+    ].
+
     self halt.
     "
      PNGReader fromFile:'/home/cg/libpng-0.89c/pngtest.png'
@@ -487,10 +494,82 @@
     "Modified: 21.6.1996 / 21:44:34 / cg"
 ! !
 
+!PNGReader methodsFor:'writing to file'!
+
+pngHeader
+    ^ #[137 80 78 71 13 10 26 10]
+!
+
+save:image onStream:aStream
+    "save image in PNG-file-format onto aStream"
+
+    outStream := aStream.
+    outStream binary.
+
+    byteOrder := #lsb.
+    width := image width.
+    height := image height.
+    photometric := image photometric.
+    samplesPerPixel := image samplesPerPixel.
+    bitsPerSample := image bitsPerSample.
+    colorMap := image colorMap.
+    data := image bits.
+
+    self writeFileHeader.
+    self writeHeaderChunk.
+    self hasColorPalette ifTrue: [self writePaletteChunk].
+    self writeImageChunk.
+    self writeEndChunk
+!
+
+writeColor:anInteger 
+    | color |
+
+    color := colorMap at: (anInteger bitAnd: 16rFFFFFF).
+    ^ outStream
+        nextPut: (color red / 100 * 255) rounded;
+        nextPut: (color green / 100 * 255) rounded;
+        nextPut: (color blue / 100 * 255) rounded
+!
+
+writeFileHeader
+    outStream nextPutAll:(self pngHeader)
+!
+
+writeHeaderChunk
+    self 
+        writeChunk: 'IHDR'
+        size: 13
+        with:[ 
+            self writeLong:width.
+            self writeLong:height.
+            outStream nextPut: 8.  "Assume that all colors are 24bit"
+            outStream nextPut: (colorMap notNil ifTrue: [3] ifFalse: [2]).    "Palette?"
+            outStream nextPut: 0.  "Compression"
+            outStream nextPut: 0.  "Filter method"
+            outStream nextPut: 0   "Non-interlaced"
+        ]
+!
+
+writePaletteChunk
+    self 
+        writeChunk: 'PLTE'
+        size: 3 * colorMap size
+        with:[
+            | table |
+
+            table := Array new: colorMap size.
+            colorMap keysAndValuesDo: [:key :value | table at: value + 1 put: key].
+            table do: [:each | 
+                self writeColor: each on: outStream
+            ]
+        ]
+! !
+
 !PNGReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.11 2008-06-30 09:36:58 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.12 2009-05-18 14:43:34 cg Exp $'
 ! !
 
 PNGReader initialize!