summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Lunger <jlunger@google.com>2017-12-27 10:18:50 -0500
committerChromium commit bot <commit-bot@chromium.org>2018-01-09 23:41:53 +0000
commitecd063eccdb25cbb573d01fc512a3d40322761be (patch)
treec190a0305bb384efe82bc08de57fede4814017d6
parent81a1ac47e5d93980b59b1c34e8cf1bb22a89a936 (diff)
downloadpdfium-ecd063eccdb25cbb573d01fc512a3d40322761be.tar.xz
Expose marked content IDs for images and alt text.
- Adds two new public bits of API: - StructElement_GetMCID(STRUCTELEMENT) to return the marked content ID of the struct element. - IMAGEOBJ_METADATA.mcid to contain the marked content ID of the image. - Restores ContentMark::GetMCID, which was removed with other dead code in https://pdfium-review.googlesource.com/c/pdfium/+/19170. - Adds a couple calls to tests, including a simple new PDF to test the struct tree marked content ID. Bug:pdfium:957 Change-Id: I92856e43d741df989e53a575a08258da19a39f22 Reviewed-on: https://pdfium-review.googlesource.com/20632 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
-rw-r--r--core/fpdfapi/page/cpdf_contentmark.cpp14
-rw-r--r--core/fpdfapi/page/cpdf_contentmark.h2
-rw-r--r--fpdfsdk/fpdf_structtree.cpp8
-rw-r--r--fpdfsdk/fpdf_structtree_embeddertest.cpp21
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp3
-rw-r--r--fpdfsdk/fpdfeditimg.cpp2
-rw-r--r--public/fpdf_edit.h3
-rw-r--r--public/fpdf_structtree.h10
-rw-r--r--testing/resources/marked_content_id.pdfbin0 -> 13109 bytes
9 files changed, 63 insertions, 0 deletions
diff --git a/core/fpdfapi/page/cpdf_contentmark.cpp b/core/fpdfapi/page/cpdf_contentmark.cpp
index 1d70edeb51..c54ef55b1f 100644
--- a/core/fpdfapi/page/cpdf_contentmark.cpp
+++ b/core/fpdfapi/page/cpdf_contentmark.cpp
@@ -25,6 +25,11 @@ const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(size_t i) const {
return m_Ref.GetObject()->GetItem(i);
}
+int CPDF_ContentMark::GetMarkedContentID() const {
+ const MarkData* pData = m_Ref.GetObject();
+ return pData ? pData->GetMarkedContentID() : -1;
+}
+
void CPDF_ContentMark::AddMark(const ByteString& name,
CPDF_Dictionary* pDict,
bool bDirect) {
@@ -53,6 +58,15 @@ const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(
return m_Marks[index];
}
+int CPDF_ContentMark::MarkData::GetMarkedContentID() const {
+ for (const auto& mark : m_Marks) {
+ const CPDF_Dictionary* pDict = mark.GetParam();
+ if (pDict && pDict->KeyExist("MCID"))
+ return pDict->GetIntegerFor("MCID");
+ }
+ return -1;
+}
+
void CPDF_ContentMark::MarkData::AddMark(const ByteString& name,
CPDF_Dictionary* pDict,
bool bDirect) {
diff --git a/core/fpdfapi/page/cpdf_contentmark.h b/core/fpdfapi/page/cpdf_contentmark.h
index d9bc35a7fb..78a948697e 100644
--- a/core/fpdfapi/page/cpdf_contentmark.h
+++ b/core/fpdfapi/page/cpdf_contentmark.h
@@ -21,6 +21,7 @@ class CPDF_ContentMark {
CPDF_ContentMark(const CPDF_ContentMark& that);
~CPDF_ContentMark();
+ int GetMarkedContentID() const;
size_t CountItems() const;
const CPDF_ContentMarkItem& GetItem(size_t i) const;
@@ -39,6 +40,7 @@ class CPDF_ContentMark {
size_t CountItems() const;
const CPDF_ContentMarkItem& GetItem(size_t index) const;
+ int GetMarkedContentID() const;
void AddMark(const ByteString& name,
CPDF_Dictionary* pDict,
bool bDictNeedClone);
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp
index 30b7c3fce7..676824ef99 100644
--- a/fpdfsdk/fpdf_structtree.cpp
+++ b/fpdfsdk/fpdf_structtree.cpp
@@ -83,6 +83,14 @@ FPDF_StructElement_GetAltText(FPDF_STRUCTELEMENT struct_element,
: 0;
}
+FPDF_EXPORT int FPDF_CALLCONV
+FPDF_StructElement_GetMarkedContentID(FPDF_STRUCTELEMENT struct_element) {
+ CPDF_StructElement* elem = ToStructTreeElement(struct_element);
+ CPDF_Object* p =
+ (elem && elem->GetDict()) ? elem->GetDict()->GetObjectFor("K") : nullptr;
+ return p && p->IsNumber() ? p->GetInteger() : -1;
+}
+
FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDF_StructElement_GetType(FPDF_STRUCTELEMENT struct_element,
void* buffer,
diff --git a/fpdfsdk/fpdf_structtree_embeddertest.cpp b/fpdfsdk/fpdf_structtree_embeddertest.cpp
index 05b77fc0f7..7ca81f7b2e 100644
--- a/fpdfsdk/fpdf_structtree_embeddertest.cpp
+++ b/fpdfsdk/fpdf_structtree_embeddertest.cpp
@@ -6,6 +6,7 @@
#include "public/fpdf_structtree.h"
#include "testing/embedder_test.h"
#include "testing/test_support.h"
+#include "third_party/base/optional.h"
class FPDFStructTreeEmbeddertest : public EmbedderTest {};
@@ -24,6 +25,7 @@ TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
EXPECT_EQ(nullptr, element);
element = FPDF_StructTree_GetChildAtIndex(struct_tree, 0);
ASSERT_NE(nullptr, element);
+ EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(element));
EXPECT_EQ(0U, FPDF_StructElement_GetAltText(element, nullptr, 0));
ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
@@ -34,6 +36,7 @@ TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
EXPECT_EQ(nullptr, child_element);
child_element = FPDF_StructElement_GetChildAtIndex(element, 0);
ASSERT_NE(nullptr, child_element);
+ EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(child_element));
EXPECT_EQ(0U, FPDF_StructElement_GetAltText(child_element, nullptr, 0));
ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
@@ -44,6 +47,7 @@ TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
EXPECT_EQ(nullptr, gchild_element);
gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 0);
ASSERT_NE(nullptr, gchild_element);
+ EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, nullptr, 0));
unsigned short buffer[12];
@@ -54,6 +58,7 @@ TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
for (size_t i = 0; i < FX_ArraySize(buffer); ++i)
EXPECT_EQ(0U, buffer[i]);
+ EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer,
sizeof(buffer)));
const wchar_t kExpected[] = L"Black Image";
@@ -69,6 +74,22 @@ TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
FPDF_ClosePage(page);
}
+TEST_F(FPDFStructTreeEmbeddertest, GetMarkedContentID) {
+ ASSERT_TRUE(OpenDocument("marked_content_id.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ FPDF_STRUCTTREE struct_tree = FPDF_StructTree_GetForPage(page);
+ ASSERT_TRUE(struct_tree);
+ ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree));
+
+ FPDF_STRUCTELEMENT element = FPDF_StructTree_GetChildAtIndex(struct_tree, 0);
+ EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentID(element));
+
+ FPDF_StructTree_Close(struct_tree);
+ FPDF_ClosePage(page);
+}
+
TEST_F(FPDFStructTreeEmbeddertest, GetType) {
ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
FPDF_PAGE page = LoadPage(0);
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 6cb2771154..ee2fc7eb85 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -1205,6 +1205,7 @@ TEST_F(FPDFEditEmbeddertest, GetImageMetadata) {
// |page|, all values are correct, with the last two being default values.
ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
ASSERT_TRUE(FPDFImageObj_GetImageMetadata(obj, nullptr, &metadata));
+ EXPECT_EQ(7, metadata.marked_content_id);
EXPECT_EQ(92u, metadata.width);
EXPECT_EQ(68u, metadata.height);
EXPECT_NEAR(96.000000, metadata.horizontal_dpi, 0.001);
@@ -1214,6 +1215,7 @@ TEST_F(FPDFEditEmbeddertest, GetImageMetadata) {
// Verify the metadata of a bitmap image with indexed colorspace.
ASSERT_TRUE(FPDFImageObj_GetImageMetadata(obj, page, &metadata));
+ EXPECT_EQ(7, metadata.marked_content_id);
EXPECT_EQ(92u, metadata.width);
EXPECT_EQ(68u, metadata.height);
EXPECT_NEAR(96.000000, metadata.horizontal_dpi, 0.001);
@@ -1225,6 +1227,7 @@ TEST_F(FPDFEditEmbeddertest, GetImageMetadata) {
obj = FPDFPage_GetObject(page, 37);
ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
ASSERT_TRUE(FPDFImageObj_GetImageMetadata(obj, page, &metadata));
+ EXPECT_EQ(9, metadata.marked_content_id);
EXPECT_EQ(126u, metadata.width);
EXPECT_EQ(106u, metadata.height);
EXPECT_NEAR(162.173752, metadata.horizontal_dpi, 0.001);
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
index 4842e35c76..0d7ba56559 100644
--- a/fpdfsdk/fpdfeditimg.cpp
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -267,6 +267,8 @@ FPDFImageObj_GetImageMetadata(FPDF_PAGEOBJECT image_object,
if (!pImg)
return false;
+ metadata->marked_content_id = pObj->m_ContentMark.GetMarkedContentID();
+
const int nPixelWidth = pImg->GetPixelWidth();
const int nPixelHeight = pImg->GetPixelHeight();
metadata->width = nPixelWidth;
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index 3bd246b0ad..685fbdd029 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -80,6 +80,9 @@ typedef struct FPDF_IMAGEOBJ_METADATA {
unsigned int bits_per_pixel;
// The image's colorspace. See above for the list of FPDF_COLORSPACE_*.
int colorspace;
+ // The image's marked content ID. Useful for pairing with associated alt-text.
+ // A value of -1 indicates no ID.
+ int marked_content_id;
} FPDF_IMAGEOBJ_METADATA;
#ifdef __cplusplus
diff --git a/public/fpdf_structtree.h b/public/fpdf_structtree.h
index 688471f28d..2e86ae65b3 100644
--- a/public/fpdf_structtree.h
+++ b/public/fpdf_structtree.h
@@ -75,6 +75,16 @@ FPDF_StructElement_GetAltText(FPDF_STRUCTELEMENT struct_element,
void* buffer,
unsigned long buflen);
+// Function: FPDF_StructElement_GetMarkedContentID
+// Get the marked content ID for a given element.
+// Parameters:
+// struct_element - Handle to the struct element.
+// Return value:
+// The marked content ID of the element. If no ID exists, returns
+// -1.
+FPDF_EXPORT int FPDF_CALLCONV
+FPDF_StructElement_GetMarkedContentID(FPDF_STRUCTELEMENT struct_element);
+
// Function: FPDF_StructElement_GetType
// Get the type (/S) for a given element.
// Parameters:
diff --git a/testing/resources/marked_content_id.pdf b/testing/resources/marked_content_id.pdf
new file mode 100644
index 0000000000..ddbf11f319
--- /dev/null
+++ b/testing/resources/marked_content_id.pdf
Binary files differ