GDAL
ogrsf_frmts.h
Go to the documentation of this file.
1 /******************************************************************************
2  * $Id: ogrsf_frmts.h decf0d0bdf8ba9b4efa471cd15c968080e656298 2021-02-27 22:56:48 +0100 Even Rouault $
3  *
4  * Project: OpenGIS Simple Features Reference Implementation
5  * Purpose: Classes related to format registration, and file opening.
6  * Author: Frank Warmerdam, warmerda@home.com
7  *
8  ******************************************************************************
9  * Copyright (c) 1999, Les Technologies SoftMap Inc.
10  * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef OGRSF_FRMTS_H_INCLUDED
32 #define OGRSF_FRMTS_H_INCLUDED
33 
34 #include "cpl_progress.h"
35 #include "ogr_feature.h"
36 #include "ogr_featurestyle.h"
37 #include "gdal_priv.h"
38 
39 #include <memory>
40 
48 #if !defined(GDAL_COMPILATION) && !defined(SUPPRESS_DEPRECATION_WARNINGS)
49 #define OGR_DEPRECATED(x) CPL_WARN_DEPRECATED(x)
50 #else
51 #define OGR_DEPRECATED(x)
52 #endif
54 
55 class OGRLayerAttrIndex;
56 class OGRSFDriver;
57 
58 /************************************************************************/
59 /* OGRLayer */
60 /************************************************************************/
61 
67 /* Note: any virtual method added to this class must also be added in the */
68 /* OGRLayerDecorator and OGRMutexedLayer classes. */
69 
70 class CPL_DLL OGRLayer : public GDALMajorObject
71 {
72  private:
73  struct Private;
74  std::unique_ptr<Private> m_poPrivate;
75 
76  void ConvertGeomsIfNecessary( OGRFeature *poFeature );
77 
78  class CPL_DLL FeatureIterator
79  {
80  struct Private;
81  std::unique_ptr<Private> m_poPrivate;
82  public:
83  FeatureIterator(OGRLayer* poLayer, bool bStart);
84  FeatureIterator(FeatureIterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
85  ~FeatureIterator();
86  OGRFeatureUniquePtr& operator*();
87  FeatureIterator& operator++();
88  bool operator!=(const FeatureIterator& it) const;
89  };
90 
91  friend inline FeatureIterator begin(OGRLayer* poLayer);
92  friend inline FeatureIterator end(OGRLayer* poLayer);
93 
95 
96  protected:
98  int m_bFilterIsEnvelope;
99  OGRGeometry *m_poFilterGeom;
100  OGRPreparedGeometry *m_pPreparedFilterGeom; /* m_poFilterGeom compiled as a prepared geometry */
101  OGREnvelope m_sFilterEnvelope;
102  int m_iGeomFieldFilter; // specify the index on which the spatial
103  // filter is active.
104 
105  int FilterGeometry( OGRGeometry * );
106  //int FilterGeometry( OGRGeometry *, OGREnvelope* psGeometryEnvelope);
107  int InstallFilter( OGRGeometry * );
108 
109  OGRErr GetExtentInternal(int iGeomField, OGREnvelope *psExtent, int bForce );
111 
112  virtual OGRErr ISetFeature( OGRFeature *poFeature ) CPL_WARN_UNUSED_RESULT;
113  virtual OGRErr ICreateFeature( OGRFeature *poFeature ) CPL_WARN_UNUSED_RESULT;
114 
115  public:
116  OGRLayer();
117  virtual ~OGRLayer();
118 
129  FeatureIterator begin();
130 
132  FeatureIterator end();
133 
134  virtual OGRGeometry *GetSpatialFilter();
135  virtual void SetSpatialFilter( OGRGeometry * );
136  virtual void SetSpatialFilterRect( double dfMinX, double dfMinY,
137  double dfMaxX, double dfMaxY );
138 
139  virtual void SetSpatialFilter( int iGeomField, OGRGeometry * );
140  virtual void SetSpatialFilterRect( int iGeomField,
141  double dfMinX, double dfMinY,
142  double dfMaxX, double dfMaxY );
143 
144  virtual OGRErr SetAttributeFilter( const char * );
145 
146  virtual void ResetReading() = 0;
148  virtual OGRErr SetNextByIndex( GIntBig nIndex );
149  virtual OGRFeature *GetFeature( GIntBig nFID ) CPL_WARN_UNUSED_RESULT;
150 
151  OGRErr SetFeature( OGRFeature *poFeature ) CPL_WARN_UNUSED_RESULT;
152  OGRErr CreateFeature( OGRFeature *poFeature ) CPL_WARN_UNUSED_RESULT;
153 
154  virtual OGRErr DeleteFeature( GIntBig nFID ) CPL_WARN_UNUSED_RESULT;
155 
156  virtual const char *GetName();
157  virtual OGRwkbGeometryType GetGeomType();
158  virtual OGRFeatureDefn *GetLayerDefn() = 0;
159  virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch );
160 
161  virtual OGRSpatialReference *GetSpatialRef();
162 
163  virtual GIntBig GetFeatureCount( int bForce = TRUE );
164  virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) CPL_WARN_UNUSED_RESULT;
165  virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
166  int bForce = TRUE) CPL_WARN_UNUSED_RESULT;
167 
168  virtual int TestCapability( const char * ) = 0;
169 
170  virtual OGRErr CreateField( OGRFieldDefn *poField,
171  int bApproxOK = TRUE );
172  virtual OGRErr DeleteField( int iField );
173  virtual OGRErr ReorderFields( int* panMap );
174  virtual OGRErr AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlagsIn );
175 
176  virtual OGRErr CreateGeomField( OGRGeomFieldDefn *poField,
177  int bApproxOK = TRUE );
178 
179  virtual OGRErr SyncToDisk();
180 
181  virtual OGRStyleTable *GetStyleTable();
182  virtual void SetStyleTableDirectly( OGRStyleTable *poStyleTable );
183 
184  virtual void SetStyleTable(OGRStyleTable *poStyleTable);
185 
186  virtual OGRErr StartTransaction() CPL_WARN_UNUSED_RESULT;
187  virtual OGRErr CommitTransaction() CPL_WARN_UNUSED_RESULT;
188  virtual OGRErr RollbackTransaction();
189 
190  virtual const char *GetFIDColumn();
191  virtual const char *GetGeometryColumn();
192 
193  virtual OGRErr SetIgnoredFields( const char **papszFields );
194 
195  OGRErr Intersection( OGRLayer *pLayerMethod,
196  OGRLayer *pLayerResult,
197  char** papszOptions = nullptr,
198  GDALProgressFunc pfnProgress = nullptr,
199  void * pProgressArg = nullptr );
200  OGRErr Union( OGRLayer *pLayerMethod,
201  OGRLayer *pLayerResult,
202  char** papszOptions = nullptr,
203  GDALProgressFunc pfnProgress = nullptr,
204  void * pProgressArg = nullptr );
205  OGRErr SymDifference( OGRLayer *pLayerMethod,
206  OGRLayer *pLayerResult,
207  char** papszOptions,
208  GDALProgressFunc pfnProgress,
209  void * pProgressArg );
210  OGRErr Identity( OGRLayer *pLayerMethod,
211  OGRLayer *pLayerResult,
212  char** papszOptions = nullptr,
213  GDALProgressFunc pfnProgress = nullptr,
214  void * pProgressArg = nullptr );
215  OGRErr Update( OGRLayer *pLayerMethod,
216  OGRLayer *pLayerResult,
217  char** papszOptions = nullptr,
218  GDALProgressFunc pfnProgress = nullptr,
219  void * pProgressArg = nullptr );
220  OGRErr Clip( OGRLayer *pLayerMethod,
221  OGRLayer *pLayerResult,
222  char** papszOptions = nullptr,
223  GDALProgressFunc pfnProgress = nullptr,
224  void * pProgressArg = nullptr );
225  OGRErr Erase( OGRLayer *pLayerMethod,
226  OGRLayer *pLayerResult,
227  char** papszOptions = nullptr,
228  GDALProgressFunc pfnProgress = nullptr,
229  void * pProgressArg = nullptr );
230 
231  int Reference();
232  int Dereference();
233  int GetRefCount() const;
235  GIntBig GetFeaturesRead();
237 
238  /* non virtual : convenience wrapper for ReorderFields() */
239  OGRErr ReorderField( int iOldFieldPos, int iNewFieldPos );
240 
242  int AttributeFilterEvaluationNeedsGeometry();
243 
244  /* consider these private */
245  OGRErr InitializeIndexSupport( const char * );
246  OGRLayerAttrIndex *GetIndex() { return m_poAttrIndex; }
247  int GetGeomFieldFilter() const { return m_iGeomFieldFilter; }
248  const char *GetAttrQueryString() const { return m_pszAttrQueryString; }
250 
254  static inline OGRLayerH ToHandle(OGRLayer* poLayer)
255  { return reinterpret_cast<OGRLayerH>(poLayer); }
256 
260  static inline OGRLayer* FromHandle(OGRLayerH hLayer)
261  { return reinterpret_cast<OGRLayer*>(hLayer); }
262 
263  protected:
265  OGRStyleTable *m_poStyleTable;
266  OGRFeatureQuery *m_poAttrQuery;
267  char *m_pszAttrQueryString;
268  OGRLayerAttrIndex *m_poAttrIndex;
269 
270  int m_nRefCount;
271 
272  GIntBig m_nFeaturesRead;
274 };
275 
287 inline OGRLayer::FeatureIterator begin(OGRLayer* poLayer) { return poLayer->begin(); }
288 
292 inline OGRLayer::FeatureIterator end(OGRLayer* poLayer) { return poLayer->end(); }
293 
297 using OGRLayerUniquePtr = std::unique_ptr<OGRLayer>;
298 
299 /************************************************************************/
300 /* OGRGetNextFeatureThroughRaw */
301 /************************************************************************/
302 
308 template<class BaseLayer> class OGRGetNextFeatureThroughRaw
309 {
310 public:
311 
314  {
315  const auto poThis = static_cast<BaseLayer*>(this);
316  while( true )
317  {
318  OGRFeature *poFeature = poThis->GetNextRawFeature();
319  if (poFeature == nullptr)
320  return nullptr;
321 
322  if((poThis->m_poFilterGeom == nullptr
323  || poThis->FilterGeometry( poFeature->GetGeometryRef() ) )
324  && (poThis->m_poAttrQuery == nullptr
325  || poThis->m_poAttrQuery->Evaluate( poFeature )) )
326  {
327  return poFeature;
328  }
329  else
330  delete poFeature;
331  }
332  }
333 };
334 
336 #define DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(BaseLayer) \
337  private: \
338  friend class OGRGetNextFeatureThroughRaw<BaseLayer>; \
339  public: \
340  OGRFeature* GetNextFeature() override { return OGRGetNextFeatureThroughRaw<BaseLayer>::GetNextFeature(); }
341 
342 
343 /************************************************************************/
344 /* OGRDataSource */
345 /************************************************************************/
346 
366 class CPL_DLL OGRDataSource : public GDALDataset
367 {
368 public:
369  OGRDataSource();
371  virtual const char *GetName() OGR_DEPRECATED("Use GDALDataset class instead") = 0;
372 
373  static void DestroyDataSource( OGRDataSource * ) OGR_DEPRECATED("Use GDALDataset class instead");
375 };
376 
377 /************************************************************************/
378 /* OGRSFDriver */
379 /************************************************************************/
380 
399 class CPL_DLL OGRSFDriver : public GDALDriver
400 {
401  public:
403  virtual ~OGRSFDriver();
404 
405  virtual const char *GetName() OGR_DEPRECATED("Use GDALDriver class instead") = 0;
406 
407  virtual OGRDataSource *Open( const char *pszName, int bUpdate=FALSE ) OGR_DEPRECATED("Use GDALDriver class instead") = 0;
408 
409  virtual int TestCapability( const char *pszCap ) OGR_DEPRECATED("Use GDALDriver class instead") = 0;
410 
411  virtual OGRDataSource *CreateDataSource( const char *pszName,
412  char ** = nullptr ) OGR_DEPRECATED("Use GDALDriver class instead");
413  virtual OGRErr DeleteDataSource( const char *pszName ) OGR_DEPRECATED("Use GDALDriver class instead");
415 };
416 
417 /************************************************************************/
418 /* OGRSFDriverRegistrar */
419 /************************************************************************/
420 
434 class CPL_DLL OGRSFDriverRegistrar
435 {
436 
439 
440  static GDALDataset* OpenWithDriverArg(GDALDriver* poDriver,
441  GDALOpenInfo* poOpenInfo);
442  static GDALDataset* CreateVectorOnly( GDALDriver* poDriver,
443  const char * pszName,
444  char ** papszOptions );
445  static CPLErr DeleteDataSource( GDALDriver* poDriver,
446  const char * pszName );
447 
448  public:
450  static OGRSFDriverRegistrar *GetRegistrar() OGR_DEPRECATED("Use GDALDriverManager class instead");
451 
452  // cppcheck-suppress functionStatic
453  void RegisterDriver( OGRSFDriver * poDriver ) OGR_DEPRECATED("Use GDALDriverManager class instead");
454 
455  // cppcheck-suppress functionStatic
456  int GetDriverCount( void ) OGR_DEPRECATED("Use GDALDriverManager class instead");
457  // cppcheck-suppress functionStatic
458  GDALDriver *GetDriver( int iDriver ) OGR_DEPRECATED("Use GDALDriverManager class instead");
459  // cppcheck-suppress functionStatic
460  GDALDriver *GetDriverByName( const char * ) OGR_DEPRECATED("Use GDALDriverManager class instead");
461 
462  // cppcheck-suppress functionStatic
463  int GetOpenDSCount() OGR_DEPRECATED("Use GDALDriverManager class instead");
464  // cppcheck-suppress functionStatic
465  OGRDataSource *GetOpenDS( int ) OGR_DEPRECATED("Use GDALDriverManager class instead");
467 };
468 
469 /* -------------------------------------------------------------------- */
470 /* Various available registration methods. */
471 /* -------------------------------------------------------------------- */
473 
475 void OGRRegisterAllInternal();
476 
477 void CPL_DLL RegisterOGRFileGDB();
478 void CPL_DLL RegisterOGRShape();
479 void CPL_DLL RegisterOGRDB2();
480 void CPL_DLL RegisterOGRNTF();
481 void CPL_DLL RegisterOGRFME();
482 void CPL_DLL RegisterOGRSDTS();
483 void CPL_DLL RegisterOGRTiger();
484 void CPL_DLL RegisterOGRS57();
485 void CPL_DLL RegisterOGRTAB();
486 void CPL_DLL RegisterOGRMIF();
487 void CPL_DLL RegisterOGROGDI();
488 void CPL_DLL RegisterOGRODBC();
489 void CPL_DLL RegisterOGRWAsP();
490 void CPL_DLL RegisterOGRPG();
491 void CPL_DLL RegisterOGRMSSQLSpatial();
492 void CPL_DLL RegisterOGRMySQL();
493 void CPL_DLL RegisterOGROCI();
494 void CPL_DLL RegisterOGRDGN();
495 void CPL_DLL RegisterOGRGML();
496 void CPL_DLL RegisterOGRLIBKML();
497 void CPL_DLL RegisterOGRKML();
498 void CPL_DLL RegisterOGRFlatGeobuf();
499 void CPL_DLL RegisterOGRGeoJSON();
500 void CPL_DLL RegisterOGRGeoJSONSeq();
501 void CPL_DLL RegisterOGRESRIJSON();
502 void CPL_DLL RegisterOGRTopoJSON();
503 void CPL_DLL RegisterOGRAVCBin();
504 void CPL_DLL RegisterOGRAVCE00();
505 void CPL_DLL RegisterOGRREC();
506 void CPL_DLL RegisterOGRMEM();
507 void CPL_DLL RegisterOGRVRT();
508 void CPL_DLL RegisterOGRDODS();
509 void CPL_DLL RegisterOGRSQLite();
510 void CPL_DLL RegisterOGRCSV();
511 void CPL_DLL RegisterOGRILI1();
512 void CPL_DLL RegisterOGRILI2();
513 void CPL_DLL RegisterOGRGRASS();
514 void CPL_DLL RegisterOGRPGeo();
515 void CPL_DLL RegisterOGRDXF();
516 void CPL_DLL RegisterOGRCAD();
517 void CPL_DLL RegisterOGRDWG();
518 void CPL_DLL RegisterOGRDGNV8();
519 void CPL_DLL RegisterOGRIDB();
520 void CPL_DLL RegisterOGRGMT();
521 void CPL_DLL RegisterOGRGPX();
522 void CPL_DLL RegisterOGRGeoconcept();
523 void CPL_DLL RegisterOGRIngres();
524 void CPL_DLL RegisterOGRNAS();
525 void CPL_DLL RegisterOGRGeoRSS();
526 void CPL_DLL RegisterOGRGTM();
527 void CPL_DLL RegisterOGRVFK();
528 void CPL_DLL RegisterOGRPGDump();
529 void CPL_DLL RegisterOGROSM();
530 void CPL_DLL RegisterOGRGPSBabel();
531 void CPL_DLL RegisterOGRPDS();
532 void CPL_DLL RegisterOGRWFS();
533 void CPL_DLL RegisterOGROAPIF();
534 void CPL_DLL RegisterOGRSOSI();
535 void CPL_DLL RegisterOGRGeomedia();
536 void CPL_DLL RegisterOGRMDB();
537 void CPL_DLL RegisterOGREDIGEO();
538 void CPL_DLL RegisterOGRSVG();
539 void CPL_DLL RegisterOGRCouchDB();
540 void CPL_DLL RegisterOGRCloudant();
541 void CPL_DLL RegisterOGRIdrisi();
542 void CPL_DLL RegisterOGRARCGEN();
543 void CPL_DLL RegisterOGRXLS();
544 void CPL_DLL RegisterOGRODS();
545 void CPL_DLL RegisterOGRXLSX();
546 void CPL_DLL RegisterOGRElastic();
547 void CPL_DLL RegisterOGRGeoPackage();
548 void CPL_DLL RegisterOGRWalk();
549 void CPL_DLL RegisterOGRCarto();
550 void CPL_DLL RegisterOGRAmigoCloud();
551 void CPL_DLL RegisterOGRSXF();
552 void CPL_DLL RegisterOGROpenFileGDB();
553 void CPL_DLL RegisterOGRSelafin();
554 void CPL_DLL RegisterOGRJML();
555 void CPL_DLL RegisterOGRPLSCENES();
556 void CPL_DLL RegisterOGRCSW();
557 void CPL_DLL RegisterOGRMongoDBv3();
558 void CPL_DLL RegisterOGRMongoDB();
559 void CPL_DLL RegisterOGRVDV();
560 void CPL_DLL RegisterOGRGMLAS();
561 void CPL_DLL RegisterOGRMVT();
562 void CPL_DLL RegisterOGRNGW();
563 void CPL_DLL RegisterOGRMapML();
564 void CPL_DLL RegisterOGRLVBAG();
565 // @endcond
566 
567 CPL_C_END
568 
569 #endif /* ndef OGRSF_FRMTS_H_INCLUDED */
A set of associated raster bands, usually from one file.
Definition: gdal_priv.h:340
Format specific driver.
Definition: gdal_priv.h:1486
Object with metadata.
Definition: gdal_priv.h:136
Class for dataset open functions.
Definition: gdal_priv.h:269
LEGACY class.
Definition: ogrsf_frmts.h:367
Simple container for a bounding region (rectangle)
Definition: ogr_core.h:58
Definition of a feature class or feature layer.
Definition: ogr_feature.h:279
A simple feature, including geometry and attributes.
Definition: ogr_feature.h:371
OGRGeometry * GetGeometryRef()
Fetch pointer to feature geometry.
Definition: ogrfeature.cpp:583
Definition of an attribute of an OGRFeatureDefn.
Definition: ogr_feature.h:99
Definition of a geometry field of an OGRFeatureDefn.
Definition: ogr_feature.h:202
Abstract base class for all geometry classes.
Definition: ogr_geometry.h:327
Template class offering a GetNextFeature() implementation relying on GetNextRawFeature()
Definition: ogrsf_frmts.h:309
OGRFeature * GetNextFeature()
Implement OGRLayer::GetNextFeature(), relying on BaseLayer::GetNextRawFeature()
Definition: ogrsf_frmts.h:313
This class represents a layer of simple features, with access methods.
Definition: ogrsf_frmts.h:71
friend FeatureIterator begin(OGRLayer *poLayer)
Return begin of feature iterator.
Definition: ogrsf_frmts.h:287
virtual OGRFeature * GetNextFeature()=0
Fetch the next available feature from this layer.
static OGRLayer * FromHandle(OGRLayerH hLayer)
Convert a OGRLayerH to a OGRLayer*.
Definition: ogrsf_frmts.h:260
static OGRLayerH ToHandle(OGRLayer *poLayer)
Convert a OGRLayer* to a OGRLayerH.
Definition: ogrsf_frmts.h:254
friend FeatureIterator end(OGRLayer *poLayer)
Return end of feature iterator.
Definition: ogrsf_frmts.h:292
virtual void ResetReading()=0
Reset feature reading to start on the first feature.
LEGACY class.
Definition: ogrsf_frmts.h:435
LEGACY class.
Definition: ogrsf_frmts.h:400
This class represents an OpenGIS Spatial Reference System, and contains methods for converting betwee...
Definition: ogr_spatialref.h:158
This class represents a style table.
Definition: ogr_featurestyle.h:85
CPLErr
Error category.
Definition: cpl_error.h:53
#define CPL_C_END
Macro to end a block of C symbols.
Definition: cpl_port.h:331
#define CPL_C_START
Macro to start a block of C symbols.
Definition: cpl_port.h:329
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:955
#define CPL_WARN_UNUSED_RESULT
Qualifier to warn when the return value of a function is not used.
Definition: cpl_port.h:894
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:244
C++ GDAL entry points.
void * OGRLayerH
Opaque type for a layer (OGRLayer)
Definition: ogr_api.h:589
OGRwkbGeometryType
List of well known binary geometry types.
Definition: ogr_core.h:346
int OGRErr
Type for a OGR error.
Definition: ogr_core.h:318
Simple feature classes.
std::unique_ptr< OGRFeature, OGRFeatureUniquePtrDeleter > OGRFeatureUniquePtr
Unique pointer type for OGRFeature.
Definition: ogr_feature.h:796
Simple feature style classes.
std::unique_ptr< OGRLayer > OGRLayerUniquePtr
Unique pointer type for OGRLayer.
Definition: ogrsf_frmts.h:297
OGRLayer::FeatureIterator begin(OGRLayer *poLayer)
Return begin of feature iterator.
Definition: ogrsf_frmts.h:287
OGRLayer::FeatureIterator end(OGRLayer *poLayer)
Return end of feature iterator.
Definition: ogrsf_frmts.h:292