LCOV - code coverage report
Current view: top level - frmts/jpeg - jpegdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 62 83.9 %
Date: 2024-11-21 22:18:42 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  JPEG JFIF Driver
       4             :  * Purpose:  Implement GDAL JPEG Support based on IJG libjpeg.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2000, Frank Warmerdam
       9             :  * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Portions Copyright (c) Her majesty the Queen in right of Canada as
      12             :  * represented by the Minister of National Defence, 2006.
      13             :  *
      14             :  * SPDX-License-Identifier: MIT
      15             :  ****************************************************************************/
      16             : 
      17             : #include "jpegdrivercore.h"
      18             : 
      19             : // So that D_LOSSLESS_SUPPORTED is visible if defined in jmorecfg of libjpeg-turbo >= 2.2
      20             : #define JPEG_INTERNAL_OPTIONS
      21             : #include "jpeglib.h"
      22             : 
      23             : /************************************************************************/
      24             : /*                    JPEGDatasetIsJPEGLS()                             */
      25             : /************************************************************************/
      26             : 
      27        6089 : bool JPEGDatasetIsJPEGLS(GDALOpenInfo *poOpenInfo)
      28             : 
      29             : {
      30        6089 :     GByte *pabyHeader = poOpenInfo->pabyHeader;
      31        6089 :     int nHeaderBytes = poOpenInfo->nHeaderBytes;
      32             : 
      33        6089 :     if (nHeaderBytes < 10)
      34           0 :         return false;
      35             : 
      36        6089 :     if (pabyHeader[0] != 0xff || pabyHeader[1] != 0xd8)
      37           0 :         return false;
      38             : 
      39       27547 :     for (int nOffset = 2; nOffset + 4 < nHeaderBytes;)
      40             :     {
      41       23109 :         if (pabyHeader[nOffset] != 0xFF)
      42           6 :             return false;
      43             : 
      44       23103 :         int nMarker = pabyHeader[nOffset + 1];
      45       23103 :         if (nMarker == 0xDA)
      46        1645 :             return false;
      47             : 
      48       21458 :         if (nMarker == 0xF7)  // JPEG Extension 7, JPEG-LS.
      49           0 :             return true;
      50       21458 :         if (nMarker == 0xF8)  // JPEG Extension 8, JPEG-LS Extension.
      51           0 :             return true;
      52       21458 :         if (nMarker == 0xC3)  // Start of Frame 3 (Lossless Huffman)
      53           0 :             return true;
      54       21458 :         if (nMarker ==
      55             :             0xC7)  // Start of Frame 7 (Differential Lossless Huffman)
      56           0 :             return true;
      57       21458 :         if (nMarker == 0xCB)  // Start of Frame 11 (Lossless Arithmetic)
      58           0 :             return true;
      59       21458 :         if (nMarker ==
      60             :             0xCF)  // Start of Frame 15 (Differential Lossless Arithmetic)
      61           0 :             return true;
      62             : 
      63       21458 :         nOffset += 2 + pabyHeader[nOffset + 2] * 256 + pabyHeader[nOffset + 3];
      64             :     }
      65             : 
      66        4438 :     return false;
      67             : }
      68             : 
      69             : /************************************************************************/
      70             : /*                     JPEGDriverIdentify()                             */
      71             : /************************************************************************/
      72             : 
      73       58260 : int JPEGDriverIdentify(GDALOpenInfo *poOpenInfo)
      74             : 
      75             : {
      76             :     // If it is a subfile, read the JPEG header.
      77       58260 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, "JPEG_SUBFILE:"))
      78         300 :         return TRUE;
      79       57960 :     if (STARTS_WITH(poOpenInfo->pszFilename, "JPEG:"))
      80          10 :         return TRUE;
      81             : 
      82             :     // First we check to see if the file has the expected header bytes.
      83       57950 :     const int nHeaderBytes = poOpenInfo->nHeaderBytes;
      84             : 
      85       57950 :     if (nHeaderBytes < 10)
      86       48123 :         return FALSE;
      87             : 
      88        9827 :     GByte *const pabyHeader = poOpenInfo->pabyHeader;
      89        9827 :     if (pabyHeader[0] != 0xff || pabyHeader[1] != 0xd8 || pabyHeader[2] != 0xff)
      90        3738 :         return FALSE;
      91             : 
      92             :         // libjpeg-turbo >= 2.2 supports lossless mode
      93             : #if !defined(D_LOSSLESS_SUPPORTED)
      94        6089 :     if (JPEGDatasetIsJPEGLS(poOpenInfo))
      95             :     {
      96           0 :         return FALSE;
      97             :     }
      98             : #endif
      99             : 
     100             :     // Some files like
     101             :     // http://dionecanali.hd.free.fr/~mdione/mapzen/N65E039.hgt.gz could be
     102             :     // mis-identfied as JPEG
     103       12178 :     CPLString osFilenameLower = CPLString(poOpenInfo->pszFilename).tolower();
     104       12178 :     if (osFilenameLower.endsWith(".hgt") ||
     105       24356 :         osFilenameLower.endsWith(".hgt.gz") ||
     106       12178 :         osFilenameLower.endsWith(".hgt.zip"))
     107             :     {
     108           0 :         return FALSE;
     109             :     }
     110             : 
     111        6089 :     return TRUE;
     112             : }
     113             : 
     114             : /************************************************************************/
     115             : /*                     JPEGDriverSetCommonMetadata()                    */
     116             : /************************************************************************/
     117             : 
     118        1293 : void JPEGDriverSetCommonMetadata(GDALDriver *poDriver)
     119             : {
     120        1293 :     poDriver->SetDescription(DRIVER_NAME);
     121        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     122        1293 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "JPEG JFIF");
     123        1293 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/jpeg.html");
     124        1293 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "jpg");
     125        1293 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "jpg jpeg");
     126        1293 :     poDriver->SetMetadataItem(GDAL_DMD_MIMETYPE, "image/jpeg");
     127             : 
     128             : #if defined(JPEG_LIB_MK1_OR_12BIT) || defined(JPEG_DUAL_MODE_8_12)
     129        1293 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES, "Byte UInt16");
     130             : #else
     131             :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES, "Byte");
     132             : #endif
     133        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     134             : 
     135        1293 :     const char *pszOpenOptions =
     136             :         "<OpenOptionList>\n"
     137             :         "   <Option name='USE_INTERNAL_OVERVIEWS' type='boolean' "
     138             :         "description='whether to use implicit internal overviews' "
     139             :         "default='YES'/>\n"
     140             :         "   <Option name='APPLY_ORIENTATION' type='boolean' "
     141             :         "description='whether to take into account EXIF Orientation to "
     142             :         "rotate/flip the image' default='NO'/>\n"
     143             :         "</OpenOptionList>\n";
     144        1293 :     poDriver->SetMetadataItem(GDAL_DMD_OPENOPTIONLIST, pszOpenOptions);
     145             : 
     146             : #ifdef D_LOSSLESS_SUPPORTED
     147             :     // For autotest purposes
     148             :     poDriver->SetMetadataItem("LOSSLESS_JPEG_SUPPORTED", "YES", "JPEG");
     149             : #endif
     150             : 
     151        1293 :     poDriver->pfnIdentify = JPEGDriverIdentify;
     152        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     153        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     154        1293 : }
     155             : 
     156             : /************************************************************************/
     157             : /*                    DeclareDeferredJPEGPlugin()                       */
     158             : /************************************************************************/
     159             : 
     160             : #ifdef PLUGIN_FILENAME
     161             : void DeclareDeferredJPEGPlugin()
     162             : {
     163             :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     164             :     {
     165             :         return;
     166             :     }
     167             :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     168             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     169             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     170             :                               PLUGIN_INSTALLATION_MESSAGE);
     171             : #endif
     172             :     JPEGDriverSetCommonMetadata(poDriver);
     173             :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     174             : }
     175             : #endif

Generated by: LCOV version 1.14