• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The PDFium Authors
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 "core/fpdfapi/page/cpdf_pageimagecache.h"
6 
7 #include <memory>
8 #include <string>
9 #include <utility>
10 
11 #include "core/fpdfapi/page/cpdf_docpagedata.h"
12 #include "core/fpdfapi/page/cpdf_image.h"
13 #include "core/fpdfapi/page/cpdf_imageobject.h"
14 #include "core/fpdfapi/page/cpdf_page.h"
15 #include "core/fpdfapi/page/cpdf_pagemodule.h"
16 #include "core/fpdfapi/parser/cpdf_parser.h"
17 #include "core/fpdfapi/render/cpdf_docrenderdata.h"
18 #include "core/fxcrt/fx_stream.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/utils/path_service.h"
21 
TEST(CPDFPageImageCache,RenderBug1924)22 TEST(CPDFPageImageCache, RenderBug1924) {
23   // If you render a page with a JPEG2000 image as a thumbnail (small picture)
24   // first, the image that gets cached has a low resolution. If you afterwards
25   // render it full-size, you should get a larger image - the image cache will
26   // be regenerate.
27 
28   CPDF_PageModule::Create();
29   {
30     std::string file_path;
31     ASSERT_TRUE(PathService::GetTestFilePath("jpx_lzw.pdf", &file_path));
32     auto document =
33         std::make_unique<CPDF_Document>(std::make_unique<CPDF_DocRenderData>(),
34                                         std::make_unique<CPDF_DocPageData>());
35     ASSERT_EQ(document->LoadDoc(
36                   IFX_SeekableReadStream::CreateFromFilename(file_path.c_str()),
37                   nullptr),
38               CPDF_Parser::SUCCESS);
39 
40     RetainPtr<CPDF_Dictionary> page_dict =
41         document->GetMutablePageDictionary(0);
42     ASSERT_TRUE(page_dict);
43     auto page =
44         pdfium::MakeRetain<CPDF_Page>(document.get(), std::move(page_dict));
45     page->AddPageImageCache();
46     page->ParseContent();
47 
48     CPDF_PageImageCache* page_image_cache = page->GetPageImageCache();
49     ASSERT_TRUE(page_image_cache);
50 
51     CPDF_PageObject* page_obj = page->GetPageObjectByIndex(0);
52     ASSERT_TRUE(page_obj);
53     CPDF_ImageObject* image = page_obj->AsImage();
54     ASSERT_TRUE(image);
55 
56     // Render with small scale.
57     bool should_continue = page_image_cache->StartGetCachedBitmap(
58         image->GetImage(), nullptr, page->GetMutablePageResources(), true,
59         CPDF_ColorSpace::Family::kICCBased, false, {50, 50});
60     while (should_continue)
61       should_continue = page_image_cache->Continue(nullptr);
62 
63     RetainPtr<CFX_DIBBase> bitmap_small = page_image_cache->DetachCurBitmap();
64 
65     // And render with large scale.
66     should_continue = page_image_cache->StartGetCachedBitmap(
67         image->GetImage(), nullptr, page->GetMutablePageResources(), true,
68         CPDF_ColorSpace::Family::kICCBased, false, {100, 100});
69     while (should_continue)
70       should_continue = page_image_cache->Continue(nullptr);
71 
72     RetainPtr<CFX_DIBBase> bitmap_large = page_image_cache->DetachCurBitmap();
73 
74     ASSERT_GT(bitmap_large->GetWidth(), bitmap_small->GetWidth());
75     ASSERT_GT(bitmap_large->GetHeight(), bitmap_small->GetHeight());
76 
77     ASSERT_TRUE(page->AsPDFPage());
78     page->AsPDFPage()->ClearView();
79   }
80   CPDF_PageModule::Destroy();
81 }
82