home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / TGAUTL.ZIP / TSTAMP.C < prev    next >
C/C++ Source or Header  |  1990-03-26  |  10KB  |  419 lines

  1. /*
  2. ** Copyright (c) 1989, 1990
  3. ** Truevision, Inc.
  4. ** All Rights Reserverd
  5. **
  6. ** TSTAMP displays postage stamp data from a Truevision(R) TGA(tm) file
  7. ** on a TARGA(R) using TARGA Tools routines.
  8. */
  9.  
  10. #include <malloc.h>
  11. #include <math.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <tardev.h>
  18. #include "tga.h"
  19.  
  20. extern void        main( int, char ** );
  21. extern void        DisplayPostageStamp( FILE *, TGAFile * );
  22. extern UINT8    ReadByte( FILE * );
  23. extern void        ReadCharField( FILE *, char *, int );
  24. extern int        ReadExtendedTGA( FILE *, TGAFile * );
  25. extern UINT16    ReadShort( FILE * );
  26. extern UINT32    ReadLong( FILE * );
  27.  
  28.  
  29. TGAFile        f;                /* control structure of image data */
  30.  
  31. char        *versionStr =
  32. "Truevision(R) TARGA(R) Postage Stamp Viewer Version 2.0 - March 24, 1990";
  33.  
  34. char        copyBuf[1024];
  35.  
  36. void
  37. main( argc, argv )
  38. int argc;
  39. char **argv;
  40. {
  41.     int            fileFound;
  42.     int            zoomFact;
  43.     int            intTmp;
  44.     char        *q;
  45.     FILE        *fp;
  46.     char        fileName[80];
  47.     struct stat    statbuf;
  48.  
  49.     puts( versionStr );
  50.     /*
  51.     ** The program can be invoked without an argument, in which case
  52.     ** the user will be prompted for the name of the image file to be
  53.     ** examined, or the image file name can be provided as an argument
  54.     ** to the command.
  55.     **
  56.     ** File names provided do not need to include the extension if
  57.     ** the image file extension is one of the standard strings common
  58.     ** to Truevision TGA image file names ( e.g., TGA, WIN, VST, VDA, ICB )
  59.     */
  60.     if ( GraphInit(-1) == -1 )
  61.     {
  62.         puts( "TStamp: Unable to find or initialize TARGA" );
  63.         GraphEnd();
  64.         exit( 0 );
  65.     }
  66.     zoomFact = 1;
  67.     if ( argc == 1 )
  68.     {
  69.         printf( "Enter name of file to examine: " );
  70.         gets( fileName );
  71.         if ( strlen( fileName ) == 0 )
  72.         {
  73.             GraphEnd();
  74.             exit( 0 );
  75.         }
  76.     }
  77.     else
  78.     {
  79.         strcpy( fileName, argv[1] );
  80.         if ( argc > 2 )
  81.         {
  82.             intTmp = atoi( argv[2] );
  83.             if ( intTmp > 0 )
  84.                 zoomFact = intTmp;
  85.         }
  86.     }
  87.     /*
  88.     ** See if we can find the file as specified or with one of the
  89.     ** standard filename extensions...
  90.     */
  91.     fileFound = 0;
  92.     if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  93.     else
  94.     {
  95.         strcat( fileName, ".tga" );
  96.         q = strchr( fileName, '.' );
  97.         if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  98.         else
  99.         {
  100.             strcpy( q, ".vst" );
  101.             if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  102.             else
  103.             {
  104.                 strcpy( q, ".vda" );
  105.                 if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  106.                 else
  107.                 {
  108.                     strcpy( q, ".icb" );
  109.                     if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  110.                     else
  111.                     {
  112.                         strcpy( q, ".win" );
  113.                         if ( stat( fileName, &statbuf ) == 0 ) fileFound = 1;
  114.                         else
  115.                         {
  116.                             *q = '\0';
  117.                             printf("Unable to open image file %s\n", fileName );
  118.                         }
  119.                     }
  120.                 }
  121.             }
  122.         }
  123.     }
  124.     if ( fileFound )
  125.     {
  126.         printf( "Image File: %s\n", fileName );
  127.         fp = fopen( fileName, "rb" );
  128.         /*
  129.         ** It would be nice to be able to read in the entire
  130.         ** structure with one fread, but compiler dependent
  131.         ** structure alignment precludes the simplistic approach.
  132.         ** Instead, fill each field individually, and use routines
  133.         ** that will allow code to execute on various hosts by
  134.         ** recompilation with particular compiler flags.
  135.         **
  136.         ** Start by reading the fields associated with the original
  137.         ** TGA format.
  138.         */
  139.         f.idLength = ReadByte( fp );
  140.         f.mapType = ReadByte( fp );
  141.         f.imageType = ReadByte( fp );
  142.         f.mapOrigin = ReadShort( fp );
  143.         f.mapLength = ReadShort( fp );
  144.         f.mapWidth = ReadByte( fp );
  145.         f.xOrigin = ReadShort( fp );
  146.         f.yOrigin = ReadShort( fp );
  147.         f.imageWidth = ReadShort( fp );
  148.         f.imageHeight = ReadShort( fp );
  149.         f.pixelDepth = ReadByte( fp );
  150.         f.imageDesc = ReadByte( fp );
  151.         memset( f.idString, 0, 256 );
  152.         if ( f.idLength > 0 )
  153.         {
  154.             fread( f.idString, 1, f.idLength, fp );
  155.         }
  156.         /*
  157.         ** Now see if the file is the new (extended) TGA format.
  158.         */
  159.         if ( !fseek( fp, statbuf.st_size - 26, SEEK_SET ) )
  160.         {
  161.             f.extAreaOffset = ReadLong( fp );
  162.             f.devDirOffset = ReadLong( fp );
  163.             fgets( f.signature, 18, fp );
  164.             if ( strcmp( f.signature, "TRUEVISION-XFILE." ) )
  165.             {
  166.                 /*
  167.                 ** Reset offset values since this is not a new TGA file
  168.                 */
  169.                 puts( "PostIt: File is not in extended TGA format." );
  170.                 GraphEnd();
  171.                 exit( 0 );
  172.             }
  173.             if ( f.extAreaOffset )
  174.             {
  175.                 if ( ReadExtendedTGA( fp, &f ) >= 0 )
  176.                 {
  177.                     if ( f.stampOffset )
  178.                     {
  179.                         DisplayPostageStamp( fp, &f );
  180.                         if ( argc > 2 )
  181.                         {
  182.                             SetZoom( zoomFact, 0, 0 );
  183.                         }
  184.                     }
  185.                     else
  186.                     {
  187.                         puts( "TStamp: File does not contain postage stamp data." );
  188.                     }
  189.                 }
  190.             }
  191.             else
  192.             {
  193.                 puts( "TStamp: File does not contain extension area." );
  194.             }
  195.         }
  196.         else
  197.         {
  198.             puts( "Error seeking to end of file for possible extension data" );
  199.         }
  200.         fclose( fp );
  201.         GraphEnd();
  202.         exit( 0 );
  203.     }
  204. }
  205.  
  206.  
  207.  
  208. void
  209. DisplayPostageStamp( fp, sp )
  210. FILE    *fp;
  211. TGAFile    *sp;
  212. {
  213.     int        x1, y, x2;
  214.     int        i;
  215.     char    *p;
  216.     int        bytesPerPixel;
  217.     int        boardBytesPerPixel;
  218.     int        bytesInRow;
  219.     int        bytesInBuffer;
  220.     int        orient;
  221.  
  222.     /*
  223.     ** If we got this far, the file pointer should be pointing
  224.     ** to the first byte of the postage stamp data (just after
  225.     ** the two bytes specifying the size of the stamp).
  226.     */
  227.     /*
  228.     ** Determine pixel size of destination board.  PutRow
  229.     ** requires 4 byte per pixel selection for T24.
  230.     */
  231.     boardBytesPerPixel = targa->BytesPerPixel;
  232.     if ( boardBytesPerPixel == 3 ) boardBytesPerPixel = 4;
  233.  
  234.     bytesPerPixel = (sp->pixelDepth + 7) >> 3;
  235.     bytesInRow = sp->stampWidth * bytesPerPixel;
  236.     /*
  237.     ** Allocate a buffer big enough for stamp width at 32 bit per pixel
  238.     */
  239.     bytesInBuffer = sp->stampWidth << 2;
  240.  
  241.     if ( (p = malloc( bytesInBuffer )) != NULL )
  242.     {
  243.         /*
  244.         ** Test for top-to-bottom or bottom-to-top, but ignore
  245.         ** left-to-right info.
  246.         */
  247.         orient = (sp->imageDesc >> 5) & 0x1;
  248.         if ( orient == 0 )
  249.         {
  250.             x1 = 0; x2 = sp->stampWidth; y = 0; 
  251.             /*
  252.             ** Postage stamp data is always stored in uncompressed format
  253.             */
  254.             for ( i = 0; i < sp->stampHeight; ++i )
  255.             {
  256.                 fread( p, 1, bytesInRow, fp );
  257.                 /*
  258.                 ** Note that UnPackBu needs to be changed from the 4.0
  259.                 ** version of the code.  The automatic variables that
  260.                 ** are declared as (char *) and (int *) need to be
  261.                 ** changed to (unsigned char *) and (unsigned int *).
  262.                 */
  263.                 UnPackBuf( p, x2, bytesPerPixel, boardBytesPerPixel );
  264.                 PutRow( p, x1, x2, y, -1 );
  265.                 y++;
  266.             }
  267.         }
  268.         else
  269.         {
  270.             x1 = 0; x2 = sp->stampWidth; y = sp->stampHeight - 1;
  271.             for ( i = 0; i < sp->stampHeight; ++i )
  272.             {
  273.                 fread( p, 1, bytesInRow, fp );
  274.                 UnPackBuf( p, x2, bytesPerPixel, boardBytesPerPixel );
  275.                 PutRow( p, x1, x2, y, -1 );
  276.                 y--;
  277.             }
  278.         }
  279.         free( p );
  280.     }
  281.     else puts( "Unable to allocate scan line buffer" );
  282. }
  283.  
  284.  
  285. UINT8
  286. ReadByte( fp )
  287. FILE *fp;
  288. {
  289.     UINT8    value;
  290.  
  291. #if MSDOS
  292.     fread( &value, 1, 1, fp );
  293. #else
  294. #endif
  295.     return( value );
  296. }
  297.  
  298.  
  299. void
  300. ReadCharField( fp, p, n )
  301. FILE    *fp;
  302. char    *p;
  303. int        n;
  304. {
  305.     while ( n )
  306.     {
  307.         *p++ = (char)fgetc( fp );    /* no error check, no char conversion */
  308.         --n;
  309.     }
  310. }
  311.  
  312.  
  313. int
  314. ReadExtendedTGA( fp, sp )
  315. FILE    *fp;
  316. TGAFile    *sp;
  317. {
  318.     if ( !fseek( fp, sp->extAreaOffset, SEEK_SET ) )
  319.     {
  320.         sp->extSize = ReadShort( fp );
  321.         memset( sp->author, 0, 41 );
  322.         ReadCharField( fp, sp->author, 41 );
  323.         memset( &sp->authorCom[0][0], 0, 81 );
  324.         ReadCharField( fp, &sp->authorCom[0][0], 81 );
  325.         memset( &sp->authorCom[1][0], 0, 81 );
  326.         ReadCharField( fp, &sp->authorCom[1][0], 81 );
  327.         memset( &sp->authorCom[2][0], 0, 81 );
  328.         ReadCharField( fp, &sp->authorCom[2][0], 81 );
  329.         memset( &sp->authorCom[3][0], 0, 81 );
  330.         ReadCharField( fp, &sp->authorCom[3][0], 81 );
  331.  
  332.         sp->month = ReadShort( fp );
  333.         sp->day = ReadShort( fp );
  334.         sp->year = ReadShort( fp );
  335.         sp->hour = ReadShort( fp );
  336.         sp->minute = ReadShort( fp );
  337.         sp->second = ReadShort( fp );
  338.  
  339.         memset( sp->jobID, 0, 41 );
  340.         ReadCharField( fp, sp->jobID, 41 );
  341.         sp->jobHours = ReadShort( fp );
  342.         sp->jobMinutes = ReadShort( fp );
  343.         sp->jobSeconds = ReadShort( fp );
  344.  
  345.         memset( sp->softID, 0, 41 );
  346.         ReadCharField( fp, sp->softID, 41 );
  347.         sp->versionNum = ReadShort( fp );
  348.         sp->versionLet = ReadByte( fp );
  349.  
  350.         sp->keyColor = ReadLong( fp );
  351.         sp->pixNumerator = ReadShort( fp );
  352.         sp->pixDenominator = ReadShort( fp );
  353.  
  354.         sp->gammaNumerator = ReadShort( fp );
  355.         sp->gammaDenominator = ReadShort( fp );
  356.  
  357.         sp->colorCorrectOffset = ReadLong( fp );
  358.         sp->stampOffset = ReadLong( fp );
  359.         sp->scanLineOffset = ReadLong( fp );
  360.  
  361.         sp->alphaAttribute = ReadByte( fp );
  362.  
  363.         sp->colorCorrectTable = (UINT16 *)0;
  364.  
  365.         sp->postStamp = (void *)0;
  366.         if ( sp->stampOffset )
  367.         {
  368.             if ( !fseek( fp, sp->stampOffset, SEEK_SET ) )
  369.             {
  370.                 sp->stampWidth = ReadByte( fp );
  371.                 sp->stampHeight = ReadByte( fp );
  372.             }
  373.             else
  374.             {
  375.                 printf( "Error seeking to Postage Stamp, offset = 0x%08lx\n",
  376.                     sp->stampOffset );
  377.             }
  378.         }
  379.  
  380.         sp->scanLineTable = (UINT32 *)0;
  381.     }
  382.     else
  383.     {
  384.         printf( "Error seeking to Extended TGA Area, offset = 0x%08lx\n",
  385.             sp->extAreaOffset );
  386.         return( -1 );
  387.     }
  388.     return( 0 );
  389. }
  390.  
  391.  
  392. UINT32
  393. ReadLong( fp )
  394. FILE *fp;
  395. {
  396.     UINT32    value;
  397.  
  398. #if MSDOS
  399.     fread( &value, 1, 4, fp );
  400. #else
  401. #endif
  402.     return( value );
  403. }
  404.  
  405.  
  406.  
  407. UINT16
  408. ReadShort( fp )
  409. FILE *fp;
  410. {
  411.     UINT16    value;
  412.  
  413. #if MSDOS
  414.     fread( &value, 1, 2, fp );
  415. #else
  416. #endif
  417.     return( value );
  418. }
  419.