Skip to content

Commit ce62391

Browse files
authored
Merge pull request #2061 from Kiradien/Image_MIME_from_signature
Generate MIME from signature
2 parents baf438e + 827c76b commit ce62391

3 files changed

Lines changed: 57 additions & 8 deletions

File tree

plugin/js/EpubItem.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,18 @@ class ImageInfo extends EpubItem {
186186
return util.makeStorageFileName("OEBPS/Images/", that.index, that.getImageName(that.wrappingUrl), suffix);
187187
}
188188

189+
getBase64(maxLength) {
190+
var binary = "";
191+
var bytes = new Uint8Array(this.arraybuffer);
192+
var len = bytes.byteLength;
193+
if (maxLength > 0) len = Math.min(len, maxLength);
194+
for (var i = 0; i < len; i++)
195+
{
196+
binary += String.fromCharCode(bytes[i]);
197+
}
198+
return window.btoa( binary );
199+
}
200+
189201
getId() {
190202
if (this.isCover) {
191203
return "cover-image";

plugin/js/ImageCollector.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ class ImageCollector {
381381
let xhr = await HttpClient.wrapFetch(initialUrl, fetchOptions);
382382
xhr = await this.findImageFileUrl(xhr, imageInfo, imageInfo.dataOrigFileUrl, fetchOptions);
383383
imageInfo.mediaType = xhr.contentType;
384-
this.fixupInvalidMediaType(imageInfo);
385384
imageInfo.arraybuffer = xhr.arrayBuffer;
385+
this.fixupInvalidMediaType(imageInfo);
386386
{
387387
let img = await this.getImageDimensions(imageInfo);
388388
await this.runCompression(imageInfo, img);
@@ -400,12 +400,16 @@ class ImageCollector {
400400

401401
fixupInvalidMediaType(imageInfo) {
402402
if (!imageInfo.mediaType?.startsWith("image")) {
403-
let path = new URL(imageInfo.sourceUrl).pathname;
404-
let index = path.lastIndexOf(".");
405-
let format = (index < 0)
406-
? "jpeg"
407-
: path.substring(index + 1);
408-
imageInfo.mediaType = "image/" + format;
403+
imageInfo.mediaType = util.detectMimeType(imageInfo.getBase64(25));
404+
if (imageInfo.mediaType == null)
405+
{
406+
let path = new URL(imageInfo.sourceUrl).pathname;
407+
let index = path.lastIndexOf(".");
408+
let format = (index < 0)
409+
? "jpeg"
410+
: path.substring(index + 1);
411+
imageInfo.mediaType = "image/" + format;
412+
}
409413
}
410414
}
411415

plugin/js/Util.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,13 @@ const util = (function() {
10471047
if (retval) retval = retval[0];
10481048
return retval;
10491049
}
1050+
function detectMimeType(b64) {
1051+
for (var s in MIME_TYPE_SIGNATURES) {
1052+
if (b64.indexOf(s) === 0) {
1053+
return MIME_TYPE_SIGNATURES[s][0];
1054+
}
1055+
}
1056+
}
10501057

10511058
function sanitize(dirty) {
10521059
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
@@ -1103,6 +1110,31 @@ const util = (function() {
11031110
"image/avif": ["avif"]
11041111
};
11051112

1113+
const MIME_TYPE_SIGNATURES = {
1114+
"/9j/": ["image/jpeg"],
1115+
"iVBORw0KGgo=": ["image/png", "image/apng"],
1116+
"R0lGODdh": ["image/gif"],
1117+
"R0lGODlh": ["image/gif"],
1118+
"UklGR": ["image/webp"],
1119+
"Qk0=": ["image/bmp"],
1120+
"SUkqAA==": ["image/tiff"],
1121+
"TU0AKg==": ["image/tiff"],
1122+
"PD94bWw=": ["image/svg+xml"],
1123+
"AAABAA==": ["image/x-icon", "image/vnd.microsoft.icon"],
1124+
"ZnR5cGhlaWZj": ["image/heif"],
1125+
"ZnR5cG1pZjE=": ["image/heif"],
1126+
"ZnR5cGhlaWNj": ["image/heic"],
1127+
"SUm8": ["image/jxr"],
1128+
"q0tUWCAxMb0NCgo=": ["image/ktx"],
1129+
"AAACAA==": ["image/x-tga"],
1130+
"ZnR5cGF2aWY=": ["image/avif"],
1131+
"UDAx": ["image/x-portable-bitmap"],
1132+
"UDAy": ["image/x-portable-graymap"],
1133+
"UDAz": ["image/x-portable-pixmap"],
1134+
"UDA0": ["image/x-portable-anymap"],
1135+
"WaZqlQ==": ["image/x-cmu-raster"]
1136+
};
1137+
11061138
return {
11071139
XMLNS: XMLNS,
11081140
INLINE_ELEMENTS: INLINE_ELEMENTS,
@@ -1209,6 +1241,7 @@ const util = (function() {
12091241
removeSpansWithNoAttributes: removeSpansWithNoAttributes,
12101242
replaceSemanticInlineStylesWithTags: replaceSemanticInlineStylesWithTags,
12111243
wrapInnerContentInTag: wrapInnerContentInTag,
1212-
getDefaultExtensionByMime: getDefaultExtensionByMime
1244+
getDefaultExtensionByMime: getDefaultExtensionByMime,
1245+
detectMimeType: detectMimeType
12131246
};
12141247
})();

0 commit comments

Comments
 (0)