Coverage Report

Created: 2025-07-23 09:13

/src/gdal/frmts/pcraster/libcsf/create2.c
Line
Count
Source (jump to first uncovered line)
1
#include "csf.h" 
2
#include "csfimpl.h" 
3
4
#include <errno.h>
5
#include <string.h>
6
7
/* M_PI */
8
#include <math.h> 
9
#ifndef M_PI
10
# define M_PI        ((double)3.14159265358979323846)
11
#endif
12
13
/* 
14
 * Create a new CSF-Raster-file
15
 * The Rcreate function
16
 * creates a new CSF-Raster-file of nrRows by nrCols where each
17
 * cell is of type cellRepr. If the file already exists its
18
 * contents is destroyed. The value of
19
 * the pixels is undefined. MinMaxStatus is MM_KEEPTRACK. The
20
 * access mode is M_READ_WRITE. 
21
 * It is not
22
 * known if a file is created after a NOSPACE message.
23
 * Returns
24
 * if the file is created successfully, Rcreate returns
25
 * a map handle. In case of an error Rcreate returns NULL.
26
 *
27
 * Merrno 
28
 * NOCORE, BAD_CELLREPR, BAD_PROJECTION, OPENFAILED, NOSPACE.
29
 * CONFL_CELLREPR and BAD_VALUESCALE will generate a failed assertion in DEBUG mode.
30
 *
31
 * Example:  
32
 * .so examples/create2.tr
33
 *
34
 */
35
36
MAP *Rcreate(
37
  const char *fileName,  /* name of the file to be created */
38
  size_t nrRows,          /* the number of rows */
39
  size_t nrCols,          /* the number of columns */
40
  CSF_CR cellRepr,       /* the cell representation must be complaint with the data type
41
                          */
42
  CSF_VS dataType,      /* a.k.a. the value scale.
43
                         */
44
  CSF_PT projection,     /* 
45
                          */
46
  REAL8 xUL,              /* x co-ordinate of upper left */
47
  REAL8 yUL,              /* y co-ordinate of upper left */
48
  REAL8 angle,           /* counter clockwise rotation angle
49
                          * of the grid top compared to the
50
                          * x-axis in radians. Legal value are 
51
                          * between -0.5 pi and 0.5 pi
52
                          */
53
  REAL8 cellSize)        /* cell size of pixel */
54
0
{
55
0
  MAP    *newMap;
56
0
  size_t  fileSize;
57
0
  char    crap = 0;
58
59
0
  if (! CsfIsBootedCsfKernel())
60
0
    CsfBootCsfKernel();
61
62
0
  newMap = (MAP *)CSF_MALLOC(sizeof(MAP));
63
0
  if (newMap == NULL)
64
0
  {
65
0
    M_ERROR(NOCORE);
66
0
    goto errorMapAlloc;
67
0
  }
68
0
  newMap->fileName = (char *)CSF_MALLOC(strlen(fileName)+1);
69
0
  if (newMap->fileName == NULL)
70
0
  {
71
0
    M_ERROR(NOCORE);
72
0
    goto errorNameAlloc;
73
0
  }
74
75
0
  if (!(
76
0
    cellRepr == CR_INT4 ||
77
0
    cellRepr == CR_UINT1 ||
78
0
    cellRepr == CR_REAL4 ||
79
0
    cellRepr == CR_REAL8 ))
80
0
  {
81
0
    M_ERROR(BAD_CELLREPR);
82
0
    goto error_notOpen;
83
0
  }
84
85
0
  switch(dataType) {
86
0
   case VS_BOOLEAN: 
87
0
   case VS_LDD: 
88
0
    if (cellRepr != CR_UINT1)
89
0
    {
90
0
      PROG_ERROR(CONFL_CELLREPR);
91
0
      goto error_notOpen;
92
0
    }
93
0
    break;
94
0
  case VS_NOMINAL: 
95
0
  case VS_ORDINAL:
96
0
    if (IS_REAL(cellRepr))
97
0
    {
98
0
      PROG_ERROR(CONFL_CELLREPR);
99
0
      goto error_notOpen;
100
0
    }
101
0
    break;
102
0
  case VS_SCALAR:
103
0
  case VS_DIRECTION:
104
0
    if (!IS_REAL(cellRepr))
105
0
    {
106
0
      PROG_ERROR(CONFL_CELLREPR);
107
0
      goto error_notOpen;
108
0
    }
109
0
    break;
110
0
  default:
111
0
    PROG_ERROR(BAD_VALUESCALE);
112
0
    goto error_notOpen;
113
0
  }
114
115
0
  if (cellSize <= 0.0)
116
0
  {
117
0
    M_ERROR(ILL_CELLSIZE);
118
0
    goto error_notOpen;
119
0
  }
120
121
0
  if ((0.5*-M_PI) >= angle || angle >= (0.5*M_PI))
122
0
  {
123
0
    M_ERROR(BAD_ANGLE);
124
0
    goto error_notOpen;
125
0
  }
126
127
0
  newMap->fileAccessMode = M_READ_WRITE;
128
0
  (void)strcpy(newMap->fileName, fileName);
129
130
0
  newMap->fp = fopen (fileName, S_CREATE);
131
0
  if(newMap->fp == NULL)
132
0
  { 
133
     /* we should analyse the errno parameter
134
      * here to get the reason
135
      */
136
0
    M_ERROR(OPENFAILED);
137
0
    goto error_notOpen;
138
0
  }
139
  /*
140
     fflush(newMap->fp); WHY? 
141
   */
142
143
0
  (void)memset(&(newMap->main),0, sizeof(CSF_MAIN_HEADER));
144
0
  (void)memset(&(newMap->raster),0, sizeof(CSF_RASTER_HEADER));
145
  /* put defaults values     */
146
147
  /* assure signature is padded with 0x0 */
148
0
  (void)memset(newMap->main.signature, 0x0, (size_t)CSF_SIG_SPACE);
149
0
  (void)strcpy(newMap->main.signature, CSF_SIG);
150
0
  newMap->main.version = CSF_VERSION_2;
151
0
  newMap->main.gisFileId = 0;
152
0
  newMap->main.projection = PROJ_DEC_T2B(projection);
153
0
  newMap->main.attrTable = 0; /* initially no attributes */
154
0
  newMap->main.mapType = T_RASTER;
155
156
  /* write endian mode current machine: */
157
0
  newMap->main.byteOrder= ORD_OK;
158
159
#ifdef DEBUG
160
  newMap->read  = (CSF_READ_FUNC)CsfReadPlain;
161
  newMap->write = (CSF_READ_FUNC)CsfWritePlain;
162
#else
163
0
  newMap->read  = (CSF_READ_FUNC)fread;
164
0
  newMap->write = (CSF_READ_FUNC)fwrite;
165
0
#endif
166
167
0
  newMap->raster.valueScale = dataType;
168
0
  newMap->raster.cellRepr = cellRepr;
169
0
  CsfSetVarTypeMV( &(newMap->raster.minVal), cellRepr);
170
0
  CsfSetVarTypeMV( &(newMap->raster.maxVal), cellRepr);
171
0
  newMap->raster.xUL = xUL;
172
0
  newMap->raster.yUL = yUL;
173
0
  newMap->raster.nrRows = (UINT4)nrRows;
174
0
  newMap->raster.nrCols = (UINT4)nrCols;
175
0
  newMap->raster.cellSize = cellSize;
176
0
  newMap->raster.cellSizeDupl = cellSize;
177
0
  newMap->raster.angle = angle;
178
0
  CsfFinishMapInit(newMap);
179
180
  /*  set types to value cellRepr 
181
  newMap->types[STORED_AS]= (UINT1)newMap->raster.cellRepr;
182
  newMap->types[READ_AS]  = (UINT1)newMap->raster.cellRepr;
183
  */
184
0
  newMap->appCR  = (UINT1)newMap->raster.cellRepr;
185
0
  newMap->app2file = CsfDummyConversion;
186
0
  newMap->file2app = CsfDummyConversion;
187
188
  /*  make file the size of the header and data */
189
0
  fileSize   = nrRows*nrCols;
190
0
  fileSize <<= LOG_CELLSIZE(cellRepr);
191
0
  fileSize  += ADDR_DATA;
192
193
  /* enlarge the file to the length needed by seeking and writing
194
  one byte of crap */
195
196
0
  if ( csf_fseek(newMap->fp, fileSize-1, SEEK_SET) || /* fsetpos() is better */
197
0
      newMap->write(&crap, (size_t)1, (size_t)1, newMap->fp) != 1 )
198
0
  {
199
0
    M_ERROR(NOSPACE);
200
0
    goto error_open;
201
0
  }
202
0
  (void)fflush(newMap->fp);
203
0
  if ( csf_ftell(newMap->fp) != (CSF_FADDR)fileSize)
204
0
  {
205
0
    M_ERROR(NOSPACE);
206
0
    goto error_open;
207
0
  }
208
209
0
  newMap->minMaxStatus = MM_KEEPTRACK;
210
211
0
  CsfRegisterMap(newMap);
212
213
0
  return(newMap);
214
0
error_open: 
215
0
  (void)fclose(newMap->fp);
216
0
error_notOpen: 
217
0
  CSF_FREE(newMap->fileName);
218
0
errorNameAlloc:
219
0
        CSF_FREE(newMap);
220
0
errorMapAlloc:
221
0
  return(NULL);
222
0
}