home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright (c) 1989
- ** Truevision, Inc.
- ** All Rights Reserverd
- **
- ** TGADUMP reads the contents of a Truevision TGA(tm) File and displays
- ** information about the file contents on the console device. This
- ** program does not display the image.
- */
-
- #include <malloc.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "tga.h"
-
- extern void main( int, char ** );
- extern void PrintColorTable( TGAFile * );
- extern void PrintExtendedTGA( TGAFile * );
- extern void PrintImageType( int );
- extern void PrintMonth( UINT16 );
- extern void PrintScanLineTable( TGAFile * );
- extern void PrintTGAInfo( TGAFile * );
- extern UINT8 ReadByte( FILE * );
- extern void ReadCharField( FILE *, char *, int );
- extern int ReadColorTable( FILE *, TGAFile * );
- extern int ReadExtendedTGA( FILE *, TGAFile * );
- extern int ReadScanLineTable( FILE *, TGAFile * );
- extern UINT16 ReadShort( FILE * );
- extern UINT32 ReadLong( FILE * );
-
-
- /*
- ** String data for performing month conversions
- */
- char *monthStr[] =
- {
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December"
- };
-
- /*
- ** String data for interpretting image orientation specification
- */
- char *orientStr[] =
- {
- "Bottom Left",
- "Bottom Right",
- "Top Left",
- "Top Right"
- };
-
- /*
- ** String data for interpretting interleave flag defined with VDA
- ** This field is now obsolete and should typically be set to zero.
- */
- char *interleaveStr[] =
- {
- " Two Way (Even-Odd) Interleave (e.g., IBM Graphics Card Adapter), Obsolete",
- " Four Way Interleave (e.g., AT&T 6300 High Resolution), Obsolete",
- };
-
- TGAFile f; /* control structure of image data */
- char *versionStr =
- "Truevision(R) TGA(tm) File Dump Utility Version 1.3 - January 2, 1990";
-
- void
- main( argc, argv )
- int argc;
- char **argv;
- {
- int fileFound;
- char *q;
- FILE *fp;
- long fsize;
- int xTGA; /* flags extended TGA file */
- UINT16 devDirEntries; /* number of entries in developer area */
- char fileName[80];
- struct stat statbuf;
-
- puts( versionStr );
- /*
- ** The program can be invoked without an argument, in which case
- ** the user will be prompted for the name of the image file to be
- ** examined, or the image file name can be provided as an argument
- ** to the command.
- **
- ** File names provided do not need to include the extension if
- ** the image file extension is one of the standard strings common
- ** to Truevision TGA image file names ( e.g., TGA, WIN, VST, VDA, ICB )
- */
- if ( argc == 1 )
- {
- printf( "Enter name of file to examine: " );
- gets( fileName );
- if ( strlen( fileName ) == 0 ) exit( 0 );
- }
- else
- {
- strcpy( fileName, argv[1] );
- }
- if ( fileName[0] == '-' )
- {
- puts( "Usage: tgadump [filename]" );
- exit( 0 );
- }
- /*
- ** See if we can find the file as specified or with one of the
- ** standard filename extensions...
- */
- fileFound = 0;
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- strcat( fileName, ".tga" );
- q = strchr( fileName, '.' );
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- strcpy( q, ".vst" );
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- strcpy( q, ".vda" );
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- strcpy( q, ".icb" );
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- strcpy( q, ".win" );
- if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
- else
- {
- *q = '\0';
- printf("Unable to open image file %s\n", fileName );
- }
- }
- }
- }
- }
- }
- if ( fileFound )
- {
- printf( "TGA File: %s\n", fileName );
- fp = fopen( fileName, "rb" );
- /*
- ** It would be nice to be able to read in the entire
- ** structure with one fread, but compiler dependent
- ** structure alignment precludes the simplistic approach.
- ** Instead, fill each field individually, and use routines
- ** that will allow code to execute on various hosts by
- ** recompilation with particular compiler flags.
- **
- ** Start by reading the fields associated with the original
- ** TGA format.
- */
- f.idLength = ReadByte( fp );
- f.mapType = ReadByte( fp );
- f.imageType = ReadByte( fp );
- f.mapOrigin = ReadShort( fp );
- f.mapLength = ReadShort( fp );
- f.mapWidth = ReadByte( fp );
- f.xOrigin = ReadShort( fp );
- f.yOrigin = ReadShort( fp );
- f.imageWidth = ReadShort( fp );
- f.imageHeight = ReadShort( fp );
- f.pixelDepth = ReadByte( fp );
- f.imageDesc = ReadByte( fp );
- memset( f.idString, 0, 256 );
- if ( f.idLength > 0 )
- {
- fread( f.idString, 1, f.idLength, fp );
- }
- PrintTGAInfo( &f );
- /*
- ** Now see if the file is the new (extended) TGA format.
- */
- xTGA = 0;
- if ( !fseek( fp, statbuf.st_size - 26, SEEK_SET ) )
- {
- f.extAreaOffset = ReadLong( fp );
- f.devDirOffset = ReadLong( fp );
- fgets( f.signature, 18, fp );
- if ( strcmp( f.signature, "TRUEVISION-XFILE." ) )
- {
- /*
- ** Reset offset values since this is not a new TGA file
- */
- f.extAreaOffset = 0L;
- f.devDirOffset = 0L;
- }
- else xTGA = 1;
- /*
- ** If the file is an original TGA file, and falls into
- ** one of the uncompressed image types, we can perform
- ** an additional file size check with very little effort.
- */
- if ( f.imageType > 0 && f.imageType < 4 && !xTGA )
- {
- /*
- ** Based on the header info, we should be able to calculate
- ** the file size.
- */
- fsize = 18; /* size of header in bytes */
- fsize += f.idLength;
- /* expect 8, 15, 16, 24, or 32 bits per map entry */
- fsize += ((f.mapWidth + 1) >> 3) * (long)f.mapLength;
- fsize += ((f.pixelDepth+1) >> 3) * (long)f.imageWidth *
- f.imageHeight;
- if ( fsize != statbuf.st_size )
- {
- puts( "Image File Format Error" );
- printf(" Uncompressed File Size Should Be %ld Bytes\n",
- fsize );
- }
- }
- if ( xTGA && f.extAreaOffset )
- {
- if ( ReadExtendedTGA( fp, &f ) >= 0 )
- {
- PrintExtendedTGA( &f );
- }
- }
- if ( xTGA && f.devDirOffset )
- {
- puts( "Developer Area Specified:" );
- if ( !fseek( fp, f.devDirOffset, SEEK_SET ) )
- {
- devDirEntries = ReadShort( fp );
- printf( "Developer Directory contains %d Entries\n",
- devDirEntries );
- }
- else
- {
- printf( "Error seeking to Developer Area, offset = 0x%08lx\n",
- f.devDirOffset );
- }
- }
- }
- else
- {
- puts( "Error seeking to end of file for possible extension data" );
- }
- if ( f.scanLineTable ) free( f.scanLineTable );
- if ( f.colorCorrectTable ) free( f.colorCorrectTable );
- fclose( fp );
- }
- }
-
-
- void
- PrintColorTable( sp )
- TGAFile *sp;
- {
- unsigned int n;
- UINT16 *p;
-
- puts( "Color Correction Table:" );
- p = sp->colorCorrectTable;
- for ( n = 0; n < 256; ++n )
- {
- printf( "Color Entry %3u: 0x%04x(%5u) A, ", n, *p, *p );
- ++p;
- printf( "0x%04x(%5u) R, ", *p, *p );
- ++p;
- printf( "0x%04x(%5u) G, ", *p, *p );
- ++p;
- printf( "0x%04x(%5u) B\n", *p, *p );
- ++p;
- }
- }
-
-
-
- void
- PrintExtendedTGA( sp )
- TGAFile *sp; /* TGA structure pointer */
- {
- register int strSize;
- char *blankChars = " \t";
-
- puts( "***** Extended TGA Fields *****" );
- printf( "Truevision TGA File Format Version = " );
- if ( sp->extSize == 495 ) puts( "2.0" );
- else printf( "UNKNOWN, extension size = %d\n", sp->extSize );
-
- /*
- ** Make sure the strings have length, and contain something
- ** other than blanks and tabs
- */
- strSize = strlen( sp->author );
- if ( strSize && strspn( sp->author, blankChars ) < strSize )
- {
- printf( "Author = %s\n", sp->author );
- }
- strSize = strlen( &sp->authorCom[0][0] );
- if ( strSize && strspn( &sp->authorCom[0][0], blankChars ) < strSize )
- {
- puts( "Author Comments:" );
- puts( &sp->authorCom[0][0] );
- strSize = strlen( &sp->authorCom[1][0] );
- if ( strSize && strspn( &sp->authorCom[1][0], blankChars ) < strSize )
- {
- puts( &sp->authorCom[1][0] );
- }
- strSize = strlen( &sp->authorCom[2][0] );
- if ( strSize && strspn( &sp->authorCom[2][0], blankChars ) < strSize )
- {
- puts( &sp->authorCom[2][0] );
- }
- strSize = strlen( &sp->authorCom[3][0] );
- if ( strSize && strspn( &sp->authorCom[3][0], blankChars ) < strSize )
- {
- puts( &sp->authorCom[3][0] );
- }
- puts( "[End of Author Comments]" );
- }
-
- if ( sp->month )
- {
- printf( "Date Image Saved = " );
- PrintMonth( sp->month );
- printf( " %02u, %4u at %02u:%02u:%02u\n", sp->day, sp->year,
- sp->hour, sp->minute, sp->second );
- }
-
- strSize = strlen( sp->jobID );
- if ( strSize && strspn( sp->jobID, blankChars ) < strSize )
- {
- printf( "Job Name/ID = %s\n", sp->jobID );
- }
-
- if ( sp->jobHours != 0 || sp->jobMinutes != 0 || sp->jobSeconds != 0 )
- {
- printf( "Job Elapsed Time = %02u:%02u:%02u\n",
- sp->jobHours, sp->jobMinutes, sp->jobSeconds );
- }
-
- strSize = strlen( sp->softID );
- if ( strSize && strspn( sp->softID, blankChars ) < strSize )
- {
- printf( "Software ID = %s\n", sp->softID );
- }
-
- if ( sp->versionNum != 0 || sp->versionLet != ' ' )
- {
- printf( "Software Version = %u.%u%c\n",
- sp->versionNum/100, sp->versionNum % 100, sp->versionLet );
- }
-
- printf( "Key Color: 0x%02lx(%ld) Alpha, 0x%02lx(%ld) Red, 0x%02lx(%ld) Green, 0x%02lx(%ld) Blue\n",
- sp->keyColor >> 24, sp->keyColor >> 24,
- (sp->keyColor >> 16) & 0xff, (sp->keyColor >> 16) & 0xff,
- (sp->keyColor >> 8) & 0xff, (sp->keyColor >> 8) & 0xff,
- sp->keyColor & 0xff, sp->keyColor & 0xff );
-
- if ( sp->pixNumerator != 0 && sp->pixDenominator != 0 )
- {
- printf( "Pixel Aspect Ratio = %f\n",
- (double)sp->pixNumerator / (double)sp->pixDenominator );
- }
-
- if ( sp->gammaDenominator != 0 )
- {
- printf( "Gamma Correction = %f\n",
- (double)sp->gammaNumerator / (double)sp->gammaDenominator );
- }
-
- if ( sp->colorCorrectOffset != 0L )
- {
- printf( "Color Correction Offset = 0x%08lx\n",
- sp->colorCorrectOffset);
- if ( sp->colorCorrectTable )
- {
- PrintColorTable( sp );
- }
- }
- if ( sp->stampOffset )
- {
- printf( "Postage Stamp Offset = 0x%08lx\n",
- sp->stampOffset );
- printf( "Postage Stamp Width, Height = %3u, %3u\n",
- sp->stampWidth, sp->stampHeight );
- }
- if ( sp->scanLineOffset != 0L )
- {
- printf( "Scan Line Offset = 0x%08lx\n",
- sp->scanLineOffset );
- if ( sp->scanLineTable )
- {
- PrintScanLineTable( sp );
- }
- }
-
- switch (sp->alphaAttribute )
- {
- case 0:
- if ( (sp->imageDesc & 0xf) == 0 ) puts( "No Alpha Data Present" );
- else puts( "Inconsistent Alpha Data Specification" );
- break;
- case 1:
- puts( "Alpha Data Undefined and Can Be Ignored" );
- break;
- case 2:
- puts( "Alpha Data Undefined but Should Be Retained" );
- break;
- case 3:
- puts( "Useful Alpha Data Present" );
- break;
- case 4:
- puts( "Pre-Multiplied Alpha Data Present" );
- break;
- default:
- puts( "Undefined Alpha Attribute Field" );
- break;
- }
- }
-
-
-
- void
- PrintImageType( Itype )
- register int Itype;
- {
- if ( Itype > 255 || Itype < 0 )
- {
- puts("Illegal/Undefined Image Type");
- return;
- }
-
- if ( Itype > 127 )
- {
- puts("Unknown Image Type - Application Specific");
- return;
- }
-
- switch (Itype)
- {
- case 0:
- puts("Unknown Image Type - No Image Data Present");
- break;
- case 1:
- puts("Uncompressed Color Mapped Image (e.g., VDA/D, TARGA M8)");
- break;
- case 2:
- puts("Uncompressed True Color Image (e.g., ICB, TARGA 16/24/32)");
- break;
- case 3:
- puts("Uncompressed Black & White Image (e.g., TARGA 8/M8)");
- break;
- case 9:
- puts("Run Length Encoded Color Mapped Image (e.g., VDA/D, TARGA M8)");
- break;
- case 10:
- puts("Run Length Encoded True Color Image (e.g., ICB, TARGA 16/24/32)");
- break;
- case 11:
- puts("Compressed Black & White Image (e.g., TARGA 8/M8)");
- break;
- case 32:
- case 34:
- puts("Compressed (Huffman/Delta/RLE) Color Mapped Image (e.g., VDA/D) - Obsolete");
- break;
- case 33:
- case 35:
- puts("Compressed (Huffman/Delta/RLE) Color Mapped Four Pass Image (e.g., VDA/D) - Obsolete");
- break;
- default:
- puts("Unknown Image Type");
- break;
- }
- }
-
-
- void
- PrintMonth( month )
- UINT16 month;
- {
- if ( month > 0 && month < 13 ) printf( monthStr[month - 1] );
- else printf( "Month Error" );
- }
-
-
- void
- PrintScanLineTable( sp )
- TGAFile *sp;
- {
- UINT16 n;
- UINT32 *p;
-
- puts( "Scan Line Table:" );
- p = sp->scanLineTable;
- for ( n = 0; n < sp->imageHeight; ++n )
- {
- printf( "Scan Line %6u, Offset 0x%08lx(%8d)\n", n, *p, *p );
- ++p;
- }
- }
-
-
-
- void
- PrintTGAInfo( sp )
- TGAFile *sp; /* TGA structure pointer */
- {
- int i;
-
- printf("ID Field Length = %3d\n", sp->idLength);
-
- printf("Color Map Type = %3d (Color Map Data is ", sp->mapType);
- if (sp->mapType) puts("Present)");
- else puts("Absent)");
-
- printf("Image Type = %3d\n ", sp->imageType);
- PrintImageType( sp->imageType );
-
- printf("Color Map Origin = 0x%04x (%5d)",
- sp->mapOrigin, sp->mapOrigin);
- puts( " (First Index To Be Loaded)" );
- printf("Color Map Length = 0x%04x (%5d)\n",
- sp->mapLength,sp->mapLength);
- printf("Color Map Entry Size = %6d\n", sp->mapWidth);
-
- printf("Image X-Origin, Y-Origin = %05d, %05d\n",
- sp->xOrigin, sp->yOrigin);
- printf("Image Width, Height = %05d, %05d\n",
- sp->imageWidth, sp->imageHeight);
-
- printf("Image Pixel Depth = 0x%04x (%5d)\n",
- sp->pixelDepth, sp->pixelDepth);
- printf("Image Descriptor = 0x%04x\n", sp->imageDesc);
- printf(" %d Attribute Bits Per Pixel\n", sp->imageDesc & 0xf );
- printf(" First Pixel Destination is ");
-
- i = (sp->imageDesc & 0x30) >> 4;
- puts( orientStr[i] );
-
- i = (sp->imageDesc & 0xc0) >> 6;
- if ( i > 0 && i < 3 ) puts( interleaveStr[i - 1] );
-
- if ( sp->idLength )
- {
- printf( "Image ID:\n " );
- puts( f.idString );
- }
- }
-
-
- UINT8
- ReadByte( fp )
- FILE *fp;
- {
- UINT8 value;
-
- #if MSDOS
- fread( &value, 1, 1, fp );
- #else
- #endif
- return( value );
- }
-
-
- void
- ReadCharField( fp, p, n )
- FILE *fp;
- char *p;
- int n;
- {
- while ( n )
- {
- *p++ = (char)fgetc( fp ); /* no error check, no char conversion */
- --n;
- }
- }
-
-
- int
- ReadColorTable( fp, sp )
- FILE *fp;
- TGAFile *sp;
- {
- UINT16 *p;
- UINT16 n;
-
- if ( !fseek( fp, sp->colorCorrectOffset, SEEK_SET ) )
- {
- if ( sp->colorCorrectTable = malloc( 1024 * sizeof( UINT16 ) ) )
- {
- p = sp->colorCorrectTable;
- for ( n = 0; n < 1024; ++n )
- {
- *p++ = ReadShort( fp );
- }
- }
- else
- {
- puts( "Unable to allocate Color Correction Table" );
- return( -1 );
- }
- }
- else
- {
- printf( "Error seeking to Color Correction Table, offset = 0x%08lx\n",
- sp->colorCorrectOffset );
- return( -1 );
- }
- return( 0 );
- }
-
-
- int
- ReadExtendedTGA( fp, sp )
- FILE *fp;
- TGAFile *sp;
- {
- if ( !fseek( fp, sp->extAreaOffset, SEEK_SET ) )
- {
- sp->extSize = ReadShort( fp );
- memset( sp->author, 0, 41 );
- ReadCharField( fp, sp->author, 41 );
- memset( &sp->authorCom[0][0], 0, 81 );
- ReadCharField( fp, &sp->authorCom[0][0], 81 );
- memset( &sp->authorCom[1][0], 0, 81 );
- ReadCharField( fp, &sp->authorCom[1][0], 81 );
- memset( &sp->authorCom[2][0], 0, 81 );
- ReadCharField( fp, &sp->authorCom[2][0], 81 );
- memset( &sp->authorCom[3][0], 0, 81 );
- ReadCharField( fp, &sp->authorCom[3][0], 81 );
-
- sp->month = ReadShort( fp );
- sp->day = ReadShort( fp );
- sp->year = ReadShort( fp );
- sp->hour = ReadShort( fp );
- sp->minute = ReadShort( fp );
- sp->second = ReadShort( fp );
-
- memset( sp->jobID, 0, 41 );
- ReadCharField( fp, sp->jobID, 41 );
- sp->jobHours = ReadShort( fp );
- sp->jobMinutes = ReadShort( fp );
- sp->jobSeconds = ReadShort( fp );
-
- memset( sp->softID, 0, 41 );
- ReadCharField( fp, sp->softID, 41 );
- sp->versionNum = ReadShort( fp );
- sp->versionLet = ReadByte( fp );
-
- sp->keyColor = ReadLong( fp );
- sp->pixNumerator = ReadShort( fp );
- sp->pixDenominator = ReadShort( fp );
-
- sp->gammaNumerator = ReadShort( fp );
- sp->gammaDenominator = ReadShort( fp );
-
- sp->colorCorrectOffset = ReadLong( fp );
- sp->stampOffset = ReadLong( fp );
- sp->scanLineOffset = ReadLong( fp );
-
- sp->alphaAttribute = ReadByte( fp );
-
- sp->colorCorrectTable = (UINT16 *)0;
- if ( sp->colorCorrectOffset )
- {
- ReadColorTable( fp, sp );
- }
-
- sp->postStamp = (void *)0;
- if ( sp->stampOffset )
- {
- if ( !fseek( fp, sp->stampOffset, SEEK_SET ) )
- {
- sp->stampWidth = ReadByte( fp );
- sp->stampHeight = ReadByte( fp );
- }
- else
- {
- printf( "Error seeking to Postage Stamp, offset = 0x%08lx\n",
- sp->stampOffset );
- }
- }
-
- sp->scanLineTable = (UINT32 *)0;
- if ( sp->scanLineOffset )
- {
- ReadScanLineTable( fp, sp );
- }
- }
- else
- {
- printf( "Error seeking to Extended TGA Area, offset = 0x%08lx\n",
- sp->extAreaOffset );
- return( -1 );
- }
- return( 0 );
- }
-
-
- UINT32
- ReadLong( fp )
- FILE *fp;
- {
- UINT32 value;
-
- #if MSDOS
- fread( &value, 1, 4, fp );
- #else
- #endif
- return( value );
- }
-
-
- int
- ReadScanLineTable( fp, sp )
- FILE *fp;
- TGAFile *sp;
- {
- UINT32 *p;
- UINT16 n;
-
- if ( !fseek( fp, sp->scanLineOffset, SEEK_SET ) )
- {
- if ( sp->scanLineTable = malloc( sp->imageHeight << 2 ) )
- {
- p = sp->scanLineTable;
- for ( n = 0; n < sp->imageHeight; ++n )
- {
- *p++ = ReadShort( fp );
- }
- }
- else
- {
- puts( "Unable to allocate Scan Line Table" );
- return( -1 );
- }
- }
- else
- {
- printf( "Error seeking to Scan Line Table, offset = 0x%08lx\n",
- sp->scanLineOffset );
- return( -1 );
- }
- return( 0 );
- }
-
-
- UINT16
- ReadShort( fp )
- FILE *fp;
- {
- UINT16 value;
-
- #if MSDOS
- fread( &value, 1, 2, fp );
- #else
- #endif
- return( value );
- }
-