Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Canary] Transcoding Support + More Image Format Support (JPEGXL) #3250

Open
wants to merge 49 commits into
base: canary
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e2a86c6
Add JXL Support.
maxpiva Aug 15, 2024
cb647ad
Make sure if djxl do not exists, continue as usual.
maxpiva Aug 15, 2024
7f6db24
Changed the way conversion happens.
maxpiva Aug 23, 2024
dd0021a
Missing file
maxpiva Aug 23, 2024
efc14ff
Merge branch 'Kareadita:develop' into develop
maxpiva Aug 23, 2024
9d48664
Revert "Changed the way conversion happens."
maxpiva Aug 26, 2024
cf05e5f
Reapply "Changed the way conversion happens."
maxpiva Aug 26, 2024
4902a74
Changed the way conversion happens.
maxpiva Aug 23, 2024
21b4c1b
Merge with Karedita
maxpiva Aug 26, 2024
7d48f6e
Add Documentation
maxpiva Aug 27, 2024
a4a12a1
FIX BOMS
maxpiva Aug 28, 2024
0f98d75
Recode SupportedImageTypesFromRequest removing possible errors.
maxpiva Aug 28, 2024
937f89c
Remove own docker build
maxpiva Aug 28, 2024
a08a795
Shell Call no longer used, since swapped image conversion to Image Ma…
maxpiva Aug 28, 2024
bc8481c
Merge branch 'Kareadita:develop' into JPEG-XL_JPG2000_HEIF
maxpiva Aug 29, 2024
e7f021a
Edit CodeStyle
maxpiva Aug 29, 2024
c624287
Remove custom docker builder
maxpiva Aug 29, 2024
6dbeaf1
Fixed discovered issues.
maxpiva Aug 30, 2024
fead3f6
Merge branch 'Kareadita:develop' into JPEG-XL_JPG2000_HEIF
maxpiva Sep 19, 2024
bf30989
Merge branch 'Kareadita:develop' into JPEG-XL_JPG2000_HEIF
maxpiva Sep 27, 2024
0cc4803
Removed NetVips and ImageSharp (Use only ImageMagick)
maxpiva Sep 28, 2024
10da91c
Remove CropFromDimensions (Geometry will take care)
maxpiva Sep 28, 2024
1541d6a
BOM Changes
maxpiva Sep 28, 2024
23a9aa8
Delete .bak
maxpiva Sep 28, 2024
b6a986a
Bug fixes.
maxpiva Sep 29, 2024
3008ae0
Merge branch 'Kareadita:develop' into RemoveSixLaborsAndNetVips
maxpiva Sep 29, 2024
9bf1fa8
Added SmartCrop (port from smartcrop.js)
maxpiva Oct 1, 2024
170c3b6
Refactor and cleanup.
maxpiva Oct 4, 2024
361c464
BOM Fixes
maxpiva Oct 4, 2024
d6056b8
Update docker-build.sh
maxpiva Oct 4, 2024
92f131a
Fixed Benchmarks
maxpiva Oct 4, 2024
b21ee66
Merge branch 'RemoveSixLaborsAndNetVips' of https://github.com/maxpiv…
maxpiva Oct 4, 2024
4f026e6
Fixed BOM
maxpiva Oct 4, 2024
00ee60b
Requested changes.
maxpiva Oct 10, 2024
fbbbbb8
Removed bak files, fixed EncodeFormat BOM
maxpiva Oct 10, 2024
a0f804b
Removed quality parameter everywhere.
maxpiva Oct 11, 2024
11749bd
Remove quality parameters after refactor.
maxpiva Oct 15, 2024
edbd44b
Bump versions by dotnet-bump-version.
majora2007 Oct 24, 2024
1a88dd4
Lots of Bugfixes (#3308)
majora2007 Oct 25, 2024
7159f40
Added Support for Q8 and Q16 ImageMagick
maxpiva Dec 10, 2024
81c04ad
Merge from develop
maxpiva Dec 10, 2024
dd33037
Merge branch 'Kareadita-develop' into RemoveSixLaborsAndNetVips
maxpiva Dec 10, 2024
9d94ecf
Fix GetRGBAColors Q8 Bug
maxpiva Dec 11, 2024
d1411c1
Merge pull request #2 from Kareadita/develop
maxpiva Dec 11, 2024
d84f07e
FIX BOMs
maxpiva Dec 11, 2024
87e976d
FIX BOMS
maxpiva Dec 11, 2024
44dc556
FIX BOMs
maxpiva Dec 11, 2024
872e64d
Merged with Canaryu
maxpiva Dec 11, 2024
9dccb2d
Merge branch 'Kareadita-canary' into RemoveSixLaborsAndNetVips
maxpiva Dec 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revert "Changed the way conversion happens."
This reverts commit 7f6db24.
  • Loading branch information
maxpiva committed Aug 26, 2024
commit 9d48664b08f01303f1527bc1c577e1d4376f89ff
6 changes: 3 additions & 3 deletions API.Tests/Services/ArchiveServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ArchiveServiceTests(ITestOutputHelper testOutputHelper)
_testOutputHelper = testOutputHelper;
_archiveService = new ArchiveService(_logger, _directoryService,
new ImageService(Substitute.For<ILogger<ImageService>>(), _directoryService, Substitute.For<IEasyCachingProviderFactory>(), Substitute.For<IImageConverterService>()),
Substitute.For<IMediaErrorService>());
Substitute.For<IMediaErrorService>(), Substitute.For<IImageConverterService>());
}

[Theory]
Expand Down Expand Up @@ -224,9 +224,9 @@ public void GetCoverImage_SharpCompress_Test(string inputFile, string expectedOu
public void CanParseCoverImage(string inputFile)
{
var imageService = Substitute.For<IImageService>();
imageService.WriteCoverThumbnail(Arg.Any<string>(), Arg.Any<Stream>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<EncodeFormat>())
imageService.WriteCoverThumbnail(Arg.Any<Stream>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<EncodeFormat>())
.Returns(x => "cover.jpg");
var archiveService = new ArchiveService(_logger, _directoryService, imageService, Substitute.For<IMediaErrorService>());
var archiveService = new ArchiveService(_logger, _directoryService, imageService, Substitute.For<IMediaErrorService>(),Substitute.For<IImageConverterService>());
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/");
var inputPath = Path.GetFullPath(Path.Join(testDirectory, inputFile));
var outputPath = Path.Join(testDirectory, Path.GetFileNameWithoutExtension(inputFile) + "_output");
Expand Down
16 changes: 8 additions & 8 deletions API.Tests/Services/CacheServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.IO.Abstractions.TestingHelpers;
Expand Down Expand Up @@ -158,7 +158,7 @@ public async Task Ensure_DirectoryAlreadyExists_DontExtractAnything()
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(),
Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

await ResetDB();
var s = new SeriesBuilder("Test").Build();
Expand Down Expand Up @@ -234,7 +234,7 @@ public void CleanupChapters_AllFilesShouldBeDeleted()
var cleanupService = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

cleanupService.CleanupChapters(new []{1, 3});
Assert.Empty(ds.GetFiles(CacheDirectory, searchOption:SearchOption.AllDirectories));
Expand All @@ -256,7 +256,7 @@ public void GetCachedEpubFile_ShouldReturnFirstEpub()
var cs = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

var c = new ChapterBuilder("1")
.WithFile(new MangaFileBuilder($"{DataDirectory}1.epub", MangaFormat.Epub).Build())
Expand Down Expand Up @@ -297,7 +297,7 @@ public void GetCachedPagePath_ReturnNullIfNoFiles()
var cs = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(),Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

// Flatten to prepare for how GetFullPath expects
ds.Flatten($"{CacheDirectory}1/");
Expand Down Expand Up @@ -341,7 +341,7 @@ public void GetCachedPagePath_GetFileFromFirstFile()
var cs = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

// Flatten to prepare for how GetFullPath expects
ds.Flatten($"{CacheDirectory}1/");
Expand Down Expand Up @@ -382,7 +382,7 @@ public void GetCachedPagePath_GetLastPageFromSingleFile()
var cs = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

// Flatten to prepare for how GetFullPath expects
ds.Flatten($"{CacheDirectory}1/");
Expand Down Expand Up @@ -427,7 +427,7 @@ public void GetCachedPagePath_GetFileFromSecondFile()
var cs = new CacheService(_logger, _unitOfWork, ds,
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds, Substitute.For<ILogger<ReadingItemService>>()),
Substitute.For<IBookmarkService>(), Substitute.For<IImageConverterService>());
Substitute.For<IBookmarkService>());

// Flatten to prepare for how GetFullPath expects
ds.Flatten($"{CacheDirectory}1/");
Expand Down
3 changes: 2 additions & 1 deletion API/API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">

<Delete Files="../openapi.json" />
<Exec Command="swagger tofile --output ../openapi.json bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).dll v1" />
</Target>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
Expand Down
4 changes: 2 additions & 2 deletions API/Controllers/OPDSController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ public async Task<ActionResult> GetPageStreamedImage(string apiKey, [FromQuery]

try
{
var path = _cacheService.GetCachedPagePath(chapter.Id, pageNumber, Request.SupportedImageTypesFromRequest());
var path = _cacheService.GetCachedPagePath(chapter.Id, pageNumber);
if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
return BadRequest(await _localizationService.Translate(userId, "no-image-for-page", pageNumber));

Expand All @@ -1252,7 +1252,7 @@ await _readerService.SaveReadingProgress(new ProgressDto()
}, userId);
}

return File(content, format.GetMimeType());
return File(content, MimeTypeMap.GetMimeType(format));
}
catch (Exception)
{
Expand Down
13 changes: 5 additions & 8 deletions API/Controllers/ReaderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using MimeTypes;
using Org.BouncyCastle.Ocsp;

namespace API.Controllers;

Expand Down Expand Up @@ -119,12 +118,12 @@ public async Task<ActionResult> GetImage(int chapterId, int page, string apiKey,
var chapter = await _cacheService.Ensure(chapterId, extractPdf);
if (chapter == null) return NoContent();
_logger.LogInformation("Fetching Page {PageNum} on Chapter {ChapterId}", page, chapterId);
var path = _cacheService.GetCachedPagePath(chapter.Id, page, Request.SupportedImageTypesFromRequest());
var path = _cacheService.GetCachedPagePath(chapter.Id, page);
if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
return BadRequest(await _localizationService.Translate(userId, "no-image-for-page", page));
var format = Path.GetExtension(path);

return PhysicalFile(path, format.GetMimeType(), Path.GetFileName(path), true);
return PhysicalFile(path, MimeTypeMap.GetMimeType(format), Path.GetFileName(path), true);
}
catch (Exception)
{
Expand All @@ -133,8 +132,6 @@ public async Task<ActionResult> GetImage(int chapterId, int page, string apiKey,
}
}



/// <summary>
/// Returns a thumbnail for the given page number
/// </summary>
Expand Down Expand Up @@ -183,11 +180,11 @@ public async Task<ActionResult> GetBookmarkImage(int seriesId, string apiKey, in

try
{
var path = _cacheService.GetCachedBookmarkPagePath(seriesId, page, Request.SupportedImageTypesFromRequest());
var path = _cacheService.GetCachedBookmarkPagePath(seriesId, page);
if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path)) return BadRequest(await _localizationService.Translate(userId, "no-image-for-page", page));
var format = Path.GetExtension(path);

return PhysicalFile(path, format.GetMimeType(), Path.GetFileName(path));
return PhysicalFile(path, MimeTypeMap.GetMimeType(format), Path.GetFileName(path));
}
catch (Exception)
{
Expand Down Expand Up @@ -732,7 +729,7 @@ public async Task<ActionResult> BookmarkPage(BookmarkDto bookmarkDto)
if (chapter == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "cache-file-find"));

bookmarkDto.Page = _readerService.CapPageToChapter(chapter, bookmarkDto.Page);
var path = _cacheService.GetCachedPagePath(chapter.Id, bookmarkDto.Page, Request.SupportedImageTypesFromRequest());
var path = _cacheService.GetCachedPagePath(chapter.Id, bookmarkDto.Page);

if (!await _bookmarkService.BookmarkPage(user, bookmarkDto, path))
return BadRequest(await _localizationService.Translate(User.GetUserId(), "bookmark-save"));
Expand Down
12 changes: 1 addition & 11 deletions API/Extensions/FileTypeGroupExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System;
using API.Entities.Enums;
using API.Services.Tasks.Scanner.Parser;
using MimeTypes;

namespace API.Extensions;

Expand All @@ -23,13 +22,4 @@ public static string GetRegex(this FileTypeGroup fileTypeGroup)
throw new ArgumentOutOfRangeException(nameof(fileTypeGroup), fileTypeGroup, null);
}
}
public static string GetMimeType(this string format)
{
//Add jxl format
format = format.ToLowerInvariant();
if (format == ".jxl")
return "image/jxl";
return MimeTypeMap.GetMimeType(format);
}

}
32 changes: 1 addition & 31 deletions API/Extensions/HttpExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
Expand Down Expand Up @@ -56,31 +53,4 @@ public static void AddCacheHeader(this HttpResponse response, string filename, i
response.Headers.CacheControl = $"max-age={maxAge}";
}
}

public static List<string> SupportedImageTypesFromRequest(this HttpRequest request)
{
var acceptHeader = request.Headers["Accept"];
string[] spl1 = acceptHeader.ToString().Split(';');
acceptHeader = spl1[0];
string[] split = acceptHeader.ToString().Split(',');
List<string> defaultExtensions = new List<string>();
defaultExtensions.Add("jpeg");
defaultExtensions.Add("jpg");
defaultExtensions.Add("png");
defaultExtensions.Add("gif");

foreach (string v in split)
{
if (v.StartsWith("image/", StringComparison.InvariantCultureIgnoreCase))
{
string n = v.Substring(6);
if (n == "svg+xml")
n = "svg";
if (n.StartsWith("*"))
continue;
defaultExtensions.Add(n.ToLowerInvariant());
}
}
return defaultExtensions;
}
}
15 changes: 9 additions & 6 deletions API/Services/ArchiveService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,17 @@ public class ArchiveService : IArchiveService
private readonly IDirectoryService _directoryService;
private readonly IImageService _imageService;
private readonly IMediaErrorService _mediaErrorService;

private readonly IImageConverterService _converterService;
private const string ComicInfoFilename = "ComicInfo.xml";

public ArchiveService(ILogger<ArchiveService> logger, IDirectoryService directoryService,
IImageService imageService, IMediaErrorService mediaErrorService)
IImageService imageService, IMediaErrorService mediaErrorService, IImageConverterService converterService)
{
_logger = logger;
_directoryService = directoryService;
_imageService = imageService;
_mediaErrorService = mediaErrorService;
_converterService = converterService;
}

/// <summary>
Expand Down Expand Up @@ -232,8 +233,8 @@ public string GetCoverImage(string archivePath, string fileName, string outputDi
var entryName = FindCoverImageFilename(archivePath, archive.Entries.Select(e => e.FullName));
var entry = archive.Entries.Single(e => e.FullName == entryName);

using var stream = entry.Open();
return _imageService.WriteCoverThumbnail(entryName, stream, fileName, outputDirectory, format, size);
using var stream = _converterService.ConvertStream(entryName, entry.Open());
return _imageService.WriteCoverThumbnail(stream, fileName, outputDirectory, format, size);
}
case ArchiveLibrary.SharpCompress:
{
Expand All @@ -243,8 +244,8 @@ public string GetCoverImage(string archivePath, string fileName, string outputDi
var entryName = FindCoverImageFilename(archivePath, entryNames);
var entry = archive.Entries.Single(e => e.Key == entryName);

using var stream = entry.OpenEntryStream();
return _imageService.WriteCoverThumbnail(entryName, stream, fileName, outputDirectory, format, size);
using var stream = _converterService.ConvertStream(entryName, entry.OpenEntryStream());
return _imageService.WriteCoverThumbnail(stream, fileName, outputDirectory, format, size);
}
case ArchiveLibrary.NotSupported:
_logger.LogWarning("[GetCoverImage] This archive cannot be read: {ArchivePath}. Defaulting to no cover image", archivePath);
Expand Down Expand Up @@ -561,6 +562,7 @@ public void ExtractArchive(string archivePath, string extractPath)
{
using var archive = ZipFile.OpenRead(archivePath);
ExtractArchiveEntries(archive, extractPath);
_converterService.ConvertDirectory(extractPath);
break;
}
case ArchiveLibrary.SharpCompress:
Expand All @@ -569,6 +571,7 @@ public void ExtractArchive(string archivePath, string extractPath)
ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory
&& !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty)
&& Tasks.Scanner.Parser.Parser.IsImage(entry.Key)), extractPath);
_converterService.ConvertDirectory(extractPath);
break;
}
case ArchiveLibrary.NotSupported:
Expand Down
6 changes: 3 additions & 3 deletions API/Services/BookService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -1229,7 +1229,7 @@ public string GetCoverImage(string fileFilePath, string fileName, string outputD
if (coverImageContent == null) return string.Empty;
using var stream = coverImageContent.GetContentStream();

return _imageService.WriteCoverThumbnail(fileFilePath, stream, fileName, outputDirectory, encodeFormat, size);
return _imageService.WriteCoverThumbnail(stream, fileName, outputDirectory, encodeFormat, size);
}
catch (Exception ex)
{
Expand All @@ -1252,7 +1252,7 @@ private string GetPdfCoverImage(string fileFilePath, string fileName, string out
using var stream = StreamManager.GetStream("BookService.GetPdfPage");
GetPdfPage(docReader, 0, stream);

return _imageService.WriteCoverThumbnail(fileFilePath, stream, fileName, outputDirectory, encodeFormat, size);
return _imageService.WriteCoverThumbnail(stream, fileName, outputDirectory, encodeFormat, size);

}
catch (Exception ex)
Expand Down
Loading