1010#include <stdlib.h>
1111#include <string.h>
1212#include <errno.h>
13+
14+ #define TINY_PDS_IMPL
1315#include <tinypds.h>
14- #include <fitsio.h>
1516
16- #ifndef ARRAY_SIZE
17- #define ARRAY_SIZE (a ) (sizeof(a) / sizeof(a[0]))
18- #endif
17+ #include "utils.h"
1918
2019const char * g_image_string = "IMAGE" ;
2120
2221void usage ()
2322{
24- fprintf (stderr , "rosetta_extract input.pds out.fits\n" );
23+ fprintf (stderr , "rosetta_extract name input.pds out.fits\n"
24+ " name is either IMAGE, SIGMA_MAP_IMAGE or QUALITY_MAP_IMAGE\n" );
2525}
26- /** Sample type **/
27- enum PDS_SAMPLE_TYPE
28- {
29- /** Unknown type. */
30- PDS_SAMPLE_UNKNOWN_TYPE = 0 ,
31- /** LSB unsigned integer. **/
32- PDS_SAMPLE_UINT_LSB ,
33- /** 32 bits IEEE float. **/
34- PDS_SAMPLE_FLOAT
35- };
3626/** Element type **/
3727enum PDS_ELEMENT_TYPE
3828{
3929 PDS_NONE = 0 ,
4030 PDS_ATTRIBUTE ,
4131 PDS_POINTER
4232};
43- /** PDS image structure. **/
44- typedef struct
45- {
46- /** Line count (height). **/
47- size_t lines ;
48- /** Samples per line (width). **/
49- size_t samples_per_line ;
50- /** Sample type (float, uint, etc...). **/
51- uint8_t sample_type ;
52- /** Sample size in bits (bits per pixel). **/
53- size_t sample_bits ;
54- /** Band count (component count). **/
55- size_t bands ;
56- } PDS_image ;
5733/** PDS parser payload. **/
5834typedef struct PDS_payload_t
5935{
@@ -82,13 +58,6 @@ typedef struct
8258 /** Attribute parser. */
8359 int (* parser )(const PDS_scalar * , PDS_payload * );
8460} PDS_attributes_infos ;
85- /**
86- * Returns a pointer to the last character of a null terminated string.
87- */
88- const char * str_last (const char * str )
89- {
90- return str + strlen (str ) - 1 ;
91- }
9261/**
9362 * Check if the PDS scalar holds an unsigned integer.
9463 * @param [in] scalar PDS scalar.
@@ -113,33 +82,6 @@ int record_size(const PDS_scalar *scalar, PDS_payload *payload)
11382 payload -> record_size = (size_t )scalar -> integer .value ;
11483 return 1 ;
11584}
116- /**
117- * Convert sample type name to PDS_SAMPLE_TYPE.
118- * @param [in] first Pointer to the first character of the type name.
119- * @param [in] last Pointer to the last character of the type name.
120- * @return PDS_SAMPLE_TYPE associated to the sample type name, or PDS_SAMPLE_UNKNOWN_TYPE if no type name matches.
121- */
122- uint8_t convert_type_name (const char * first , const char * last )
123- {
124- static const struct
125- {
126- const char * name ;
127- uint8_t type ;
128- } type_names [] =
129- {
130- { "LSB_UNSIGNED_INTEGER" , PDS_SAMPLE_UINT_LSB },
131- { "PC_REAL" , PDS_SAMPLE_FLOAT }
132- };
133- size_t i ;
134- for (i = 0 ; i < ARRAY_SIZE (type_names ); i ++ )
135- {
136- if (PDS_string_case_compare (type_names [i ].name , str_last (type_names [i ].name ), first , last ))
137- {
138- return type_names [i ].type ;
139- }
140- }
141- return PDS_SAMPLE_UNKNOWN_TYPE ;
142- }
14385/**
14486 * Get image record from PDS scalar.
14587 * @param [in] scalar PDS scalar.
@@ -372,7 +314,8 @@ int parse_scalar(const PDS_scalar *scalar, void *user_data)
372314}
373315/**
374316 * Global pointer parser.
375- * We are only interested in IMAGE pointer. The rest is ignored.
317+ * We are only interested in the pointer associated to the image.
318+ * The rest is ignored.
376319 * @param [in] first Pointer to the first character of the pointer name.
377320 * @param [in] last Pointer to the last character of the pointer name.
378321 * @param [in,out] user_data PDS parser user data.
@@ -430,7 +373,8 @@ int dummy_begin_end(void *user_data)
430373}
431374/**
432375 * Object start callback.
433- * Only IMAGE object is being parsed. All other objects are ignored.
376+ * Only the specified image object is being parsed.
377+ * All other objects are ignored.
434378 * @param [in] first Pointer to the first character of the object name.
435379 * @param [in] last Pointer to the last character of the object name.
436380 * @param [in,out] user_data PDS parser user data.
@@ -457,7 +401,8 @@ int object_begin(const char *first, const char *last, void *user_data)
457401}
458402/**
459403 * Object end callback.
460- * Only IMAGE object is being parsed. All other objects are ignored.
404+ * Only the specified image object is being parsed.
405+ * All other objects are ignored.
461406 * @param [in] first Pointer to the first character of the object name.
462407 * @param [in] last Pointer to the last character of the object name.
463408 * @param [in,out] user_data PDS parser user data.
@@ -523,132 +468,6 @@ int group_end(const char *first, const char *last, void *user_data)
523468 (void )last ;
524469 return 1 ;
525470}
526- /**
527- * Store file content to memory.
528- * @param [in] filename Source filename.
529- * @param [out] buffer Destination buffer.
530- * @param [out] len Bytes stored.
531- * @return 1 if the whole file content was succesfully tranfered to the destination buffer.
532- * 0 if an error occured.
533- */
534- int buffer_from_file (const char * filename , char * * buffer , size_t * len )
535- {
536- FILE * stream ;
537- char * data ;
538- size_t size ;
539-
540- * buffer = NULL ;
541- * len = 0 ;
542-
543- stream = fopen (filename , "rb" );
544- if (NULL == stream )
545- {
546- fprintf (stderr , "failed to open %s: %s\n" , filename , strerror (errno ));
547- return 0 ;
548- }
549-
550- fseek (stream , 0 , SEEK_END );
551- size = (size_t )ftell (stream );
552- fseek (stream , 0 , SEEK_SET );
553- size -= (size_t )ftell (stream );
554-
555- data = (char * )malloc (size );
556- if (data )
557- {
558- if (size == fread (data , 1 , size , stream ))
559- {
560- * buffer = data ;
561- * len = size ;
562- }
563- else
564- {
565- fprintf (stderr , "read error from %s : %s\n" , filename , strerror (errno ));
566- free (data );
567- }
568- }
569- else
570- {
571- fprintf (stderr , "allocation error : %s\n" , strerror (errno ));
572- }
573- fclose (stream );
574- return * buffer ? 1 : 0 ;
575- }
576- /**
577- * Convert embedded image to FITS.
578- * @param [in] filename Output filename.
579- * @param [in] buffer PDS buffer.
580- * @param [in] size PDS buffer size.
581- * @param [in] payload PDS payload.
582- * @return 1 upon success, 0 otherwise.
583- */
584- int write_image (const char * filename , char * buffer , size_t size , PDS_payload * payload )
585- {
586- size_t bytes_per_sample = payload -> image .sample_bits / 8 ;
587- size_t element_count = payload -> image .lines * payload -> image .samples_per_line ;
588- size_t byte_count = element_count * bytes_per_sample ;
589- size_t offset = (payload -> image_record - 1 ) * payload -> record_size ;
590- if ((offset + byte_count ) > size )
591- {
592- return 0 ;
593- }
594-
595- fitsfile * fptr ;
596- int status = 0 ;
597- long axis_count [] = { payload -> image .samples_per_line , payload -> image .lines };
598-
599- int bitpix , datatype ;
600- switch (payload -> image .sample_type )
601- {
602- case PDS_SAMPLE_UINT_LSB :
603- switch (payload -> image .sample_bits )
604- {
605- case 8 :
606- bitpix = BYTE_IMG ;
607- datatype = TBYTE ;
608- break ;
609- case 16 :
610- bitpix = USHORT_IMG ;
611- datatype = TUSHORT ;
612- break ;
613- case 32 :
614- bitpix = ULONG_IMG ;
615- datatype = TUINT ;
616- break ;
617- default :
618- fprintf (stderr , "Invalid type (uint)\n" );
619- return 0 ;
620- }
621- break ;
622- case PDS_SAMPLE_FLOAT :
623- switch (payload -> image .sample_bits )
624- {
625- // [todo] 16bit float => pfm or OpenEXR
626- case 32 :
627- bitpix = FLOAT_IMG ;
628- datatype = TFLOAT ;
629- break ;
630- case 64 :
631- bitpix = DOUBLE_IMG ;
632- datatype = TDOUBLE ;
633- break ;
634- default :
635- fprintf (stderr , "Invalid type (float)\n" );
636- return 0 ;
637- }
638- break ;
639- default :
640- fprintf (stderr , "Invalid type\n" );
641- return 0 ;
642- }
643-
644- fits_create_file (& fptr , filename , & status );
645- fits_create_img (fptr , bitpix , 2 , axis_count , & status );
646- fits_write_img (fptr , datatype , payload -> image .bands , element_count , buffer + offset , & status );
647- fits_close_file (fptr , & status );
648- fits_report_error (stderr , status );
649-
650- return status ? 0 : 1 ;
651- }
652471/*
653472 * Main entry point.
654473 */
@@ -662,13 +481,15 @@ int main(int argc, char **argv)
662481
663482 int ret ;
664483
665- if (3 != argc )
484+ if (4 != argc )
666485 {
667486 usage ();
668487 return EXIT_FAILURE ;
669488 }
670489
671- if (!buffer_from_file (argv [1 ], & buffer , & size ))
490+ g_image_string = argv [1 ];
491+
492+ if (!buffer_from_file (argv [2 ], & buffer , & size ))
672493 {
673494 return EXIT_FAILURE ;
674495 }
@@ -687,7 +508,7 @@ int main(int argc, char **argv)
687508 ret = PDS_parse (& callbacks , buffer , (int )size , & payload );
688509 if (ret )
689510 {
690- ret = write_image (argv [2 ], buffer , size , & payload );
511+ ret = write_image (argv [3 ], buffer , size , ( payload . image_record - 1 ) * payload . record_size , & payload . image );
691512 }
692513
693514 free (buffer );
0 commit comments