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