| // Copyright 2023 The PDFium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "core/fpdfapi/page/cpdf_pageimagecache.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "core/fpdfapi/page/cpdf_docpagedata.h" |
| #include "core/fpdfapi/page/cpdf_image.h" |
| #include "core/fpdfapi/page/cpdf_imageobject.h" |
| #include "core/fpdfapi/page/cpdf_page.h" |
| #include "core/fpdfapi/page/cpdf_pagemodule.h" |
| #include "core/fpdfapi/parser/cpdf_parser.h" |
| #include "core/fpdfapi/render/cpdf_docrenderdata.h" |
| #include "core/fxcrt/fx_stream.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/utils/path_service.h" |
| |
| TEST(CPDFPageImageCache, RenderBug1924) { |
| // If you render a page with a JPEG2000 image as a thumbnail (small picture) |
| // first, the image that gets cached has a low resolution. If you afterwards |
| // render it full-size, you should get a larger image - the image cache will |
| // be regenerate. |
| |
| CPDF_PageModule::Create(); |
| { |
| std::string file_path = PathService::GetTestFilePath("jpx_lzw.pdf"); |
| ASSERT_FALSE(file_path.empty()); |
| auto document = |
| std::make_unique<CPDF_Document>(std::make_unique<CPDF_DocRenderData>(), |
| std::make_unique<CPDF_DocPageData>()); |
| ASSERT_EQ(document->LoadDoc( |
| IFX_SeekableReadStream::CreateFromFilename(file_path.c_str()), |
| nullptr), |
| CPDF_Parser::SUCCESS); |
| |
| RetainPtr<CPDF_Dictionary> page_dict = |
| document->GetMutablePageDictionary(0); |
| ASSERT_TRUE(page_dict); |
| auto page = |
| pdfium::MakeRetain<CPDF_Page>(document.get(), std::move(page_dict)); |
| page->AddPageImageCache(); |
| page->ParseContent(); |
| |
| CPDF_PageImageCache* page_image_cache = page->GetPageImageCache(); |
| ASSERT_TRUE(page_image_cache); |
| |
| CPDF_PageObject* page_obj = page->GetPageObjectByIndex(0); |
| ASSERT_TRUE(page_obj); |
| CPDF_ImageObject* image = page_obj->AsImage(); |
| ASSERT_TRUE(image); |
| |
| // Render with small scale. |
| bool should_continue = page_image_cache->StartGetCachedBitmap( |
| image->GetImage(), nullptr, page->GetMutablePageResources(), true, |
| CPDF_ColorSpace::Family::kICCBased, false, {50, 50}); |
| while (should_continue) |
| should_continue = page_image_cache->Continue(nullptr); |
| |
| RetainPtr<CFX_DIBBase> bitmap_small = page_image_cache->DetachCurBitmap(); |
| |
| // And render with large scale. |
| should_continue = page_image_cache->StartGetCachedBitmap( |
| image->GetImage(), nullptr, page->GetMutablePageResources(), true, |
| CPDF_ColorSpace::Family::kICCBased, false, {100, 100}); |
| while (should_continue) |
| should_continue = page_image_cache->Continue(nullptr); |
| |
| RetainPtr<CFX_DIBBase> bitmap_large = page_image_cache->DetachCurBitmap(); |
| |
| ASSERT_GT(bitmap_large->GetWidth(), bitmap_small->GetWidth()); |
| ASSERT_GT(bitmap_large->GetHeight(), bitmap_small->GetHeight()); |
| |
| ASSERT_TRUE(page->AsPDFPage()); |
| page->AsPDFPage()->ClearView(); |
| } |
| CPDF_PageModule::Destroy(); |
| } |