blob: 547c7b0225fe39268ea425d3536c9dd692b8ac4b [file] [log] [blame]
K. Moon832a6942022-10-31 20:11:31 +00001// Copyright 2019 The PDFium Authors
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "public/fpdf_thumbnail.h"
6
Tom Sepezbb040742022-09-28 16:33:34 +00007#include <utility>
8
Lei Zhang87c415a2020-01-14 19:54:36 +00009#include "core/fpdfapi/page/cpdf_dib.h"
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000010#include "core/fpdfapi/page/cpdf_page.h"
11#include "core/fpdfapi/parser/cpdf_dictionary.h"
12#include "core/fpdfapi/parser/cpdf_stream.h"
13#include "core/fpdfapi/parser/cpdf_stream_acc.h"
Tom Sepez3b679fe2024-04-09 18:49:32 +000014#include "core/fxcrt/compiler_specific.h"
15#include "core/fxcrt/span.h"
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000016#include "core/fxge/dib/cfx_dibitmap.h"
17#include "fpdfsdk/cpdfsdk_helpers.h"
18#include "public/fpdfview.h"
19
20namespace {
21
Tom Sepez7870d8d2022-09-30 00:06:05 +000022RetainPtr<const CPDF_Stream> CPDFStreamForThumbnailFromPage(FPDF_PAGE page) {
Tom Sepez4ede0792022-10-07 20:25:36 +000023 const CPDF_Page* pdf_page = CPDFPageFromFPDFPage(page);
Lei Zhangd0dcedc2025-04-09 10:24:44 -070024 if (!pdf_page) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000025 return nullptr;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070026 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000027
Tom Sepez4ede0792022-10-07 20:25:36 +000028 RetainPtr<const CPDF_Dictionary> page_dict = pdf_page->GetDict();
Lei Zhangd0dcedc2025-04-09 10:24:44 -070029 if (!page_dict->KeyExist("Type")) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000030 return nullptr;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070031 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000032
Tom Sepez7870d8d2022-09-30 00:06:05 +000033 return page_dict->GetStreamFor("Thumb");
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000034}
35
36} // namespace
37
38FPDF_EXPORT unsigned long FPDF_CALLCONV
Lei Zhanga04a6542019-07-08 20:37:44 +000039FPDFPage_GetDecodedThumbnailData(FPDF_PAGE page,
40 void* buffer,
41 unsigned long buflen) {
Tom Sepez7870d8d2022-09-30 00:06:05 +000042 RetainPtr<const CPDF_Stream> thumb_stream =
43 CPDFStreamForThumbnailFromPage(page);
Lei Zhangd0dcedc2025-04-09 10:24:44 -070044 if (!thumb_stream) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000045 return 0u;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070046 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000047
Tom Sepez3b679fe2024-04-09 18:49:32 +000048 // SAFETY: caller ensures `buffer` points to at least `buflen` bytes.
Tom Sepez06943a92022-11-10 20:29:34 +000049 return DecodeStreamMaybeCopyAndReturnLength(
50 std::move(thumb_stream),
Tom Sepez3b679fe2024-04-09 18:49:32 +000051 UNSAFE_BUFFERS(pdfium::make_span(static_cast<uint8_t*>(buffer),
52 static_cast<size_t>(buflen))));
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000053}
54
55FPDF_EXPORT unsigned long FPDF_CALLCONV
Lei Zhanga04a6542019-07-08 20:37:44 +000056FPDFPage_GetRawThumbnailData(FPDF_PAGE page,
57 void* buffer,
58 unsigned long buflen) {
Tom Sepez7870d8d2022-09-30 00:06:05 +000059 RetainPtr<const CPDF_Stream> thumb_stream =
60 CPDFStreamForThumbnailFromPage(page);
Lei Zhangd0dcedc2025-04-09 10:24:44 -070061 if (!thumb_stream) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000062 return 0u;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070063 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000064
Tom Sepez3b679fe2024-04-09 18:49:32 +000065 // SAFETY: caller ensures `buffer` points to at least `buflen` bytes.
Tom Sepez06943a92022-11-10 20:29:34 +000066 return GetRawStreamMaybeCopyAndReturnLength(
67 std::move(thumb_stream),
Tom Sepez3b679fe2024-04-09 18:49:32 +000068 UNSAFE_BUFFERS(pdfium::make_span(static_cast<uint8_t*>(buffer),
69 static_cast<size_t>(buflen))));
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000070}
71
72FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
Lei Zhanga04a6542019-07-08 20:37:44 +000073FPDFPage_GetThumbnailAsBitmap(FPDF_PAGE page) {
Tom Sepezbb040742022-09-28 16:33:34 +000074 RetainPtr<const CPDF_Stream> thumb_stream =
Tom Sepez7870d8d2022-09-30 00:06:05 +000075 CPDFStreamForThumbnailFromPage(page);
Lei Zhangd0dcedc2025-04-09 10:24:44 -070076 if (!thumb_stream) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000077 return nullptr;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070078 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000079
Tom Sepez4ede0792022-10-07 20:25:36 +000080 const CPDF_Page* pdf_page = CPDFPageFromFPDFPage(page);
81 auto dib_source = pdfium::MakeRetain<CPDF_DIB>(pdf_page->GetDocument(),
82 std::move(thumb_stream));
83 const CPDF_DIB::LoadState start_status = dib_source->StartLoadDIBBase(
84 false, nullptr, pdf_page->GetPageResources().Get(), false,
fineaskotnikov231e7e12022-10-28 20:23:20 +000085 CPDF_ColorSpace::Family::kUnknown, false, {0, 0});
Lei Zhangd0dcedc2025-04-09 10:24:44 -070086 if (start_status == CPDF_DIB::LoadState::kFail) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000087 return nullptr;
Lei Zhangd0dcedc2025-04-09 10:24:44 -070088 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000089
90 auto thumb_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
Lei Zhang68f94c82024-01-11 05:53:52 +000091 if (!thumb_bitmap->Copy(std::move(dib_source))) {
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000092 return nullptr;
Lei Zhang68f94c82024-01-11 05:53:52 +000093 }
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000094
Lei Zhang1b73b022025-03-28 21:35:05 -070095 ValidateBitmapPremultiplyState(thumb_bitmap);
Jeremy Chinsen801e1bf2019-06-25 20:46:13 +000096 return FPDFBitmapFromCFXDIBitmap(thumb_bitmap.Leak());
97}