Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <direct.h>
  11. #include "bitmap/tgaloader.h"
  12. #include "bitmap/tgawriter.h"
  13. #include "tier1/utlbuffer.h"
  14. #include "tier2/tier2.h"
  15. #include "mathlib/mathlib.h"
  16. #include "filesystem.h"
  17. void Usage( void )
  18. {
  19. printf( "Usage: tgadiff src1.tga src2.tga diff.tga\n" );
  20. exit( -1 );
  21. }
  22. int main( int argc, char **argv )
  23. {
  24. if( argc != 4 )
  25. {
  26. Usage();
  27. }
  28. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
  29. InitDefaultFileSystem();
  30. char pCurrentDirectory[MAX_PATH];
  31. if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL )
  32. {
  33. fprintf( stderr, "Unable to get the current directory\n" );
  34. return -1;
  35. }
  36. Q_FixSlashes( pCurrentDirectory );
  37. Q_StripTrailingSlash( pCurrentDirectory );
  38. char pBuf[3][MAX_PATH];
  39. const char *pFileName[3];
  40. for ( int i = 0; i < 3; ++i )
  41. {
  42. if ( !Q_IsAbsolutePath( argv[i+1] ) )
  43. {
  44. Q_snprintf( pBuf[i], sizeof(pBuf[i]), "%s\\%s", pCurrentDirectory, argv[i+1] );
  45. pFileName[i] = pBuf[i];
  46. }
  47. else
  48. {
  49. pFileName[i] = argv[i+1];
  50. }
  51. }
  52. int width1, height1;
  53. ImageFormat imageFormat1;
  54. float gamma1;
  55. CUtlBuffer buf1;
  56. if ( !g_pFullFileSystem->ReadFile( pFileName[0], NULL, buf1 ) )
  57. {
  58. fprintf( stderr, "%s not found\n", pFileName[0] );
  59. return -1;
  60. }
  61. if( !TGALoader::GetInfo( buf1, &width1, &height1, &imageFormat1, &gamma1 ) )
  62. {
  63. printf( "error loading %s\n", pFileName[0] );
  64. exit( -1 );
  65. }
  66. int width2, height2;
  67. ImageFormat imageFormat2;
  68. float gamma2;
  69. CUtlBuffer buf2;
  70. if ( !g_pFullFileSystem->ReadFile( pFileName[1], NULL, buf2 ) )
  71. {
  72. fprintf( stderr, "%s not found\n", pFileName[1] );
  73. return -1;
  74. }
  75. if( !TGALoader::GetInfo( buf2, &width2, &height2, &imageFormat2, &gamma2 ) )
  76. {
  77. printf( "error loading %s\n", pFileName[1] );
  78. exit( -1 );
  79. }
  80. if( width1 != width2 || height1 != height2 )
  81. {
  82. printf( "image dimensions different (%dx%d!=%dx%d): can't do diff for %s\n",
  83. width1, height1, width2, height2, pFileName[2] );
  84. exit( -1 );
  85. }
  86. #if 0
  87. // have to allow for different formats for now due to *.txt file screwup.
  88. if( imageFormat1 != imageFormat2 )
  89. {
  90. printf( "image format different (%s!=%s). . can't do diff for %s\n",
  91. ImageLoader::GetName( imageFormat1 ), ImageLoader::GetName( imageFormat2 ), pFileName[2] );
  92. exit( -1 );
  93. }
  94. #endif
  95. if( gamma1 != gamma2 )
  96. {
  97. printf( "image gamma different (%f!=%f). . can't do diff for %s\n", gamma1, gamma2, pFileName[2] );
  98. exit( -1 );
  99. }
  100. unsigned char *pImage1Tmp = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, imageFormat1, false )];
  101. unsigned char *pImage2Tmp = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, imageFormat2, false )];
  102. buf1.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
  103. if( !TGALoader::Load( pImage1Tmp, buf1, width1, height1, imageFormat1, 2.2f, false ) )
  104. {
  105. printf( "error loading %s\n", pFileName[0] );
  106. exit( -1 );
  107. }
  108. buf2.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
  109. if( !TGALoader::Load( pImage2Tmp, buf2, width2, height2, imageFormat2, 2.2f, false ) )
  110. {
  111. printf( "error loading %s\n", pFileName[1] );
  112. exit( -1 );
  113. }
  114. unsigned char *pImage1 = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, IMAGE_FORMAT_ABGR8888, false )];
  115. unsigned char *pImage2 = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
  116. unsigned char *pDiff = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
  117. ImageLoader::ConvertImageFormat( pImage1Tmp, imageFormat1, pImage1, IMAGE_FORMAT_ABGR8888, width1, height1, 0, 0 );
  118. ImageLoader::ConvertImageFormat( pImage2Tmp, imageFormat2, pImage2, IMAGE_FORMAT_ABGR8888, width2, height2, 0, 0 );
  119. int sizeInBytes = ImageLoader::SizeInBytes( IMAGE_FORMAT_ABGR8888 );
  120. bool isDifferent = false;
  121. for( int i = 0; i < width1 * height1 * sizeInBytes; i++ )
  122. {
  123. int d;
  124. d = pImage2[i] - pImage1[i];
  125. pDiff[i] = d > 0 ? d : -d;
  126. if( d != 0 )
  127. {
  128. isDifferent = true;
  129. }
  130. }
  131. if( !isDifferent )
  132. {
  133. printf( "Files are the same %s %s : not generating %s\n", pFileName[0], pFileName[1], pFileName[2] );
  134. exit( -1 );
  135. }
  136. else
  137. {
  138. printf( "Generating diff: %s!\n", pFileName[2] );
  139. }
  140. ImageFormat dstImageFormat;
  141. // get rid of this until we get the formats matching
  142. // if( sizeInBytes == 3 )
  143. // {
  144. // dstImageFormat = IMAGE_FORMAT_RGB888;
  145. // }
  146. // else
  147. {
  148. dstImageFormat = IMAGE_FORMAT_RGBA8888;
  149. }
  150. CUtlBuffer outBuffer;
  151. if ( !TGAWriter::WriteToBuffer( pDiff, outBuffer, width1, height1, dstImageFormat, dstImageFormat ) )
  152. {
  153. printf( "error writing %s to buffer\n", pFileName[2] );
  154. exit( -1 );
  155. }
  156. if ( !g_pFullFileSystem->WriteFile( pFileName[2], NULL, outBuffer ) )
  157. {
  158. fprintf( stderr, "unable to write %s\n", pFileName[2] );
  159. return -1;
  160. }
  161. return 0;
  162. }