Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: JPEG2000 driver based on OpenJPEG or Grok library
4 : * Purpose: JPEG2000 driver based on OpenJPEG or Grok library
5 : * Authors: Even Rouault, <even dot rouault at spatialys dot com>
6 : * Aaron Boxer, <boxerab at protonmail dot com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2010-2014, Even Rouault <even dot rouault at spatialys dot com>
10 : * Copyright (c) 2015, European Union (European Environment Agency)
11 : * Copyright (c) 2023, Grok Image Compression Inc.
12 : *
13 : * SPDX-License-Identifier: MIT
14 : ****************************************************************************/
15 :
16 : #pragma once
17 :
18 : #include "cpl_atomic_ops.h"
19 : #include "cpl_multiproc.h"
20 : #include "cpl_string.h"
21 : #include "cpl_worker_thread_pool.h"
22 : #include "gdaljp2abstractdataset.h"
23 : #include "gdaljp2metadata.h"
24 :
25 : typedef int JP2_COLOR_SPACE;
26 : typedef int JP2_PROG_ORDER;
27 :
28 : #define JP2_LRCP 0
29 : #define JP2_RLCP 1
30 : #define JP2_RPCL 2
31 : #define JP2_PCRL 3
32 : #define JP2_CPRL 4
33 :
34 : enum JP2_ENUM
35 : {
36 : JP2_CLRSPC_UNKNOWN,
37 : JP2_CLRSPC_SRGB,
38 : JP2_CLRSPC_GRAY,
39 : JP2_CLRSPC_SYCC,
40 : JP2_CODEC_J2K,
41 : JP2_CODEC_JP2
42 : };
43 :
44 : typedef struct
45 : {
46 : VSILFILE *fp_;
47 : vsi_l_offset nBaseOffset;
48 : } JP2File;
49 :
50 : /************************************************************************/
51 : /* ==================================================================== */
52 : /* JP2DatasetBase */
53 : /* ==================================================================== */
54 : /************************************************************************/
55 :
56 1902 : struct JP2DatasetBase
57 : {
58 1657 : int GetNumThreads()
59 : {
60 1657 : if (nThreads >= 1)
61 446 : return nThreads;
62 :
63 : const char *pszThreads =
64 1211 : CPLGetConfigOption("GDAL_NUM_THREADS", "ALL_CPUS");
65 1211 : if (EQUAL(pszThreads, "ALL_CPUS"))
66 1211 : nThreads = CPLGetNumCPUs();
67 : else
68 0 : nThreads = atoi(pszThreads);
69 1211 : if (nThreads > 128)
70 0 : nThreads = 128;
71 1211 : if (nThreads <= 0)
72 0 : nThreads = 1;
73 1211 : return nThreads;
74 : }
75 :
76 : std::string m_osFilename{};
77 : VSILFILE *fp_ = nullptr; /* Large FILE API */
78 : vsi_l_offset nCodeStreamStart = 0;
79 : vsi_l_offset nCodeStreamLength = 0;
80 :
81 : int nRedIndex = 0;
82 : int nGreenIndex = 1;
83 : int nBlueIndex = 2;
84 : int nAlphaIndex = -1;
85 :
86 : int bIs420 = FALSE;
87 :
88 : int nParentXSize = 0;
89 : int nParentYSize = 0;
90 : int iLevel = 0;
91 : int nOverviewCount = 0;
92 :
93 : int bEnoughMemoryToLoadOtherBands = TRUE;
94 : int bRewrite = FALSE;
95 : int bHasGeoreferencingAtOpening = FALSE;
96 :
97 : int nThreads = -1;
98 : bool bUseSetDecodeArea = false;
99 : bool bSingleTiled = false;
100 : int m_nBlocksToLoad = 0;
101 : int m_nX0 = 0;
102 : int m_nY0 = 0;
103 : uint32_t m_nTileWidth = 0;
104 : uint32_t m_nTileHeight = 0;
105 :
106 : virtual ~JP2DatasetBase();
107 : };
108 :
109 : /************************************************************************/
110 : /* ==================================================================== */
111 : /* JP2OPJLikeDataset */
112 : /* ==================================================================== */
113 : /************************************************************************/
114 : template <typename CODEC, typename BASE> class JP2OPJLikeRasterBand;
115 :
116 : template <typename CODEC, typename BASE>
117 : class JP2OPJLikeDataset final : public GDALJP2AbstractDataset, public BASE
118 : {
119 : friend class JP2OPJLikeRasterBand<CODEC, BASE>;
120 : JP2OPJLikeDataset **papoOverviewDS = nullptr;
121 :
122 : JP2OPJLikeDataset(const JP2OPJLikeDataset &) = delete;
123 : JP2OPJLikeDataset &operator=(const JP2OPJLikeDataset &) = delete;
124 :
125 : protected:
126 : virtual int CloseDependentDatasets() override;
127 : virtual VSILFILE *GetFileHandle() override;
128 : CPLErr Close() override;
129 :
130 : public:
131 : JP2OPJLikeDataset();
132 : virtual ~JP2OPJLikeDataset();
133 :
134 : static int Identify(GDALOpenInfo *poOpenInfo);
135 : static GDALDataset *Open(GDALOpenInfo *);
136 : static GDALDataset *CreateCopy(const char *pszFilename,
137 : GDALDataset *poSrcDS, int bStrict,
138 : char **papszOptions,
139 : GDALProgressFunc pfnProgress,
140 : void *pProgressData);
141 :
142 : CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
143 :
144 : virtual CPLErr SetGeoTransform(double *) override;
145 :
146 : CPLErr SetGCPs(int nGCPCountIn, const GDAL_GCP *pasGCPListIn,
147 : const OGRSpatialReference *poSRS) override;
148 :
149 : virtual CPLErr SetMetadata(char **papszMetadata,
150 : const char *pszDomain = "") override;
151 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
152 : const char *pszDomain = "") override;
153 :
154 : virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
155 : int nXSize, int nYSize, void *pData, int nBufXSize,
156 : int nBufYSize, GDALDataType eBufType,
157 : int nBandCount, BANDMAP_TYPE panBandMap,
158 : GSpacing nPixelSpace, GSpacing nLineSpace,
159 : GSpacing nBandSpace,
160 : GDALRasterIOExtraArg *psExtraArg) override;
161 :
162 : virtual GIntBig GetEstimatedRAMUsage() override;
163 :
164 : CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
165 : const int *panOverviewList, int nListBands,
166 : const int *panBandList, GDALProgressFunc pfnProgress,
167 : void *pProgressData,
168 : CSLConstList papszOptions) override;
169 :
170 : static bool WriteBox(VSILFILE *fp, GDALJP2Box *poBox);
171 : static bool WriteGDALMetadataBox(VSILFILE *fp, GDALDataset *poSrcDS,
172 : char **papszOptions);
173 : static bool WriteXMLBoxes(VSILFILE *fp, GDALDataset *poSrcDS);
174 : static bool WriteXMPBox(VSILFILE *fp, GDALDataset *poSrcDS);
175 : static bool WriteIPRBox(VSILFILE *fp, GDALDataset *poSrcDS);
176 :
177 : CPLErr ReadBlock(int nBand, VSILFILE *fp, int nBlockXOff, int nBlockYOff,
178 : void *pImage, int nBandCount, const int *panBandMap);
179 :
180 : int PreloadBlocks(JP2OPJLikeRasterBand<CODEC, BASE> *poBand, int nXOff,
181 : int nYOff, int nXSize, int nYSize, int nBandCount,
182 : const int *panBandMap);
183 :
184 : static void ReadBlockInThread(void *userdata);
185 : };
186 :
187 : /************************************************************************/
188 : /* ==================================================================== */
189 : /* JP2OPJLikeRasterBand */
190 : /* ==================================================================== */
191 : /************************************************************************/
192 :
193 : template <typename CODEC, typename BASE>
194 : class JP2OPJLikeRasterBand final : public GDALPamRasterBand
195 : {
196 : friend class JP2OPJLikeDataset<CODEC, BASE>;
197 : int bPromoteTo8Bit = false;
198 : GDALColorTable *poCT = nullptr;
199 :
200 : JP2OPJLikeRasterBand(const JP2OPJLikeRasterBand &) = delete;
201 : JP2OPJLikeRasterBand &operator=(const JP2OPJLikeRasterBand &) = delete;
202 :
203 : public:
204 : JP2OPJLikeRasterBand(JP2OPJLikeDataset<CODEC, BASE> *poDSIn, int nBandIn,
205 : GDALDataType eDataTypeIn, int nBits,
206 : int bPromoteTo8BitIn, int nBlockXSizeIn,
207 : int nBlockYSizeIn);
208 : virtual ~JP2OPJLikeRasterBand();
209 :
210 : virtual CPLErr IReadBlock(int, int, void *) override;
211 : virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
212 : int nXSize, int nYSize, void *pData, int nBufXSize,
213 : int nBufYSize, GDALDataType eBufType,
214 : GSpacing nPixelSpace, GSpacing nLineSpace,
215 : GDALRasterIOExtraArg *psExtraArg) override;
216 :
217 : virtual GDALColorInterp GetColorInterpretation() override;
218 : virtual GDALColorTable *GetColorTable() override;
219 :
220 : virtual int GetOverviewCount() override;
221 : virtual GDALRasterBand *GetOverview(int iOvrLevel) override;
222 :
223 : virtual int HasArbitraryOverviews() override;
224 : };
225 :
226 : #ifdef unused
227 : void GDALRegisterJP2();
228 : #endif
|