Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: HEIF Driver
4 : * Author: Even Rouault <even.rouault at spatialys.com>
5 : *
6 : ******************************************************************************
7 : * Copyright (c) 2020, Even Rouault <even.rouault at spatialys.com>
8 : *
9 : * SPDX-License-Identifier: MIT
10 : ****************************************************************************/
11 :
12 : #include "gdal_frmts.h"
13 : #include "gdalplugindriverproxy.h"
14 :
15 : #include "include_libheif.h"
16 :
17 : #include "heifdrivercore.h"
18 :
19 : /************************************************************************/
20 : /* HEIFDriverIdentifySimplified() */
21 : /************************************************************************/
22 :
23 : static const GByte FTYP_4CC[] = {'f', 't', 'y', 'p'};
24 : static const GByte supportedBrands[][4]{
25 : {'a', 'v', 'i', 'f'}, {'h', 'e', 'i', 'c'}, {'h', 'e', 'i', 'x'},
26 : {'j', '2', 'k', 'i'}, {'j', 'p', 'e', 'g'}, {'m', 'i', 'a', 'f'},
27 : {'m', 'i', 'f', '1'}, {'m', 'i', 'f', '2'}, {'v', 'v', 'i', 'c'}};
28 :
29 57663 : int HEIFDriverIdentifySimplified(GDALOpenInfo *poOpenInfo)
30 : {
31 57663 : if (STARTS_WITH_CI(poOpenInfo->pszFilename, "HEIF:"))
32 : {
33 9 : return true;
34 : }
35 57654 : if (poOpenInfo->nHeaderBytes < 16 || poOpenInfo->fpL == nullptr)
36 : {
37 54635 : return false;
38 : }
39 3019 : if (memcmp(poOpenInfo->pabyHeader + 4, FTYP_4CC, sizeof(FTYP_4CC)) != 0)
40 : {
41 2986 : return false;
42 : }
43 : uint32_t lengthBigEndian;
44 33 : memcpy(&lengthBigEndian, poOpenInfo->pabyHeader, sizeof(uint32_t));
45 33 : uint32_t lengthHostEndian = CPL_MSBWORD32(lengthBigEndian);
46 33 : if (lengthHostEndian > static_cast<uint32_t>(poOpenInfo->nHeaderBytes))
47 : {
48 0 : lengthHostEndian = static_cast<uint32_t>(poOpenInfo->nHeaderBytes);
49 : }
50 225 : for (const GByte *supportedBrand : supportedBrands)
51 : {
52 208 : if (memcmp(poOpenInfo->pabyHeader + 8, supportedBrand, 4) == 0)
53 : {
54 16 : return true;
55 : }
56 : }
57 31 : for (uint32_t offset = 16; offset + 4 <= lengthHostEndian; offset += 4)
58 : {
59 155 : for (const GByte *supportedBrand : supportedBrands)
60 : {
61 141 : if (memcmp(poOpenInfo->pabyHeader + offset, supportedBrand, 4) == 0)
62 : {
63 3 : return true;
64 : }
65 : }
66 : }
67 14 : return false;
68 : }
69 :
70 : /************************************************************************/
71 : /* HEIFDriverSetCommonMetadata() */
72 : /************************************************************************/
73 :
74 1760 : void HEIFDriverSetCommonMetadata(GDALDriver *poDriver)
75 : {
76 1760 : poDriver->SetDescription(DRIVER_NAME);
77 1760 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
78 1760 : poDriver->SetMetadataItem(
79 : GDAL_DMD_LONGNAME,
80 1760 : "ISO/IEC 23008-12:2017 High Efficiency Image File Format");
81 1760 : poDriver->SetMetadataItem(GDAL_DMD_MIMETYPE, "image/heic");
82 1760 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/heif.html");
83 1760 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "heic");
84 : #ifdef HAS_CUSTOM_FILE_READER
85 1760 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
86 : #endif
87 :
88 1760 : poDriver->SetMetadataItem("LIBHEIF_VERSION", LIBHEIF_VERSION);
89 :
90 1760 : poDriver->pfnIdentify = HEIFDriverIdentifySimplified;
91 1760 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
92 : #ifdef HAS_CUSTOM_FILE_WRITER
93 1760 : poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
94 : #endif
95 1760 : }
96 :
97 : /************************************************************************/
98 : /* DeclareDeferredHEIFPlugin() */
99 : /************************************************************************/
100 :
101 : #ifdef PLUGIN_FILENAME
102 2033 : void DeclareDeferredHEIFPlugin()
103 : {
104 2033 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
105 : {
106 283 : return;
107 : }
108 1750 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
109 : #ifdef PLUGIN_INSTALLATION_MESSAGE
110 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
111 : PLUGIN_INSTALLATION_MESSAGE);
112 : #endif
113 1750 : HEIFDriverSetCommonMetadata(poDriver);
114 1750 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
115 : }
116 : #endif
|