Support --md5 with pdfium_test --skp
Supports --md5 with pdfium_test's SKP output format by playing back the
SKP to an intermediate buffer.
Bug: pdfium:1929
Change-Id: I9f2b3bedb1a9c6cb1c16872e3df8bd8f444cc959
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/101474
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: K. Moon <kmoon@chromium.org>
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 1e63000..42f33ec 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -56,6 +56,16 @@
#include <valgrind/callgrind.h>
#endif // ENABLE_CALLGRIND
+#ifdef PDF_ENABLE_SKIA
+#include "third_party/skia/include/core/SkCanvas.h" // nogncheck
+#include "third_party/skia/include/core/SkColor.h" // nogncheck
+#include "third_party/skia/include/core/SkPicture.h" // nogncheck
+#include "third_party/skia/include/core/SkPictureRecorder.h" // nogncheck
+#include "third_party/skia/include/core/SkPixmap.h" // nogncheck
+#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck
+#include "third_party/skia/include/core/SkSurface.h" // nogncheck
+#endif
+
#ifdef PDF_ENABLE_V8
#include "testing/v8_initializer.h"
#include "v8/include/libplatform/libplatform.h"
@@ -757,7 +767,7 @@
public:
virtual ~PageRenderer() = default;
- // Returns `true` if the rendered output exists. Must call `Start()` first.
+ // Returns `true` if the rendered output exists. Must call `Finish()` first.
virtual bool HasOutput() const = 0;
// Starts rendering the page, returning `false` on failure.
@@ -808,7 +818,7 @@
bool alpha = FPDFPage_HasTransparency(page());
bitmap_.reset(FPDFBitmap_Create(/*width=*/width(), /*height=*/height(),
/*alpha=*/alpha));
- if (!HasOutput())
+ if (!bitmap_)
return false;
FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
@@ -958,37 +968,54 @@
/*height=*/height,
/*flags=*/flags) {}
- bool HasOutput() const override { return !!recorder_; }
+ bool HasOutput() const override { return !!picture_; }
bool Start() override {
recorder_.reset(reinterpret_cast<SkPictureRecorder*>(
FPDF_RenderPageSkp(page(), /*size_x=*/width(), /*size_y=*/height())));
- return HasOutput();
+ return !!recorder_;
}
void Finish(FPDF_FORMHANDLE form) override {
FPDF_FFLRecord(form, reinterpret_cast<FPDF_RECORDER>(recorder_.get()),
page(), /*start_x=*/0, /*start_y=*/0, /*size_x=*/width(),
/*size_y=*/height(), /*rotate=*/0, /*flags=*/0);
+
+ picture_ = recorder_->finishRecordingAsPicture();
+ recorder_.reset();
}
bool Write(const std::string& name, int page_index, bool md5) override {
- std::string image_file_name =
- WriteSkp(name.c_str(), page_index, recorder_.get());
+ std::string image_file_name = WriteSkp(name.c_str(), page_index, *picture_);
if (image_file_name.empty())
return false;
if (md5) {
- // Supporting --md5 would require rasterization.
- // TODO(crbug.com/pdfium/1929): It may be useful to compute the MD5 of the
- // replayed SKP, in order to compare with direct rasterization.
- return false;
+ // Play back the `SkPicture` so we can take a hash of the result.
+ sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
+ /*width=*/width(), /*height=*/height());
+ if (!surface)
+ return false;
+
+ // Must clear to white before replay to match initial `CFX_DIBitmap`.
+ surface->getCanvas()->clear(SK_ColorWHITE);
+ surface->getCanvas()->drawPicture(picture_);
+
+ // Write the filename and the MD5 of the buffer to stdout.
+ SkPixmap pixmap;
+ if (!surface->peekPixels(&pixmap))
+ return false;
+
+ OutputMD5Hash(image_file_name.c_str(),
+ {static_cast<const uint8_t*>(pixmap.addr()),
+ pixmap.computeByteSize()});
}
return true;
}
private:
std::unique_ptr<SkPictureRecorder> recorder_;
+ sk_sp<SkPicture> picture_;
};
#endif // PDF_ENABLE_SKIA
diff --git a/samples/pdfium_test_write_helper.cc b/samples/pdfium_test_write_helper.cc
index 4111208..c3e170e 100644
--- a/samples/pdfium_test_write_helper.cc
+++ b/samples/pdfium_test_write_helper.cc
@@ -19,6 +19,11 @@
#include "testing/image_diff/image_diff_png.h"
#include "third_party/base/notreached.h"
+#ifdef PDF_ENABLE_SKIA
+#include "third_party/skia/include/core/SkPicture.h" // nogncheck
+#include "third_party/skia/include/core/SkStream.h" // nogncheck
+#endif
+
namespace {
bool CheckDimensions(int stride, int width, int height) {
@@ -513,9 +518,7 @@
#endif // _WIN32
#ifdef PDF_ENABLE_SKIA
-std::string WriteSkp(const char* pdf_name,
- int num,
- SkPictureRecorder* recorder) {
+std::string WriteSkp(const char* pdf_name, int num, const SkPicture& picture) {
char filename[256];
int chars_formatted =
snprintf(filename, sizeof(filename), "%s.%d.skp", pdf_name, num);
@@ -526,9 +529,8 @@
return "";
}
- sk_sp<SkPicture> picture(recorder->finishRecordingAsPicture());
SkFILEWStream wStream(filename);
- picture->serialize(&wStream);
+ picture.serialize(&wStream);
return std::string(filename);
}
#endif
diff --git a/samples/pdfium_test_write_helper.h b/samples/pdfium_test_write_helper.h
index 06f1e34..ffeba1f 100644
--- a/samples/pdfium_test_write_helper.h
+++ b/samples/pdfium_test_write_helper.h
@@ -10,8 +10,7 @@
#include "public/fpdfview.h"
#ifdef PDF_ENABLE_SKIA
-#include "third_party/skia/include/core/SkPictureRecorder.h" // nogncheck
-#include "third_party/skia/include/core/SkStream.h" // nogncheck
+class SkPicture;
#endif
std::string WritePpm(const char* pdf_name,
@@ -41,9 +40,7 @@
#endif // _WIN32
#ifdef PDF_ENABLE_SKIA
-std::string WriteSkp(const char* pdf_name,
- int num,
- SkPictureRecorder* recorder);
+std::string WriteSkp(const char* pdf_name, int num, const SkPicture& picture);
#endif // PDF_ENABLE_SKIA
void WriteAttachments(FPDF_DOCUMENT doc, const std::string& name);