1 : /******************************************************************************
2 : * $Id: rcreatecopy.cpp 17425 2009-07-21 21:05:07Z rouault $
3 : *
4 : * Project: R Format Driver
5 : * Purpose: CreateCopy() implementation for R stats package object format.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2009, 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 "gdal_pam.h"
31 : #include "cpl_string.h"
32 :
33 : CPL_CVSID("$Id: rcreatecopy.cpp 17425 2009-07-21 21:05:07Z rouault $");
34 :
35 : /************************************************************************/
36 : /* ==================================================================== */
37 : /* Writer Implementation */
38 : /* ==================================================================== */
39 : /************************************************************************/
40 :
41 : /************************************************************************/
42 : /* RWriteInteger() */
43 : /************************************************************************/
44 :
45 360 : static void RWriteInteger( FILE *fp, int bASCII, int nValue )
46 :
47 : {
48 360 : if( bASCII )
49 : {
50 : char szOutput[50];
51 20 : sprintf( szOutput, "%d\n", nValue );
52 20 : VSIFWriteL( szOutput, 1, strlen(szOutput), fp );
53 : }
54 : else
55 : {
56 340 : CPL_MSBPTR32( &nValue );
57 340 : VSIFWriteL( &nValue, 4, 1, fp );
58 : }
59 360 : }
60 :
61 : /************************************************************************/
62 : /* RWriteString() */
63 : /************************************************************************/
64 :
65 36 : static void RWriteString( FILE *fp, int bASCII, const char *pszValue )
66 :
67 : {
68 36 : RWriteInteger( fp, bASCII, 4105 );
69 36 : RWriteInteger( fp, bASCII, (int) strlen(pszValue) );
70 :
71 36 : if( bASCII )
72 : {
73 2 : VSIFWriteL( pszValue, 1, strlen(pszValue), fp );
74 2 : VSIFWriteL( "\n", 1, 1, fp );
75 : }
76 : else
77 : {
78 34 : VSIFWriteL( pszValue, 1, (int) strlen(pszValue), fp );
79 : }
80 36 : }
81 :
82 : /************************************************************************/
83 : /* RCreateCopy() */
84 : /************************************************************************/
85 :
86 : GDALDataset *
87 18 : RCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
88 : int bStrict, char ** papszOptions,
89 : GDALProgressFunc pfnProgress, void * pProgressData )
90 :
91 : {
92 18 : int nBands = poSrcDS->GetRasterCount();
93 18 : int nXSize = poSrcDS->GetRasterXSize();
94 18 : int nYSize = poSrcDS->GetRasterYSize();
95 18 : int bASCII = CSLFetchBoolean( papszOptions, "ASCII", FALSE );
96 18 : int bCompressed = CSLFetchBoolean( papszOptions, "COMPRESS", !bASCII );
97 :
98 : /* -------------------------------------------------------------------- */
99 : /* Some some rudimentary checks */
100 : /* -------------------------------------------------------------------- */
101 :
102 : /* -------------------------------------------------------------------- */
103 : /* Setup the filename to actually use. We prefix with */
104 : /* /vsigzip/ if we want compressed output. */
105 : /* -------------------------------------------------------------------- */
106 18 : CPLString osAdjustedFilename;
107 :
108 18 : if( bCompressed )
109 17 : osAdjustedFilename = "/vsigzip/";
110 :
111 18 : osAdjustedFilename += pszFilename;
112 :
113 : /* -------------------------------------------------------------------- */
114 : /* Create the file. */
115 : /* -------------------------------------------------------------------- */
116 : FILE *fp;
117 :
118 18 : fp = VSIFOpenL( osAdjustedFilename, "wb" );
119 18 : if( fp == NULL )
120 : {
121 : CPLError( CE_Failure, CPLE_OpenFailed,
122 : "Unable to create file %s.\n",
123 0 : pszFilename );
124 0 : return NULL;
125 : }
126 :
127 : /* -------------------------------------------------------------------- */
128 : /* Write header with version, etc. */
129 : /* -------------------------------------------------------------------- */
130 18 : if( bASCII )
131 : {
132 1 : const char *pszHeader = "RDA2\nA\n";
133 1 : VSIFWriteL( pszHeader, 1, strlen(pszHeader), fp );
134 : }
135 : else
136 : {
137 17 : const char *pszHeader = "RDX2\nX\n";
138 17 : VSIFWriteL( pszHeader, 1, strlen(pszHeader), fp );
139 : }
140 :
141 18 : RWriteInteger( fp, bASCII, 2 );
142 18 : RWriteInteger( fp, bASCII, 133377 );
143 18 : RWriteInteger( fp, bASCII, 131840 );
144 :
145 : /* -------------------------------------------------------------------- */
146 : /* Establish the primary pairlist with one component object. */
147 : /* -------------------------------------------------------------------- */
148 18 : RWriteInteger( fp, bASCII, 1026 );
149 18 : RWriteInteger( fp, bASCII, 1 );
150 :
151 : /* -------------------------------------------------------------------- */
152 : /* Write the object name. Eventually we should derive this */
153 : /* from the filename, possible with override by a creation */
154 : /* option. */
155 : /* -------------------------------------------------------------------- */
156 18 : RWriteString( fp, bASCII, "gg" );
157 :
158 : /* -------------------------------------------------------------------- */
159 : /* For now we write the raster as a numeric array with */
160 : /* attributes (526). */
161 : /* -------------------------------------------------------------------- */
162 18 : RWriteInteger( fp, bASCII, 526 );
163 18 : RWriteInteger( fp, bASCII, nXSize * nYSize * nBands );
164 :
165 : /* -------------------------------------------------------------------- */
166 : /* Write the raster data. */
167 : /* -------------------------------------------------------------------- */
168 : double *padfScanline;
169 18 : CPLErr eErr = CE_None;
170 : int iLine;
171 :
172 18 : padfScanline = (double *) CPLMalloc( nXSize * sizeof(double) );
173 :
174 45 : for( int iBand = 0; iBand < nBands; iBand++ )
175 : {
176 27 : GDALRasterBand * poBand = poSrcDS->GetRasterBand( iBand+1 );
177 :
178 317 : for( iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ )
179 : {
180 : int iValue;
181 :
182 : eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
183 : padfScanline, nXSize, 1, GDT_Float64,
184 290 : sizeof(double), 0 );
185 :
186 290 : if( bASCII )
187 : {
188 420 : for( iValue = 0; iValue < nXSize; iValue++ )
189 : {
190 : char szValue[128];
191 400 : sprintf(szValue,"%.16g\n", padfScanline[iValue] );
192 400 : VSIFWriteL( szValue, 1, strlen(szValue), fp );
193 : }
194 : }
195 : else
196 : {
197 3170 : for( iValue = 0; iValue < nXSize; iValue++ )
198 2900 : CPL_MSBPTR64( padfScanline + iValue );
199 :
200 270 : VSIFWriteL( padfScanline, 8, nXSize, fp );
201 : }
202 :
203 290 : if( eErr == CE_None
204 : && !pfnProgress( (iLine+1) / (double) nYSize,
205 : NULL, pProgressData ) )
206 : {
207 0 : eErr = CE_Failure;
208 : CPLError( CE_Failure, CPLE_UserInterrupt,
209 0 : "User terminated CreateCopy()" );
210 : }
211 : }
212 : }
213 :
214 18 : CPLFree( padfScanline );
215 :
216 : /* -------------------------------------------------------------------- */
217 : /* Write out the dims attribute. */
218 : /* -------------------------------------------------------------------- */
219 18 : RWriteInteger( fp, bASCII, 1026 );
220 18 : RWriteInteger( fp, bASCII, 1 );
221 :
222 18 : RWriteString( fp, bASCII, "dim" );
223 :
224 18 : RWriteInteger( fp, bASCII, 13 );
225 18 : RWriteInteger( fp, bASCII, 3 );
226 18 : RWriteInteger( fp, bASCII, nXSize );
227 18 : RWriteInteger( fp, bASCII, nYSize );
228 18 : RWriteInteger( fp, bASCII, nBands );
229 :
230 18 : RWriteInteger( fp, bASCII, 254 );
231 :
232 : /* -------------------------------------------------------------------- */
233 : /* Terminate overall pairlist. */
234 : /* -------------------------------------------------------------------- */
235 18 : RWriteInteger( fp, bASCII, 254 );
236 :
237 : /* -------------------------------------------------------------------- */
238 : /* Cleanup. */
239 : /* -------------------------------------------------------------------- */
240 18 : VSIFCloseL( fp );
241 :
242 18 : if( eErr != CE_None )
243 0 : return NULL;
244 :
245 : /* -------------------------------------------------------------------- */
246 : /* Re-open dataset, and copy any auxilary pam information. */
247 : /* -------------------------------------------------------------------- */
248 : GDALPamDataset *poDS =
249 18 : (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly );
250 :
251 18 : if( poDS )
252 2 : poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
253 :
254 18 : return poDS;
255 : }
256 :
|