1 // Copyright 2019 PDFium Authors. All rights reserved.
2 // 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 
7 #include <vector>
8 
9 #include "core/fpdfapi/page/cpdf_dib.h"
10 #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"
14 #include "core/fxge/dib/cfx_dibitmap.h"
15 #include "fpdfsdk/cpdfsdk_helpers.h"
16 #include "public/fpdfview.h"
17 
18 namespace {
19 
CPDFStreamForThumbnailFromPage(FPDF_PAGE page)20 const CPDF_Stream* CPDFStreamForThumbnailFromPage(FPDF_PAGE page) {
21   const CPDF_Page* p_page = CPDFPageFromFPDFPage(page);
22   if (!p_page)
23     return nullptr;
24 
25   const CPDF_Dictionary* page_dict = p_page->GetDict();
26   if (!page_dict->KeyExist("Type"))
27     return nullptr;
28 
29   return page_dict->GetStreamFor("Thumb");
30 }
31 
32 }  // namespace
33 
34 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFPage_GetDecodedThumbnailData(FPDF_PAGE page,void * buffer,unsigned long buflen)35 FPDFPage_GetDecodedThumbnailData(FPDF_PAGE page,
36                                  void* buffer,
37                                  unsigned long buflen) {
38   const CPDF_Stream* thumb_stream = CPDFStreamForThumbnailFromPage(page);
39   if (!thumb_stream)
40     return 0u;
41 
42   return DecodeStreamMaybeCopyAndReturnLength(thumb_stream, buffer, buflen);
43 }
44 
45 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFPage_GetRawThumbnailData(FPDF_PAGE page,void * buffer,unsigned long buflen)46 FPDFPage_GetRawThumbnailData(FPDF_PAGE page,
47                              void* buffer,
48                              unsigned long buflen) {
49   const CPDF_Stream* thumb_stream = CPDFStreamForThumbnailFromPage(page);
50   if (!thumb_stream)
51     return 0u;
52 
53   return GetRawStreamMaybeCopyAndReturnLength(thumb_stream, buffer, buflen);
54 }
55 
56 FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
FPDFPage_GetThumbnailAsBitmap(FPDF_PAGE page)57 FPDFPage_GetThumbnailAsBitmap(FPDF_PAGE page) {
58   const CPDF_Stream* thumb_stream = CPDFStreamForThumbnailFromPage(page);
59   if (!thumb_stream)
60     return nullptr;
61 
62   const CPDF_Page* p_page = CPDFPageFromFPDFPage(page);
63 
64   auto p_source = pdfium::MakeRetain<CPDF_DIB>();
65   const CPDF_DIB::LoadState start_status = p_source->StartLoadDIBBase(
66       p_page->GetDocument(), thumb_stream, false, nullptr,
67       p_page->m_pPageResources.Get(), false, 0, false);
68   if (start_status == CPDF_DIB::LoadState::kFail)
69     return nullptr;
70 
71   auto thumb_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
72   if (!thumb_bitmap->Copy(p_source))
73     return nullptr;
74 
75   return FPDFBitmapFromCFXDIBitmap(thumb_bitmap.Leak());
76 }
77