TIFFReader.st
changeset 744 363d53be9eb0
parent 743 43be299fc515
child 814 6240dfc2fd3b
--- a/TIFFReader.st	Mon Dec 01 19:01:48 1997 +0100
+++ b/TIFFReader.st	Mon Dec 01 19:51:00 1997 +0100
@@ -997,6 +997,52 @@
     'TIFFReader [warning]: unknown tag type ' errorPrint. tagType errorPrintCR
 
     "Modified: 11.4.1997 / 01:11:17 / cg"
+!
+
+decompressPackBits:nIn from:srcBytes to:dstBytes startingAt:dstOffset
+    |i b v dstOffs|
+
+    dstOffs := dstOffset.
+    i := 1.
+
+    [i <= nIn] whileTrue:[
+        b := srcBytes at:i.
+        i := i + 1.
+
+        b ~~ 16rFF ifTrue:[   "/ not a NOP
+            b <= 127 ifTrue:[
+                "/ 0..127 literal bytes
+                dstBytes replaceFrom:dstOffs to:dstOffs+b with:srcBytes startingAt:i.
+                i := i + b+1.
+                dstOffs := dstOffs + b+1.
+
+"/                1 to:(b+1) do:[:nLit|
+"/                    dstBytes at:dstOffs put:(srcBytes at:i).
+"/                    i := i + 1.
+"/                    dstOffs := dstOffs + 1
+"/                ]
+            ] ifFalse:[                  
+                "/ 128..254 a run        
+                b := b - 256.
+                b := b negated + 1.
+
+                v := srcBytes at:i.
+                i := i + 1.
+
+                dstBytes from:dstOffs to:dstOffs+b-1 put:v.
+                dstOffs := dstOffs+b.
+
+"/                1 to:b do:[:nRun |
+"/                    dstBytes at:dstOffs put:v.
+"/                    dstOffs := dstOffs + 1.
+"/                ]
+            ]
+        ]
+    ].
+    ^ dstOffs - dstOffset
+
+    "Created: / 1.12.1997 / 18:39:23 / cg"
+    "Modified: / 1.12.1997 / 18:49:58 / cg"
 ! !
 
 !TIFFReader methodsFor:'private - data reading'!
@@ -1210,13 +1256,84 @@
 !
 
 readPackbitsTiffImageData
-    "had no samples yet - however, packbits decompression
-     is rather trivial to add ..."
+    "this has only been tested with monochrome images"
+
+    |bytesPerRow bitsPerRow nPlanes 
+     stripNr       "{ Class: SmallInteger }"
+     offset        "{ Class: SmallInteger }"
+     row           "{ Class: SmallInteger }" 
+     nBytes        "{ Class: SmallInteger }"
+     nDecompressedBytes  "{ Class: SmallInteger }"
+     bitsPerPixel overAllBytes buffer|
+
+    nPlanes := samplesPerPixel.
+
+    "only support 1-sample/pixel,
+     with alpha - if separate planes,
+     or rgb - if non separate planes and no alpha"
 
-    'TIFFReader [warning]: packbits compression not implemented' errorPrintCR.
-    ^ nil.
+    (nPlanes == 2) ifTrue:[
+        (planarConfiguration ~~ 2) ifTrue:[
+            'TIFFReader [warning]: with alpha, only separate planes supported' errorPrintCR.
+            ^ nil
+        ].
+        'TIFFReader [info]: ignoring alpha plane' infoPrintCR.
+        nPlanes := 1.
+        bitsPerPixel := bitsPerSample at:1.
+        bitsPerSample := Array with:bitsPerPixel.
+        samplesPerPixel := 1.
+    ] ifFalse:[
+        (nPlanes == 3) ifTrue:[
+            (planarConfiguration ~~ 1) ifTrue:[
+                'TIFFReader [warning]: only non separate planes supported' errorPrintCR.
+                ^ nil
+            ].
+            bitsPerSample ~= #(8 8 8) ifTrue:[
+                'TIFFReader [warning]: only 8/8/8 rgb images supported' errorPrintCR.
+                ^ nil
+            ].
+            bitsPerPixel := 24
+        ] ifFalse:[
+            (nPlanes ~~ 1) ifTrue:[
+                'TIFFReader [warning]: format not supported' errorPrintCR.
+                ^ nil
+            ].
+            bitsPerPixel := bitsPerSample at:1.
+        ]
+    ].
 
-    "Modified: / 1.12.1997 / 17:49:03 / cg"
+    bitsPerRow := width * bitsPerPixel.
+    bytesPerRow := bitsPerRow // 8.
+    ((bitsPerRow \\ 8) ~~ 0) ifTrue:[
+        bytesPerRow := bytesPerRow + 1
+    ].
+
+    overAllBytes := bytesPerRow * height.
+    data := ByteArray uninitializedNew:overAllBytes.
+
+    offset := 1.
+    stripNr := 0.
+
+    buffer := nil.
+    row := 1.
+    [row <= height] whileTrue:[
+        stripNr := stripNr + 1.
+        nBytes := stripByteCounts at:stripNr.
+        inStream position:((stripOffsets at:stripNr) + 1).
+
+        nBytes > buffer size ifTrue:[
+            "/ realloc
+            buffer := ByteArray uninitializedNew:nBytes.
+        ].
+        inStream nextBytes:nBytes into:buffer.
+
+        nDecompressedBytes := self decompressPackBits:nBytes from:buffer to:data startingAt:offset.
+
+        offset := offset + nDecompressedBytes.
+        row := row + rowsPerStrip
+    ]
+
+    "Modified: / 1.12.1997 / 18:50:43 / cg"
 !
 
 readPixarFilmTiffImageData
@@ -2110,6 +2227,6 @@
 !TIFFReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/TIFFReader.st,v 1.57 1997-12-01 18:01:48 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/TIFFReader.st,v 1.58 1997-12-01 18:51:00 cg Exp $'
 ! !
 TIFFReader initialize!