diff --git a/backend/src/main/java/com/storycove/service/EPUBImportService.java b/backend/src/main/java/com/storycove/service/EPUBImportService.java index 54536b1..0c0671a 100644 --- a/backend/src/main/java/com/storycove/service/EPUBImportService.java +++ b/backend/src/main/java/com/storycove/service/EPUBImportService.java @@ -481,18 +481,23 @@ public class EPUBImportService { return htmlContent; } - // Index all image resources by href and by bare filename for flexible lookup + // Index all image resources by href and by bare filename for flexible lookup. + // Also index resources whose media type epublib could not recognise (returns null for formats + // like WebP that are absent from its built-in type registry) by falling back to the href extension. Map byHref = new HashMap<>(); Map byFilename = new HashMap<>(); for (Resource resource : book.getResources().getAll()) { - if (resource.getMediaType() != null && - resource.getMediaType().toString().startsWith("image/")) { - String href = resource.getHref(); - if (href != null) { - byHref.put(href, resource); - String filename = href.contains("/") ? href.substring(href.lastIndexOf('/') + 1) : href; - byFilename.putIfAbsent(filename, resource); - } + String href = resource.getHref(); + if (href == null) continue; + + boolean isImageByMediaType = resource.getMediaType() != null && + resource.getMediaType().toString().startsWith("image/"); + boolean isImageByExtension = hasImageExtension(href); + + if (isImageByMediaType || isImageByExtension) { + byHref.put(href, resource); + String filename = href.contains("/") ? href.substring(href.lastIndexOf('/') + 1) : href; + byFilename.putIfAbsent(filename, resource); } } @@ -530,7 +535,7 @@ public class EPUBImportService { } String mediaType = resource.getMediaType() != null ? - resource.getMediaType().toString() : "image/jpeg"; + resource.getMediaType().toString() : getMediaTypeFromHref(resource.getHref()); String extension = getExtensionFromMediaType(mediaType); String filename = "epub-img-" + System.currentTimeMillis() + "-" + (int) (Math.random() * 100000) + "." + extension; @@ -619,6 +624,32 @@ public class EPUBImportService { return "jpg"; // Default fallback } } + + /** + * Determine MIME type from the file extension in an EPUB resource href. + * Used as a fallback when epublib does not recognise the media type (e.g. WebP). + */ + private String getMediaTypeFromHref(String href) { + if (href == null) return "image/jpeg"; + String lower = href.toLowerCase(); + if (lower.endsWith(".png")) return "image/png"; + if (lower.endsWith(".gif")) return "image/gif"; + if (lower.endsWith(".webp")) return "image/webp"; + if (lower.endsWith(".svg")) return "image/svg+xml"; + return "image/jpeg"; // covers .jpg, .jpeg and unknown formats + } + + /** + * Returns true if the href path ends with a known image file extension. + * Used to index EPUB resources whose media type epublib could not determine. + */ + private boolean hasImageExtension(String href) { + if (href == null) return false; + String lower = href.toLowerCase(); + return lower.endsWith(".jpg") || lower.endsWith(".jpeg") || + lower.endsWith(".png") || lower.endsWith(".gif") || + lower.endsWith(".webp") || lower.endsWith(".svg"); + } private ReadingPositionDto convertToDto(ReadingPosition position) { if (position == null) return null;