diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index a9e501d..c583332 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -425,8 +425,7 @@ const std::string& Epub::getLanguage() const { } std::string Epub::getCoverBmpPath(bool cropped) const { - const auto coverFileName = "cover" + cropped ? "_crop" : ""; - return cachePath + "/" + coverFileName + ".bmp"; + return cropped ? (cachePath + "/cover_crop.bmp") : (cachePath + "/cover_fit.bmp"); } bool Epub::generateCoverBmp(bool cropped) const { @@ -462,12 +461,37 @@ bool Epub::generateCoverBmp(bool cropped) const { return false; } + // Get JPEG dimensions to calculate target dimensions for FIT/CROP + int jpegWidth, jpegHeight; + if (!JpegToBmpConverter::getJpegDimensions(coverJpg, jpegWidth, jpegHeight)) { + Serial.printf("[%lu] [EBP] Failed to get JPEG dimensions\n", millis()); + coverJpg.close(); + return false; + } + + // Calculate target dimensions based on FIT/CROP mode + // FIT: ancho fijo 480px, alto proporcional = 480 * (jpegHeight / jpegWidth) + // CROP: alto fijo 800px, ancho proporcional = 800 * (jpegWidth / jpegHeight) + int targetWidth, targetHeight; + if (cropped) { + // CROP mode: height = 800, width proportional + targetHeight = 800; + targetWidth = (800 * jpegWidth) / jpegHeight; + } else { + // FIT mode: width = 480, height proportional + targetWidth = 480; + targetHeight = (480 * jpegHeight) / jpegWidth; + } + + Serial.printf("[%lu] [EBP] Calculated %s dimensions: %dx%d (original JPEG: %dx%d)\n", millis(), + cropped ? "CROP" : "FIT", targetWidth, targetHeight, jpegWidth, jpegHeight); + FsFile coverBmp; if (!SdMan.openFileForWrite("EBP", getCoverBmpPath(cropped), coverBmp)) { coverJpg.close(); return false; } - const bool success = JpegToBmpConverter::jpegFileToBmpStream(coverJpg, coverBmp); + const bool success = JpegToBmpConverter::jpegFileToBmpStreamWithSize(coverJpg, coverBmp, targetWidth, targetHeight); coverJpg.close(); coverBmp.close(); SdMan.remove(coverJpgTempPath.c_str()); diff --git a/lib/JpegToBmpConverter/JpegToBmpConverter.cpp b/lib/JpegToBmpConverter/JpegToBmpConverter.cpp index 01451a0..0f5c7be 100644 --- a/lib/JpegToBmpConverter/JpegToBmpConverter.cpp +++ b/lib/JpegToBmpConverter/JpegToBmpConverter.cpp @@ -565,3 +565,32 @@ bool JpegToBmpConverter::jpegFileTo1BitBmpStreamWithSize(FsFile& jpegFile, Print int targetMaxHeight) { return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, true); } + +// Get JPEG dimensions without full conversion +bool JpegToBmpConverter::getJpegDimensions(FsFile& jpegFile, int& width, int& height) { + // Reset file position to beginning + if (!jpegFile.seek(0)) { + Serial.printf("[%lu] [JPG] Failed to seek to beginning of JPEG file\n", millis()); + return false; + } + + // Initialize JPEG decoder + pjpeg_image_info_t imageInfo = {}; + JpegReadContext context{jpegFile, {}, 0, 0}; + + const int decodeStatus = pjpeg_decode_init(&imageInfo, jpegReadCallback, &context, false); + if (decodeStatus != 0) { + Serial.printf("[%lu] [JPG] pjpeg_decode_init failed with status %d\n", millis(), decodeStatus); + return false; + } + + // Get dimensions from image info + width = imageInfo.m_width; + height = imageInfo.m_height; + + Serial.printf("[%lu] [JPG] Read JPEG dimensions: %dx%d\n", millis(), width, height); + + // Reset file position after reading + jpegFile.seek(0); + return true; +} diff --git a/lib/JpegToBmpConverter/JpegToBmpConverter.h b/lib/JpegToBmpConverter/JpegToBmpConverter.h index d5e9b95..98fe7b4 100644 --- a/lib/JpegToBmpConverter/JpegToBmpConverter.h +++ b/lib/JpegToBmpConverter/JpegToBmpConverter.h @@ -16,4 +16,6 @@ class JpegToBmpConverter { static bool jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight); // Convert to 1-bit BMP (black and white only, no grays) for fast home screen rendering static bool jpegFileTo1BitBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight); + // Get JPEG dimensions without full conversion + static bool getJpegDimensions(FsFile& jpegFile, int& width, int& height); };