LCOV - code coverage report
Current view: top level - frmts/ceos2 - ceosrecipe.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 156 250 62.4 %
Date: 2024-05-06 13:02:59 Functions: 9 11 81.8 %

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

Generated by: LCOV version 1.14