Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: NITF Read/Write Library
4 : * Purpose: Creates RPFHDR, RPFIMG, RPFDES TREs and RPF image data
5 : * Author: Even Rouault, even dot rouault at spatialys dot com
6 : *
7 : **********************************************************************
8 : * Copyright (c) 2026, T-Kartor
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef RPFFRAME_WRITER_INCLUDED
14 : #define RPFFRAME_WRITER_INCLUDED
15 :
16 : #include "cpl_string.h"
17 : #include "cpl_vsi_virtual.h"
18 :
19 : #include "gdal_colortable.h"
20 :
21 : #include <string>
22 : #include <variant>
23 : #include <vector>
24 :
25 : namespace GDALOffsetPatcher
26 : {
27 : class OffsetPatcher;
28 : }
29 :
30 : class GDALDataset;
31 :
32 : constexpr int CADRG_MAX_COLOR_ENTRY_COUNT = 216;
33 : constexpr int CADRG_FRAME_PIXEL_COUNT = 1536;
34 :
35 : constexpr int Kilo = 1000;
36 : constexpr int Million = Kilo * Kilo;
37 :
38 : constexpr int MIN_ZONE = 1;
39 : constexpr int MAX_ZONE_NORTHERN_HEMISPHERE = 9;
40 : constexpr int MIN_ZONE_SOUTHERN_HEMISPHERE = 1 + MAX_ZONE_NORTHERN_HEMISPHERE;
41 : constexpr int MAX_ZONE = 18;
42 :
43 : constexpr const char *pszNorthPolarProjection =
44 : "PROJCS[\"ARC_System_Zone_09\",GEOGCS[\"GCS_Sphere\","
45 : "DATUM[\"D_Sphere\",SPHEROID[\"Sphere\",6378137.0,0.0]],"
46 : "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],"
47 : "PROJECTION[\"Azimuthal_Equidistant\"],"
48 : "PARAMETER[\"latitude_of_center\",90],"
49 : "PARAMETER[\"longitude_of_center\",0],"
50 : "PARAMETER[\"false_easting\",0],"
51 : "PARAMETER[\"false_northing\",0],"
52 : "UNIT[\"metre\",1]]";
53 :
54 : constexpr const char *pszSouthPolarProjection =
55 : "PROJCS[\"ARC_System_Zone_18\",GEOGCS[\"GCS_Sphere\","
56 : "DATUM[\"D_Sphere\",SPHEROID[\"Sphere\",6378137.0,0.0]],"
57 : "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],"
58 : "PROJECTION[\"Azimuthal_Equidistant\"],"
59 : "PARAMETER[\"latitude_of_center\",-90],"
60 : "PARAMETER[\"longitude_of_center\",0],"
61 : "PARAMETER[\"false_easting\",0],"
62 : "PARAMETER[\"false_northing\",0],"
63 : "UNIT[\"metre\",1]]";
64 :
65 : /** Opaque class containing CADRG related information */
66 33 : class CADRGInformation
67 : {
68 : public:
69 : class Private;
70 : explicit CADRGInformation(std::unique_ptr<Private>);
71 : ~CADRGInformation();
72 :
73 : bool HasTransparentPixels() const;
74 :
75 : std::unique_ptr<Private> m_private{};
76 : };
77 :
78 : void Create_CADRG_RPFHDR(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
79 : const std::string &osFilename,
80 : CPLStringList &aosOptions);
81 :
82 : struct CADRGCreateCopyContext
83 : {
84 : int nReciprocalScale = 0;
85 : GDALColorTable oCT2{};
86 : std::vector<int> anMapCT1ToCT2{};
87 : GDALColorTable oCT3{};
88 : std::vector<int> anMapCT1ToCT3{};
89 : };
90 :
91 : std::unique_ptr<CADRGInformation>
92 : RPFFrameCreateCADRG_TREs(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
93 : const std::string &osFilename, GDALDataset *poSrcDS,
94 : CPLStringList &aosOptions,
95 : const CADRGCreateCopyContext ©Context);
96 :
97 : bool RPFFrameWriteCADRG_RPFIMG(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
98 : VSILFILE *fp, int &nUDIDL);
99 :
100 : bool RPFFrameWriteCADRG_ImageContent(
101 : GDALOffsetPatcher::OffsetPatcher *offsetPatcher, VSILFILE *fp,
102 : GDALDataset *poSrcDS, CADRGInformation *info);
103 :
104 : const char *RPFFrameWriteGetDESHeader();
105 :
106 : bool RPFFrameWriteCADRG_RPFDES(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
107 : VSILFILE *fp, vsi_l_offset nOffsetLDSH,
108 : const CPLStringList &aosOptions,
109 : int nReciprocalScale);
110 :
111 : int RPFGetCADRGClosestReciprocalScale(GDALDataset *poSrcDS,
112 : double dfDPIOverride, bool &bGotDPI);
113 :
114 : std::variant<bool, std::unique_ptr<GDALDataset>>
115 : CADRGCreateCopy(const char *pszFilename, GDALDataset *poSrcDS, int bStrict,
116 : CSLConstList papszOptions, GDALProgressFunc pfnProgress,
117 : void *pProgressData, int nRecLevel,
118 : CADRGCreateCopyContext *copyContext);
119 :
120 : struct RPFFrameDef
121 : {
122 : int nZone;
123 : int nReciprocalScale;
124 : int nFrameMinX;
125 : int nFrameMinY;
126 : int nFrameMaxX;
127 : int nFrameMaxY;
128 : double dfResX;
129 : double dfResY;
130 : };
131 :
132 : void RPFGetCADRGResolutionAndInterval(int nZone, int nReciprocalScale,
133 : double &latResolution,
134 : double &lonResolution,
135 : double &latInterval, double &lonInterval);
136 : std::vector<RPFFrameDef> RPFGetCADRGFramesForEnvelope(int nZoneIn,
137 : int nReciprocalScale,
138 : GDALDataset *poSrcDS);
139 :
140 : void RPFGetCADRGFrameExtent(int nZone, int nReciprocalScale, int nFrameX,
141 : int nFrameY, double &dfXMin, double &dfYMin,
142 : double &dfXMax, double &dfYMax);
143 :
144 : bool RPFCADRGIsKnownDataSeriesCode(const char *pszCode);
145 :
146 : char RPFCADRGZoneNumToChar(int nZone);
147 :
148 : int RPFCADRGZoneCharToNum(char chZone);
149 :
150 : int RPFCADRGGetScaleFromDataSeriesCode(const char *pszCode);
151 :
152 : std::string RPFGetCADRGFrameNumberAsString(int nZone, int nReciprocalScale,
153 : int nFrameX, int nFrameY);
154 :
155 : #endif // RPFFRAME_WRITER_INCLUDED
|