67c15e0ea5d224dfbba70f1dc9c2c21e1ba4c9c8
[pdfium.git] / samples / pdfium_test.cc
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 #include <limits.h>\r
6 #include <stdio.h>\r
7 #include <stdlib.h>\r
8 #include <string.h>\r
9 \r
10 #include <list>\r
11 #include <string>\r
12 #include <utility>\r
13 \r
14 #include "fpdfsdk/include/fpdf_dataavail.h"\r
15 #include "fpdfsdk/include/fpdf_ext.h"\r
16 #include "fpdfsdk/include/fpdfformfill.h"\r
17 #include "fpdfsdk/include/fpdftext.h"\r
18 #include "fpdfsdk/include/fpdfview.h"\r
19 #include "v8/include/v8.h"\r
20 \r
21 #ifdef _WIN32\r
22   #define snprintf _snprintf\r
23   /* in Windows, rb for open and read binary file */\r
24   #define FOPEN_READ "rb"\r
25 #else\r
26   #define FOPEN_READ "r"\r
27 #endif\r
28 \r
29 static void WritePpm(const char* pdf_name, int num,\r
30                      const char* buffer, int stride, int width, int height) {\r
31   if (stride < 0 || width < 0 || height < 0)\r
32     return;\r
33   if (height > 0 && width > INT_MAX / height)\r
34     return;\r
35   int out_len = width * height;\r
36   if (out_len > INT_MAX / 3)\r
37     return;\r
38   out_len *= 3;\r
39 \r
40   char filename[256];\r
41   snprintf(filename, sizeof(filename), "%s.%d.ppm", pdf_name, num);\r
42   FILE* fp = fopen(filename, "w");\r
43   if (!fp)\r
44     return;\r
45   fprintf(fp, "P6\n# PDF test render\n%d %d\n255\n", width, height);\r
46   // Source data is B, G, R, unused.\r
47   // Dest data is R, G, B.\r
48   char* result = new char[out_len];\r
49   if (result) {\r
50     for (int h = 0; h < height; ++h) {\r
51       const char* src_line = buffer + (stride * h);\r
52       char* dest_line = result + (width * h * 3);\r
53       for (int w = 0; w < width; ++w) {\r
54         // R\r
55         dest_line[w * 3] = src_line[(w * 4) + 2];\r
56         // G\r
57         dest_line[(w * 3) + 1] = src_line[(w * 4) + 1];\r
58         // B\r
59         dest_line[(w * 3) + 2] = src_line[w * 4];\r
60       }\r
61     }\r
62     fwrite(result, out_len, 1, fp);\r
63     delete [] result;\r
64   }\r
65   fclose(fp);\r
66 }\r
67 \r
68 int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) {\r
69   printf("Form_Alert called.\n");\r
70   return 0;\r
71 }\r
72 \r
73 void Unsupported_Handler(UNSUPPORT_INFO*, int type) {\r
74   std::string feature = "Unknown";\r
75   switch (type) {\r
76     case FPDF_UNSP_DOC_XFAFORM:\r
77       feature = "XFA";\r
78       break;\r
79     case FPDF_UNSP_DOC_PORTABLECOLLECTION:\r
80       feature = "Portfolios_Packages";\r
81       break;\r
82     case FPDF_UNSP_DOC_ATTACHMENT:\r
83     case FPDF_UNSP_ANNOT_ATTACHMENT:\r
84       feature = "Attachment";\r
85       break;\r
86     case FPDF_UNSP_DOC_SECURITY:\r
87       feature = "Rights_Management";\r
88       break;\r
89     case FPDF_UNSP_DOC_SHAREDREVIEW:\r
90       feature = "Shared_Review";\r
91       break;\r
92     case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT:\r
93     case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM:\r
94     case FPDF_UNSP_DOC_SHAREDFORM_EMAIL:\r
95       feature = "Shared_Form";\r
96       break;\r
97     case FPDF_UNSP_ANNOT_3DANNOT:\r
98       feature = "3D";\r
99       break;\r
100     case FPDF_UNSP_ANNOT_MOVIE:\r
101       feature = "Movie";\r
102       break;\r
103     case FPDF_UNSP_ANNOT_SOUND:\r
104       feature = "Sound";\r
105       break;\r
106     case FPDF_UNSP_ANNOT_SCREEN_MEDIA:\r
107     case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA:\r
108       feature = "Screen";\r
109       break;\r
110     case FPDF_UNSP_ANNOT_SIG:\r
111       feature = "Digital_Signature";\r
112       break;\r
113   }\r
114   printf("Unsupported feature: %s.\n", feature.c_str());\r
115 }\r
116 \r
117 bool ParseCommandLine(int argc, const char* argv[], bool* write_images,\r
118                       std::list<const char*>* files) {\r
119   *write_images = false;\r
120   files->clear();\r
121 \r
122   int cur_arg = 1;\r
123   if (cur_arg < argc &&\r
124       strcmp(argv[cur_arg], "--write_images") == 0) {\r
125     *write_images = true;\r
126     cur_arg++;\r
127   }\r
128 \r
129   if (cur_arg >= argc)\r
130     return false;\r
131 \r
132   for (int i = cur_arg; i < argc; i++)\r
133     files->push_back(argv[i]);\r
134 \r
135   return true;\r
136 }\r
137 \r
138 class TestLoader {\r
139  public:\r
140   TestLoader(const char* pBuf, size_t len);\r
141 \r
142   const char* m_pBuf;\r
143   size_t m_Len;\r
144 };\r
145 \r
146 TestLoader::TestLoader(const char* pBuf, size_t len)\r
147     : m_pBuf(pBuf), m_Len(len) {\r
148 }\r
149 \r
150 int Get_Block(void* param, unsigned long pos, unsigned char* pBuf,\r
151               unsigned long size) {\r
152   TestLoader* pLoader = (TestLoader*) param;\r
153   if (pos + size < pos || pos + size > pLoader->m_Len) return 0;\r
154   memcpy(pBuf, pLoader->m_pBuf + pos, size);\r
155   return 1;\r
156 }\r
157 \r
158 bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {\r
159   return true;\r
160 }\r
161 \r
162 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {\r
163 }\r
164 \r
165 void RenderPdf(const char* name, const char* pBuf, size_t len,\r
166                bool write_images) {\r
167   printf("Rendering PDF file %s.\n", name);\r
168 \r
169   IPDF_JSPLATFORM platform_callbacks;\r
170   memset(&platform_callbacks, '\0', sizeof(platform_callbacks));\r
171   platform_callbacks.version = 1;\r
172   platform_callbacks.app_alert = Form_Alert;\r
173 \r
174   FPDF_FORMFILLINFO form_callbacks;\r
175   memset(&form_callbacks, '\0', sizeof(form_callbacks));\r
176   form_callbacks.version = 1;\r
177   form_callbacks.m_pJsPlatform = &platform_callbacks;\r
178 \r
179   TestLoader loader(pBuf, len);\r
180 \r
181   FPDF_FILEACCESS file_access;\r
182   memset(&file_access, '\0', sizeof(file_access));\r
183   file_access.m_FileLen = len;\r
184   file_access.m_GetBlock = Get_Block;\r
185   file_access.m_Param = &loader;\r
186 \r
187   FX_FILEAVAIL file_avail;\r
188   memset(&file_avail, '\0', sizeof(file_avail));\r
189   file_avail.version = 1;\r
190   file_avail.IsDataAvail = Is_Data_Avail;\r
191 \r
192   FX_DOWNLOADHINTS hints;\r
193   memset(&hints, '\0', sizeof(hints));\r
194   hints.version = 1;\r
195   hints.AddSegment = Add_Segment;\r
196 \r
197   FPDF_DOCUMENT doc;\r
198   FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access);\r
199 \r
200   (void) FPDFAvail_IsDocAvail(pdf_avail, &hints);\r
201 \r
202   if (!FPDFAvail_IsLinearized(pdf_avail)) {\r
203     printf("Non-linearized path...\n");\r
204     doc = FPDF_LoadCustomDocument(&file_access, NULL);\r
205   } else {\r
206     printf("Linearized path...\n");\r
207     doc = FPDFAvail_GetDocument(pdf_avail, NULL);\r
208   }\r
209 \r
210   (void) FPDF_GetDocPermissions(doc);\r
211   (void) FPDFAvail_IsFormAvail(pdf_avail, &hints);\r
212 \r
213   FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnviroument(doc, &form_callbacks);\r
214   FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD);\r
215   FPDF_SetFormFieldHighlightAlpha(form, 100);\r
216 \r
217   int first_page = FPDFAvail_GetFirstPageNum(doc);\r
218   (void) FPDFAvail_IsPageAvail(pdf_avail, first_page, &hints);\r
219 \r
220   int page_count = FPDF_GetPageCount(doc);\r
221   for (int i = 0; i < page_count; ++i) {\r
222     (void) FPDFAvail_IsPageAvail(pdf_avail, i, &hints);\r
223   }\r
224 \r
225   FORM_DoDocumentJSAction(form);\r
226   FORM_DoDocumentOpenAction(form);\r
227 \r
228   for (int i = 0; i < page_count; ++i) {\r
229     FPDF_PAGE page = FPDF_LoadPage(doc, i);\r
230     FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page);\r
231     FORM_OnAfterLoadPage(page, form);\r
232     FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN);\r
233 \r
234     int width = static_cast<int>(FPDF_GetPageWidth(page));\r
235     int height = static_cast<int>(FPDF_GetPageHeight(page));\r
236     FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);\r
237     FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 255, 255, 255, 255);\r
238 \r
239     FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);\r
240     FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0);\r
241     if (write_images) {\r
242       const char* buffer = reinterpret_cast<const char*>(\r
243           FPDFBitmap_GetBuffer(bitmap));\r
244       int stride = FPDFBitmap_GetStride(bitmap);\r
245       WritePpm(name, i, buffer, stride, width, height);\r
246     }\r
247 \r
248     FPDFBitmap_Destroy(bitmap);\r
249 \r
250     FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE);\r
251     FORM_OnBeforeClosePage(page, form);\r
252     FPDFText_ClosePage(text_page);\r
253     FPDF_ClosePage(page);\r
254   }\r
255 \r
256   FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC);\r
257   FPDFDOC_ExitFormFillEnviroument(form);\r
258   FPDF_CloseDocument(doc);\r
259   FPDFAvail_Destroy(pdf_avail);\r
260 \r
261   printf("Loaded, parsed and rendered %d pages.\n", page_count);\r
262 }\r
263 \r
264 int main(int argc, const char* argv[]) {\r
265   v8::V8::InitializeICU();\r
266   bool write_images = false;\r
267   std::list<const char*> files;\r
268   if (!ParseCommandLine(argc, argv, &write_images, &files)) {\r
269     printf("Usage is: test [--write_images] /path/to/pdf\n");\r
270     printf("--write_images - to write page images <pdf-name>.<page-number>.ppm\n");\r
271     return 1;\r
272   }\r
273 \r
274   FPDF_InitLibrary(NULL);\r
275 \r
276   UNSUPPORT_INFO unsuppored_info;\r
277   memset(&unsuppored_info, '\0', sizeof(unsuppored_info));\r
278   unsuppored_info.version = 1;\r
279   unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler;\r
280 \r
281   FSDK_SetUnSpObjProcessHandler(&unsuppored_info);\r
282 \r
283   while (!files.empty()) {\r
284     const char* filename = files.front();\r
285     files.pop_front();\r
286     FILE* file = fopen(filename, FOPEN_READ);\r
287     if (!file) {\r
288       fprintf(stderr, "Failed to open: %s\n", filename);\r
289       continue;\r
290     }\r
291     (void) fseek(file, 0, SEEK_END);\r
292     size_t len = ftell(file);\r
293     (void) fseek(file, 0, SEEK_SET);\r
294     char* pBuf = (char*) malloc(len);\r
295     size_t ret = fread(pBuf, 1, len, file);\r
296     (void) fclose(file);\r
297     if (ret != len) {\r
298       fprintf(stderr, "Failed to read: %s\n", filename);\r
299     } else {\r
300       RenderPdf(filename, pBuf, len, write_images);\r
301     }\r
302     free(pBuf);\r
303   }\r
304 \r
305   FPDF_DestroyLibrary();\r
306 \r
307   return 0;\r
308 }\r
309 \r