• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15899174551

26 Jun 2025 10:15AM UTC coverage: 71.083% (-0.001%) from 71.084%
15899174551

push

github

web-flow
Merge pull request #12647 from rouault/parquet_compression_level

Parquet: add a COMPRESSION_LEVEL layer creation option

32 of 32 new or added lines in 2 files covered. (100.0%)

88 existing lines in 42 files now uncovered.

573828 of 807268 relevant lines covered (71.08%)

250001.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.92
/frmts/gtiff/libgeotiff/geo_new.c
1
/**********************************************************************
2
 *
3
 *  geo_new.c  -- Public routines for GEOTIFF GeoKey access.
4
 *
5
 *    Written By: Niles D. Ritter.
6
 *
7
 *  copyright (c) 1995   Niles D. Ritter
8
 *
9
 *  Permission granted to use this software, so long as this copyright
10
 *  notice accompanies any products derived therefrom.
11
 *
12
 **********************************************************************/
13

14
#include <stdarg.h>
15
#include <stdio.h>
16
#include <string.h>
17

18
#include "geotiffio.h"   /* public interface        */
19
#include "geo_tiffp.h" /* external TIFF interface */
20
#include "geo_keyp.h"  /* private interface       */
21
#include "geo_simpletags.h"
22

23
/* private local routines */
24
static int ReadKey(GTIF* gt, TempKeyData* tempData,
25
                   KeyEntry* entptr, GeoKey* keyptr);
26

27

28
static void GTIFErrorFunction(GTIF* gt, int level, const char* msg, ...)
×
29
{
30
    (void)gt;
31
    va_list list;
32

33
    va_start(list, msg);
×
34
    if( level == LIBGEOTIFF_WARNING )
×
35
        fprintf(stderr, "Warning: ");
×
36
    else if( level == LIBGEOTIFF_ERROR )
×
37
        fprintf(stderr, "Error: ");
×
38
    vfprintf(stderr, msg, list);
×
39
    fprintf(stderr, "\n");
×
40
    va_end(list);
×
41
}
×
42

43
/**********************************************************************
44
 *
45
 *                        Public Routines
46
 *
47
 **********************************************************************/
48

49

50
/**
51
 * Given an open TIFF file, look for GTIF keys and
52
 *  values and return GTIF structure.
53

54
This function creates a GeoTIFF information interpretation handle
55
(GTIF *) based on a passed in TIFF handle originally from
56
XTIFFOpen().  Even though the argument
57
(<b>tif</b>) is shown as type <tt>void *</tt>, it is really normally
58
of type <tt>TIFF *</tt>.<p>
59

60
The returned GTIF handle can be used to read or write GeoTIFF tags
61
using the various GTIF functions.  The handle should be destroyed using
62
GTIFFree() before the file is closed with TIFFClose().<p>
63

64
If the file accessed has no GeoTIFF keys, an valid (but empty) GTIF is
65
still returned.  GTIFNew() is used both for existing files being read, and
66
for new TIFF files that will have GeoTIFF tags written to them.<p>
67

68
 */
69

70
GTIF* GTIFNew(void *tif)
819✔
71

72
{
73
    return GTIFNewEx( tif, GTIFErrorFunction, NULL );
819✔
74
}
75

76
GTIF* GTIFNewEx(void *tif,
33,537✔
77
                GTErrorCallback error_callback, void* user_data)
78

79
{
80
    TIFFMethod default_methods;
81
    _GTIFSetDefaultTIFF( &default_methods );
33,537✔
82

83
    return GTIFNewWithMethodsEx( tif, &default_methods,
33,537✔
84
                                 error_callback, user_data );
85
}
86

87
GTIF *GTIFNewSimpleTags( void *tif )
×
88

89
{
90
    TIFFMethod default_methods;
91
    GTIFSetSimpleTagsMethods( &default_methods );
×
92

93
    return GTIFNewWithMethods( tif, &default_methods );
×
94
}
95

96
/************************************************************************/
97
/*                         GTIFNewWithMethods()                         */
98
/*                                                                      */
99
/*      Create a new geotiff, passing in the methods structure to       */
100
/*      support not libtiff implementations without replacing the       */
101
/*      default methods.                                                */
102
/************************************************************************/
103

104
GTIF* GTIFNewWithMethods(void *tif, TIFFMethod* methods)
×
105
{
106
    return GTIFNewWithMethodsEx(tif, methods, GTIFErrorFunction, NULL);
×
107
}
108

109
GTIF* GTIFNewWithMethodsEx(void *tif, TIFFMethod* methods,
33,537✔
110
                           GTErrorCallback error_callback, void* user_data)
111
{
112
    TempKeyData tempData;
113
    memset( &tempData, 0, sizeof(tempData) );
33,537✔
114

115
    GTIF* gt = (GTIF*)_GTIFcalloc( sizeof(GTIF));
33,537✔
116
    if (!gt) goto failure;
33,536✔
117

118
    gt->gt_error_callback = error_callback;
33,536✔
119
    gt->gt_user_data = user_data;
33,536✔
120

121
    /* install TIFF file and I/O methods */
122
    gt->gt_tif = (tiff_t *)tif;
33,536✔
123
    memcpy( &gt->gt_methods, methods, sizeof(TIFFMethod) );
33,536✔
124

125
    /* since this is an array, GTIF will allocate the memory */
126
    pinfo_t *data;
127
    if ( tif == NULL
33,536✔
128
         || !(gt->gt_methods.get)(tif, GTIFF_GEOKEYDIRECTORY, &gt->gt_nshorts, &data ))
33,536✔
129
    {
15,141✔
130
        /* No ProjectionInfo, create a blank one */
131
        data=(pinfo_t*)_GTIFcalloc((4+MAX_VALUES)*sizeof(pinfo_t));
15,142✔
132
        if (!data) goto failure;
15,141✔
133
        KeyHeader *header = (KeyHeader *)data;
15,141✔
134
        header->hdr_version = GvCurrentVersion;
15,141✔
135
        header->hdr_rev_major = GvCurrentRevision;
15,141✔
136
        header->hdr_rev_minor = GvCurrentMinorRev;
15,141✔
137
        gt->gt_nshorts=sizeof(KeyHeader)/sizeof(pinfo_t);
15,141✔
138
    }
139
    else
140
    {
141
        /* resize data array so it can be extended if needed */
142
        data = (pinfo_t*) _GTIFrealloc(data,(4+MAX_VALUES)*sizeof(pinfo_t));
18,395✔
143
    }
144
    gt->gt_short = data;
33,536✔
145
    KeyHeader *header = (KeyHeader *)data;
33,536✔
146

147
    if (header->hdr_version > GvCurrentVersion) goto failure;
33,536✔
148
    if (header->hdr_rev_major > GvCurrentRevision)
33,536✔
149
    {
150
        /* issue warning */
151
    }
152

153
    /* If we got here, then the geokey can be parsed */
154
    const int count = header->hdr_num_keys;
33,536✔
155

156
    if (count * sizeof(KeyEntry) >= (4 + MAX_VALUES) * sizeof(pinfo_t))
33,536✔
157
        goto failure;
×
158

159
    gt->gt_num_keys = count;
33,536✔
160
    gt->gt_version  = header->hdr_version;
33,536✔
161
    gt->gt_rev_major  = header->hdr_rev_major;
33,536✔
162
    gt->gt_rev_minor  = header->hdr_rev_minor;
33,536✔
163

164
    const int bufcount = count + MAX_KEYS; /* allow for expansion */
33,536✔
165

166
    /* Get the PARAMS Tags, if any */
167
    if (tif == NULL
33,536✔
168
        || !(gt->gt_methods.get)(tif, GTIFF_DOUBLEPARAMS,
33,536✔
169
                                 &gt->gt_ndoubles, &gt->gt_double ))
33,537✔
170
    {
171
        gt->gt_double=(double*)_GTIFcalloc(MAX_VALUES*sizeof(double));
25,091✔
172
        if (!gt->gt_double) goto failure;
25,093✔
173
    }
174
    else
175
    {
176
        if( gt->gt_ndoubles > MAX_VALUES )
8,444✔
177
            goto failure;
×
178
        /* resize data array so it can be extended if needed */
179
        gt->gt_double = (double*) _GTIFrealloc(gt->gt_double,
8,444✔
180
                                               (MAX_VALUES)*sizeof(double));
181
    }
182

183
    if ( tif == NULL
33,537✔
184
         || !(gt->gt_methods.get)(tif, GTIFF_ASCIIPARAMS,
33,537✔
185
                                  &tempData.tk_asciiParamsLength,
186
                                  &tempData.tk_asciiParams ))
187
    {
188
        tempData.tk_asciiParams         = 0;
15,544✔
189
        tempData.tk_asciiParamsLength   = 0;
15,544✔
190
    }
191
    else
192
    {
193
        /* last NULL doesn't count; "|" used for delimiter */
194
        if( tempData.tk_asciiParamsLength > 0
17,993✔
195
            && tempData.tk_asciiParams[tempData.tk_asciiParamsLength-1] == '\0')
17,993✔
196
        {
197
            --tempData.tk_asciiParamsLength;
17,992✔
198
        }
199
    }
200

201
    /* allocate space for GeoKey array and its index */
202
    gt->gt_keys = (GeoKey *)_GTIFcalloc( sizeof(GeoKey)*bufcount);
33,537✔
203
    if (!gt->gt_keys) goto failure;
33,537✔
204
    gt->gt_keyindex = (int *)_GTIFcalloc( sizeof(int)*(MAX_KEYINDEX+1));
33,537✔
205
    if (!gt->gt_keyindex) goto failure;
33,537✔
206

207
    /*  Loop to get all GeoKeys */
208
    KeyEntry *entptr = ((KeyEntry *)data) + 1;
33,537✔
209
    GeoKey *keyptr = gt->gt_keys;
33,537✔
210
    gt->gt_keymin = MAX_KEYINDEX;
33,537✔
211
    gt->gt_keymax = 0;
33,537✔
212
    for (int nIndex=1; nIndex<=count; nIndex++,entptr++)
150,304✔
213
    {
214
        if (!ReadKey(gt, &tempData, entptr, ++keyptr))
116,766✔
215
            goto failure;
×
216

217
        /* Set up the index (start at 1, since 0=unset) */
218
        gt->gt_keyindex[entptr->ent_key] = nIndex;
116,767✔
219
    }
220

221
    if( tempData.tk_asciiParams != NULL )
33,538✔
222
        _GTIFFree( tempData.tk_asciiParams );
17,993✔
223

224
    return gt;
33,536✔
225

226
  failure:
×
227
    /* Notify of error */
228
    if( tempData.tk_asciiParams != NULL )
×
229
        _GTIFFree( tempData.tk_asciiParams );
×
230
    GTIFFree (gt);
×
231
    return (GTIF *)0;
×
232
}
233

234
/**********************************************************************
235
 *
236
 *                        Private Routines
237
 *
238
 **********************************************************************/
239

240
/*
241
 * Given KeyEntry, read in the GeoKey value location and set up
242
 *  the Key structure, returning 0 if failure.
243
 */
244

245
static int ReadKey(GTIF* gt, TempKeyData* tempData,
116,767✔
246
                   KeyEntry* entptr, GeoKey* keyptr)
247
{
248
    keyptr->gk_key = entptr->ent_key;
116,767✔
249
    keyptr->gk_count = entptr->ent_count;
116,767✔
250
    int count = entptr->ent_count;
116,767✔
251
    const int offset = entptr->ent_val_offset;
116,767✔
252
    if (gt->gt_keymin > keyptr->gk_key)  gt->gt_keymin=keyptr->gk_key;
116,767✔
253
    if (gt->gt_keymax < keyptr->gk_key)  gt->gt_keymax=keyptr->gk_key;
116,767✔
254

255
    if (entptr->ent_location)
116,767✔
256
        keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,entptr->ent_location);
39,405✔
257
    else
258
        keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,GTIFF_GEOKEYDIRECTORY);
77,362✔
259

260
    switch (entptr->ent_location)
116,766✔
261
    {
262
        case GTIFF_LOCAL:
77,361✔
263
            /* store value into data value */
264
            if (count != 1 )
77,361✔
265
            {
266
                if( gt->gt_error_callback )
×
267
                {
268
                    gt->gt_error_callback(
×
269
                        gt,
270
                        LIBGEOTIFF_ERROR,
271
                        "Key %s of TIFFTagLocation=0 has count=%d, "
272
                        "whereas only 1 is legal.",
273
                        GTIFKeyName(keyptr->gk_key), count);
×
274
                }
275
                return 0;
×
276
            }
277
            memcpy(&keyptr->gk_data, &(entptr->ent_val_offset), sizeof(pinfo_t));
77,361✔
278
            break;
77,361✔
279
        case GTIFF_GEOKEYDIRECTORY:
×
280
            keyptr->gk_data = (char *)(gt->gt_short+offset);
×
281
            if (gt->gt_nshorts < offset+count)
×
282
            {
283
                if( gt->gt_error_callback )
×
284
                {
285
                    gt->gt_error_callback(
×
286
                        gt,
287
                        LIBGEOTIFF_ERROR,
288
                        "Key %s of type SHORT has offset=%d and count=%d, "
289
                        "but the GeoKeyDirectory tag has only %d values.",
290
                        GTIFKeyName(keyptr->gk_key),
×
291
                        offset, count, gt->gt_nshorts);
292
                }
293
                return 0;
×
294
            }
295
            break;
×
296
        case GTIFF_DOUBLEPARAMS:
17,842✔
297
            keyptr->gk_data = (char *)(gt->gt_double+offset);
17,842✔
298
            if (gt->gt_ndoubles < offset+count)
17,842✔
299
            {
300
                if( gt->gt_error_callback )
×
301
                {
302
                    gt->gt_error_callback(
×
303
                        gt,
304
                        LIBGEOTIFF_ERROR,
305
                        "Key %s of type SHORT has offset=%d and count=%d, "
306
                        "but the GeoDoubleParams tag has only %d values.",
307
                        GTIFKeyName(keyptr->gk_key),
×
308
                        offset, count, gt->gt_ndoubles);
309
                }
310
                return 0;
×
311
            }
312
            break;
17,842✔
313
        case GTIFF_ASCIIPARAMS:
21,564✔
314
            if( tempData->tk_asciiParams == NULL )
21,564✔
315
            {
316
                if( gt->gt_error_callback )
×
317
                {
318
                    gt->gt_error_callback(
×
319
                        gt,
320
                        LIBGEOTIFF_ERROR,
321
                        "Key %s is of type ASCII but GeoAsciiParams is "
322
                        "missing or corrupted.",
323
                        GTIFKeyName(keyptr->gk_key));
×
324
                }
325
                return 0;
×
326
            }
327
            if( offset + count == tempData->tk_asciiParamsLength + 1
21,564✔
328
                && count > 0 )
7✔
329
            {
330
                /* some vendors seem to feel they should not use the
331
                   terminating '|' char, but do include a terminating '\0'
332
                   which we lose in the low level reading code.
333
                   If this is the case, drop the extra character */
334
                count--;
7✔
335
            }
336
            else if (offset < tempData->tk_asciiParamsLength
21,557✔
337
                     && offset + count > tempData->tk_asciiParamsLength )
21,556✔
338
            {
339
                if( gt->gt_error_callback )
×
340
                {
341
                    gt->gt_error_callback(
×
342
                        gt,
343
                        LIBGEOTIFF_WARNING,
344
                        "Key %s of type ASCII has offset=%d and count=%d, but "
345
                        "the GeoAsciiParams tag has only %d bytes. "
346
                        "Truncating the value of the key.",
347
                        GTIFKeyName(keyptr->gk_key), offset, count,
×
348
                        tempData->tk_asciiParamsLength);
349
                }
350
                count = tempData->tk_asciiParamsLength - offset;
×
351
            }
352
            else if (offset + count > tempData->tk_asciiParamsLength)
21,557✔
353
            {
354
                if( gt->gt_error_callback )
×
355
                {
356
                    gt->gt_error_callback(
×
357
                        gt,
358
                        LIBGEOTIFF_ERROR,
359
                        "Key %s of type ASCII has offset=%d and count=%d, "
360
                        "but the GeoAsciiParams tag has only %d values.",
361
                        GTIFKeyName(keyptr->gk_key), offset, count,
×
362
                        tempData->tk_asciiParamsLength);
363
                }
364
                return 0;
×
365
            }
366

367
            keyptr->gk_count = MAX(1,count+1);
21,564✔
368
            keyptr->gk_data = (char *) _GTIFcalloc (keyptr->gk_count);
21,564✔
369

370
            _GTIFmemcpy (keyptr->gk_data,
21,564✔
371
                         tempData->tk_asciiParams + offset, count);
21,564✔
372
            if( keyptr->gk_data[MAX(0,count-1)] == '|' )
21,564✔
373
            {
374
                keyptr->gk_data[MAX(0,count-1)] = '\0';
21,557✔
375
                keyptr->gk_count = count;
21,557✔
376
            }
377
            else
378
                keyptr->gk_data[MAX(0,count)] = '\0';
7✔
379
            break;
21,564✔
UNCOV
380
        default:
×
UNCOV
381
            if( gt->gt_error_callback )
×
382
            {
383
                gt->gt_error_callback(
×
384
                    gt,
385
                    LIBGEOTIFF_ERROR,
386
                    "Key %d of unknown type.",
387
                    keyptr->gk_key);
388
            }
389
            return 0; /* failure */
×
390
    }
391
    keyptr->gk_size = _gtiff_size[keyptr->gk_type];
116,767✔
392

393
    return 1; /* success */
116,767✔
394
}
395

396
void *GTIFGetUserData(GTIF *gtif)
×
397
{
398
    return gtif->gt_user_data;
×
399
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc