ImageReader.st
changeset 8110 19a15da94872
parent 8107 154acb64bf45
child 8129 a84ca4eab4ae
--- a/ImageReader.st	Sat Aug 26 13:46:24 2017 +0200
+++ b/ImageReader.st	Sun Aug 27 19:59:56 2017 +0200
@@ -18,7 +18,8 @@
 		samplesPerPixel bitsPerSample colorMap mask maskPixel
 		dimensionCallBack dimensionHolder progressHolder imageSequence
 		metaData'
-	classVariableNames:'ReverseBits'
+	classVariableNames:'ReverseBits WhiteCountTable WhiteShiftTable BlackCountTable
+		LeftBits BlackShiftTable'
 	poolDictionaries:''
 	category:'Graphics-Images-Readers'
 !
@@ -1033,32 +1034,246 @@
 
 !ImageReader class methodsFor:'decompression support'!
 
+_decompressCCITT3From:src count:inCount into:dst startingAt:dstIndexIn 
+    |srcIndex dstIndex countTable shiftTable 
+     outCount outBitOffset bits nBitsLess13 bits13 cnt shift
+     nLeft t leftBits|
+    
+    WhiteCountTable isNil ifTrue:[
+        self initCCITTTables.
+    ].
+    countTable := WhiteCountTable.
+    shiftTable := WhiteShiftTable.
+    leftBits := #[ 0 16r80 16rC0 16rE0 16rF0 16rF8 16rFC 16rFE 16rFF ].
+
+    srcIndex := 1.
+    dstIndex := dstIndexIn.
+    
+    outCount := 0.
+    outBitOffset := 0.
+    bits := ((src at:srcIndex) bitShift:8) bitOr:(src at:srcIndex+1).
+    srcIndex := srcIndex + 2.
+    nBitsLess13 := 3.
+
+    [
+        bits13 := (bits rightShift: nBitsLess13) bitAnd: 16r1FFF.
+        cnt := countTable at:(bits13+1).
+        cnt < 0 ifTrue:[
+            ^ dstIndex
+        ].
+        shift := shiftTable at:(bits13+1).
+        outCount := outCount + cnt.
+        
+        countTable == BlackCountTable ifTrue:[
+            "/ toggle if it was a terminating code
+            cnt < 64 ifTrue:[
+                countTable := WhiteCountTable.
+                shiftTable := WhiteShiftTable
+            ].    
+            "/ draw cnt black bits 
+            cnt ~~ 0 ifTrue:[
+                outBitOffset > 0 ifTrue:[
+                    nLeft := 8 - outBitOffset.
+                    (cnt < nLeft) ifTrue:[ nLeft := cnt ].
+                    t := (leftBits at:(nLeft+1)) rightShift: outBitOffset.
+                    dst at:dstIndex put: ((dst at:dstIndex) bitOr:(t bitAnd:16rFF)).
+                    cnt := cnt - nLeft.
+                    outBitOffset := outBitOffset + nLeft.
+                    (outBitOffset >= 8) ifTrue:[
+                        dstIndex := dstIndex + 1.
+                        outBitOffset := outBitOffset - 8.
+                    ]
+                ].
+                [ cnt >= 8 ] whileTrue:[
+                    dst at:dstIndex put:16rFF.
+                    dstIndex := dstIndex + 1.
+                    cnt := cnt - 8.
+                ].
+                dst at:dstIndex put:((dst at:dstIndex) bitOr:(leftBits at:(cnt+1))).
+                outBitOffset := outBitOffset + cnt.
+            ]
+        ] ifFalse:[
+            "/ toggle if it was a terminating code
+            cnt < 64 ifTrue:[
+                countTable := BlackCountTable.
+                shiftTable := BlackShiftTable
+            ].    
+
+            "/ skip cnt bits
+            dstIndex := dstIndex + (cnt rightShift: 3).
+            outBitOffset := outBitOffset + (cnt bitAnd: 7).
+            (outBitOffset >= 8)  ifTrue:[
+                dstIndex := dstIndex + 1.
+                outBitOffset := outBitOffset - 8.
+            ]
+        ].
+        
+        nBitsLess13 := nBitsLess13 - shift.
+        
+        "/ fill bits from the input
+        [ nBitsLess13 < 0 ] whileTrue:[
+            srcIndex > inCount ifTrue:[^ 1].
+            
+            bits := (bits bitShift:8) bitOr:( src at:srcIndex ).
+            srcIndex := srcIndex + 1.
+            nBitsLess13 := nBitsLess13 + 8.
+        ].        
+    ] loop.
+
+    "Created: / 25-08-2017 / 13:34:29 / cg"
+    "Modified: / 26-08-2017 / 18:12:15 / cg"
+!
+
+_decompressCCITT3From:src count:inCount into:dst startingAt:dstIndexIn count:len
+    |srcIndex dstIndex countTable shiftTable 
+     outCount outBitOffset bits nBitsLess13 bits13 cnt shift
+     nLeft t leftBits|
+    
+    WhiteCountTable isNil ifTrue:[
+        self initCCITTTables.
+    ].
+    countTable := WhiteCountTable.
+    shiftTable := WhiteShiftTable.
+    leftBits := #[ 0 16r80 16rC0 16rE0 16rF0 16rF8 16rFC 16rFE 16rFF ].
+
+    srcIndex := 1.
+    dstIndex := dstIndexIn.
+    
+    outCount := 0.
+    outBitOffset := 0.
+    bits := ((src at:srcIndex) bitShift:8) bitOr:(src at:srcIndex+1).
+    srcIndex := srcIndex + 2.
+    nBitsLess13 := 3.
+
+    [
+        bits13 := (bits rightShift: nBitsLess13) bitAnd: 16r1FFF.
+        cnt := countTable at:(bits13+1).
+        cnt < 0 ifTrue:[
+            ^ 1
+        ].
+        shift := shiftTable at:(bits13+1).
+        outCount := outCount + cnt.
+        outCount > len ifTrue:[
+            self error:'out buffer overflow'.
+            ^ 0
+        ].
+        
+        countTable == BlackCountTable ifTrue:[
+            "/ toggle if it was a terminating code
+            cnt < 64 ifTrue:[
+                countTable := WhiteCountTable.
+                shiftTable := WhiteShiftTable
+            ].    
+            "/ draw cnt black bits 
+            cnt > 0 ifTrue:[
+                outBitOffset > 0 ifTrue:[
+                    nLeft := 8 - outBitOffset.
+                    (cnt < nLeft) ifTrue:[ nLeft := cnt ].
+                    t := (leftBits at:(nLeft+1)) rightShift: outBitOffset.
+                    dst at:dstIndex put: ((dst at:dstIndex) bitOr:(t bitAnd:16rFF)).
+                    cnt := cnt - nLeft.
+                    outBitOffset := outBitOffset + nLeft.
+                    (outBitOffset >= 8) ifTrue:[
+                        dstIndex := dstIndex + 1.
+                        outBitOffset := outBitOffset - 8.
+                    ]
+                ].
+                [ cnt >= 8 ] whileTrue:[
+                    dst at:dstIndex put:16rFF.
+                    dstIndex := dstIndex + 1.
+                    cnt := cnt - 8.
+                ].
+                dst at:dstIndex put:((dst at:dstIndex) bitOr:(leftBits at:(cnt+1))).
+                outBitOffset := outBitOffset + cnt.
+            ]
+        ] ifFalse:[
+            "/ toggle if it was a terminating code
+            cnt < 64 ifTrue:[
+                countTable := BlackCountTable.
+                shiftTable := BlackShiftTable
+            ].    
+
+            "/ skip cnt bits
+            dstIndex := dstIndex + (cnt rightShift: 3).
+            outBitOffset := outBitOffset + (cnt bitAnd: 7).
+            (outBitOffset >= 8)  ifTrue:[
+                dstIndex := dstIndex + 1.
+                outBitOffset := outBitOffset - 8.
+            ]
+        ].
+        
+        outCount >= len ifTrue:[
+            ^ 1
+        ].
+        nBitsLess13 := nBitsLess13 - shift.
+        
+        "/ fill bits from the input
+        [ nBitsLess13 < 0 ] whileTrue:[
+            bits := (bits bitShift:8) bitOr:( src at:srcIndex ).
+            srcIndex := srcIndex + 1.
+            nBitsLess13 := nBitsLess13 + 8.
+        ].        
+    ] loop.
+
+    "
+     |bytes outBytes|
+
+     bytes := '/Users/cg/DownloadsUnsaved/images/software/libtiffpic/g3test.g3'
+                asFilename binaryContentsOfEntireFile.
+     outBytes := ByteArray new:100000.
+     ImageReader 
+        _decompressCCITT3From:bytes
+        count:bytes size    
+        into:outBytes
+        startingAt:1.
+    "
+
+    "Created: / 26-08-2017 / 14:16:54 / cg"
+!
+
 decodeDelta:step in:data width:width height:height
-    "perform NeXT special predictor delta decoding inplace in data.
+    "perform TIFF predictor = 2 delta decoding inplace on data.
      Calls primitive c function for speed"
 
+    |idx values ov nv|
+    
     (step == 3) ifTrue:[
 %{
-	if (__isByteArray(data)
-	 && __bothSmallInteger(width, height)) {
-	    __decodeDelta3__(__ByteArrayInstPtr(data)->ba_element,
-			     __intVal(width), __intVal(height));
-	    RETURN ( self );
-	}
+        if (__isByteArray(data)
+         && __bothSmallInteger(width, height)) {
+            __decodeDelta3__(__ByteArrayInstPtr(data)->ba_element,
+                             __intVal(width), __intVal(height));
+            RETURN ( self );
+        }
 %}.
     ].
     (step == 4) ifTrue:[
 %{
-	if (__isByteArray(data)
-	 && __bothSmallInteger(width, height)) {
-	    __decodeDelta4__(__ByteArrayInstPtr(data)->ba_element,
-			     __intVal(width), __intVal(height));
-	    RETURN ( self );
-	}
+        if (__isByteArray(data)
+         && __bothSmallInteger(width, height)) {
+            __decodeDelta4__(__ByteArrayInstPtr(data)->ba_element,
+                             __intVal(width), __intVal(height));
+            RETURN ( self );
+        }
 %}.
     ].
 
-    self primitiveFailed
+    "/ slow fallback
+    idx := 1.
+    1 to:height do:[:y |
+        values := Array new:step withAll:0.
+        1 to:width do:[:x |
+            1 to:step do:[:chNr |
+                ov := (values at:chNr).
+                nv := (ov + (data at:idx)) bitAnd:16rFF.
+                values at:chNr put:nv.
+                data at:idx put:nv.
+                idx := idx + 1.
+            ].
+        ].
+    ].
+
+    "Modified: / 27-08-2017 / 16:52:37 / cg"
 !
 
 decompressCCITT3From:srcBytes into:dstBytes startingAt:offset count:count
@@ -1172,50 +1387,6 @@
     "Modified: / 1.12.1997 / 18:49:58 / cg"
 !
 
-decompressPackBitsFrom:srcBytes at:srcStart to:dstBytes at:dstStart count:outCount
-    "decompress until a number of output bytes has been decompressed.
-     Used by some mac image formats.
-     Return the number of processed input bytes.
-     This DOES TREAT FF as a noop."
-
-    |i b n v dstOffs nRemaining|
-
-    dstOffs := dstStart.
-    i := srcStart.
-    nRemaining := outCount.
-    [nRemaining > 0] whileTrue:[
-	b := srcBytes at:i.
-	i := i + 1.
-
-	"/ mhmh - other packbits decoders seem to treat FF as a noop
-	"/ here, we do.
-	b ~~ 16rFF ifTrue:[   "/ not a NOP
-	    b <= 127 ifTrue:[
-		"/ 0..127: 1..128 literal bytes
-		n := b + 1.
-		dstBytes replaceFrom:dstOffs to:dstOffs+b with:srcBytes startingAt:i.
-		nRemaining := nRemaining - n.
-		i := i + n.
-	    ] ifFalse:[
-		"/ 128..255 a run of length 3..130
-		n := b - 125.
-
-		v := srcBytes at:i.
-		i := i + 1.
-
-		dstBytes from:dstOffs to:dstOffs+n-1 put:v.
-		nRemaining := nRemaining - n.
-	    ].
-	    dstOffs := dstOffs + n.
-	] ifFalse:[
-	    self halt
-	].
-    ].
-    ^ i-srcStart
-
-    "Modified: / 22-02-2017 / 12:05:50 / cg"
-!
-
 decompressPackBitsV2From:srcBytes at:srcStart to:dstBytes at:dstStart count:outCount
     "decompress until a number of output bytes has been decompressed.
      Used by some mac image formats.
@@ -1319,6 +1490,328 @@
     "Modified: 23.4.1997 / 18:54:05 / cg"
 !
 
+decompressTiffPackBitsFrom:srcBytes to:dstBytes at:dstStart count:maxOutCount
+    "decompress all of srcBytes to dstBytes starting at dstStart.
+     Used by TIFF image formats.
+     This DOES TREAT FF as a noop."
+
+    |i b n v dstOffs dstLast end srcSize|
+
+    dstOffs := dstStart.
+    dstLast := (dstStart + maxOutCount - 1) min:(dstBytes size).
+
+    i := 1.
+    srcSize := srcBytes size.
+    
+    [i <= srcSize] whileTrue:[
+        b := srcBytes at:i.
+        i := i + 1.
+
+        "/ treat FF as a noop
+        b ~~ 128 ifTrue:[   "/ not a NOP
+            b <= 127 ifTrue:[
+                "/ 0..127: 1..128 literal bytes
+                n := b + 1.
+                end := (dstOffs+n-1) min:dstLast.
+                dstBytes replaceFrom:dstOffs to:end with:srcBytes startingAt:i.
+                i := i + n.
+            ] ifFalse:[
+                n := 1 - (b - 256).
+                v := srcBytes at:i.
+                i := i + 1.
+                end := (dstOffs+n-1) min:dstLast.
+                dstBytes from:dstOffs to:end put:v.
+            ].
+            dstOffs := dstOffs + n.
+            dstOffs > dstLast ifTrue:[
+                ^ dstLast-1-dstStart.
+            ].    
+        ].
+    ].
+    ^ dstOffs-dstStart
+
+    "Created: / 26-08-2017 / 17:50:13 / cg"
+    "Modified: / 27-08-2017 / 12:32:17 / cg"
+!
+
+initCCITTTables
+    |whiteDef blackDef index value| 
+
+    whiteDef := #(
+        ( 16r3500 8 ) "/ 0 
+        ( 16r1c00 6 )
+        ( 16r7000 4 )
+        ( 16r8000 4 )
+        ( 16rb000 4 )
+        ( 16rc000 4 )
+        ( 16re000 4 )
+        ( 16rf000 4 )
+        ( 16r9800 5 )
+        ( 16rA000 5 )
+        ( 16r3800 5 ) "/ 10 
+        ( 16r4000 5 )
+        ( 16r2000 6 )
+        ( 16r0c00 6 )
+        ( 16rd000 6 )
+        ( 16rd400 6 )
+        ( 16ra800 6 )
+        ( 16rac00 6 )
+        ( 16r4e00 7 )
+        ( 16r1800 7 )
+        ( 16r1000 7 ) "/ 20 
+        ( 16r2e00 7 )
+        ( 16r0600 7 )
+        ( 16r0800 7 )
+        ( 16r5000 7 )
+        ( 16r5600 7 )
+        ( 16r2600 7 )
+        ( 16r4800 7 )
+        ( 16r3000 7 )
+        ( 16r0200 8 )
+        ( 16r0300 8 ) "/ 30 
+        ( 16r1a00 8 )
+        ( 16r1b00 8 )
+        ( 16r1200 8 )
+        ( 16r1300 8 )
+        ( 16r1400 8 )
+        ( 16r1500 8 )
+        ( 16r1600 8 )
+        ( 16r1700 8 )
+        ( 16r2800 8 )
+        ( 16r2900 8 ) "/ 40 
+        ( 16r2a00 8 )
+        ( 16r2b00 8 )
+        ( 16r2c00 8 )
+        ( 16r2d00 8 )
+        ( 16r0400 8 )
+        ( 16r0500 8 )
+        ( 16r0a00 8 )
+        ( 16r0b00 8 )
+        ( 16r5200 8 )
+        ( 16r5300 8 ) "/ 50 
+        ( 16r5400 8 )
+        ( 16r5500 8 )
+        ( 16r2400 8 )
+        ( 16r2500 8 )
+        ( 16r5800 8 )
+        ( 16r5900 8 )
+        ( 16r5a00 8 )
+        ( 16r5b00 8 )
+        ( 16r4a00 8 )
+        ( 16r4b00 8 ) "/ 60 
+        ( 16r3200 8 )
+        ( 16r3300 8 )
+        ( 16r3400 8 )
+        "/ ---------------- 
+        ( 16rd800 5 ) "/ 64 
+        ( 16r9000 5 ) "/ 128 
+        ( 16r5c00 6 ) "/ 192 
+        ( 16r6e00 7 ) "/ 256 
+        ( 16r3600 8 ) "/ 320 
+        ( 16r3700 8 )
+        ( 16r6400 8 )
+        ( 16r6500 8 )
+        ( 16r6800 8 )
+        ( 16r6700 8 ) "/ 640 
+        ( 16r6600 9 ) "/ 704 
+        ( 16r6680 9 )
+        ( 16r6900 9 )
+        ( 16r6980 9 )
+        ( 16r6a00 9 )
+        ( 16r6a80 9 )
+        ( 16r6b00 9 )
+        ( 16r6b80 9 )
+        ( 16r6c00 9 )
+        ( 16r6c80 9 )
+        ( 16r6d00 9 )
+        ( 16r6d80 9 )
+        ( 16r4c00 9 )
+        ( 16r4c80 9 )
+        ( 16r4d00 9 ) "/ 1600 
+        ( 16r6000 6 ) "/ 1664 
+        ( 16r4d80 9 ) "/ 1728 
+        "/ -------------------------------- 
+        ( 16r0100 11 ) "/ 1792 
+        ( 16r0180 11 )
+        ( 16r01a0 11 ) "/ 1920 
+        ( 16r0120 12 ) "/ 1984 
+        ( 16r0130 12 )
+        ( 16r0140 12 )
+        ( 16r0150 12 )
+        ( 16r0160 12 )
+        ( 16r0170 12 )
+        ( 16r01c0 12 )
+        ( 16r01d0 12 )
+        ( 16r01e0 12 )
+        ( 16r01f0 12 ) "/ 2560 
+        "/ -------------------------------- 
+        ( 16r0010 12 ) "/ EOL 
+    ).
+
+    blackDef := #(
+        ( 16r0dc0 10 ) "/ 0 
+        ( 16r4000 3 )
+        ( 16rc000 2 )
+        ( 16r8000 2 )
+        ( 16r6000 3 )
+        ( 16r3000 4 )
+        ( 16r2000 4 )
+        ( 16r1800 5 )
+        ( 16r1400 6 )
+        ( 16r1000 6 )
+        ( 16r0800 7 ) "/ 10 
+        ( 16r0a00 7 )
+        ( 16r0e00 7 )
+        ( 16r0400 8 )
+        ( 16r0700 8 )
+        ( 16r0c00 9 )
+        ( 16r05c0 10 )
+        ( 16r0600 10 )
+        ( 16r0200 10 )
+        ( 16r0ce0 11 )
+        ( 16r0d00 11 ) "/ 20 
+        ( 16r0d80 11 )
+        ( 16r06e0 11 )
+        ( 16r0500 11 )
+        ( 16r02e0 11 )
+        ( 16r0300 11 )
+        ( 16r0ca0 12 )
+        ( 16r0cb0 12 )
+        ( 16r0cc0 12 )
+        ( 16r0cd0 12 )
+        ( 16r0680 12 ) "/ 30 
+        ( 16r0690 12 )
+        ( 16r06a0 12 )
+        ( 16r06b0 12 )
+        ( 16r0d20 12 )
+        ( 16r0d30 12 )
+        ( 16r0d40 12 )
+        ( 16r0d50 12 )
+        ( 16r0d60 12 )
+        ( 16r0d70 12 )
+        ( 16r06c0 12 ) "/ 40 
+        ( 16r06d0 12 )
+        ( 16r0da0 12 )
+        ( 16r0db0 12 )
+        ( 16r0540 12 )
+        ( 16r0550 12 )
+        ( 16r0560 12 )
+        ( 16r0570 12 )
+        ( 16r0640 12 )
+        ( 16r0650 12 )
+        ( 16r0520 12 ) "/ 50 
+        ( 16r0530 12 )
+        ( 16r0240 12 )
+        ( 16r0370 12 )
+        ( 16r0380 12 )
+        ( 16r0270 12 )
+        ( 16r0280 12 )
+        ( 16r0580 12 )
+        ( 16r0590 12 )
+        ( 16r02b0 12 )
+        ( 16r02c0 12 ) "/ 60 
+        ( 16r05a0 12 )
+        ( 16r0660 12 )
+        ( 16r0670 12 )
+        "/ ---------------- 
+        ( 16r03c0 10 ) "/ 64 
+        ( 16r0c80 12 ) "/ 128 
+        ( 16r0c90 12 ) "/ 192 
+        ( 16r05b0 12 ) "/ 256 
+        ( 16r0330 12 ) "/ 320 
+        ( 16r0340 12 )
+        ( 16r0350 12 ) "/ 448 
+        ( 16r0360 13 ) "/ 512 
+        ( 16r0368 13 )
+        ( 16r0250 13 ) "/ 640 
+        ( 16r0258 13 ) "/ 704 
+        ( 16r0260 13 )
+        ( 16r0268 13 )
+        ( 16r0390 13 )
+        ( 16r0398 13 )
+        ( 16r03a0 13 )
+        ( 16r03a8 13 )
+        ( 16r03b0 13 )
+        ( 16r03b8 13 )
+        ( 16r0290 13 )
+        ( 16r0298 13 )
+        ( 16r02a0 13 )
+        ( 16r02a8 13 )
+        ( 16r02d0 13 )
+        ( 16r02d8 13 ) "/ 1600 
+        ( 16r0320 13 ) "/ 1664 
+        ( 16r0328 13 ) "/ 1728 
+        "/ -------------------------------- 
+    ).
+    
+    WhiteCountTable := SignedWordArray new: 8192 withAll:-1.
+    BlackCountTable := SignedWordArray new: 8192 withAll:-1.   
+    WhiteShiftTable := SignedWordArray new: 8192.    
+    BlackShiftTable := SignedWordArray new: 8192. 
+
+    0 to:63 do:[:value |
+        |def nBits bits|
+
+        def := whiteDef at:(value+1).
+        nBits := def second.
+        bits := def first >> 3.
+        (1 << (13 - nBits)) to:1 by:-1 do:[:cnt |
+            WhiteCountTable at:bits+1 put:value.
+            WhiteShiftTable at:bits+1 put:nBits.
+            bits := bits + 1.
+        ].
+        def := blackDef at:(value+1).
+        nBits := def second.
+        bits := def first >> 3.
+        (1 << (13 - nBits)) to:1 by:-1 do:[:cnt |
+            BlackCountTable at:bits+1 put:value.
+            BlackShiftTable at:bits+1 put:nBits.
+            bits := bits + 1.
+        ].
+    ].
+    
+    index := value := 64.
+    [ value <= 1728 ] whileTrue:[
+        |nBits bits|
+        
+        nBits := (whiteDef at:(index+1)) second.
+        bits := (whiteDef at:(index+1)) first >> 3.
+        
+        (1 << (13 - nBits)) to:1 by:-1 do:[:cnt |
+            WhiteCountTable at:bits+1 put:value.
+            WhiteShiftTable at:bits+1 put:nBits.
+            bits := bits + 1.
+        ].
+        nBits := (blackDef at:(index+1)) second.
+        bits := (blackDef at:(index+1)) first >> 3.
+        (1 << (13 - nBits)) to:1 by:-1 do:[:cnt |
+            BlackCountTable at:bits+1 put:value.
+            BlackShiftTable at:bits+1 put:nBits.
+            bits := bits + 1.
+        ].
+        index := index + 1.
+        value := value + 64.
+    ].
+
+    [ value <= 2560 ] whileTrue:[
+        |nBits bits|
+
+        nBits := (whiteDef at:(index+1)) second.
+        bits := (whiteDef at:(index+1)) first >> 3.
+        (1 << (13 - nBits)) to:1 by:-1 do:[:cnt |
+            WhiteCountTable at:bits+1 put:value.
+            WhiteShiftTable at:bits+1 put:nBits.
+            BlackCountTable at:bits+1 put:value.
+            BlackShiftTable at:bits+1 put:nBits.
+            bits := bits + 1.
+        ].
+        index := index + 1.
+        value := value + 64.
+    ].
+
+    "Created: / 25-08-2017 / 13:25:46 / cg"
+!
+
 swap:nBytes bytesFromRGBA_to_BGRA_in:data startingAt:startIndex
     "swap bytes from RGBA into BGRA order.
      The argument is a pixel data buffer (byteArray)"
@@ -1971,13 +2464,12 @@
      If my file contained multiple images, return the first one."
 
     imageSequence notEmptyOrNil ifTrue:[
-	^ self images first.
+        ^ imageSequence first image
     ].
     ^ self makeImage.
 
     "Modified: / 15-01-1998 / 15:46:24 / stefan"
-    "Modified: / 17-02-2017 / 11:58:16 / cg"
-    "Modified (format): / 22-02-2017 / 18:07:45 / cg"
+    "Modified: / 26-08-2017 / 14:38:18 / cg"
 !
 
 imageFrames
@@ -1994,7 +2486,7 @@
 images
     "return a collection of all images as represented by myself.
      For compatibility with single-image formats, return a collection
-     containing my single image here if the reader does not support
+     containing my single image here if the file format does not support
      multiple images.
      Readers for formats with multiple images should leave the images
      in the imageSequence instVar as a side effect of reading."
@@ -2002,16 +2494,17 @@
     |img|
 
     imageSequence notNil ifTrue:[
-	^ (imageSequence collect:[:aFrame | aFrame image])
+        ^ (imageSequence collect:[:aFrame | aFrame image])
     ].
 
     img := self makeImage.
     img isNil ifTrue:[
-	^ img
+        ^ img
     ].
     ^ Array with:img
 
-    "Modified: / 1.4.1998 / 14:36:23 / cg"
+    "Modified: / 01-04-1998 / 14:36:23 / cg"
+    "Modified (comment): / 26-08-2017 / 14:38:48 / cg"
 !
 
 makeImage
@@ -2135,16 +2628,16 @@
 
     |errorString|
 
-    errorString := self class name , ' [info]: ' , aMessage.
+    errorString := self class name , ' [error]: ' , aMessage.
     inStream isFileStream ifTrue:[
-	errorString := errorString , ' [in ' , inStream pathName , ']'
+        errorString := errorString , Character cr, '[in "' , inStream pathName , '"]'
     ].
 
     Image badImageFormatQuerySignal raiseRequestErrorString:errorString.
     ^ nil
 
     "Created: / 03-02-1998 / 17:50:06 / cg"
-    "Modified (comment): / 22-02-2017 / 10:26:05 / cg"
+    "Modified: / 26-08-2017 / 10:37:04 / cg"
 ! !
 
 !ImageReader methodsFor:'i/o support'!
@@ -2382,3 +2875,4 @@
 version_CVS
     ^ '$Header$'
 ! !
+