Add FPDFSaveEmbedderTest.SaveLinearizedDoc

Bug: pdfium:614
Change-Id: I3c6cd16dfe0ac5db66cc9e996d3f4e74a5d9d716
Reviewed-on: https://pdfium-review.googlesource.com/18251
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdfppo_embeddertest.cpp b/fpdfsdk/fpdfppo_embeddertest.cpp
index 1df677f..c642b71 100644
--- a/fpdfsdk/fpdfppo_embeddertest.cpp
+++ b/fpdfsdk/fpdfppo_embeddertest.cpp
@@ -158,7 +158,7 @@
     ASSERT_EQ(200, FPDFBitmap_GetHeight(bitmap));
     ASSERT_EQ(800, FPDFBitmap_GetStride(bitmap));
 
-    std::string digest = HashBitmap(bitmap, 200, 200);
+    std::string digest = HashBitmap(bitmap);
     FPDFBitmap_Destroy(bitmap);
     UnloadPage(page);
     EXPECT_EQ(kHashes[i], digest);
@@ -177,7 +177,7 @@
     ASSERT_EQ(200, FPDFBitmap_GetHeight(bitmap));
     ASSERT_EQ(800, FPDFBitmap_GetStride(bitmap));
 
-    std::string digest = HashBitmap(bitmap, 200, 200);
+    std::string digest = HashBitmap(bitmap);
     FPDFBitmap_Destroy(bitmap);
     FPDF_ClosePage(page);
     EXPECT_EQ(kHashes[i], digest);
@@ -195,7 +195,7 @@
   ASSERT_EQ(200, FPDFBitmap_GetHeight(bitmap));
   ASSERT_EQ(800, FPDFBitmap_GetStride(bitmap));
 
-  std::string digest = HashBitmap(bitmap, 200, 200);
+  std::string digest = HashBitmap(bitmap);
   FPDFBitmap_Destroy(bitmap);
   FPDF_ClosePage(page);
 
@@ -211,7 +211,7 @@
   ASSERT_EQ(200, FPDFBitmap_GetHeight(new_bitmap));
   ASSERT_EQ(800, FPDFBitmap_GetStride(new_bitmap));
 
-  std::string new_digest = HashBitmap(new_bitmap, 200, 200);
+  std::string new_digest = HashBitmap(new_bitmap);
   FPDFBitmap_Destroy(new_bitmap);
   FPDF_ClosePage(new_page);
   FPDF_CloseDocument(new_doc);
diff --git a/fpdfsdk/fpdfsave_embeddertest.cpp b/fpdfsdk/fpdfsave_embeddertest.cpp
index 54eb347..3122be1 100644
--- a/fpdfsdk/fpdfsave_embeddertest.cpp
+++ b/fpdfsdk/fpdfsave_embeddertest.cpp
@@ -4,7 +4,7 @@
 
 #include "public/fpdf_save.h"
 
-#include <string.h>
+#include <string>
 
 #include "core/fxcrt/fx_string.h"
 #include "public/fpdf_edit.h"
@@ -59,6 +59,39 @@
   UnloadPage(page);
 }
 
+TEST_F(FPDFSaveEmbedderTest, SaveLinearizedDoc) {
+  const int kPageCount = 3;
+  std::string original_md5[kPageCount];
+
+  EXPECT_TRUE(OpenDocument("linearized.pdf"));
+  for (int i = 0; i < kPageCount; ++i) {
+    FPDF_PAGE page = LoadPage(i);
+    FPDF_BITMAP bitmap = RenderPage(page);
+    EXPECT_EQ(612, FPDFBitmap_GetWidth(bitmap));
+    EXPECT_EQ(792, FPDFBitmap_GetHeight(bitmap));
+    original_md5[i] = HashBitmap(bitmap);
+    FPDFBitmap_Destroy(bitmap);
+    UnloadPage(page);
+  }
+
+  EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+  EXPECT_THAT(GetString(), testing::StartsWith("%PDF-1.6\r\n"));
+  EXPECT_THAT(GetString(), testing::HasSubstr("/Root "));
+  EXPECT_THAT(GetString(), testing::HasSubstr("/Info "));
+  EXPECT_EQ(8219u, GetString().length());
+
+  // Make sure new document renders the same as the old one.
+  EXPECT_TRUE(OpenSavedDocument());
+  for (int i = 0; i < kPageCount; ++i) {
+    FPDF_PAGE page = LoadSavedPage(i);
+    FPDF_BITMAP bitmap = RenderSavedPage(page);
+    EXPECT_EQ(original_md5[i], HashBitmap(bitmap));
+    FPDFBitmap_Destroy(bitmap);
+    CloseSavedPage(page);
+  }
+  CloseSavedDocument();
+}
+
 TEST_F(FPDFSaveEmbedderTest, BUG_342) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index 36ee08f..bb202bf 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -106,6 +106,8 @@
   info->version = 1;
   info->FSDK_UnSupport_Handler = UnsupportedHandlerTrampoline;
   FSDK_SetUnSpObjProcessHandler(info);
+
+  m_SavedDocument = nullptr;
 }
 
 void EmbedderTest::TearDown() {
@@ -347,6 +349,10 @@
   return page;
 }
 
+FPDF_BITMAP EmbedderTest::RenderSavedPage(FPDF_PAGE page) {
+  return RenderPageWithFlags(page, m_SavedForm, 0);
+}
+
 void EmbedderTest::CloseSavedPage(FPDF_PAGE page) {
   ASSERT(page);
   FPDF_ClosePage(page);
@@ -424,14 +430,14 @@
                                                               page_index);
 }
 
-std::string EmbedderTest::HashBitmap(FPDF_BITMAP bitmap,
-                                     int expected_width,
-                                     int expected_height) {
+// static
+std::string EmbedderTest::HashBitmap(FPDF_BITMAP bitmap) {
   uint8_t digest[16];
-  CRYPT_MD5Generate(
-      static_cast<uint8_t*>(FPDFBitmap_GetBuffer(bitmap)),
-      expected_width * GetBitmapBytesPerPixel(bitmap) * expected_height,
-      digest);
+  CRYPT_MD5Generate(static_cast<uint8_t*>(FPDFBitmap_GetBuffer(bitmap)),
+                    FPDFBitmap_GetWidth(bitmap) *
+                        GetBitmapBytesPerPixel(bitmap) *
+                        FPDFBitmap_GetHeight(bitmap),
+                    digest);
   return CryptToBase16(digest);
 }
 
@@ -452,8 +458,7 @@
   if (!expected_md5sum)
     return;
 
-  EXPECT_EQ(expected_md5sum,
-            HashBitmap(bitmap, expected_width, expected_height));
+  EXPECT_EQ(expected_md5sum, HashBitmap(bitmap));
 }
 
 // static
diff --git a/testing/embedder_test.h b/testing/embedder_test.h
index df9e837..7b6b40a 100644
--- a/testing/embedder_test.h
+++ b/testing/embedder_test.h
@@ -125,9 +125,7 @@
   FPDF_FORMHANDLE SetupFormFillEnvironment(FPDF_DOCUMENT doc);
 
   // Return the hash of |bitmap|.
-  static std::string HashBitmap(FPDF_BITMAP bitmap,
-                                int expected_width,
-                                int expected_height);
+  static std::string HashBitmap(FPDF_BITMAP bitmap);
 
   // Check |bitmap| to make sure it has the right dimensions and content.
   static void CompareBitmap(FPDF_BITMAP bitmap,
@@ -146,6 +144,7 @@
   FPDF_DOCUMENT OpenSavedDocument(const char* password = nullptr);
   void CloseSavedDocument();
   FPDF_PAGE LoadSavedPage(int page_number);
+  FPDF_BITMAP RenderSavedPage(FPDF_PAGE page);
   void CloseSavedPage(FPDF_PAGE page);
   void VerifySavedRendering(FPDF_PAGE page,
                             int width,
diff --git a/testing/resources/linearized.pdf b/testing/resources/linearized.pdf
new file mode 100644
index 0000000..3c2d3a2
--- /dev/null
+++ b/testing/resources/linearized.pdf
Binary files differ