 Chromium Code Reviews
 Chromium Code Reviews Issue 1412083010:
  Merge to XFA: Support linearized loading  (Closed) 
  Base URL: https://pdfium.googlesource.com/pdfium.git@xfa
    
  
    Issue 1412083010:
  Merge to XFA: Support linearized loading  (Closed) 
  Base URL: https://pdfium.googlesource.com/pdfium.git@xfa| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <limits.h> | 5 #include <limits.h> | 
| 6 #include <stdio.h> | 6 #include <stdio.h> | 
| 7 #include <stdlib.h> | 7 #include <stdlib.h> | 
| 8 #include <string.h> | 8 #include <string.h> | 
| 9 #include <wchar.h> | 9 #include <wchar.h> | 
| 10 | 10 | 
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 return true; | 325 return true; | 
| 326 } | 326 } | 
| 327 | 327 | 
| 328 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { | 328 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { | 
| 329 return true; | 329 return true; | 
| 330 } | 330 } | 
| 331 | 331 | 
| 332 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { | 332 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { | 
| 333 } | 333 } | 
| 334 | 334 | 
| 335 FPDF_BOOL RenderPage(const std::string& name, | |
| 336 const FPDF_DOCUMENT& doc, | |
| 337 const FPDF_FORMHANDLE& form, | |
| 338 const int page_index, | |
| 339 const Options& options) { | |
| 340 FPDF_PAGE page = FPDF_LoadPage(doc, page_index); | |
| 341 if (!page) { | |
| 342 return FALSE; | |
| 343 } | |
| 344 FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); | |
| 345 FORM_OnAfterLoadPage(page, form); | |
| 346 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); | |
| 347 | |
| 348 double scale = 1.0; | |
| 349 if (!options.scale_factor_as_string.empty()) { | |
| 350 std::stringstream(options.scale_factor_as_string) >> scale; | |
| 351 } | |
| 352 int width = static_cast<int>(FPDF_GetPageWidth(page) * scale); | |
| 353 int height = static_cast<int>(FPDF_GetPageHeight(page) * scale); | |
| 354 | |
| 355 FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); | |
| 356 if (!bitmap) { | |
| 357 fprintf(stderr, "Page was too large to be rendered.\n"); | |
| 358 return FALSE; | |
| 359 } | |
| 360 | |
| 361 FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); | |
| 362 FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); | |
| 363 | |
| 364 FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); | |
| 365 int stride = FPDFBitmap_GetStride(bitmap); | |
| 366 const char* buffer = | |
| 367 reinterpret_cast<const char*>(FPDFBitmap_GetBuffer(bitmap)); | |
| 368 | |
| 369 switch (options.output_format) { | |
| 370 #ifdef _WIN32 | |
| 371 case OUTPUT_BMP: | |
| 372 WriteBmp(name.c_str(), page_index, buffer, stride, width, height); | |
| 373 break; | |
| 374 | |
| 375 case OUTPUT_EMF: | |
| 376 WriteEmf(page, name.c_str(), page_index); | |
| 377 break; | |
| 378 #endif | |
| 379 case OUTPUT_PNG: | |
| 380 WritePng(name.c_str(), page_index, buffer, stride, width, height); | |
| 381 break; | |
| 382 | |
| 383 case OUTPUT_PPM: | |
| 384 WritePpm(name.c_str(), page_index, buffer, stride, width, height); | |
| 385 break; | |
| 386 | |
| 387 default: | |
| 388 break; | |
| 389 } | |
| 390 | |
| 391 FPDFBitmap_Destroy(bitmap); | |
| 392 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); | |
| 393 FORM_OnBeforeClosePage(page, form); | |
| 394 FPDFText_ClosePage(text_page); | |
| 395 FPDF_ClosePage(page); | |
| 396 return TRUE; | |
| 397 } | |
| 398 | |
| 335 void RenderPdf(const std::string& name, const char* pBuf, size_t len, | 399 void RenderPdf(const std::string& name, const char* pBuf, size_t len, | 
| 336 const Options& options) { | 400 const Options& options) { | 
| 337 fprintf(stderr, "Rendering PDF file %s.\n", name.c_str()); | 401 fprintf(stderr, "Rendering PDF file %s.\n", name.c_str()); | 
| 338 | 402 | 
| 339 IPDF_JSPLATFORM platform_callbacks; | 403 IPDF_JSPLATFORM platform_callbacks; | 
| 340 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); | 404 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); | 
| 341 platform_callbacks.version = 3; | 405 platform_callbacks.version = 3; | 
| 342 platform_callbacks.app_alert = ExampleAppAlert; | 406 platform_callbacks.app_alert = ExampleAppAlert; | 
| 343 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; | 407 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; | 
| 344 | 408 | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 358 memset(&file_avail, '\0', sizeof(file_avail)); | 422 memset(&file_avail, '\0', sizeof(file_avail)); | 
| 359 file_avail.version = 1; | 423 file_avail.version = 1; | 
| 360 file_avail.IsDataAvail = Is_Data_Avail; | 424 file_avail.IsDataAvail = Is_Data_Avail; | 
| 361 | 425 | 
| 362 FX_DOWNLOADHINTS hints; | 426 FX_DOWNLOADHINTS hints; | 
| 363 memset(&hints, '\0', sizeof(hints)); | 427 memset(&hints, '\0', sizeof(hints)); | 
| 364 hints.version = 1; | 428 hints.version = 1; | 
| 365 hints.AddSegment = Add_Segment; | 429 hints.AddSegment = Add_Segment; | 
| 366 | 430 | 
| 367 FPDF_DOCUMENT doc; | 431 FPDF_DOCUMENT doc; | 
| 432 int nRet = PDF_DATA_NOTAVAIL; | |
| 433 FPDF_BOOL bIsLinearized = FALSE; | |
| 368 FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access); | 434 FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access); | 
| 369 | 435 | 
| 
Lei Zhang
2015/11/10 04:40:19
nit: there's no white space here on master
 
jun_fang
2015/11/10 06:13:57
Acknowledged.
 | |
| 370 (void)FPDFAvail_IsDocAvail(pdf_avail, &hints); | 436 if (FPDFAvail_IsLinearized(pdf_avail) == PDF_LINEARIZED) { | 
| 371 | 437 fprintf(stderr, "Linearized path...\n"); | 
| 372 if (FPDFAvail_IsLinearized(pdf_avail)) | |
| 373 doc = FPDFAvail_GetDocument(pdf_avail, nullptr); | 438 doc = FPDFAvail_GetDocument(pdf_avail, nullptr); | 
| 374 else | 439 if (doc) { | 
| 440 while (nRet == PDF_DATA_NOTAVAIL) { | |
| 441 nRet = FPDFAvail_IsDocAvail(pdf_avail, &hints); | |
| 442 } | |
| 443 if (nRet == PDF_DATA_ERROR) { | |
| 444 fprintf(stderr, "Unknown error in checking if doc was available.\n"); | |
| 445 return; | |
| 446 } | |
| 447 nRet = FPDFAvail_IsFormAvail(pdf_avail, &hints); | |
| 448 if (nRet == PDF_FORM_ERROR || nRet == PDF_FORM_NOTAVAIL) { | |
| 449 fprintf(stderr, | |
| 450 "Error %d was returned in checking if form was available.\n", | |
| 451 nRet); | |
| 452 return; | |
| 453 } | |
| 454 bIsLinearized = TRUE; | |
| 455 } | |
| 456 } else { | |
| 457 fprintf(stderr, "Non-linearized path...\n"); | |
| 375 doc = FPDF_LoadCustomDocument(&file_access, nullptr); | 458 doc = FPDF_LoadCustomDocument(&file_access, nullptr); | 
| 459 } | |
| 376 | 460 | 
| 377 if (!doc) { | 461 if (!doc) { | 
| 378 unsigned long err = FPDF_GetLastError(); | 462 unsigned long err = FPDF_GetLastError(); | 
| 379 fprintf(stderr, "Load pdf docs unsuccessful: "); | 463 fprintf(stderr, "Load pdf docs unsuccessful: "); | 
| 380 switch (err) { | 464 switch (err) { | 
| 381 case FPDF_ERR_SUCCESS: | 465 case FPDF_ERR_SUCCESS: | 
| 382 fprintf(stderr, "Success"); | 466 fprintf(stderr, "Success"); | 
| 383 break; | 467 break; | 
| 384 case FPDF_ERR_UNKNOWN: | 468 case FPDF_ERR_UNKNOWN: | 
| 385 fprintf(stderr, "Unknown error"); | 469 fprintf(stderr, "Unknown error"); | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 402 default: | 486 default: | 
| 403 fprintf(stderr, "Unknown error %ld", err); | 487 fprintf(stderr, "Unknown error %ld", err); | 
| 404 } | 488 } | 
| 405 fprintf(stderr, ".\n"); | 489 fprintf(stderr, ".\n"); | 
| 406 | 490 | 
| 407 FPDFAvail_Destroy(pdf_avail); | 491 FPDFAvail_Destroy(pdf_avail); | 
| 408 return; | 492 return; | 
| 409 } | 493 } | 
| 410 | 494 | 
| 411 (void)FPDF_GetDocPermissions(doc); | 495 (void)FPDF_GetDocPermissions(doc); | 
| 412 (void)FPDFAvail_IsFormAvail(pdf_avail, &hints); | |
| 413 | 496 | 
| 414 FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); | 497 FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); | 
| 415 int docType = DOCTYPE_PDF; | 498 int docType = DOCTYPE_PDF; | 
| 416 if (FPDF_HasXFAField(doc, &docType) && docType != DOCTYPE_PDF && | 499 if (FPDF_HasXFAField(doc, &docType) && docType != DOCTYPE_PDF && | 
| 417 !FPDF_LoadXFA(doc)) { | 500 !FPDF_LoadXFA(doc)) { | 
| 418 fprintf(stderr, "LoadXFA unsuccessful, continuing anyway.\n"); | 501 fprintf(stderr, "LoadXFA unsuccessful, continuing anyway.\n"); | 
| 419 } | 502 } | 
| 420 FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD); | 503 FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD); | 
| 421 FPDF_SetFormFieldHighlightAlpha(form, 100); | 504 FPDF_SetFormFieldHighlightAlpha(form, 100); | 
| 422 | 505 | 
| 423 int first_page = FPDFAvail_GetFirstPageNum(doc); | |
| 424 (void)FPDFAvail_IsPageAvail(pdf_avail, first_page, &hints); | |
| 425 | |
| 426 int page_count = FPDF_GetPageCount(doc); | |
| 427 for (int i = 0; i < page_count; ++i) { | |
| 428 (void)FPDFAvail_IsPageAvail(pdf_avail, i, &hints); | |
| 429 } | |
| 430 | |
| 431 FORM_DoDocumentJSAction(form); | 506 FORM_DoDocumentJSAction(form); | 
| 432 FORM_DoDocumentOpenAction(form); | 507 FORM_DoDocumentOpenAction(form); | 
| 433 | 508 | 
| 509 int page_count = FPDF_GetPageCount(doc); | |
| 434 int rendered_pages = 0; | 510 int rendered_pages = 0; | 
| 435 int bad_pages = 0; | 511 int bad_pages = 0; | 
| 436 for (int i = 0; i < page_count; ++i) { | 512 for (int i = 0; i < page_count; ++i) { | 
| 437 FPDF_PAGE page = FPDF_LoadPage(doc, i); | 513 if (bIsLinearized) { | 
| 438 if (!page) { | 514 nRet = PDF_DATA_NOTAVAIL; | 
| 515 while (nRet == PDF_DATA_NOTAVAIL) { | |
| 516 nRet = FPDFAvail_IsPageAvail(pdf_avail, i, &hints); | |
| 517 } | |
| 518 if (nRet == PDF_DATA_ERROR) { | |
| 519 fprintf(stderr, "Unknown error in checking if page %d is available.\n", | |
| 520 i); | |
| 521 return; | |
| 522 } | |
| 523 } | |
| 524 if (RenderPage(name, doc, form, i, options)) { | |
| 525 ++rendered_pages; | |
| 526 } else { | |
| 439 ++bad_pages; | 527 ++bad_pages; | 
| 440 continue; | |
| 441 } | 528 } | 
| 442 FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); | |
| 443 FORM_OnAfterLoadPage(page, form); | |
| 444 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); | |
| 445 | |
| 446 double scale = 1.0; | |
| 447 if (!options.scale_factor_as_string.empty()) { | |
| 448 std::stringstream(options.scale_factor_as_string) >> scale; | |
| 449 } | |
| 450 int width = static_cast<int>(FPDF_GetPageWidth(page) * scale); | |
| 451 int height = static_cast<int>(FPDF_GetPageHeight(page) * scale); | |
| 452 | |
| 453 FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); | |
| 454 if (!bitmap) { | |
| 455 fprintf(stderr, "Page was too large to be rendered.\n"); | |
| 456 bad_pages++; | |
| 457 continue; | |
| 458 } | |
| 459 | |
| 460 FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); | |
| 461 FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); | |
| 462 ++rendered_pages; | |
| 463 | |
| 464 FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); | |
| 465 int stride = FPDFBitmap_GetStride(bitmap); | |
| 466 const char* buffer = | |
| 467 reinterpret_cast<const char*>(FPDFBitmap_GetBuffer(bitmap)); | |
| 468 | |
| 469 switch (options.output_format) { | |
| 470 #ifdef _WIN32 | |
| 471 case OUTPUT_BMP: | |
| 472 WriteBmp(name.c_str(), i, buffer, stride, width, height); | |
| 473 break; | |
| 474 | |
| 475 case OUTPUT_EMF: | |
| 476 WriteEmf(page, name.c_str(), i); | |
| 477 break; | |
| 478 #endif | |
| 479 case OUTPUT_PPM: | |
| 480 WritePpm(name.c_str(), i, buffer, stride, width, height); | |
| 481 break; | |
| 482 | |
| 483 case OUTPUT_PNG: | |
| 484 WritePng(name.c_str(), i, buffer, stride, width, height); | |
| 485 break; | |
| 486 | |
| 487 default: | |
| 488 break; | |
| 489 } | |
| 490 | |
| 491 FPDFBitmap_Destroy(bitmap); | |
| 492 | |
| 493 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); | |
| 494 FORM_OnBeforeClosePage(page, form); | |
| 495 FPDFText_ClosePage(text_page); | |
| 496 FPDF_ClosePage(page); | |
| 497 } | 529 } | 
| 498 | 530 | 
| 499 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); | 531 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); | 
| 500 | 532 | 
| 501 // Note: The shut down order here is the reverse of the non-XFA branch order. | 533 // Note: The shut down order here is the reverse of the non-XFA branch order. | 
| 502 // Need to work out if this is required, and if it is, the lifetimes of | 534 // Need to work out if this is required, and if it is, the lifetimes of | 
| 503 // objects owned by |doc| that |form| reference. | 535 // objects owned by |doc| that |form| reference. | 
| 504 FPDF_CloseDocument(doc); | 536 FPDF_CloseDocument(doc); | 
| 505 FPDFDOC_ExitFormFillEnvironment(form); | 537 FPDFDOC_ExitFormFillEnvironment(form); | 
| 506 | 538 | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 } | 608 } | 
| 577 | 609 | 
| 578 FPDF_DestroyLibrary(); | 610 FPDF_DestroyLibrary(); | 
| 579 #ifdef PDF_ENABLE_V8 | 611 #ifdef PDF_ENABLE_V8 | 
| 580 v8::V8::ShutdownPlatform(); | 612 v8::V8::ShutdownPlatform(); | 
| 581 delete platform; | 613 delete platform; | 
| 582 #endif // PDF_ENABLE_V8 | 614 #endif // PDF_ENABLE_V8 | 
| 583 | 615 | 
| 584 return 0; | 616 return 0; | 
| 585 } | 617 } | 
| OLD | NEW |