Leaked source code of windows server 2003
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.

211 lines
4.9 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Program Name:
  6. *
  7. * ImgDiff
  8. *
  9. * ImgDiff source_file_1 source_file_2 destination_file
  10. *
  11. * This will difference the two source files (provided they're the same size)
  12. * and output the resulting image.
  13. *
  14. * Technically it does:
  15. *
  16. * CD[i] = | S1[i] - S2[i] |
  17. *
  18. * where i indexes the color channels rather than the pixels.
  19. * because it's an abs computation, the input source file order is unimportant.
  20. *
  21. *
  22. * Created:
  23. *
  24. * 06/25/2000 asecchia
  25. * Created it.
  26. *
  27. **************************************************************************/
  28. #include <stdio.h>
  29. #include <windows.h>
  30. #include <objbase.h>
  31. #include <gdiplus.h>
  32. INT AsciiToUnicodeStr(
  33. const CHAR* ansiStr,
  34. WCHAR* unicodeStr,
  35. INT unicodeSize
  36. )
  37. {
  38. return( MultiByteToWideChar(
  39. CP_ACP,
  40. 0,
  41. ansiStr,
  42. -1,
  43. unicodeStr,
  44. unicodeSize
  45. ) > 0 );
  46. }
  47. #define Fail() goto cleanup
  48. void _cdecl main(int argc, char **argv)
  49. {
  50. if(argc<4)
  51. {
  52. printf("error - need source1 and source2 and destination filename\n");
  53. printf("usage: ImgDiff srcfilename srcfilename dstfilename\n");
  54. return;
  55. }
  56. using namespace Gdiplus;
  57. Status status;
  58. WCHAR source1[1024];
  59. WCHAR source2[1024];
  60. WCHAR outfilename[1024];
  61. AsciiToUnicodeStr(argv[1], source1, 1024);
  62. AsciiToUnicodeStr(argv[2], source2, 1024);
  63. AsciiToUnicodeStr(argv[3], outfilename, 1024);
  64. ImageCodecInfo* codecs = NULL;
  65. UINT count;
  66. UINT cbCodecs;
  67. // Open the source images
  68. Bitmap *srcBmp1 = new Bitmap(source1);
  69. Bitmap *srcBmp2 = new Bitmap(source2);
  70. // Ask the source image for it's size.
  71. int width = srcBmp1->GetWidth();
  72. int height = srcBmp1->GetHeight();
  73. if( (width != (int)srcBmp2->GetWidth()) ||
  74. (height != (int)srcBmp2->GetHeight()) )
  75. {
  76. printf("the two input files are different sizes\n");
  77. return;
  78. }
  79. printf("Input images are (%d x %d)\n", width, height);
  80. // Create a destination image to draw onto
  81. Bitmap *dstBmp = new Bitmap(
  82. width,
  83. height,
  84. PixelFormat32bppARGB
  85. );
  86. BitmapData bdSrc1;
  87. BitmapData bdSrc2;
  88. BitmapData bdDst;
  89. Rect rect(0,0,width,height);
  90. srcBmp1->LockBits(rect, ImageLockModeRead, PixelFormat32bppARGB, &bdSrc1);
  91. srcBmp2->LockBits(rect, ImageLockModeRead, PixelFormat32bppARGB, &bdSrc2);
  92. dstBmp->LockBits(rect, ImageLockModeWrite, PixelFormat32bppARGB, &bdDst);
  93. int x, y;
  94. unsigned char *s1, *s2, *d;
  95. for(y = 0; y < (int)bdSrc1.Height; y++)
  96. {
  97. for(x = 0; x < (int)bdSrc1.Width; x++)
  98. {
  99. s1 = (unsigned char *)((ARGB*)(bdSrc1.Scan0) + x + y * bdSrc1.Width);
  100. s2 = (unsigned char *)((ARGB*)(bdSrc2.Scan0) + x + y * bdSrc2.Width);
  101. d = (unsigned char *)((ARGB*)(bdDst.Scan0) + x + y * bdDst.Width);
  102. // per channel subtract.
  103. d[0] = (unsigned char)abs(s1[0] - s2[0]);
  104. d[1] = (unsigned char)abs(s1[1] - s2[1]);
  105. d[2] = (unsigned char)abs(s1[2] - s2[2]);
  106. d[3] = (unsigned char)abs(s1[3] - s2[3]);
  107. }
  108. }
  109. srcBmp1->UnlockBits(&bdSrc1);
  110. srcBmp2->UnlockBits(&bdSrc2);
  111. dstBmp->UnlockBits(&bdDst);
  112. // Now start finding a codec to output the image.
  113. cbCodecs = 0;
  114. GetImageEncodersSize(&count, &cbCodecs);
  115. // Allocate space for the codec list
  116. codecs = static_cast<ImageCodecInfo *>(malloc (cbCodecs));
  117. if (codecs == NULL)
  118. {
  119. printf("error: failed to allocate memory for codecs\n");
  120. Fail();
  121. }
  122. // Get the list of encoders
  123. status = GetImageEncoders(count, cbCodecs, codecs);
  124. if (status != Ok)
  125. {
  126. printf("Error: GetImageEncoders returned %d\n", status);
  127. Fail();
  128. }
  129. // Search the codec list for the JPEG codec.
  130. // Use the Mime Type field to specify the correct codec.
  131. for(UINT i=0; i<count; i++) {
  132. if(wcscmp(codecs[i].MimeType, L"image/bmp")==0) {break;}
  133. }
  134. if(i>=count)
  135. {
  136. fprintf(stderr, "failed to find the codec\n");
  137. Fail();
  138. }
  139. // Output the image to disk.
  140. CLSID tempClsID;
  141. tempClsID = codecs[i].Clsid;
  142. status = dstBmp->Save(
  143. outfilename,
  144. &tempClsID,
  145. NULL
  146. );
  147. if (status != Ok)
  148. {
  149. fprintf(stderr, "SaveImage--Save() failed\n");
  150. Fail();
  151. }
  152. // We're golden - everything worked.
  153. printf("Done\n");
  154. // Clean up the objects we used.
  155. cleanup:
  156. free(codecs);
  157. delete dstBmp;
  158. delete srcBmp1;
  159. delete srcBmp2;
  160. }