| 564 | } |
| 565 | |
| 566 | bool Epub::generateCoverBmp(bool cropped) const { |
| 567 | // Already generated, return true |
| 568 | if (Storage.exists(getCoverBmpPath(cropped).c_str())) { |
| 569 | return true; |
| 570 | } |
| 571 | |
| 572 | if (!bookMetadataCache || !bookMetadataCache->isLoaded()) { |
| 573 | LOG_ERR("EBP", "Cannot generate cover BMP, cache not loaded"); |
| 574 | return false; |
| 575 | } |
| 576 | |
| 577 | const auto coverImageHref = bookMetadataCache->coreMetadata.coverItemHref; |
| 578 | if (coverImageHref.empty()) { |
| 579 | LOG_ERR("EBP", "No known cover image"); |
| 580 | return false; |
| 581 | } |
| 582 | |
| 583 | if (FsHelpers::hasJpgExtension(coverImageHref)) { |
| 584 | LOG_DBG("EBP", "Generating BMP from JPG cover image (%s mode)", cropped ? "cropped" : "fit"); |
| 585 | const auto coverJpgTempPath = getCachePath() + "/.cover.jpg"; |
| 586 | |
| 587 | HalFile coverJpg; |
| 588 | if (!Storage.openFileForWrite("EBP", coverJpgTempPath, coverJpg)) { |
| 589 | return false; |
| 590 | } |
| 591 | readItemContentsToStream(coverImageHref, coverJpg, 1024); |
| 592 | // Explicitly close() file before reopening for reading |
| 593 | coverJpg.close(); |
| 594 | |
| 595 | if (!Storage.openFileForRead("EBP", coverJpgTempPath, coverJpg)) { |
| 596 | return false; |
| 597 | } |
| 598 | |
| 599 | HalFile coverBmp; |
| 600 | if (!Storage.openFileForWrite("EBP", getCoverBmpPath(cropped), coverBmp)) { |
| 601 | return false; |
| 602 | } |
| 603 | const bool success = JpegToBmpConverter::jpegFileToBmpStream(coverJpg, coverBmp, cropped); |
| 604 | // Explicitly close() files before calling Storage.remove() |
| 605 | coverJpg.close(); |
| 606 | coverBmp.close(); |
| 607 | Storage.remove(coverJpgTempPath.c_str()); |
| 608 | |
| 609 | if (!success) { |
| 610 | LOG_ERR("EBP", "Failed to generate BMP from cover image"); |
| 611 | Storage.remove(getCoverBmpPath(cropped).c_str()); |
| 612 | } |
| 613 | LOG_DBG("EBP", "Generated BMP from JPG cover image, success: %s", success ? "yes" : "no"); |
| 614 | return success; |
| 615 | } |
| 616 | |
| 617 | if (FsHelpers::hasPngExtension(coverImageHref)) { |
| 618 | LOG_DBG("EBP", "Generating BMP from PNG cover image (%s mode)", cropped ? "cropped" : "fit"); |
| 619 | const auto coverPngTempPath = getCachePath() + "/.cover.png"; |
| 620 | |
| 621 | HalFile coverPng; |
| 622 | if (!Storage.openFileForWrite("EBP", coverPngTempPath, coverPng)) { |
| 623 | return false; |
nothing calls this directly
no test coverage detected