LCOV - code coverage report
Current view: top level - frmts/jpegxl - jpegxldrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 40 40 100.0 %
Date: 2024-11-21 22:18:42 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  JPEGXL driver
       5             :  * Author:   Even Rouault, <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault, <even.rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "jpegxldrivercore.h"
      14             : 
      15             : /************************************************************************/
      16             : /*                      IsJPEGXLContainer()                             */
      17             : /************************************************************************/
      18             : 
      19        2788 : bool IsJPEGXLContainer(GDALOpenInfo *poOpenInfo)
      20             : {
      21        2788 :     constexpr const GByte abyJXLContainerSignature[] = {
      22             :         0x00, 0x00, 0x00, 0x0C, 'J', 'X', 'L', ' ', 0x0D, 0x0A, 0x87, 0x0A};
      23        2788 :     return (poOpenInfo->nHeaderBytes >=
      24        5367 :                 static_cast<int>(sizeof(abyJXLContainerSignature)) &&
      25        2579 :             memcmp(poOpenInfo->pabyHeader, abyJXLContainerSignature,
      26        2788 :                    sizeof(abyJXLContainerSignature)) == 0);
      27             : }
      28             : 
      29             : /************************************************************************/
      30             : /*                JPEGXLDatasetIdentifyPartial()                        */
      31             : /************************************************************************/
      32             : 
      33       18905 : static int JPEGXLDatasetIdentifyPartial(GDALOpenInfo *poOpenInfo)
      34             : {
      35       18905 :     if (poOpenInfo->fpL == nullptr)
      36       17790 :         return false;
      37             : 
      38        1115 :     if (EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "jxl"))
      39           1 :         return true;
      40             : 
      41             :     // See
      42             :     // https://github.com/libjxl/libjxl/blob/c98f133f3f5e456caaa2ba00bc920e923b713abc/lib/jxl/decode.cc#L107-L138
      43             : 
      44             :     // JPEG XL codestream
      45        1114 :     if (poOpenInfo->nHeaderBytes >= 2 && poOpenInfo->pabyHeader[0] == 0xff &&
      46          10 :         poOpenInfo->pabyHeader[1] == 0x0a)
      47             :     {
      48             :         // Two bytes is not enough to reliably identify
      49             :         // JPEGXLDataset::Identify() does a bit more work then
      50           1 :         return GDAL_IDENTIFY_UNKNOWN;
      51             :     }
      52             : 
      53        1113 :     return IsJPEGXLContainer(poOpenInfo);
      54             : }
      55             : 
      56             : /************************************************************************/
      57             : /*                   JPEGXLDriverSetCommonMetadata()                    */
      58             : /************************************************************************/
      59             : 
      60        1304 : void JPEGXLDriverSetCommonMetadata(GDALDriver *poDriver)
      61             : {
      62             :     // Set the driver details.
      63        1304 :     poDriver->SetDescription(DRIVER_NAME);
      64             : 
      65        1304 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
      66        1304 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "JPEG-XL");
      67        1304 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/jpegxl.html");
      68        1304 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "jxl");
      69        1304 :     poDriver->SetMetadataItem(GDAL_DMD_MIMETYPE, "image/jxl");
      70             : 
      71        1304 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES,
      72        1304 :                               "Byte UInt16 Float32");
      73             : 
      74             : #ifdef HAVE_JXL_BOX_API
      75        1304 :     const char *pszOpenOptions =
      76             :         "<OpenOptionList>\n"
      77             :         "   <Option name='APPLY_ORIENTATION' type='boolean' "
      78             :         "description='whether to take into account EXIF Orientation to "
      79             :         "rotate/flip the image' default='NO'/>\n"
      80             :         "</OpenOptionList>\n";
      81        1304 :     poDriver->SetMetadataItem(GDAL_DMD_OPENOPTIONLIST, pszOpenOptions);
      82             : #endif
      83             : 
      84        1304 :     poDriver->SetMetadataItem(
      85             :         GDAL_DMD_CREATIONOPTIONLIST,
      86             :         "<CreationOptionList>\n"
      87             :         "   <Option name='LOSSLESS' type='boolean' description='Whether JPEGXL "
      88             :         "compression should be lossless' default='YES'/>"
      89             :         "   <Option name='LOSSLESS_COPY' type='string-select' "
      90             :         "description='Whether conversion should be lossless' default='AUTO'>"
      91             :         "     <Value>AUTO</Value>"
      92             :         "     <Value>YES</Value>"
      93             :         "     <Value>NO</Value>"
      94             :         "   </Option>"
      95             :         "   <Option name='EFFORT' type='int' description='Level of effort "
      96             :         "1(fast)-9(slow)' default='5'/>"
      97             :         "   <Option name='DISTANCE' type='float' description='Distance level "
      98             :         "for lossy compression (0=mathematically lossless, 1.0=visually "
      99             :         "lossless, usual range [0.5,3])' default='1.0' min='0.01' max='25.0'/>"
     100             : #ifdef HAVE_JxlEncoderSetExtraChannelDistance
     101             :         "  <Option name='ALPHA_DISTANCE' type='float' "
     102             :         "description='Distance level for alpha channel "
     103             :         "(-1=same as non-alpha channels, "
     104             :         "0=mathematically lossless, 1.0=visually lossless, "
     105             :         "usual range [0.5,3])' default='-1' min='-1' max='25.0'/>"
     106             : #endif
     107             :         "   <Option name='QUALITY' type='float' description='Alternative "
     108             :         "setting to DISTANCE to specify lossy compression, roughly matching "
     109             :         "libjpeg quality setting in the [0,100] range' default='90' max='100'/>"
     110             :         "   <Option name='NBITS' type='int' description='BITS for sub-byte "
     111             :         "files (1-7), sub-uint16_t (9-15)'/>"
     112             :         "   <Option name='SOURCE_ICC_PROFILE' description='ICC profile encoded "
     113             :         "in Base64' type='string'/>\n"
     114             : #ifdef HAVE_JXL_THREADS
     115             :         "   <Option name='NUM_THREADS' type='string' description='Number of "
     116             :         "worker threads for compression. Can be set to ALL_CPUS' "
     117             :         "default='ALL_CPUS'/>"
     118             : #endif
     119             : #ifdef HAVE_JXL_BOX_API
     120             :         "   <Option name='WRITE_EXIF_METADATA' type='boolean' "
     121             :         "description='Whether to write EXIF_ metadata in a Exif box' "
     122             :         "default='YES'/>"
     123             :         "   <Option name='WRITE_XMP' type='boolean' description='Whether to "
     124             :         "write xml:XMP metadata in a xml box' default='YES'/>"
     125             :         "   <Option name='WRITE_GEOJP2' type='boolean' description='Whether to "
     126             :         "write georeferencing in a jumb.uuid box' default='YES'/>"
     127             :         "   <Option name='COMPRESS_BOXES' type='boolean' description='Whether "
     128             :         "to decompress Exif/XMP/GeoJP2 boxes' default='NO'/>"
     129             : #endif
     130        1304 :         "</CreationOptionList>\n");
     131             : 
     132        1304 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     133             : 
     134             : #ifdef HAVE_JxlEncoderInitExtraChannelInfo
     135        1304 :     poDriver->SetMetadataItem("JXL_ENCODER_SUPPORT_EXTRA_CHANNELS", "YES");
     136             : #endif
     137             : 
     138        1304 :     poDriver->pfnIdentify = JPEGXLDatasetIdentifyPartial;
     139        1304 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     140        1304 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     141        1304 : }
     142             : 
     143             : /************************************************************************/
     144             : /*                    DeclareDeferredJPEGXLPlugin()                     */
     145             : /************************************************************************/
     146             : 
     147             : #ifdef PLUGIN_FILENAME
     148        1595 : void DeclareDeferredJPEGXLPlugin()
     149             : {
     150        1595 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     151             :     {
     152         302 :         return;
     153             :     }
     154        1293 :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     155             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     156             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     157             :                               PLUGIN_INSTALLATION_MESSAGE);
     158             : #endif
     159        1293 :     JPEGXLDriverSetCommonMetadata(poDriver);
     160        1293 :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     161             : }
     162             : #endif

Generated by: LCOV version 1.14