TargaReader.st
changeset 4002 91e154c3580d
parent 4001 153c0234371a
child 4016 47c4ea8134ec
--- a/TargaReader.st	Tue Aug 29 23:23:24 2017 +0200
+++ b/TargaReader.st	Tue Aug 29 23:45:29 2017 +0200
@@ -62,6 +62,18 @@
         XBMReader XPMReader XWDReader
         
         http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
+
+    [examples:]
+        Smalltalk loadPackage:'stx:goodies/communication'.
+        Smalltalk loadPackage:'exept:libcrypt/ssl'.
+
+        |file|
+        file := (HTTPInterface getStreamFor:'https://samples.libav.org/image-samples/TGA/rgb32rle.tga') stream contents.
+        (TargaReader fromStream:file readStream) inspect.
+
+        |file|
+        file := (HTTPInterface getStreamFor:'https://samples.libav.org/image-samples/TGA/rgb16rle.tga') stream contents.
+        TargaReader fromStream:file readStream.
 "
 !
 
@@ -214,6 +226,62 @@
     'TargaReader [warning]: unsupported orientation: ' errorPrint. orientation errorPrintCR.
 !
 
+read16
+    "read a 16 bit/pixel targa-image"
+
+    |totalBytes remainingBytes dstIndex b1 b2|
+
+    totalBytes := width * height * 2.
+    data := ByteArray new:totalBytes.
+
+    dstIndex := 1.
+    remainingBytes := totalBytes.
+    [remainingBytes > 0] whileTrue:[
+        b1 := inStream nextByte.
+        b2 := inStream nextByte.
+        data at:dstIndex   put:b1.
+        data at:dstIndex+1 put:b2.
+        dstIndex := dstIndex + 2.
+        remainingBytes := remainingBytes - 2.
+    ].
+
+    "Created: / 29-08-2017 / 23:38:30 / cg"
+!
+
+read16RLE
+    "read a 16 bit/pixel rle encoded targa-image"
+
+    |total count dstIndex code n b1 b2|
+
+    data := ByteArray new:((total := width * height * 2)).
+    count := 0.
+    dstIndex := 1.
+    [count < total] whileTrue:[
+        code := inStream nextByte.
+        n := (code bitAnd:16r7F) + 1.
+        (code bitAnd:16r80) ~~ 0 ifTrue:[
+            b1 := inStream nextByte.
+            b2 := inStream nextByte.
+            n timesRepeat:[
+                data at:dstIndex put:b1.
+                data at:dstIndex+1 put:b2.
+                dstIndex := dstIndex + 2
+            ].
+        ] ifFalse:[
+            n timesRepeat:[
+                b1 := inStream nextByte.
+                b2 := inStream nextByte.
+                data at:dstIndex put:b1.
+                data at:dstIndex+1 put:b2.
+                dstIndex := dstIndex + 2
+            ]
+        ].
+        count := count + (n * 2).
+    ].
+
+    "Created: / 29-08-2017 / 23:39:19 / cg"
+!
+
 read24
     "read a 24 bit/pixel targa-image"
 
@@ -339,11 +407,11 @@
                 dstIndex := dstIndex + 4
             ]
         ].
-        count := count + (n * 3).
+        count := count + (n * 4).
     ].
 
     "Created: / 21-04-1997 / 20:43:54 / cg"
-    "Modified: / 29-08-2017 / 23:09:01 / cg"
+    "Modified: / 29-08-2017 / 23:35:48 / cg"
 !
 
 read8
@@ -420,7 +488,7 @@
     width := inStream nextShortMSB:false.
     height := inStream nextShortMSB:false.
     depth := inStream next.
-    (#(8 "16" 24 32) includes:depth) ifFalse:[
+    (#(8 15 16 24 32) includes:depth) ifFalse:[
         ^ self fileFormatError:'unsupported depth: %1' with:depth printString.
     ].
     depth == 32 ifTrue:[
@@ -526,6 +594,23 @@
         bytesPerPixel := 3.
     ].
     
+    ((depth == 15) or:[depth == 16]) ifTrue:[
+        imageType == 2 ifTrue:[
+            "/ rle ifTrue:[self halt:'oops - should not happen'].
+            self read16.
+        ] ifFalse:[
+            "/ rle ifFalse:[self halt:'oops - should not happen'].
+            self read16RLE.
+        ].
+
+        photometric := #rgb.
+        samplesPerPixel := 3.
+        bitsPerSample := #(5 5 5).
+
+        bytesPerRow := width*2.
+        bytesPerPixel := 2.
+    ].
+
     depth == 8 ifTrue:[
         (imageType == 1 or:[imageType == 3]) ifTrue:[
             "/ rle ifTrue:[self halt:'oops - should not happen'].
@@ -554,7 +639,7 @@
     "
 
     "Modified: / 13-10-1998 / 19:50:48 / ps"
-    "Modified: / 29-08-2017 / 23:10:23 / cg"
+    "Modified: / 29-08-2017 / 23:41:12 / cg"
 ! !
 
 !TargaReader class methodsFor:'documentation'!