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: 2025-01-18 12:42:00 Functions: 9 11 81.8 %

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

Generated by: LCOV version 1.14