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

Generated by: LCOV version 1.14