~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to frmts/pcidsk/gdal_edb.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: gdal_edb.cpp 20632 2010-09-16 19:49:24Z rouault $
 
3
 *
 
4
 * Project:  PCIDSK Database File
 
5
 * Purpose:  External Database access interface implementation (EDBFile).
 
6
 * Author:   Frank Warmerdam, warmerdam@pobox.com
 
7
 *
 
8
 ******************************************************************************
 
9
 * Copyright (c) 2010, Frank Warmerdam <warmerdam@pobox.com>
 
10
 *
 
11
 * Permission is hereby granted, free of charge, to any person obtaining a
 
12
 * copy of this software and associated documentation files (the "Software"),
 
13
 * to deal in the Software without restriction, including without limitation
 
14
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
15
 * and/or sell copies of the Software, and to permit persons to whom the
 
16
 * Software is furnished to do so, subject to the following conditions:
 
17
 *
 
18
 * The above copyright notice and this permission notice shall be included
 
19
 * in all copies or substantial portions of the Software.
 
20
 *
 
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
24
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
26
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
27
 * DEALINGS IN THE SOFTWARE.
 
28
 ****************************************************************************/
 
29
 
 
30
#include "cpl_conv.h"
 
31
#include "cpl_multiproc.h"
 
32
#include "gdal_priv.h"
 
33
#include "pcidsk.h"
 
34
 
 
35
CPL_CVSID("$Id: gdal_edb.cpp 20632 2010-09-16 19:49:24Z rouault $");
 
36
 
 
37
using namespace PCIDSK;
 
38
 
 
39
/************************************************************************/
 
40
/* ==================================================================== */
 
41
/*                            GDAL_EDBFile                              */
 
42
/* ==================================================================== */
 
43
/************************************************************************/
 
44
 
 
45
class GDAL_EDBFile : public EDBFile
 
46
{
 
47
    GDALDataset     *poDS;
 
48
 
 
49
public:
 
50
 
 
51
    GDAL_EDBFile( GDALDataset *poDSIn ) { poDS = poDSIn; }
 
52
    ~GDAL_EDBFile() { if( poDS ) Close(); }
 
53
 
 
54
    int Close() const;
 
55
    int GetWidth() const;
 
56
    int GetHeight() const;
 
57
    int GetChannels() const;
 
58
    int GetBlockWidth(int channel ) const;
 
59
    int GetBlockHeight(int channel ) const;
 
60
    eChanType GetType(int channel ) const;
 
61
    int ReadBlock(int channel,
 
62
                  int block_index, void *buffer,
 
63
                  int win_xoff, int win_yoff,
 
64
                  int win_xsize, int win_ysize );
 
65
    int WriteBlock( int channel, int block_index, void *buffer);
 
66
};
 
67
 
 
68
/************************************************************************/
 
69
/*                            GDAL_EDBOpen()                            */
 
70
/************************************************************************/
 
71
 
 
72
EDBFile *GDAL_EDBOpen( std::string osFilename, std::string osAccess )
 
73
 
 
74
{
 
75
    GDALDataset *poDS;
 
76
 
 
77
    if( osAccess == "r" )
 
78
        poDS = (GDALDataset *) GDALOpen( osFilename.c_str(), GA_ReadOnly );
 
79
    else
 
80
        poDS = (GDALDataset *) GDALOpen( osFilename.c_str(), GA_Update );
 
81
 
 
82
    if( poDS == NULL )
 
83
        ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() );
 
84
 
 
85
    return new GDAL_EDBFile( poDS );
 
86
}
 
87
 
 
88
/************************************************************************/
 
89
/*                               Close()                                */
 
90
/************************************************************************/
 
91
 
 
92
int GDAL_EDBFile::Close() const
 
93
 
 
94
{
 
95
    if( poDS != NULL )
 
96
    {
 
97
        delete poDS;
 
98
        ((GDAL_EDBFile*)this)->poDS = NULL;
 
99
    }
 
100
 
 
101
    return 1;
 
102
}
 
103
 
 
104
/************************************************************************/
 
105
/*                              GetWidth()                              */
 
106
/************************************************************************/
 
107
 
 
108
int GDAL_EDBFile::GetWidth() const
 
109
 
 
110
{
 
111
    return poDS->GetRasterXSize();
 
112
}
 
113
 
 
114
/************************************************************************/
 
115
/*                             GetHeight()                              */
 
116
/************************************************************************/
 
117
 
 
118
int GDAL_EDBFile::GetHeight() const
 
119
 
 
120
{
 
121
    return poDS->GetRasterYSize();
 
122
}
 
123
 
 
124
/************************************************************************/
 
125
/*                            GetChannels()                             */
 
126
/************************************************************************/
 
127
 
 
128
int GDAL_EDBFile::GetChannels() const
 
129
 
 
130
{
 
131
    return poDS->GetRasterCount();
 
132
}
 
133
 
 
134
/************************************************************************/
 
135
/*                           GetBlockWidth()                            */
 
136
/************************************************************************/
 
137
 
 
138
int GDAL_EDBFile::GetBlockWidth( int nChannel ) const
 
139
 
 
140
{
 
141
    int nWidth, nHeight;
 
142
 
 
143
    poDS->GetRasterBand(nChannel)->GetBlockSize( &nWidth, &nHeight );
 
144
 
 
145
    return nWidth;
 
146
}
 
147
 
 
148
/************************************************************************/
 
149
/*                           GetBlockHeight()                           */
 
150
/************************************************************************/
 
151
 
 
152
int GDAL_EDBFile::GetBlockHeight( int nChannel ) const
 
153
 
 
154
{
 
155
    int nWidth, nHeight;
 
156
 
 
157
    poDS->GetRasterBand(nChannel)->GetBlockSize( &nWidth, &nHeight );
 
158
 
 
159
    return nHeight;
 
160
}
 
161
 
 
162
/************************************************************************/
 
163
/*                              GetType()                               */
 
164
/************************************************************************/
 
165
 
 
166
eChanType GDAL_EDBFile::GetType( int nChannel ) const
 
167
{
 
168
    switch( poDS->GetRasterBand(nChannel)->GetRasterDataType() )
 
169
    {
 
170
      case GDT_Byte:
 
171
        return CHN_8U;
 
172
 
 
173
      case GDT_Int16:
 
174
        return CHN_16S;
 
175
 
 
176
      case GDT_UInt16:
 
177
        return CHN_16U;
 
178
 
 
179
      case GDT_Float32:
 
180
        return CHN_32R;
 
181
 
 
182
      case GDT_CInt16:
 
183
        return CHN_C16S;
 
184
 
 
185
      default:
 
186
        return CHN_UNKNOWN;
 
187
    }
 
188
}
 
189
 
 
190
/************************************************************************/
 
191
/*                             ReadBlock()                              */
 
192
/************************************************************************/
 
193
 
 
194
int GDAL_EDBFile::ReadBlock( int channel,
 
195
                             int block_index, void *buffer,
 
196
                             int win_xoff, int win_yoff,
 
197
                             int win_xsize, int win_ysize )
 
198
 
 
199
{
 
200
    GDALRasterBand *poBand = poDS->GetRasterBand(channel);
 
201
    int nBlockXSize, nBlockYSize;
 
202
    int nBlockX, nBlockY;
 
203
    int nWidthInBlocks;
 
204
    int nPixelOffset;
 
205
    int nLineOffset;
 
206
 
 
207
    if( GetType(channel) == CHN_UNKNOWN )
 
208
    {
 
209
        ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
 
210
                             GDALGetDataTypeName(poBand->GetRasterDataType()) );
 
211
    }
 
212
 
 
213
    poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
 
214
 
 
215
    nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
 
216
    
 
217
    nBlockX = block_index % nWidthInBlocks;
 
218
    nBlockY = block_index / nWidthInBlocks;
 
219
 
 
220
    nPixelOffset = GDALGetDataTypeSize(poBand->GetRasterDataType()) / 8;
 
221
    nLineOffset = win_xsize * nPixelOffset;
 
222
 
 
223
/* -------------------------------------------------------------------- */
 
224
/*      Are we reading a partial block at the edge of the database?     */
 
225
/*      If so, ensure we don't read off the database.                   */
 
226
/* -------------------------------------------------------------------- */
 
227
    if( nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize() )
 
228
        win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff;
 
229
 
 
230
    if( nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize() )
 
231
        win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff;
 
232
 
 
233
    CPLErr eErr = poBand->RasterIO( GF_Read, 
 
234
                                    nBlockX * nBlockXSize + win_xoff, 
 
235
                                    nBlockY * nBlockYSize + win_yoff,
 
236
                                    win_xsize, win_ysize, 
 
237
                                    buffer, win_xsize, win_ysize, 
 
238
                                    poBand->GetRasterDataType(),
 
239
                                    nPixelOffset, nLineOffset );
 
240
 
 
241
    if( eErr != CE_None )
 
242
    {
 
243
        ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() );
 
244
    }
 
245
 
 
246
    return 1;
 
247
}
 
248
 
 
249
/************************************************************************/
 
250
/*                             WriteBlock()                             */
 
251
/************************************************************************/
 
252
 
 
253
int GDAL_EDBFile::WriteBlock( int channel, int block_index, void *buffer)
 
254
 
 
255
{
 
256
    GDALRasterBand *poBand = poDS->GetRasterBand(channel);
 
257
    int nBlockXSize, nBlockYSize;
 
258
    int nBlockX, nBlockY;
 
259
    int nWinXSize, nWinYSize;
 
260
    int nWidthInBlocks;
 
261
 
 
262
    if( GetType(channel) == CHN_UNKNOWN )
 
263
    {
 
264
        ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
 
265
                             GDALGetDataTypeName(poBand->GetRasterDataType()) );
 
266
    }
 
267
 
 
268
    poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
 
269
 
 
270
    nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
 
271
    
 
272
    nBlockX = block_index % nWidthInBlocks;
 
273
    nBlockY = block_index / nWidthInBlocks;
 
274
 
 
275
/* -------------------------------------------------------------------- */
 
276
/*      Are we reading a partial block at the edge of the database?     */
 
277
/*      If so, ensure we don't read off the database.                   */
 
278
/* -------------------------------------------------------------------- */
 
279
    if( nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize() )
 
280
        nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize;
 
281
    else
 
282
        nWinXSize = nBlockXSize;
 
283
 
 
284
    if( nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize() )
 
285
        nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize;
 
286
    else
 
287
        nWinYSize = nBlockYSize;
 
288
 
 
289
    CPLErr eErr = poBand->RasterIO( GF_Write, 
 
290
                                    nBlockX * nBlockXSize, 
 
291
                                    nBlockY * nBlockYSize,
 
292
                                    nWinXSize, nWinYSize,
 
293
                                    buffer, nWinXSize, nWinYSize,
 
294
                                    poBand->GetRasterDataType(), 0, 0 );
 
295
 
 
296
    if( eErr != CE_None )
 
297
    {
 
298
        ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() );
 
299
    }
 
300
 
 
301
    return 1;
 
302
}