1 : /******************************************************************************
2 : * $Id: ceosrecipe.c 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: ASI CEOS Translator
5 : * Purpose: CEOS field layout recipes.
6 : * Author: Paul Lahaie, pjlahaie@atlsci.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2000, Atlantis Scientific Inc
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 "ceos.h"
31 :
32 : CPL_CVSID("$Id: ceosrecipe.c 10645 2007-01-18 02:22:39Z warmerdam $");
33 :
34 : /* Array of Datatypes and their names/values */
35 :
36 : typedef struct {
37 : char *String;
38 : int Type;
39 : } CeosStringType_t;
40 :
41 : typedef struct {
42 : int (*function)(CeosSARVolume_t *volume, void *token);
43 : void *token;
44 : const char *name;
45 : } RecipeFunctionData_t;
46 :
47 :
48 : CeosStringType_t CeosDataType[] = { { "IU1", __CEOS_TYP_UCHAR },
49 : { "IU2", __CEOS_TYP_USHORT },
50 : { "UI1", __CEOS_TYP_UCHAR },
51 : { "UI2", __CEOS_TYP_USHORT },
52 : { "CI*2", __CEOS_TYP_COMPLEX_CHAR },
53 : { "CI*4", __CEOS_TYP_COMPLEX_SHORT },
54 : { "CIS4", __CEOS_TYP_COMPLEX_SHORT },
55 : { "CI*8", __CEOS_TYP_COMPLEX_LONG },
56 : { "C*8", __CEOS_TYP_COMPLEX_FLOAT },
57 : { "R*4", __CEOS_TYP_FLOAT },
58 : { NULL, 0 } };
59 :
60 : CeosStringType_t CeosInterleaveType[] = { { "BSQ", __CEOS_IL_BAND },
61 : { " BSQ", __CEOS_IL_BAND },
62 : { "BIL", __CEOS_IL_LINE },
63 : { " BIL", __CEOS_IL_LINE },
64 : { NULL, 0 } };
65 :
66 : #define IMAGE_OPT { 63, 192, 18, 18 }
67 : #define IMAGE_JERS_OPT { 50, 192, 18, 18 } /* Some JERS data uses this instead of IMAGE_OPT */
68 : #define PROC_DATA_REC { 50, 11, 18, 20 }
69 : #define PROC_DATA_REC_ALT { 50, 11, 31, 20 }
70 : #define PROC_DATA_REC_ALT2 { 50, 11, 31, 50 } /* Some cases of ERS 1, 2 */
71 : #define DATA_SET_SUMMARY { 18, 10, 18, 20 }
72 :
73 : /* NOTE: This seems to be the generic recipe used for most things */
74 : CeosRecipeType_t RadarSatRecipe[] =
75 : {
76 : { __CEOS_REC_NUMCHANS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
77 : 233, 4, __CEOS_REC_TYP_I }, /* Number of channels */
78 : { __CEOS_REC_INTERLEAVE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
79 : 269, 4, __CEOS_REC_TYP_A }, /* Interleaving type */
80 : { __CEOS_REC_DATATYPE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
81 : 429, 4, __CEOS_REC_TYP_A }, /* Data type */
82 : { __CEOS_REC_BPR, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
83 : 0, 0, __CEOS_REC_TYP_A }, /* For Defeault CEOS, this is done using other vals */
84 : { __CEOS_REC_LINES, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
85 : 237, 8, __CEOS_REC_TYP_I }, /* How many lines */
86 : { __CEOS_REC_TBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
87 : 261, 4, __CEOS_REC_TYP_I },
88 : { __CEOS_REC_BBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
89 : 265, 4, __CEOS_REC_TYP_I }, /* Bottom border pixels */
90 : { __CEOS_REC_PPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
91 : 249, 8, __CEOS_REC_TYP_I }, /* Pixels per line */
92 : { __CEOS_REC_LBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
93 : 245, 4, __CEOS_REC_TYP_I }, /* Left Border Pixels */
94 : { __CEOS_REC_RBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
95 : 257, 4, __CEOS_REC_TYP_I }, /* Isn't available for RadarSAT */
96 : { __CEOS_REC_BPP, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
97 : 225, 4, __CEOS_REC_TYP_I }, /* Bytes Per Pixel */
98 : { __CEOS_REC_RPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
99 : 273, 2, __CEOS_REC_TYP_I }, /* Records per line */
100 : { __CEOS_REC_PPR, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
101 : 0, 0, __CEOS_REC_TYP_I }, /* Pixels Per Record -- need to fill record type */
102 : { __CEOS_REC_PDBPR, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
103 : 281, 8, __CEOS_REC_TYP_I }, /* pixel data bytes per record */
104 : { __CEOS_REC_IDS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
105 : 277, 4, __CEOS_REC_TYP_I }, /* Prefix data per record */
106 : { __CEOS_REC_FDL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
107 : 9, 4, __CEOS_REC_TYP_B }, /* Length of Imagry Options Header */
108 : { __CEOS_REC_PIXORD, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
109 : 0, 0, __CEOS_REC_TYP_I }, /* Must be calculated */
110 : { __CEOS_REC_LINORD, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
111 : 0, 0, __CEOS_REC_TYP_I }, /* Must be calculated */
112 : { __CEOS_REC_PRODTYPE, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
113 : 0, 0, __CEOS_REC_TYP_I },
114 :
115 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC,
116 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
117 :
118 : /* Some ERS-1 products use an alternate data record subtype2. */
119 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC_ALT,
120 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
121 :
122 : /* Yet another ERS-1 and ERS-2 alternate data record subtype2. */
123 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC_ALT2,
124 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
125 :
126 : { __CEOS_REC_SUFFIX_SIZE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
127 : 289, 4, __CEOS_REC_TYP_I }, /* Suffix data per record */
128 : { 0, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 } /* Last record is Zero */
129 : } ;
130 :
131 :
132 : CeosRecipeType_t JersRecipe[] =
133 : {
134 : { __CEOS_REC_NUMCHANS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
135 : 233, 4, __CEOS_REC_TYP_I }, /* Number of channels */
136 : { __CEOS_REC_INTERLEAVE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
137 : 269, 4, __CEOS_REC_TYP_A }, /* Interleaving type */
138 : { __CEOS_REC_DATATYPE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
139 : 429, 4, __CEOS_REC_TYP_A }, /* Data type */
140 : { __CEOS_REC_BPR, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
141 : 0, 0, __CEOS_REC_TYP_A }, /* For Defeault CEOS, this is done using other vals */
142 : { __CEOS_REC_LINES, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
143 : 237, 8, __CEOS_REC_TYP_I }, /* How many lines */
144 : { __CEOS_REC_TBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
145 : 261, 4, __CEOS_REC_TYP_I },
146 : { __CEOS_REC_BBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
147 : 265, 4, __CEOS_REC_TYP_I }, /* Bottom border pixels */
148 : { __CEOS_REC_PPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
149 : 249, 8, __CEOS_REC_TYP_I }, /* Pixels per line */
150 : { __CEOS_REC_LBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
151 : 245, 4, __CEOS_REC_TYP_I }, /* Left Border Pixels */
152 : { __CEOS_REC_RBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
153 : 257, 4, __CEOS_REC_TYP_I }, /* Isn't available for RadarSAT */
154 : { __CEOS_REC_BPP, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
155 : 225, 4, __CEOS_REC_TYP_I }, /* Bytes Per Pixel */
156 : { __CEOS_REC_RPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
157 : 273, 2, __CEOS_REC_TYP_I }, /* Records per line */
158 : { __CEOS_REC_PPR, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
159 : 0, 0, __CEOS_REC_TYP_I }, /* Pixels Per Record -- need to fill record type */
160 : { __CEOS_REC_PDBPR, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
161 : 281, 8, __CEOS_REC_TYP_I }, /* pixel data bytes per record */
162 : { __CEOS_REC_IDS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
163 : 277, 4, __CEOS_REC_TYP_I }, /* Prefix data per record */
164 : { __CEOS_REC_FDL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
165 : 9, 4, __CEOS_REC_TYP_B }, /* Length of Imagry Options Header */
166 : { __CEOS_REC_PIXORD, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
167 : 0, 0, __CEOS_REC_TYP_I }, /* Must be calculated */
168 : { __CEOS_REC_LINORD, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
169 : 0, 0, __CEOS_REC_TYP_I }, /* Must be calculated */
170 : { __CEOS_REC_PRODTYPE, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
171 : 0, 0, __CEOS_REC_TYP_I },
172 :
173 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC,
174 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
175 :
176 : { __CEOS_REC_SUFFIX_SIZE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_JERS_OPT,
177 : 289, 4, __CEOS_REC_TYP_I }, /* Suffix data per record */
178 : { 0, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 } /* Last record is Zero */
179 : } ;
180 :
181 : CeosRecipeType_t ScanSARRecipe[] =
182 : {
183 : { __CEOS_REC_NUMCHANS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
184 : 233, 4, __CEOS_REC_TYP_I }, /* Number of channels */
185 : { __CEOS_REC_INTERLEAVE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
186 : 269, 4, __CEOS_REC_TYP_A }, /* Interleaving type */
187 : { __CEOS_REC_DATATYPE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
188 : 429, 4, __CEOS_REC_TYP_A }, /* Data type */
189 : { __CEOS_REC_LINES, 1, __CEOS_ANY_FILE, DATA_SET_SUMMARY,
190 : 325, 8, __CEOS_REC_TYP_I }, /* How many lines */
191 : { __CEOS_REC_PPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
192 : 249, 8, __CEOS_REC_TYP_I }, /* Pixels per line */
193 : { __CEOS_REC_BPP, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
194 : 225, 4, __CEOS_REC_TYP_I }, /* Bytes Per Pixel */
195 : { __CEOS_REC_RPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
196 : 273, 2, __CEOS_REC_TYP_I }, /* Records per line */
197 : { __CEOS_REC_IDS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
198 : 277, 4, __CEOS_REC_TYP_I }, /* Prefix data per record */
199 : { __CEOS_REC_FDL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
200 : 9, 4, __CEOS_REC_TYP_B }, /* Length of Imagry Options Header */
201 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC,
202 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
203 : { __CEOS_REC_SUFFIX_SIZE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
204 : 289, 4, __CEOS_REC_TYP_I }, /* Suffix data per record */
205 : { 0, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 } /* Last record is Zero */
206 : } ;
207 :
208 : CeosRecipeType_t SIRCRecipe[] =
209 : {
210 : { __CEOS_REC_NUMCHANS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
211 : 233, 4, __CEOS_REC_TYP_I }, /* Number of channels */
212 : { __CEOS_REC_INTERLEAVE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
213 : 269, 4, __CEOS_REC_TYP_A }, /* Interleaving type */
214 : { __CEOS_REC_DATATYPE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
215 : 429, 4, __CEOS_REC_TYP_A }, /* Data type */
216 : { __CEOS_REC_LINES, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
217 : 237, 8, __CEOS_REC_TYP_I }, /* How many lines */
218 : { __CEOS_REC_TBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
219 : 261, 4, __CEOS_REC_TYP_I },
220 : { __CEOS_REC_BBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
221 : 265, 4, __CEOS_REC_TYP_I }, /* Bottom border pixels */
222 : { __CEOS_REC_PPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
223 : 249, 8, __CEOS_REC_TYP_I }, /* Pixels per line */
224 : { __CEOS_REC_LBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
225 : 245, 4, __CEOS_REC_TYP_I }, /* Left Border Pixels */
226 : { __CEOS_REC_RBP, 0, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
227 : 257, 4, __CEOS_REC_TYP_I }, /* Right Border Pixels */
228 : { __CEOS_REC_BPP, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
229 : 225, 4, __CEOS_REC_TYP_I }, /* Bytes Per Pixel */
230 : { __CEOS_REC_RPL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
231 : 273, 2, __CEOS_REC_TYP_I }, /* Records per line */
232 : { __CEOS_REC_IDS, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
233 : 277, 4, __CEOS_REC_TYP_I }, /* Prefix data per record */
234 : { __CEOS_REC_FDL, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
235 : 9, 4, __CEOS_REC_TYP_B }, /* Length of Imagry Options Header */
236 : { __CEOS_REC_RECORDSIZE, 1, __CEOS_IMAGRY_OPT_FILE, PROC_DATA_REC,
237 : 9, 4, __CEOS_REC_TYP_B }, /* The processed image record size */
238 : { __CEOS_REC_SUFFIX_SIZE, 1, __CEOS_IMAGRY_OPT_FILE, IMAGE_OPT,
239 : 289, 4, __CEOS_REC_TYP_I }, /* Suffix data per record */
240 :
241 : { 0, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 } /* Last record is Zero */
242 : } ;
243 :
244 : #undef PROC_DATA_REC
245 :
246 : static void ExtractInt( CeosRecord_t *record, int type, unsigned int offset, unsigned int length, int *value );
247 :
248 : static char *ExtractString( CeosRecord_t *record, unsigned int offset, unsigned int length, char *string );
249 :
250 : static int GetCeosStringType(const CeosStringType_t *CeosType, const char *string);
251 :
252 : static int SIRCRecipeFCN( CeosSARVolume_t *volume, void *token );
253 : static int PALSARRecipeFCN( CeosSARVolume_t *volume, void *token );
254 :
255 : Link_t *RecipeFunctions = NULL;
256 :
257 : void RegisterRecipes( void )
258 1 : {
259 :
260 1 : AddRecipe( SIRCRecipeFCN, SIRCRecipe, "SIR-C" );
261 1 : AddRecipe( ScanSARRecipeFCN, ScanSARRecipe, "ScanSAR" );
262 1 : AddRecipe( CeosDefaultRecipe, RadarSatRecipe, "RadarSat" );
263 1 : AddRecipe( CeosDefaultRecipe, JersRecipe, "Jers" );
264 1 : AddRecipe( PALSARRecipeFCN, RadarSatRecipe, "PALSAR-ALOS" );
265 : /* AddRecipe( CeosDefaultRecipe, AtlantisRecipe ); */
266 1 : }
267 :
268 : void FreeRecipes( void )
269 :
270 1 : {
271 : Link_t *link;
272 :
273 6 : for( link = RecipeFunctions; link != NULL; link = link->next )
274 5 : HFree( link->object );
275 :
276 1 : DestroyList( RecipeFunctions );
277 1 : RecipeFunctions = NULL;
278 1 : }
279 :
280 : void AddRecipe( int (*function)(CeosSARVolume_t *volume,
281 : void *token),
282 : void *token,
283 : const char *name )
284 5 : {
285 :
286 : RecipeFunctionData_t *TempData;
287 :
288 : Link_t *Link;
289 :
290 5 : TempData = HMalloc( sizeof( RecipeFunctionData_t ) );
291 :
292 5 : TempData->function = function;
293 5 : TempData->token = token;
294 5 : TempData->name = name;
295 :
296 5 : Link = ceos2CreateLink( TempData );
297 :
298 5 : if( RecipeFunctions == NULL)
299 : {
300 1 : RecipeFunctions = Link;
301 : } else {
302 4 : RecipeFunctions = InsertLink( RecipeFunctions, Link );
303 : }
304 5 : }
305 :
306 : int CeosDefaultRecipe( CeosSARVolume_t *volume, void *token )
307 2 : {
308 : CeosRecipeType_t *recipe;
309 : CeosRecord_t *record;
310 : CeosTypeCode_t TypeCode;
311 2 : struct CeosSARImageDesc *ImageDesc = &(volume->ImageDesc);
312 : char temp_str[1024];
313 : int i, temp_int;
314 :
315 : #define DoExtractInt(a) ExtractInt( record, recipe[i].Type, recipe[i].Offset, recipe[i].Length, &a)
316 :
317 2 : if(token == NULL)
318 : {
319 0 : return 0;
320 : }
321 :
322 2 : memset(ImageDesc, 0, sizeof( struct CeosSARImageDesc ) );
323 :
324 : /* temp_imagerecipe = (CeosSARImageDescRecipe_t *) token;
325 : recipe = temp_imagerecipe->Recipe; */
326 :
327 2 : recipe = token;
328 :
329 46 : for(i = 0; recipe[i].ImageDescValue != 0; i++ )
330 : {
331 44 : if(recipe[i].Override)
332 : {
333 26 : TypeCode.UCharCode.Subtype1 = recipe[i].TypeCode.Subtype1;
334 26 : TypeCode.UCharCode.Type = recipe[i].TypeCode.Type;
335 26 : TypeCode.UCharCode.Subtype2 = recipe[i].TypeCode.Subtype2;
336 26 : TypeCode.UCharCode.Subtype3 = recipe[i].TypeCode.Subtype3;
337 :
338 26 : record = FindCeosRecord( volume->RecordList, TypeCode, recipe[i].FileId, -1, -1 );
339 :
340 26 : if(record == NULL)
341 : {
342 13 : temp_int = 0;
343 : } else {
344 :
345 13 : switch( recipe[i].ImageDescValue )
346 : {
347 : case __CEOS_REC_NUMCHANS:
348 1 : DoExtractInt( ImageDesc->NumChannels );
349 1 : break;
350 : case __CEOS_REC_LINES:
351 1 : DoExtractInt( ImageDesc->Lines );
352 1 : break;
353 : case __CEOS_REC_BPP:
354 1 : DoExtractInt( ImageDesc->BytesPerPixel );
355 1 : break;
356 : case __CEOS_REC_RPL:
357 1 : DoExtractInt( ImageDesc->RecordsPerLine );
358 1 : break;
359 : case __CEOS_REC_PDBPR:
360 1 : DoExtractInt( ImageDesc->PixelDataBytesPerRecord );
361 1 : break;
362 : case __CEOS_REC_FDL:
363 1 : DoExtractInt( ImageDesc->FileDescriptorLength );
364 1 : break;
365 : case __CEOS_REC_IDS:
366 1 : DoExtractInt( ImageDesc->ImageDataStart );
367 : /*
368 : ** This is really reading the quantity of prefix data
369 : ** per data record. We want the offset from the very
370 : ** beginning of the record to the data, so we add another
371 : ** 12 to that. I think some products incorrectly indicate
372 : ** 192 (prefix+12) instead of 180 so if we see 192 assume
373 : ** the 12 bytes of record start data has already been
374 : ** added. Frank Warmerdam.
375 : */
376 1 : if( ImageDesc->ImageDataStart != 192 )
377 1 : ImageDesc->ImageDataStart += 12;
378 1 : break;
379 : case __CEOS_REC_SUFFIX_SIZE:
380 1 : DoExtractInt( ImageDesc->ImageSuffixData );
381 1 : break;
382 : case __CEOS_REC_RECORDSIZE:
383 2 : DoExtractInt( ImageDesc->BytesPerRecord );
384 2 : break;
385 : case __CEOS_REC_PPL:
386 1 : DoExtractInt( ImageDesc->PixelsPerLine );
387 1 : break;
388 : case __CEOS_REC_TBP:
389 0 : DoExtractInt( ImageDesc->TopBorderPixels );
390 0 : break;
391 : case __CEOS_REC_BBP:
392 0 : DoExtractInt( ImageDesc->BottomBorderPixels );
393 0 : break;
394 : case __CEOS_REC_LBP:
395 0 : DoExtractInt( ImageDesc->LeftBorderPixels );
396 0 : break;
397 : case __CEOS_REC_RBP:
398 0 : DoExtractInt( ImageDesc->RightBorderPixels );
399 0 : break;
400 : case __CEOS_REC_INTERLEAVE:
401 1 : ExtractString( record, recipe[i].Offset, recipe[i].Length, temp_str );
402 :
403 1 : ImageDesc->ChannelInterleaving = GetCeosStringType( CeosInterleaveType, temp_str );
404 1 : break;
405 : case __CEOS_REC_DATATYPE:
406 1 : ExtractString( record, recipe[i].Offset, recipe[i].Length, temp_str );
407 :
408 1 : ImageDesc->DataType = GetCeosStringType( CeosDataType, temp_str );
409 : break;
410 : }
411 :
412 : }
413 : }
414 : }
415 :
416 : /* Some files (Telaviv) don't record the number of pixel groups per line.
417 : * Try to derive it from the size of a data group, and the number of
418 : * bytes of pixel data if necessary.
419 : */
420 :
421 2 : if( ImageDesc->PixelsPerLine == 0
422 : && ImageDesc->PixelDataBytesPerRecord != 0
423 : && ImageDesc->BytesPerPixel != 0 )
424 : {
425 0 : ImageDesc->PixelsPerLine =
426 : ImageDesc->PixelDataBytesPerRecord / ImageDesc->BytesPerPixel;
427 0 : CPLDebug( "SAR_CEOS", "Guessing PixelPerLine to be %d\n",
428 : ImageDesc->PixelsPerLine );
429 : }
430 :
431 : /* Some files don't have the BytesPerRecord stuff, so we calculate it if possible */
432 :
433 2 : if( ImageDesc->BytesPerRecord == 0 && ImageDesc->RecordsPerLine == 1 &&
434 : ImageDesc->PixelsPerLine > 0 && ImageDesc->BytesPerPixel > 0 )
435 : {
436 : CeosRecord_t *img_rec;
437 :
438 0 : ImageDesc->BytesPerRecord = ImageDesc->PixelsPerLine *
439 : ImageDesc->BytesPerPixel + ImageDesc->ImageDataStart +
440 : ImageDesc->ImageSuffixData ;
441 :
442 0 : TypeCode.UCharCode.Subtype1 = 0xed;
443 0 : TypeCode.UCharCode.Type = 0xed;
444 0 : TypeCode.UCharCode.Subtype2 = 0x12;
445 0 : TypeCode.UCharCode.Subtype3 = 0x12;
446 :
447 0 : img_rec = FindCeosRecord( volume->RecordList, TypeCode,
448 : __CEOS_IMAGRY_OPT_FILE, -1, -1 );
449 0 : if( img_rec == NULL )
450 : {
451 0 : CPLDebug( "SAR_CEOS",
452 : "Unable to find imagery rec to check record length." );
453 0 : return 0;
454 : }
455 :
456 0 : if( img_rec->Length != ImageDesc->BytesPerRecord )
457 : {
458 0 : CPLDebug( "SAR_CEOS",
459 : "Guessed record length (%d) did not match\n"
460 : "actual imagery record length (%d), recipe fails.",
461 : ImageDesc->BytesPerRecord, img_rec->Length );
462 0 : return 0;
463 : }
464 : }
465 :
466 2 : if( ImageDesc->PixelsPerRecord == 0 &&
467 : ImageDesc->BytesPerRecord != 0 && ImageDesc->BytesPerPixel != 0 )
468 : {
469 1 : ImageDesc->PixelsPerRecord = ( ( ImageDesc->BytesPerRecord -
470 : (ImageDesc->ImageSuffixData +
471 : ImageDesc->ImageDataStart )) /
472 : ImageDesc->BytesPerPixel );
473 :
474 1 : if(ImageDesc->PixelsPerRecord > ImageDesc->PixelsPerLine)
475 0 : ImageDesc->PixelsPerRecord = ImageDesc->PixelsPerLine;
476 : }
477 :
478 : /* If we didn't get a data type, try guessing. */
479 2 : if( ImageDesc->DataType == 0
480 : && ImageDesc->BytesPerPixel != 0
481 : && ImageDesc->NumChannels != 0 )
482 : {
483 0 : int nDataTypeSize = ImageDesc->BytesPerPixel / ImageDesc->NumChannels;
484 :
485 0 : if( nDataTypeSize == 1 )
486 0 : ImageDesc->DataType = __CEOS_TYP_UCHAR;
487 0 : else if( nDataTypeSize == 2 )
488 0 : ImageDesc->DataType = __CEOS_TYP_USHORT;
489 : }
490 :
491 : /* Sanity checking */
492 :
493 2 : if( ImageDesc->PixelsPerLine == 0 || ImageDesc->Lines == 0 ||
494 : ImageDesc->RecordsPerLine == 0 || ImageDesc->ImageDataStart == 0 ||
495 : ImageDesc->FileDescriptorLength == 0 || ImageDesc->DataType == 0 ||
496 : ImageDesc->NumChannels == 0 || ImageDesc->BytesPerPixel == 0 ||
497 : ImageDesc->ChannelInterleaving == 0 || ImageDesc->BytesPerRecord == 0)
498 : {
499 1 : return 0;
500 : } else {
501 :
502 1 : ImageDesc->ImageDescValid = TRUE;
503 1 : return 1;
504 : }
505 : }
506 :
507 : int ScanSARRecipeFCN( CeosSARVolume_t *volume, void *token )
508 0 : {
509 0 : struct CeosSARImageDesc *ImageDesc = &(volume->ImageDesc);
510 :
511 0 : memset( ImageDesc, 0, sizeof( struct CeosSARImageDesc ) );
512 :
513 0 : if( CeosDefaultRecipe( volume, token ) )
514 : {
515 0 : ImageDesc->Lines *= 2;
516 0 : return 1;
517 : }
518 :
519 0 : return 0;
520 : }
521 :
522 : static int SIRCRecipeFCN( CeosSARVolume_t *volume, void *token )
523 0 : {
524 0 : struct CeosSARImageDesc *ImageDesc = &(volume->ImageDesc);
525 : CeosTypeCode_t TypeCode;
526 : CeosRecord_t *record;
527 : char szSARDataFormat[29];
528 :
529 0 : memset( ImageDesc, 0, sizeof( struct CeosSARImageDesc ) );
530 :
531 : /* -------------------------------------------------------------------- */
532 : /* First, we need to check if the "SAR Data Format Type */
533 : /* identifier" is set to "COMPRESSED CROSS-PRODUCTS" which is */
534 : /* pretty idiosyncratic to SIRC products. It might also appear */
535 : /* for some other similarly encoded Polarimetric data I suppose. */
536 : /* -------------------------------------------------------------------- */
537 : /* IMAGE_OPT */
538 0 : TypeCode.UCharCode.Subtype1 = 63;
539 0 : TypeCode.UCharCode.Type = 192;
540 0 : TypeCode.UCharCode.Subtype2 = 18;
541 0 : TypeCode.UCharCode.Subtype3 = 18;
542 :
543 0 : record = FindCeosRecord( volume->RecordList, TypeCode,
544 : __CEOS_IMAGRY_OPT_FILE, -1, -1 );
545 0 : if( record == NULL )
546 0 : return 0;
547 :
548 0 : ExtractString( record, 401, 28, szSARDataFormat );
549 0 : if( !EQUALN( szSARDataFormat, "COMPRESSED CROSS-PRODUCTS", 25) )
550 0 : return 0;
551 :
552 : /* -------------------------------------------------------------------- */
553 : /* Apply normal handling... */
554 : /* -------------------------------------------------------------------- */
555 0 : CeosDefaultRecipe( volume, token );
556 :
557 : /* -------------------------------------------------------------------- */
558 : /* Make sure this looks like the SIRC product we are expecting. */
559 : /* -------------------------------------------------------------------- */
560 0 : if( ImageDesc->BytesPerPixel != 10 )
561 0 : return 0;
562 :
563 : /* -------------------------------------------------------------------- */
564 : /* Then fix up a few values. */
565 : /* -------------------------------------------------------------------- */
566 : /* It seems the bytes of pixel data per record is just wrong. Fix. */
567 0 : ImageDesc->PixelDataBytesPerRecord =
568 : ImageDesc->BytesPerPixel * ImageDesc->PixelsPerLine;
569 :
570 0 : ImageDesc->DataType = __CEOS_TYP_CCP_COMPLEX_FLOAT;
571 :
572 : /* -------------------------------------------------------------------- */
573 : /* Sanity checking */
574 : /* -------------------------------------------------------------------- */
575 0 : if( ImageDesc->PixelsPerLine == 0 || ImageDesc->Lines == 0 ||
576 : ImageDesc->RecordsPerLine == 0 || ImageDesc->ImageDataStart == 0 ||
577 : ImageDesc->FileDescriptorLength == 0 || ImageDesc->DataType == 0 ||
578 : ImageDesc->NumChannels == 0 || ImageDesc->BytesPerPixel == 0 ||
579 : ImageDesc->ChannelInterleaving == 0 || ImageDesc->BytesPerRecord == 0)
580 : {
581 0 : return 0;
582 : } else {
583 :
584 0 : ImageDesc->ImageDescValid = TRUE;
585 0 : return 1;
586 : }
587 : }
588 :
589 : static int PALSARRecipeFCN( CeosSARVolume_t *volume, void *token )
590 1 : {
591 1 : struct CeosSARImageDesc *ImageDesc = &(volume->ImageDesc);
592 : CeosTypeCode_t TypeCode;
593 : CeosRecord_t *record;
594 : char szSARDataFormat[29], szProduct[32];
595 :
596 1 : memset( ImageDesc, 0, sizeof( struct CeosSARImageDesc ) );
597 :
598 : /* -------------------------------------------------------------------- */
599 : /* First, we need to check if the "SAR Data Format Type */
600 : /* identifier" is set to "COMPRESSED CROSS-PRODUCTS" which is */
601 : /* pretty idiosyncratic to SIRC products. It might also appear */
602 : /* for some other similarly encoded Polarimetric data I suppose. */
603 : /* -------------------------------------------------------------------- */
604 : /* IMAGE_OPT */
605 1 : TypeCode.UCharCode.Subtype1 = 63;
606 1 : TypeCode.UCharCode.Type = 192;
607 1 : TypeCode.UCharCode.Subtype2 = 18;
608 1 : TypeCode.UCharCode.Subtype3 = 18;
609 :
610 1 : record = FindCeosRecord( volume->RecordList, TypeCode,
611 : __CEOS_IMAGRY_OPT_FILE, -1, -1 );
612 1 : if( record == NULL )
613 0 : return 0;
614 :
615 1 : ExtractString( record, 401, 28, szSARDataFormat );
616 1 : if( !EQUALN( szSARDataFormat, "INTEGER*18 ", 25) )
617 1 : return 0;
618 :
619 0 : ExtractString( record, 49, 16, szProduct );
620 0 : if( !EQUALN( szProduct, "ALOS-", 5 ) )
621 0 : return 0;
622 :
623 : /* -------------------------------------------------------------------- */
624 : /* Apply normal handling... */
625 : /* -------------------------------------------------------------------- */
626 0 : CeosDefaultRecipe( volume, token );
627 :
628 : /* -------------------------------------------------------------------- */
629 : /* Make sure this looks like the SIRC product we are expecting. */
630 : /* -------------------------------------------------------------------- */
631 0 : if( ImageDesc->BytesPerPixel != 18 )
632 0 : return 0;
633 :
634 : /* -------------------------------------------------------------------- */
635 : /* Then fix up a few values. */
636 : /* -------------------------------------------------------------------- */
637 0 : ImageDesc->DataType = __CEOS_TYP_PALSAR_COMPLEX_SHORT;
638 0 : ImageDesc->NumChannels = 6;
639 :
640 : /* -------------------------------------------------------------------- */
641 : /* Sanity checking */
642 : /* -------------------------------------------------------------------- */
643 0 : if( ImageDesc->PixelsPerLine == 0 || ImageDesc->Lines == 0 ||
644 : ImageDesc->RecordsPerLine == 0 || ImageDesc->ImageDataStart == 0 ||
645 : ImageDesc->FileDescriptorLength == 0 || ImageDesc->DataType == 0 ||
646 : ImageDesc->NumChannels == 0 || ImageDesc->BytesPerPixel == 0 ||
647 : ImageDesc->ChannelInterleaving == 0 || ImageDesc->BytesPerRecord == 0)
648 : {
649 0 : return 0;
650 : } else {
651 :
652 0 : ImageDesc->ImageDescValid = TRUE;
653 0 : return 1;
654 : }
655 : }
656 :
657 : void GetCeosSARImageDesc( CeosSARVolume_t *volume )
658 1 : {
659 : Link_t *link;
660 : RecipeFunctionData_t *rec_data;
661 : int (*function)(CeosSARVolume_t *volume, void *token);
662 :
663 1 : if( RecipeFunctions == NULL )
664 : {
665 1 : RegisterRecipes();
666 : }
667 :
668 1 : if(RecipeFunctions == NULL )
669 : {
670 0 : return ;
671 : }
672 :
673 3 : for(link = RecipeFunctions; link != NULL; link = link->next)
674 : {
675 3 : if(link->object)
676 : {
677 3 : rec_data = link->object;
678 3 : function = rec_data->function;
679 3 : if(( *function )( volume, rec_data->token ) )
680 : {
681 1 : CPLDebug( "CEOS", "Using recipe '%s'.",
682 : rec_data->name );
683 1 : return;
684 : }
685 : }
686 : }
687 :
688 0 : return ;
689 :
690 : }
691 :
692 :
693 : static void ExtractInt(CeosRecord_t *record, int type, unsigned int offset, unsigned int length, int *value)
694 11 : {
695 : void *buffer;
696 : char format[32];
697 :
698 11 : buffer = HMalloc( length + 1 );
699 :
700 11 : switch(type)
701 : {
702 : case __CEOS_REC_TYP_A:
703 0 : sprintf( format, "A%u", length );
704 0 : GetCeosField( record, offset, format, buffer );
705 0 : *value = atoi( buffer );
706 0 : break;
707 : case __CEOS_REC_TYP_B:
708 3 : sprintf( format, "B%u", length );
709 : #ifdef notdef
710 : GetCeosField( record, offset, format, buffer );
711 : if( length <= 4 )
712 : CeosToNative( value, buffer, length, length );
713 : else
714 : *value = 0;
715 : #else
716 3 : GetCeosField( record, offset, format, value );
717 : #endif
718 3 : break;
719 : case __CEOS_REC_TYP_I:
720 8 : sprintf( format, "I%u", length );
721 8 : GetCeosField( record, offset, format, value );
722 : break;
723 : }
724 :
725 11 : HFree( buffer );
726 :
727 11 : }
728 :
729 : static char *ExtractString( CeosRecord_t *record, unsigned int offset, unsigned int length, char *string )
730 3 : {
731 : char format[12];
732 :
733 3 : if(string == NULL)
734 : {
735 0 : string = HMalloc( length + 1 );
736 : }
737 :
738 3 : sprintf( format, "A%u", length );
739 :
740 3 : GetCeosField( record, offset, format, string );
741 :
742 3 : return string;
743 : }
744 :
745 : static int GetCeosStringType(const CeosStringType_t *CeosStringType, const char *string)
746 2 : {
747 : int i;
748 :
749 3 : for(i = 0;CeosStringType[i].String != NULL;i++)
750 : {
751 3 : if(strncmp(CeosStringType[i].String ,string, strlen( CeosStringType[i].String ) ) == 0 )
752 : {
753 2 : return CeosStringType[i].Type;
754 : }
755 : }
756 :
757 0 : return 0;
758 : }
|