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.

216 lines
6.0 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <objbase.h>
  4. #include "gdiplus.h"
  5. #include <shlwapi.h>
  6. #include <initguid.h>
  7. //#include <shlwapip.h>
  8. using namespace Gdiplus;
  9. DEFINE_GUID(GUID_NULL, 0L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  10. UINT FindInDecoderList(ImageCodecInfo *pici, UINT cDecoders, LPCTSTR pszFile)
  11. {
  12. LPCTSTR pszExt = PathFindExtension(pszFile); // speed up PathMatchSpec calls
  13. // look at the list of decoders to see if this format is there
  14. for (UINT i = 0; i < cDecoders; i++)
  15. {
  16. if (PathMatchSpec(pszExt, pici[i].FilenameExtension))
  17. return i;
  18. }
  19. return (UINT)-1; // not found!
  20. }
  21. class CEncoderInfo
  22. {
  23. public:
  24. Status GetDataFormatFromPath(LPCWSTR pszPath, GUID *pguidFmt);
  25. Status GetEncoderList();
  26. Status GetEncoderFromFormat(const GUID *pfmt, CLSID *pclsidEncoder);
  27. CEncoderInfo();
  28. ~CEncoderInfo();
  29. private:
  30. UINT _cEncoders; // number of encoders discovered
  31. ImageCodecInfo *_pici; // array of image encoder classes
  32. };
  33. CEncoderInfo::CEncoderInfo()
  34. {
  35. _cEncoders = 0;
  36. _pici = NULL;
  37. }
  38. CEncoderInfo::~CEncoderInfo()
  39. {
  40. LocalFree (_pici);
  41. }
  42. Status CEncoderInfo::GetDataFormatFromPath(LPCWSTR pszPath, GUID *pguidFmt)
  43. {
  44. *pguidFmt = GUID_NULL;
  45. Status s = GetEncoderList();
  46. if (Ok == s)
  47. {
  48. UINT i = FindInDecoderList(_pici, _cEncoders, pszPath);
  49. if (-1 != i)
  50. {
  51. *pguidFmt = _pici[i].FormatID;
  52. }
  53. else
  54. {
  55. s = GenericError;
  56. }
  57. }
  58. return s;
  59. }
  60. Status CEncoderInfo::GetEncoderList()
  61. {
  62. Status s = Ok;
  63. if (!_pici)
  64. {
  65. // lets pick up the list of encoders, first we get the encoder size which
  66. // gives us the CB and the number of encoders that are installed on the
  67. // machine.
  68. UINT cb;
  69. s = GetImageEncodersSize(&_cEncoders, &cb);
  70. if (Ok == s)
  71. {
  72. // allocate the buffer for the encoders and then fill it
  73. // with the encoder list.
  74. _pici = (ImageCodecInfo*)LocalAlloc(LPTR, cb);
  75. if (_pici)
  76. {
  77. s = GetImageEncoders(_cEncoders, cb, _pici);
  78. if (Ok != s)
  79. {
  80. LocalFree(_pici);
  81. _pici = NULL;
  82. }
  83. }
  84. else
  85. {
  86. s = OutOfMemory;
  87. }
  88. }
  89. }
  90. return s;
  91. }
  92. Status CEncoderInfo::GetEncoderFromFormat(const GUID *pfmt, CLSID *pclsidEncoder)
  93. {
  94. Status s = GetEncoderList();
  95. if (Ok == s)
  96. {
  97. s = GenericError;
  98. for (UINT i = 0; i != _cEncoders; i++)
  99. {
  100. if (_pici[i].FormatID == *pfmt)
  101. {
  102. if (pclsidEncoder)
  103. {
  104. *pclsidEncoder = _pici[i].Clsid; // return the CLSID of the encoder so we can create again
  105. }
  106. s = Ok;
  107. break;
  108. }
  109. }
  110. }
  111. return s;
  112. }
  113. void AddEncParameter(EncoderParameters *pep, GUID guidProperty, ULONG type, void *pv)
  114. {
  115. pep->Parameter[pep->Count].Guid = guidProperty;
  116. pep->Parameter[pep->Count].Type = type;
  117. pep->Parameter[pep->Count].NumberOfValues = 1;
  118. pep->Parameter[pep->Count].Value = pv;
  119. pep->Count++;
  120. }
  121. class CGraphicsInit
  122. {
  123. ULONG_PTR _token;
  124. public:
  125. CGraphicsInit()
  126. {
  127. GdiplusStartupInput gsi;
  128. GdiplusStartupOutput gso;
  129. GdiplusStartup(&_token, &gsi, &gso);
  130. };
  131. ~CGraphicsInit()
  132. {
  133. GdiplusShutdown(_token);
  134. };
  135. };
  136. int __cdecl wmain(int argc, LPCWSTR argv[])
  137. {
  138. if (argc < 2)
  139. {
  140. printf("Usage: rotimg <filename> <targetfile>\n");
  141. }
  142. else
  143. {
  144. CGraphicsInit cgi;
  145. LPCWSTR szSrc = argv[1];
  146. LPCWSTR szSave = argc > 2 ? argv[2] : argv[1];
  147. Status s;
  148. printf("Source image: %ls, Target image: %ls\n", szSrc, szSave);
  149. Image *pimg = new Image(szSrc, TRUE);
  150. s = pimg->GetLastStatus();
  151. if (Ok != s)
  152. {
  153. printf("Error %d constructing Image\n", s);
  154. }
  155. UINT nPages = pimg->GetFrameCount(&FrameDimensionPage);
  156. Image *pimgWork = pimg->Clone();
  157. s = pimgWork->RotateFlip(Rotate90FlipNone);
  158. if (Ok != s)
  159. {
  160. printf("RotateFlip returned %d\n", s);
  161. }
  162. else
  163. {
  164. IStream *pstrm;
  165. SHCreateStreamOnFileEx(szSave, STGM_WRITE | STGM_CREATE, 0, TRUE, NULL, &pstrm);
  166. CEncoderInfo cei;
  167. GUID guidFmt;
  168. CLSID clsidEncoder;
  169. cei.GetDataFormatFromPath(szSave, &guidFmt);
  170. cei.GetEncoderFromFormat(&guidFmt, &clsidEncoder);
  171. EncoderParameters ep[1] = {0};
  172. ULONG flagValueMulti = nPages > 1 ? EncoderValueMultiFrame : EncoderValueLastFrame;
  173. AddEncParameter(ep, EncoderSaveFlag, EncoderParameterValueTypeLong, &flagValueMulti);
  174. pimgWork->SelectActiveFrame(&FrameDimensionPage, 0);
  175. s = pimgWork->Save(pstrm,&clsidEncoder, ep);
  176. printf("first Save returned %d\n", s);
  177. if (Ok == s && nPages > 1)
  178. {
  179. EncoderParameters ep[2] = {0};
  180. ULONG flagValueDim = EncoderValueFrameDimensionPage;
  181. ULONG flagValueLastFrame = EncoderValueLastFrame;
  182. pimg->SelectActiveFrame(&FrameDimensionPage, 1);
  183. AddEncParameter(ep, EncoderSaveFlag, EncoderParameterValueTypeLong, &flagValueDim);
  184. AddEncParameter(ep, EncoderSaveFlag, EncoderParameterValueTypeLong, &flagValueLastFrame);
  185. s = pimgWork->SaveAdd(pimg, ep);
  186. printf("SaveAdd returned %d\n", s);
  187. }
  188. pstrm->Release();
  189. }
  190. delete pimg;
  191. delete pimgWork;
  192. }
  193. printf("Rotimg complete\n");
  194. }