tdf#156931 add import support for JPEG XL image format

Change-Id: I5b8c70d5739fdc91b0ca30fbaa780a5c7004741d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208352
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Jesus Solis
2026-08-26 11:43:32 +02:00
committed by Xisco Fauli
parent 5d72f86b56
commit 39dcff4a99
30 changed files with 425 additions and 8 deletions
+5
View File
@@ -715,6 +715,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_drawgraphics_typ
gif_Graphics_Interchange \
graphic_HTML \
jpg_JPEG \
jxl_JPEG_XL \
met_OS2_Metafile \
mov_MOV \
pbm_Portable_Bitmap \
@@ -750,6 +751,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_drawgraphics_f
EPS___Encapsulated_PostScript \
GIF___Graphics_Interchange \
JPG___JPEG \
JXL___JPEG_XL \
MET___OS_2_Metafile \
mov__MOV \
PBM___Portable_Bitmap \
@@ -801,6 +803,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_impressgraphics_
graphic_HTML \
impress_CGM_Computer_Graphics_Metafile \
jpg_JPEG \
jxl_JPEG_XL \
met_OS2_Metafile \
pbm_Portable_Bitmap \
pct_Mac_Pict \
@@ -871,6 +874,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_internalgraphics
eps_Encapsulated_PostScript \
gif_Graphics_Interchange \
jpg_JPEG \
jxl_JPEG_XL \
met_OS2_Metafile \
mov_MOV \
pbm_Portable_Bitmap \
@@ -911,6 +915,7 @@ $(eval $(call filter_Configuration_add_internal_filters,fcfg_langpack,fcfg_inter
gif_Import \
jpg_Export \
jpg_Import \
jxl_Import \
met_Import \
pbm_Import \
pcd_Import_Base \
+1
View File
@@ -234,6 +234,7 @@ int getFlatTypeRank(std::u16string_view rType)
"psd_Adobe_Photoshop",
"png_Portable_Network_Graphic",
"jpg_JPEG",
"jxl_JPEG_XL",
"mov_MOV",
"gif_Graphics_Interchange",
"bmp_MS_Windows",
@@ -0,0 +1,30 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<node oor:name="JXL - JPEG XL" oor:op="replace">
<prop oor:name="Flags"><value>IMPORT ALIEN</value></prop>
<prop oor:name="UIComponent"/>
<prop oor:name="FilterService"/>
<prop oor:name="UserData"><value></value></prop>
<prop oor:name="UIName">
<value xml:lang="en-US">JXL - JPEG XL Image</value>
</prop>
<prop oor:name="FileFormatVersion"><value>0</value></prop>
<prop oor:name="Type"><value>jxl_JPEG_XL</value></prop>
<prop oor:name="TemplateName"/>
<prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop>
</node>
@@ -0,0 +1,27 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<node oor:name="jxl_Import" oor:op="replace" >
<prop oor:name="Type"><value>jxl_JPEG_XL</value></prop>
<prop oor:name="FormatName"><value>SVIJXL</value></prop>
<prop oor:name="RealFilterName"><value>JXL - JPEG XL</value></prop>
<prop oor:name="UIComponent"/>
<prop oor:name="UIName">
<value xml:lang="en-US">JXL - JPEG XL Image</value>
</prop>
<prop oor:name="Flags"><value>IMPORT</value></prop>
</node>
@@ -0,0 +1,29 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<node oor:name="jxl_JPEG_XL" oor:op="replace" >
<prop oor:name="DetectService"><value>com.sun.star.comp.draw.FormatDetector</value></prop>
<prop oor:name="URLPattern"/>
<prop oor:name="Extensions"><value>jxl</value></prop>
<prop oor:name="MediaType"><value>image/jxl</value></prop>
<prop oor:name="Preferred"><value>false</value></prop>
<prop oor:name="PreferredFilter"><value>JXL - JPEG XL</value></prop>
<prop oor:name="UIName">
<value>JXL - JPEG XL Image</value>
</prop>
<prop oor:name="ClipboardFormat"/>
</node>
+1
View File
@@ -501,6 +501,7 @@ certain functionality.
@li @c vcl.emf - EMF/EMF+ processing
@li @c vcl.filter
@li @c vcl.filter.webp
@li @c vcl.filter.jxl
@li @c vcl.fonts - font-specific code
@li @c vcl.fonts.detail
@li @c vcl.gdi - the GDI part of VCL, devices, bitmaps, etc.
+1
View File
@@ -166,6 +166,7 @@ enum INetContentType
CONTENT_TYPE_AUDIO_WEBM,
CONTENT_TYPE_IMAGE_GIF,
CONTENT_TYPE_IMAGE_JPEG,
CONTENT_TYPE_IMAGE_JXL,
CONTENT_TYPE_IMAGE_PCX,
CONTENT_TYPE_IMAGE_PNG,
CONTENT_TYPE_IMAGE_TIFF,
+1
View File
@@ -40,6 +40,7 @@ enum class SvImageId {
HTML = START + 63,
JPG = START + 64,
WEBP = START + 65,
JXL = START + 66,
Math = START + 68,
MathTemplate = START + 69,
File = START + 74,
+1
View File
@@ -1426,6 +1426,7 @@
#define STR_IMAGE_CAPACITY_WITH_REDUCTION NC_("STR_IMAGE_CAPACITY_WITH_REDUCTION", "$(CAPACITY) KiB ($(REDUCTION)% reduction)")
#define STR_IMAGE_GIF NC_("STR_IMAGE_GIF", "GIF image")
#define STR_IMAGE_JPEG NC_("STR_IMAGE_JPEG", "JPEG image")
#define STR_IMAGE_JXL NC_("STR_IMAGE_JXL", "JPEG XL image")
#define STR_IMAGE_PNG NC_("STR_IMAGE_PNG", "PNG image")
#define STR_IMAGE_TIFF NC_("STR_IMAGE_TIFF", "TIFF image")
#define STR_IMAGE_WMF NC_("STR_IMAGE_WMF", "WMF image")
+3 -2
View File
@@ -48,12 +48,13 @@ enum class GfxLinkType
NativeMov = 10,
NativeBmp = 11,
NativePdf = 12,
NativeWebp = 13, // If a new type is added, make sure to change NativeLast too
NativeWebp = 13,
NativeJxl = 14, // If a new type is added, make sure to change NativeLast too
// Alias for when the first native type starts and last native
// type ends.
NativeFirst = NativeGif,
NativeLast = NativeWebp,
NativeLast = NativeJxl,
};
class Graphic;
+1
View File
@@ -38,6 +38,7 @@ enum class GraphicFileFormat
PSD = 0x000f,
EPS = 0x0010,
WEBP = 0x0011,
JXL = 0x0012,
MOV = 0x00e0,
PDF = 0x00e1,
DXF = 0x00f1,
+5
View File
@@ -81,6 +81,7 @@ namespace o3tl
#define IMP_GIF "SVIGIF"
#define IMP_PNG "SVIPNG"
#define IMP_JPEG "SVIJPEG"
#define IMP_JXL "SVIJXL"
#define IMP_XBM "SVIXBM"
#define IMP_XPM "SVIXPM"
#define IMP_SVG "SVISVG"
@@ -106,6 +107,7 @@ namespace o3tl
#define EXP_EMF "SVEMF"
#define EXP_EMZ "SVEMZ"
#define EXP_JPEG "SVEJPEG"
#define EXP_JXL "SVEJXL"
#define EXP_SVG "SVESVG"
#define EXP_SVGZ "SVESVGZ"
#define EXP_PDF "SVEPDF"
@@ -120,6 +122,7 @@ namespace o3tl
inline constexpr OUString BMP_SHORTNAME = u"BMP"_ustr;
inline constexpr OUString GIF_SHORTNAME = u"GIF"_ustr;
inline constexpr OUString JPG_SHORTNAME = u"JPG"_ustr;
inline constexpr OUString JXL_SHORTNAME = u"JXL"_ustr;
inline constexpr OUString MET_SHORTNAME = u"MET"_ustr;
inline constexpr OUString PCT_SHORTNAME = u"PCT"_ustr;
inline constexpr OUString PNG_SHORTNAME = u"PNG"_ustr;
@@ -141,6 +144,7 @@ class VCL_DLLPUBLIC GraphicDescriptor final
SAL_DLLPRIVATE bool ImpDetectBMP( SvStream& rStm, bool bExtendedInfo );
SAL_DLLPRIVATE bool ImpDetectGIF( SvStream& rStm, bool bExtendedInfo );
SAL_DLLPRIVATE bool ImpDetectJPG( SvStream& rStm, bool bExtendedInfo );
SAL_DLLPRIVATE bool ImpDetectJXL( SvStream& rStm, bool bExtendedInfo );
SAL_DLLPRIVATE bool ImpDetectPCD( SvStream& rStm, bool bExtendedInfo );
SAL_DLLPRIVATE bool ImpDetectPCX( SvStream& rStm );
SAL_DLLPRIVATE bool ImpDetectPNG( SvStream& rStm, bool bExtendedInfo );
@@ -319,6 +323,7 @@ public:
BinaryDataContainer & rpGraphicContent);
SAL_DLLPRIVATE static ErrCode readJPEG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType,
GraphicFilterImportFlags nImportFlags);
SAL_DLLPRIVATE static ErrCode readJXL(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType);
SAL_DLLPRIVATE static ErrCode readSVG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType,
BinaryDataContainer & rpGraphicContent);
SAL_DLLPRIVATE static ErrCode readXBM(SvStream & rStream, Graphic & rGraphic);
+1
View File
@@ -31,6 +31,7 @@ enum class ConvertDataFormat
BMP,
GIF,
JPG,
JXL,
MET,
PCT,
PNG,
+1
View File
@@ -1079,6 +1079,7 @@ CONDITIONAL_REGISTER_DOC_EXTENSION( Gif, gid_Module_Prg_Draw_Other_Reg, gif, G
CONDITIONAL_REGISTER_DOC_EXTENSION( Jpg, gid_Module_Prg_Draw_Other_Reg, jpg, JPG, JOINT_PHOTOGRAPHIC_EXPERTS_GROUP, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Jpeg, gid_Module_Prg_Draw_Other_Reg, jpeg, JPEG, JOINT_PHOTOGRAPHIC_EXPERTS_GROUP, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Jpe, gid_Module_Prg_Draw_Other_Reg, jpe, JPE, JOINT_PHOTOGRAPHIC_EXPERTS_GROUP, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Jxl, gid_Module_Prg_Draw_Other_Reg, jxl, JXL, JPEG_XL, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Pbm, gid_Module_Prg_Draw_Other_Reg, pbm, PBM, PORTABLE_BITMAP_FORMAT, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Pcx, gid_Module_Prg_Draw_Other_Reg, pcx, PCX, PERSONAL_COMPUTER_EXCHANGE, 5, sdraw.exe, open, Draw )
CONDITIONAL_REGISTER_DOC_EXTENSION( Pgm, gid_Module_Prg_Draw_Other_Reg, pgm, PGM, PORTABLE_GRAYMAP_FORMAT, 5, sdraw.exe, open, Draw )
+2
View File
@@ -74,6 +74,7 @@ const auto constGfxTypeToExtension = frozen::make_unordered_map<GfxLinkType, OUS
{ GfxLinkType::NativeMet, u"met"_ustr },
{ GfxLinkType::NativePct, u"pct"_ustr },
{ GfxLinkType::NativeJpg, u"jpg"_ustr },
{ GfxLinkType::NativeJxl, u"jxl"_ustr },
{ GfxLinkType::NativeBmp, u"bmp"_ustr },
{ GfxLinkType::NativeSvg, u"svg"_ustr },
{ GfxLinkType::NativePdf, u"pdf"_ustr },
@@ -96,6 +97,7 @@ const auto constGfxTypeToString = frozen::make_unordered_map<GfxLinkType, Transl
{ GfxLinkType::NativeMet, STR_IMAGE_MET },
{ GfxLinkType::NativePct, STR_IMAGE_PCT },
{ GfxLinkType::NativeJpg, STR_IMAGE_JPEG },
{ GfxLinkType::NativeJxl, STR_IMAGE_JXL },
{ GfxLinkType::NativeBmp, STR_IMAGE_BMP },
{ GfxLinkType::NativeSvg, STR_IMAGE_SVG },
{ GfxLinkType::NativePdf, STR_IMAGE_PNG },
+1
View File
@@ -403,6 +403,7 @@ bool GalleryTheme::InsertGraphic(const Graphic& rGraphic, sal_uInt32 nInsertPos)
case GfxLinkType::NativeBmp: nExportFormat = ConvertDataFormat::BMP; break;
case GfxLinkType::NativeJpg: nExportFormat = ConvertDataFormat::JPG; break;
case GfxLinkType::NativeJxl: nExportFormat = ConvertDataFormat::JXL; break;
case GfxLinkType::NativePng: nExportFormat = ConvertDataFormat::PNG; break;
case GfxLinkType::NativeTif: nExportFormat = ConvertDataFormat::TIF; break;
case GfxLinkType::NativeWmf: nExportFormat = ConvertDataFormat::WMF; break;
+3
View File
@@ -54,6 +54,7 @@ constexpr OUStringLiteral FORMAT_PDF = u"pdf";
constexpr OUString FORMAT_BMP = u"bmp"_ustr;
constexpr OUString FORMAT_GIF = u"gif"_ustr;
constexpr OUStringLiteral FORMAT_JPG = u"jpg";
constexpr OUStringLiteral FORMAT_JXL = u"jxl";
constexpr OUString FORMAT_PNG = u"png"_ustr;
constexpr OUStringLiteral FORMAT_TIF = u"tif";
constexpr OUStringLiteral FORMAT_WEBP = u"webp";
@@ -171,6 +172,8 @@ static OUString isKnownRasterFormat(const GfxLink& rLink, std::u16string_view rF
case GfxLinkType::NativeJpg:
return match(rFilter, FORMAT_JPG);
case GfxLinkType::NativeJxl:
return match(rFilter, FORMAT_JXL);
case GfxLinkType::NativePng:
return match(rFilter, FORMAT_PNG);
case GfxLinkType::NativeTif:
+2
View File
@@ -101,6 +101,7 @@ $(eval $(call gb_Library_use_externals,vcl,\
lcms2 \
libeot \
libjpeg \
libjxl \
libpng \
libtiff \
libwebp \
@@ -542,6 +543,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/filter/jpeg/JpegReader \
vcl/source/filter/jpeg/JpegWriter \
vcl/source/filter/jpeg/JpegTransform \
vcl/source/filter/jxl/reader \
vcl/source/filter/svm/SvmConverter \
vcl/source/filter/svm/SvmReader \
vcl/source/filter/svm/SvmWriter \
+26
View File
@@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <vcl/graph.hxx>
VCL_DLLPUBLIC bool ImportJxlGraphic(SvStream& rStream, Graphic& rGraphic);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -40,6 +40,9 @@ static inline OUString getImportFormatShortName(GraphicFileFormat nFormat)
case GraphicFileFormat::JPG:
aKeyName = u"JPG"_ustr;
break;
case GraphicFileFormat::JXL:
aKeyName = u"JXL"_ustr;
break;
case GraphicFileFormat::PCD:
aKeyName = u"PCD"_ustr;
break;
@@ -165,6 +168,7 @@ public:
bool checkPNG();
bool checkAPNG();
bool checkJPG();
bool checkJXL();
SAL_DLLPRIVATE bool checkSVM();
SAL_DLLPRIVATE bool checkPCD();
bool checkPSD();
+1
View File
@@ -30,6 +30,7 @@ class SvStream;
inline constexpr OUString MIMETYPE_BMP = u"image/x-MS-bmp"_ustr;
inline constexpr OUString MIMETYPE_GIF = u"image/gif"_ustr;
inline constexpr OUString MIMETYPE_JPG = u"image/jpeg"_ustr;
inline constexpr OUString MIMETYPE_JXL = u"image/jxl"_ustr;
inline constexpr OUString MIMETYPE_PCD = u"image/x-photo-cd"_ustr;
inline constexpr OUString MIMETYPE_PCX = u"image/x-pcx"_ustr;
inline constexpr OUString MIMETYPE_PNG = u"image/png"_ustr;
+5 -3
View File
@@ -42,9 +42,10 @@ using namespace ::com::sun::star::configuration ;
const char* const FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList[] =
{
IMP_BMP, IMP_GIF, IMP_PNG, IMP_JPEG, IMP_TIFF, IMP_WEBP,
IMP_XBM, IMP_XPM, IMP_TGA, IMP_PICT, IMP_MET, IMP_RAS,
IMP_PCX, IMP_MOV, IMP_PSD, IMP_PCD, IMP_PBM, IMP_DXF,
IMP_BMP, IMP_GIF, IMP_PNG, IMP_JPEG, IMP_JXL, IMP_TIFF,
IMP_WEBP, IMP_XBM, IMP_XPM, IMP_TGA, IMP_PICT, IMP_MET,
IMP_RAS, IMP_PCX, IMP_MOV, IMP_PSD, IMP_PCD, IMP_PBM,
IMP_DXF,
EXP_BMP, EXP_GIF, EXP_PNG, EXP_JPEG, EXP_TIFF, EXP_WEBP,
nullptr
};
@@ -211,6 +212,7 @@ constexpr FilterEntry InternalFilterListForSvxLight[]
{ u"gif"_ustr, 2, u"SVEGIF"_ustr },
{ u"jpg"_ustr, 1, u"SVIJPEG"_ustr },
{ u"jpg"_ustr, 2, u"SVEJPEG"_ustr },
{ u"jxl"_ustr, 1, u"SVIJXL"_ustr },
{ u"mov"_ustr, 1, u"SVMOV"_ustr },
{ u"mov"_ustr, 2, u"SVMOV"_ustr },
{ u"met"_ustr, 1, u"SVMET"_ustr },
@@ -28,6 +28,7 @@
#include <tools/zcodec.hxx>
#include <tools/fract.hxx>
#include <tools/mapunit.hxx>
#include <filter/JxlReader.hxx>
#include <filter/WebpReader.hxx>
#include "igif/gifread.hxx"
#include <vcl/TypeSerializer.hxx>
@@ -166,6 +167,16 @@ bool peekGraphicFormat(SvStream& rStream, OUString& rFormatExtension, bool bTest
}
}
if (!bTest || rFormatExtension.startsWith("JXL"))
{
bSomethingTested = true;
if (aDetector.checkJXL())
{
rFormatExtension = getImportFormatShortName(aDetector.getMetadata().mnFormat);
return true;
}
}
if (!bTest || rFormatExtension.startsWith("SVM"))
{
bSomethingTested = true;
@@ -980,6 +991,20 @@ bool GraphicFormatDetector::checkJPG()
return false;
}
bool GraphicFormatDetector::checkJXL()
{
if ((maFirstBytes[0] == 0xFF && maFirstBytes[1] == 0x0A)
|| (maFirstBytes[0] == 0x00 && maFirstBytes[1] == 0x00 && maFirstBytes[2] == 0x00
&& maFirstBytes[3] == 0x0C && maFirstBytes[4] == 0x4A && maFirstBytes[5] == 0x58
&& maFirstBytes[6] == 0x4C && maFirstBytes[7] == 0x20 && maFirstBytes[8] == 0x0D
&& maFirstBytes[9] == 0x0A && maFirstBytes[10] == 0x87 && maFirstBytes[11] == 0x0A))
{
maMetadata.mnFormat = GraphicFileFormat::JXL;
return true;
}
return false;
}
bool GraphicFormatDetector::checkSVM()
{
sal_uInt32 n32 = 0;
+22
View File
@@ -66,6 +66,7 @@
#include <filter/GifWriter.hxx>
#include <filter/BmpReader.hxx>
#include <filter/BmpWriter.hxx>
#include <filter/JxlReader.hxx>
#include <filter/WebpReader.hxx>
#include <filter/WebpWriter.hxx>
#include <osl/module.hxx>
@@ -724,6 +725,11 @@ ErrCode prepareImageTypeAndData(SvStream& rStream, sal_uInt32 nStreamLength, Bin
rLinkType = GfxLinkType::NativeJpg;
nStatus = ERRCODE_NONE;
}
else if (o3tl::equalsIgnoreAsciiCase(rFilterName, IMP_JXL))
{
rLinkType = GfxLinkType::NativeJxl;
nStatus = ERRCODE_NONE;
}
else if (o3tl::equalsIgnoreAsciiCase(rFilterName, IMP_SVG))
{
rStream.Seek(nStreamBegin);
@@ -943,6 +949,17 @@ ErrCode GraphicFilter::readJPEG(SvStream & rStream, Graphic & rGraphic, GfxLinkT
return ERRCODE_NONE;
}
ErrCode GraphicFilter::readJXL(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
{
if (ImportJxlGraphic(rStream, rGraphic))
{
rLinkType = GfxLinkType::NativeJxl;
return ERRCODE_NONE;
}
else
return ERRCODE_GRFILTER_FILTERERROR;
}
ErrCode GraphicFilter::readSVG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, BinaryDataContainer& rpGraphicContent)
{
ErrCode aReturnCode = ERRCODE_NONE;
@@ -1333,6 +1350,10 @@ ErrCode GraphicFilter::ImportGraphic(Graphic& rGraphic, std::u16string_view rPat
{
nStatus = readJPEG(rIStream, rGraphic, eLinkType, nImportFlags);
}
else if (aFilterName.equalsIgnoreAsciiCase(IMP_JXL))
{
nStatus = readJXL(rIStream, rGraphic, eLinkType);
}
else if (aFilterName.equalsIgnoreAsciiCase(IMP_SVG) || aFilterName.equalsIgnoreAsciiCase(IMP_SVGZ))
{
nStatus = readSVG(rIStream, rGraphic, eLinkType, aGraphicContent);
@@ -1839,6 +1860,7 @@ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData&, rData, bool )
case ConvertDataFormat::BMP: aShortName = BMP_SHORTNAME; break;
case ConvertDataFormat::GIF: aShortName = GIF_SHORTNAME; break;
case ConvertDataFormat::JPG: aShortName = JPG_SHORTNAME; break;
case ConvertDataFormat::JXL: aShortName = JXL_SHORTNAME; break;
case ConvertDataFormat::MET: aShortName = MET_SHORTNAME; break;
case ConvertDataFormat::PCT: aShortName = PCT_SHORTNAME; break;
case ConvertDataFormat::PNG: aShortName = PNG_SHORTNAME; break;
+10
View File
@@ -62,6 +62,7 @@ bool GraphicDescriptor::Detect( bool bExtendedInfo )
if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = true;
else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = true;
else if ( ImpDetectJXL( rStm, bExtendedInfo ) ) bRet = true;
else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = true;
else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = true;
else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = true;
@@ -301,6 +302,15 @@ bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, bool bExtendedInfo )
return bRet;
}
bool GraphicDescriptor::ImpDetectJXL( SvStream& rStm, bool bExtendedInfo )
{
vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
bool bRet = aDetector.detect() && aDetector.checkJXL();
if ( bRet )
aMetadata = aDetector.getMetadata();
return bRet;
}
bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, bool )
{
vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
+203
View File
@@ -0,0 +1,203 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <memory>
#include <vcl/graph.hxx>
#include <tools/stream.hxx>
#include <filter/JxlReader.hxx>
#include <vcl/BitmapWriteAccess.hxx>
#include <salinst.hxx>
#include <sal/log.hxx>
#include <jxl/codestream_header.h>
#include <jxl/decode.h>
#include <jxl/decode_cxx.h>
#include <jxl/resizable_parallel_runner.h>
#include <jxl/resizable_parallel_runner_cxx.h>
#include <jxl/types.h>
static bool readJxl(SvStream& stream, Graphic& graphic)
{
std::vector<uint8_t> data;
std::vector<uint8_t> pixels;
size_t xsize = 0;
size_t ysize = 0;
// Multi-threaded parallel runner.
JxlResizableParallelRunnerPtr runner = JxlResizableParallelRunnerMake(nullptr);
JxlDecoderPtr dec = JxlDecoderMake(nullptr);
if (JXL_DEC_SUCCESS
!= JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING
| JXL_DEC_FULL_IMAGE))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderSubscribeEvents failed");
return false;
}
if (JXL_DEC_SUCCESS
!= JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, runner.get()))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderSetParallelRunner failed");
return false;
}
JxlBasicInfo info;
JxlPixelFormat format = { 4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 };
size_t chunksize = 4096;
// Read first chunksize bytes.
data.resize(chunksize);
sal_Size nBytesRead = stream.ReadBytes(data.data(), chunksize);
if (nBytesRead <= 0)
return false; // no bytes to read
data.resize(nBytesRead);
if (JXL_DEC_SUCCESS != JxlDecoderSetInput(dec.get(), data.data(), nBytesRead))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderSetInput failed");
return false;
}
// Try using partially read image if there is an error.
bool success = true;
for (;;)
{
JxlDecoderStatus status = JxlDecoderProcessInput(dec.get());
if (status == JXL_DEC_ERROR)
{
SAL_WARN("vcl.filter.jxl", "Decoder error");
success = false;
break;
}
else if (status == JXL_DEC_NEED_MORE_INPUT || status == JXL_DEC_SUCCESS
|| status == JXL_DEC_FULL_IMAGE)
{
JxlDecoderReleaseInput(dec.get());
JxlDecoderFlushImage(dec.get());
// Read 4096 (more) bytes.
data.resize(chunksize);
nBytesRead = stream.ReadBytes(data.data(), chunksize);
if (nBytesRead <= 0)
{
if (status == JXL_DEC_NEED_MORE_INPUT)
{
SAL_WARN("vcl.filter.jxl", "Incomplete/truncated file");
success = false;
break;
}
else
{
// Finished decoding complete file.
break;
}
}
data.resize(nBytesRead);
if (JXL_DEC_SUCCESS != JxlDecoderSetInput(dec.get(), data.data(), nBytesRead))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderSetInput failed");
success = false;
break;
}
}
else if (status == JXL_DEC_BASIC_INFO)
{
if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec.get(), &info))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderGetBasicInfo failed");
success = false;
break;
}
xsize = info.xsize;
ysize = info.ysize;
JxlResizableParallelRunnerSetThreads(
runner.get(), JxlResizableParallelRunnerSuggestThreads(info.xsize, info.ysize));
}
else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER)
{
size_t buffer_size;
if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderImageOutBufferSize failed");
success = false;
break;
}
if (buffer_size != xsize * ysize * 4)
{
SAL_WARN("vcl.filter.jxl", "Invalid out buffer size, expected "
<< xsize * ysize * 4 << " but got " << buffer_size);
success = false;
break;
}
pixels.resize(xsize * ysize * 4);
if (JXL_DEC_SUCCESS
!= JxlDecoderSetImageOutBuffer(dec.get(), &format, pixels.data(), pixels.size()))
{
SAL_WARN("vcl.filter.jxl", "JxlDecoderSetImageOutBuffer failed");
success = false;
break;
}
}
else if (status != JXL_DEC_COLOR_ENCODING) // not using color profile
{
SAL_WARN("vcl.filter.jxl", "Unknown JxlDecoderStatus");
success = false;
break;
}
}
// convert pixels into a bitmap
Bitmap bitmap(Size(xsize, ysize), vcl::PixelFormat::N32_BPP);
BitmapScopedWriteAccess access(bitmap);
if (!access)
return false;
for (tools::Long y = 0, nHeight = access->Height(); y < nHeight; ++y)
{
const unsigned char* src = pixels.data() + xsize * 4 * y;
for (tools::Long x = 0, nWidth = access->Width(); x < nWidth; ++x)
{
sal_uInt8 r = src[0];
sal_uInt8 g = src[1];
sal_uInt8 b = src[2];
sal_uInt8 a = src[3];
access->SetPixel(y, x, Color(ColorAlpha, a, r, g, b));
src += 4;
}
}
access.reset(); // Flush BitmapScopedWriteAccess
graphic = bitmap;
return success;
}
bool ImportJxlGraphic(SvStream& rStream, Graphic& rGraphic)
{
bool bRetValue = readJxl(rStream, rGraphic);
if (!bRetValue)
rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
return bRetValue;
}
+1
View File
@@ -117,6 +117,7 @@ bool GfxLink::LoadNative(Graphic& rGraphic, sal_Int32 nPageNum) const
{
case GfxLinkType::NativeGif: aShortName = GIF_SHORTNAME; break;
case GfxLinkType::NativeJpg: aShortName = JPG_SHORTNAME; break;
case GfxLinkType::NativeJxl: aShortName = JXL_SHORTNAME; break;
case GfxLinkType::NativePng: aShortName = PNG_SHORTNAME; break;
case GfxLinkType::NativeTif: aShortName = TIF_SHORTNAME; break;
case GfxLinkType::NativeWmf: aShortName = WMF_SHORTNAME; break;
+1
View File
@@ -490,6 +490,7 @@ OUString convertGfxLinkTypeToString(GfxLinkType eGfxLinkType)
case GfxLinkType::NativeBmp: return u"NativeBmp"_ustr;
case GfxLinkType::NativeGif: return u"NativeGif"_ustr;
case GfxLinkType::NativeJpg: return u"NativeJpg"_ustr;
case GfxLinkType::NativeJxl: return u"NativeJxl"_ustr;
case GfxLinkType::NativeMet: return u"NativeMet"_ustr;
case GfxLinkType::NativeMov: return u"NativeMov"_ustr;
case GfxLinkType::NativePct: return u"NativePct"_ustr;
@@ -116,6 +116,7 @@ void GraphicDescriptor::implCreate( SvStream& rIStm, const OUString& rURL )
case GraphicFileFormat::BMP: aMimeType = MIMETYPE_BMP; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::GIF: aMimeType = MIMETYPE_GIF; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::JPG: aMimeType = MIMETYPE_JPG; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::JXL: aMimeType = MIMETYPE_JXL; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::PCD: aMimeType = MIMETYPE_PCD; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::PCX: aMimeType = MIMETYPE_PCX; cType = graphic::GraphicType::PIXEL; break;
case GraphicFileFormat::PNG: aMimeType = MIMETYPE_PNG; cType = graphic::GraphicType::PIXEL; break;
@@ -290,6 +291,7 @@ void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry**
case GfxLinkType::NativeBmp: aMimeType = MIMETYPE_BMP; break;
case GfxLinkType::NativeJpg: aMimeType = MIMETYPE_JPG; break;
case GfxLinkType::NativeJxl: aMimeType = MIMETYPE_JXL; break;
case GfxLinkType::NativePng: aMimeType = MIMETYPE_PNG; break;
case GfxLinkType::NativeTif: aMimeType = MIMETYPE_TIF; break;
case GfxLinkType::NativeWmf: aMimeType = aLink.IsEMF() ? MIMETYPE_EMF : MIMETYPE_WMF; break;
+7
View File
@@ -48,6 +48,7 @@
#include <vcl/font/EOTConverter.hxx>
#include <vcl/svapp.hxx>
#include <vcl/wmf.hxx>
#include <filter/JxlReader.hxx>
#include <filter/TiffReader.hxx>
#include <filter/TgaReader.hxx>
#include <filter/PictReader.hxx>
@@ -147,6 +148,12 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
SvFileStream aFileStream(out, StreamMode::READ);
ret = static_cast<int>(ImportJPEG(aFileStream, aImportOutput, GraphicFilterImportFlags::NONE, nullptr));
}
else if (strcmp(argv[2], "jxl") == 0)
{
Graphic aGraphic;
SvFileStream aFileStream(out, StreamMode::READ);
ret = static_cast<int>(ImportJxlGraphic(aFileStream, aGraphic));
}
else if (strcmp(argv[2], "gif") == 0)
{
ImportOutput aImportOutput;