TargaReader.st
author Claus Gittinger <cg@exept.de>
Sat, 01 Feb 1997 15:07:04 +0100
changeset 398 aef700d15416
parent 299 23d89531904f
child 551 7e0fb2e4f214
permissions -rw-r--r--
new suffix-table

"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

ImageReader subclass:#TargaReader
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Graphics-Images-Support'
!

!TargaReader class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    this class provides methods for loading targa-file (tga) images.
    Limitations: 
        not fully tested (I only had a few targe files to check things)
        only supports 24 bits/pixel uncompressed format
        Image saving not supported

    I had two tga files to test this code with - it may not work with
    other targa files (it certainly does not work with RLE-encoded or
    1/8 bit images).

    Suggestions: adapt & use the pbmplus library here.

    [See also:]
        Image Form Icon
        BlitImageReader FaceReader GIFReader JPEGReader PBMReader PCXReader 
        ST80FormReader SunRasterReader TIFFReader WindowsIconReader 
        XBMReader XPMReader XWDReader
"
! !

!TargaReader class methodsFor:'initialization'!

initialize
    "tell Image-class, that a new fileReader is present
     for the '.tga' extension."

    Image addReader:self suffix:'tga'.

    "Modified: 1.2.1997 / 15:03:37 / cg"
! !

!TargaReader class methodsFor:'testing'!

isValidImageFile:aFileName
    "return true, if aFileName contains a targa-file image"

    |aStream w h depth flags|

    aStream := self streamReadingFile:aFileName.
    aStream isNil ifTrue:[^ false].
    aStream binary.
    aStream skip:12.   "/ skip 12 bytes

    w := aStream nextShortMSB:false.
    h := aStream nextShortMSB:false.

    depth := aStream next.
    flags := aStream next.

    (#("8" 24) includes:depth) ifFalse:[
	aStream close. ^ false
    ].
    flags ~~ 16r20 ifTrue:[
	aStream close. ^ false
    ].

    aStream close. 
    ^ true

    "
     TargaReader isValidImageFile:'bitmaps/test.tga'    
     TargaReader isValidImageFile:'bitmaps/garfield.gif'  
    " 
! !

!TargaReader methodsFor:'reading from file'!

fromStream:aStream
    "read a targa-image from aFileName. return the receiver (with all
     relevant instance variables set for the image) or nil on error"

    |depth flags nBytes ok lenID hasColorMap imageType 
     cmapOffset cmapLength cmapEntrySize xOrg yOrg
     t
     dSize "{ Class: SmallInteger }" |

    inStream := aStream.
    aStream binary.

    lenID := aStream next.
    hasColorMap := aStream next.
    imageType := aStream next.
    cmapOffset := aStream nextShortMSB:false.
    cmapLength := aStream nextShortMSB:false.
    cmapEntrySize := aStream next.
    xOrg := aStream nextShortMSB:false.
    yOrg := aStream nextShortMSB:false.

    width := aStream nextShortMSB:false.
    height := aStream nextShortMSB:false.
    depth := aStream next.
    depth ~~ 24 ifTrue:[
        'TARGA: unsupported depth' errorPrintNL.
        ^ nil
    ].

    "/ flags:
    "/    0000 xxxx  attribute-bits-per-pixel
    "/    00xx 0000  origin (0 -> lower-left / 1 -> l-r / 2 -> u-l / 3 -> u-r)
    "/    xx00 0000  interleave (0 -> none / 1 -> odd/even / 2 ->4-fould / 3 reserved)
    "/
    flags := aStream next.
    flags ~~ 16r20 ifTrue:[
        ^ false
    ].

    lenID ~~ 0 ifTrue:[
        aStream skip:lenID
    ].

    data := ByteArray new:(width * height * (depth / 8)).
    aStream nextBytes:(data size) into:data.


    "
     mhmh - pixel-byte order is blue-green-red
     swap blue & red bytes
    "
    nBytes := data size.
    ok := false.

%{  /* OPTIONAL */
    if (__isByteArray(_INST(data))) {
        int __lastIndex = __intVal(nBytes) - 2;
        unsigned char *__cp = __ByteArrayInstPtr(_INST(data))->ba_element;
        int __i;
        unsigned char __t;

        for (__i=0; __i<__lastIndex; __i+=3, __cp+=3) {
            __t = __cp[0];
            __cp[0] = __cp[2];
            __cp[2] = __t;
        }
        ok = true;
    }
%}.
    ok ifFalse:[
        dSize := data size.
        1 to:(dSize - 2) by:3 do:[:i |
            t := data at:i.
            data at:i put:(data at:i+2).
            data at:i+2 put:t
        ]
    ].

    photometric := #rgb.
    samplesPerPixel := 3.
    bitsPerSample := #(8 8 8).

    "
     TargaReader fromFile:'bitmaps/test.tga' 
    " 
! !

!TargaReader class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview2/TargaReader.st,v 1.10 1997-02-01 14:05:35 cg Exp $'
! !
TargaReader initialize!