Source code of Windows XP (NT5)
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.

378 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. faxview.c
  5. Abstract:
  6. This file implements a simple TIFF image viewer.
  7. Environment:
  8. WIN32 User Mode
  9. Author:
  10. Wesley Witt (wesw) 17-Feb-1996
  11. --*/
  12. #include <windows.h>
  13. #include <commctrl.h>
  14. #include <commdlg.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <tchar.h>
  18. #include "resource.h"
  19. #include "tifflib.h"
  20. #include "faxutil.h"
  21. typedef struct _PRINT_INFO {
  22. HWND hwnd;
  23. LPWSTR FileName;
  24. HDC hdc;
  25. DWORD FromPage;
  26. DWORD ToPage;
  27. DWORD Copies;
  28. } PRINT_INFO, *PPRINT_INFO;
  29. static HANDLE hDevMode = NULL;
  30. static HANDLE hDevNames = NULL;
  31. extern HWND hwndStatusbar;
  32. BOOL
  33. ReadTiffData(
  34. HANDLE hTiff,
  35. LPBYTE *TiffData,
  36. DWORD Width,
  37. LPDWORD TiffDataLinesAlloc,
  38. DWORD PageNumber
  39. );
  40. BOOL
  41. PrintSetup(
  42. HWND hwnd
  43. )
  44. {
  45. PRINTDLG pdlg = {0};
  46. pdlg.lStructSize = sizeof(PRINTDLG);
  47. pdlg.hwndOwner = hwnd;
  48. pdlg.hDevMode = hDevMode;
  49. pdlg.hDevNames = hDevNames;
  50. pdlg.Flags = PD_PRINTSETUP;
  51. if (PrintDlg( &pdlg )) {
  52. hDevMode = pdlg.hDevMode;
  53. hDevNames = pdlg.hDevNames;
  54. return TRUE;
  55. }
  56. return FALSE;
  57. }
  58. DWORD
  59. PrintThread(
  60. PPRINT_INFO pi
  61. )
  62. {
  63. LPBYTE bmiBuf[sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*2)];
  64. PBITMAPINFO bmi = (PBITMAPINFO) bmiBuf;
  65. HANDLE hTiff;
  66. TIFF_INFO TiffInfo;
  67. LPBYTE TiffData;
  68. DWORD TiffDataSize;
  69. DWORD i;
  70. INT HorzRes;
  71. INT VertRes;
  72. INT PrintJobId = 0;
  73. DOCINFO DocInfo;
  74. DWORD TiffDataLinesAlloc;
  75. DWORD VertResFactor = 1;
  76. hTiff = TiffOpen(
  77. pi->FileName,
  78. &TiffInfo,
  79. TRUE
  80. );
  81. if (!hTiff) {
  82. return 0;
  83. }
  84. TiffDataSize = TiffInfo.ImageHeight * (TiffInfo.ImageWidth / 8);
  85. TiffData = (LPBYTE) VirtualAlloc(
  86. NULL,
  87. TiffDataSize,
  88. MEM_COMMIT,
  89. PAGE_READWRITE
  90. );
  91. if (!TiffData) {
  92. return 0;
  93. }
  94. TiffDataLinesAlloc = TiffInfo.ImageHeight;
  95. bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  96. bmi->bmiHeader.biWidth = TiffInfo.ImageWidth;
  97. bmi->bmiHeader.biHeight = - (INT) TiffInfo.ImageHeight;
  98. bmi->bmiHeader.biPlanes = 1;
  99. bmi->bmiHeader.biBitCount = 1;
  100. bmi->bmiHeader.biCompression = BI_RGB;
  101. bmi->bmiHeader.biSizeImage = 0;
  102. bmi->bmiHeader.biXPelsPerMeter = 7874;
  103. bmi->bmiHeader.biYPelsPerMeter = 7874;
  104. bmi->bmiHeader.biClrUsed = 0;
  105. bmi->bmiHeader.biClrImportant = 0;
  106. if (TiffInfo.PhotometricInterpretation) {
  107. bmi->bmiColors[0].rgbBlue = 0;
  108. bmi->bmiColors[0].rgbGreen = 0;
  109. bmi->bmiColors[0].rgbRed = 0;
  110. bmi->bmiColors[0].rgbReserved = 0;
  111. bmi->bmiColors[1].rgbBlue = 0xff;
  112. bmi->bmiColors[1].rgbGreen = 0xff;
  113. bmi->bmiColors[1].rgbRed = 0xff;
  114. bmi->bmiColors[1].rgbReserved = 0;
  115. } else {
  116. bmi->bmiColors[0].rgbBlue = 0xff;
  117. bmi->bmiColors[0].rgbGreen = 0xff;
  118. bmi->bmiColors[0].rgbRed = 0xff;
  119. bmi->bmiColors[0].rgbReserved = 0;
  120. bmi->bmiColors[1].rgbBlue = 0;
  121. bmi->bmiColors[1].rgbGreen = 0;
  122. bmi->bmiColors[1].rgbRed = 0;
  123. bmi->bmiColors[1].rgbReserved = 0;
  124. }
  125. if (TiffInfo.YResolution <= 100) {
  126. bmi->bmiHeader.biYPelsPerMeter /= 2;
  127. VertResFactor = 2;
  128. }
  129. HorzRes = GetDeviceCaps( pi->hdc, HORZRES );
  130. VertRes = GetDeviceCaps( pi->hdc, VERTRES );
  131. DocInfo.cbSize = sizeof(DOCINFO);
  132. DocInfo.lpszOutput = NULL;
  133. DocInfo.lpszDatatype = NULL;
  134. DocInfo.fwType = 0;
  135. DocInfo.lpszDocName = wcsrchr( pi->FileName, L'\\' );
  136. if (DocInfo.lpszDocName) {
  137. DocInfo.lpszDocName += 1;
  138. } else {
  139. DocInfo.lpszDocName = pi->FileName;
  140. }
  141. while( pi->Copies ) {
  142. PrintJobId = StartDoc( pi->hdc, &DocInfo );
  143. if (PrintJobId <= 0) {
  144. DeleteDC( pi->hdc );
  145. return FALSE;
  146. }
  147. for (i=pi->FromPage-1; i<min(pi->ToPage,TiffInfo.PageCount); i++)
  148. {
  149. DWORD Lines;
  150. DWORD StripDataSize;
  151. DWORD ImageWidth = TiffInfo.ImageWidth;
  152. DWORD ImageHeight = TiffInfo.ImageHeight;
  153. DWORD LinesAllocated = MAXVERTBITS;
  154. INT DestWidth;
  155. INT DestHeight;
  156. FLOAT ScaleX;
  157. FLOAT ScaleY;
  158. FLOAT Scale;
  159. SendMessage(
  160. hwndStatusbar,
  161. SB_SETTEXT,
  162. 1,
  163. (LPARAM) L"Printing"
  164. );
  165. ReadTiffData( hTiff, &TiffData, TiffInfo.ImageWidth, &TiffDataLinesAlloc, i+1 );
  166. TiffGetCurrentPageData(
  167. hTiff,
  168. &Lines,
  169. &StripDataSize,
  170. &ImageWidth,
  171. &ImageHeight
  172. );
  173. ScaleX = (FLOAT) ImageWidth / (FLOAT) HorzRes;
  174. ScaleY = ((FLOAT) ImageHeight * VertResFactor) / (FLOAT) VertRes;
  175. Scale = ScaleX > ScaleY ? ScaleX : ScaleY;
  176. DestWidth = (int) ((FLOAT) ImageWidth / Scale);
  177. DestHeight = (int) (((FLOAT) ImageHeight * VertResFactor) / Scale);
  178. bmi->bmiHeader.biWidth = ImageWidth;
  179. bmi->bmiHeader.biHeight = - (INT)ImageHeight;
  180. StartPage( pi->hdc );
  181. StretchDIBits(
  182. pi->hdc,
  183. 0,
  184. 0,
  185. DestWidth,
  186. DestHeight,
  187. 0,
  188. 0,
  189. ImageWidth,
  190. ImageHeight,
  191. TiffData,
  192. (BITMAPINFO *) bmi,
  193. DIB_RGB_COLORS,
  194. SRCCOPY
  195. );
  196. EndPage ( pi->hdc ) ;
  197. }
  198. pi->Copies -= 1;
  199. EndDoc( pi->hdc );
  200. }
  201. DeleteDC( pi->hdc );
  202. TiffClose( hTiff );
  203. VirtualFree( TiffData, 0, MEM_RELEASE );
  204. MemFree( pi->FileName );
  205. MemFree( pi );
  206. return 0;
  207. }
  208. HANDLE
  209. PrintTiffFile(
  210. HWND hwnd,
  211. LPWSTR FileName,
  212. LPWSTR PrinterName
  213. )
  214. {
  215. static DWORD Flags = PD_ALLPAGES | PD_RETURNDC | PD_HIDEPRINTTOFILE | PD_NOSELECTION | PD_NOWARNING;
  216. static WORD nFromPage = 0xFFFF;
  217. static WORD nToPage = 0xFFFF;
  218. static WORD nCopies = 1;
  219. DWORD ThreadId;
  220. HANDLE hThread;
  221. PPRINT_INFO pi;
  222. PRINTDLG pd = {0};
  223. WCHAR DefaultPrinter[1024];
  224. if (hwnd) {
  225. pd.lStructSize = sizeof(pd);
  226. pd.hwndOwner = hwnd;
  227. pd.hDevMode = hDevMode;
  228. pd.hDevNames = hDevNames;
  229. pd.Flags = Flags;
  230. pd.nFromPage = nFromPage;
  231. pd.nToPage = nToPage;
  232. pd.nMinPage = 1;
  233. pd.nMaxPage = 65535;
  234. pd.nCopies = nCopies;
  235. if (!PrintDlg(&pd)) {
  236. return NULL;
  237. }
  238. hDevMode = pd.hDevMode;
  239. hDevNames = pd.hDevNames;
  240. Flags = pd.Flags;
  241. nFromPage = pd.nFromPage;
  242. nToPage = pd.nToPage;
  243. pi = (PPRINT_INFO) MemAlloc( sizeof(PRINT_INFO) );
  244. if (!pi) {
  245. return NULL;
  246. }
  247. pi->hwnd = hwnd;
  248. pi->hdc = pd.hDC;
  249. pi->FromPage = Flags & PD_PAGENUMS ? pd.nFromPage : 1;
  250. pi->ToPage = pd.nToPage;
  251. pi->Copies = pd.nCopies;
  252. pi->FileName = StringDup( FileName );
  253. } else {
  254. if (!PrinterName) {
  255. //
  256. // get the default printer name
  257. //
  258. GetProfileString(
  259. L"windows",
  260. L"device",
  261. NULL,
  262. DefaultPrinter,
  263. sizeof(DefaultPrinter)
  264. );
  265. if (!DefaultPrinter[0]) {
  266. return NULL;
  267. }
  268. PrinterName = wcschr( DefaultPrinter, L',' );
  269. if (PrinterName) {
  270. *PrinterName = 0;
  271. }
  272. PrinterName = DefaultPrinter;
  273. }
  274. pi = (PPRINT_INFO) MemAlloc( sizeof(PRINT_INFO) );
  275. if (!pi) {
  276. return NULL;
  277. }
  278. pi->hdc = CreateDC( TEXT("WINSPOOL"), PrinterName, NULL, NULL );
  279. if (!pi->hdc) {
  280. return NULL;
  281. }
  282. pi->hwnd = NULL;
  283. pi->FromPage = 1;
  284. pi->ToPage = 65535;
  285. pi->Copies = 1;
  286. pi->FileName = StringDup( FileName );
  287. }
  288. hThread = CreateThread(
  289. NULL,
  290. 1024*100,
  291. (LPTHREAD_START_ROUTINE) PrintThread,
  292. (LPVOID) pi,
  293. 0,
  294. &ThreadId
  295. );
  296. if (!hThread) {
  297. return NULL;
  298. }
  299. return hThread;
  300. }